ADR-340: Add PassFilter/MinMaxFilter/NormalFilter and VariationGenerator randomization primitives - #254
Conversation
…tor randomization primitives Precision-quantized rejection sampling (PassFilter.quantize()) and seed/name-hash-derived formulas (should_vary/generate/generate_int/choose) per ml/_spec_OopPipeline.md. PassFilter is concrete (uniform density=1.0); MinMaxFilter is a semantic subclass with no added behavior; NormalFilter overrides density() with a Gaussian PDF used as VariationGenerator.generate()'s rejection-sampling acceptance probability -- resolves the spec's open NormalFilter-shape ambiguity conservatively (explicit min_val/max_val/mean/std, no implicit bounds heuristic).
jodavis-claude
left a comment
There was a problem hiding this comment.
Reviewed against ADR-340's exit criteria (ml/_spec_OopPipeline.md "## Tasks" section) and the Precision-quantized rejection sampling / Seed-based randomisation with pass filters design decisions.
All four exit criteria are met: PassFilter/MinMaxFilter/NormalFilter compute the quantization grid at construction; VariationGenerator implements should_vary/generate/generate_int/choose per the spec's formulas, with generate() raising ValueError after 1000 attempts; the independence property has a dedicated test; and all tests are test-first in ml/test/pipeline/core/. Verified mypy --strict pipeline test (clean) and pytest test/ (62 passed) both pass locally.
No correctness, fault-tolerance, or security issues found. Two minor, non-blocking style notes below.
jodavis-claude
left a comment
There was a problem hiding this comment.
Sign-off review — PR #254 (ADR-340)
No new commits since the first-pass review; re-verified independently from the shared worktree: cd ml && python3 -m mypy --strict pipeline test (clean, 12 source files) and cd ml && python3 -m pytest test/ (62 passed, no regressions).
Prior review threads (both Priority 6/style-only, explicitly non-blocking):
NormalFilter.__init__constructor-argument ordering (mean, std, min_val, max_val) vs.PassFilter'smin_val, max_val— not addressed in code, but non-blocking per CONTRIBUTING.md's review priority ordering (style is noted, not enforced). Resolved with an acknowledging reply.- Independence test not exercising the "adding a variable" half of the exit criterion's wording (only reordering) — same disposition: non-blocking, resolved with an acknowledging reply.
Re-scanned both modified files (ml/pipeline/core/randomization.py, ml/test/pipeline/core/test_randomization.py) for new Priority 1-4 issues (correctness/fault-tolerance, security, performance, documentation): none found. Exception paths (min_val > max_val, std <= 0, empty options, 1000-attempt exhaustion in both generate/generate_int) all raise ValueError explicitly; no shared mutable state across calls so the independence property holds by construction; no I/O, no injection surface, no sensitive data. Module docstring correctly cites the spec decisions it implements; no _doc_*.md update expected or needed for this task.
Outcome: signed off. All exit criteria met, no outstanding Priority 1-4 issues, both prior threads resolved.
Precision-quantized rejection sampling (PassFilter.quantize()) and seed/name-hash-derived formulas (should_vary/generate/generate_int/choose) per ml/_spec_OopPipeline.md. PassFilter is concrete (uniform density=1.0); MinMaxFilter is a semantic subclass with no added behavior; NormalFilter overrides density() with a Gaussian PDF used as VariationGenerator.generate()'s rejection-sampling acceptance probability -- resolves the spec's open NormalFilter-shape ambiguity conservatively (explicit min_val/max_val/mean/std, no implicit bounds heuristic).
Stack created with GitHub Stacks CLI • Give Feedback 💬