Overview
Phase 2 (of 4) of the test-mode size-realistic-samples feature: implement the PYAUTO_TEST_MODE_SAMPLES knob so PYAUTO_TEST_MODE=2/3 bypass runs write a samples.csv whose row count and byte size match a production Nautilus SLaM stage (N ~ 10k–100k), making cold SLaM runs instant while keeping resume-overhead profiling honest. The design is locked — implement D1–D4 from the phase 1 issue verbatim: #1378 (comment) (phase 1 record: PyAutoMind complete/2026/07/test-mode-representative-samples-phase-1-design.md).
Blocked at creation: PyAutoFit is claimed by aggregator-sqlite (#1377). Parked in PyAutoMind planned.md; starts when the claim frees.
Plan
- PyAutoConf (PR 1, merges first):
test_mode_samples() accessor in autoconf/test_mode.py next to test_mode_level() — env var PYAUTO_TEST_MODE_SAMPLES, default 4, N < 4 raises ValueError.
- PyAutoFit (PR 2): re-export via the
autofit/non_linear/test_mode.py shim; extend _build_fake_samples — N == 4 keeps today's literal branch byte-identical; N > 4 vectorized numpy synthesis (seed 0, prior-median row 0, logL_i = best − i, weights ∝ exp(−i/(N/10)) normalized) through the production Sample.from_lists → SamplesPDF → write_table path.
- Tests: the 7-item numpy-only list from D3 (exact 4-sample back-compat; summary/chaining; save→load round-trip; aggregator + database at N=1000; functional N=50k, no hard timing asserts;
N=3 → ValueError).
Detailed implementation plan
Affected Repositories
- PyAutoFit (primary)
- PyAutoConf (accessor; merge first — dependency direction autofit → autoconf)
Branch Survey
| Repository |
Current Branch |
Dirty? |
| ./PyAutoFit |
main |
clean — claimed by aggregator-sqlite (#1377) |
| ./PyAutoConf |
main |
clean |
Branch: feature/test-mode-representative-samples · Worktree: ~/Code/PyAutoLabs-wt/test-mode-representative-samples/ (created by /start_library once unblocked)
Implementation Steps
- PyAutoConf
autoconf/test_mode.py: add test_mode_samples() (D1 semantics; docstring in the module's existing register).
- PyAutoFit
autofit/non_linear/test_mode.py: add to import + __all__.
- PyAutoFit
autofit/non_linear/search/abstract_search.py _build_fake_samples: keep the N == 4 literal branch untouched; add the N > 4 vectorized branch per D2 (numpy (N, D) scatter p·(1+1e-3·G), zero-handling as today, best-first monotone logL, normalized exp-decay weights, log_prior = 0).
- Tests per D3 in
test_autofit/non_linear/ (numpy-only; no JAX anywhere).
- Note in the PR's API-change summary: new env var, default-unset behaviour unchanged — phases 3 (autolens_profiling recipe) and 4 (docs) consume it.
Key Files
PyAutoConf/autoconf/test_mode.py — new accessor (D1)
PyAutoFit/autofit/non_linear/test_mode.py — shim re-export
PyAutoFit/autofit/non_linear/search/abstract_search.py — _build_fake_samples (D2)
Guard-rails from the design (do not re-derive)
- Bypass write path applies no weight pruning (
samples_above_weight_threshold_from is updater.py-only); the D2 weight floor w_min ≈ (10/N)e⁻¹⁰ ≥ 4.5e-10 keeps threshold-applying loads safe for N ≤ 1e5 (threshold 1.0e-10).
- Parity target measured: 10,187 rows × 21 cols = 9.07 MB (
hst_fast source_lp[1]).
- Mode 3 (
logL_best = -1e99) must work unchanged in both branches.
Original Prompt
Click to expand starting prompt
Test-mode representative outputs — Phase 2: core API
Type: feature
Target: autofit
Repos:
- PyAutoFit
- PyAutoConf
Difficulty: medium
Autonomy: supervised
Priority: normal
Status: formalised
Phase 2 of 4 of draft/feature/autofit/test_mode_representative_outputs_size_realistic.md.
Implements the D1–D4 decisions locked in phase 1 (..._phase_1_design.md) — do not
reopen them. Blocked until phase 1's decisions are posted.
Scope
- Implement the sample-count knob (per D1) — default 4, so existing behaviour is
byte-identical when the knob is unset. Touch @PyAutoConf only if D1 placed the
accessor next to test_mode_level() in autoconf/test_mode.py.
- Extend
_build_fake_samples in @PyAutoFit
(autofit/non_linear/search/abstract_search.py) to synthesize N samples per the
D2 recipe. Vectorized numpy — no per-Sample python loops; N=50k must generate
in seconds or the feature defeats its purpose.
- Unit tests for the D3 downstream contract at large N:
samples.summary()
quantiles, result.model / result.instance chaining, multi-batch structural
guarantees; plus default-unset back-compat (exactly today's 4 samples). Library
unit tests are numpy-only — no JAX.
- Aggregator scrape / database load on a large-N synthetic output verified as part
of the ship gate (workspace_test if a library unit test can't cover it cleanly).
Ship
ship_library: PyAutoFit PR (+ PyAutoConf PR if touched, merged first per the
dependency graph). The PR's API-change summary unblocks phase 3.
Overview
Phase 2 (of 4) of the test-mode size-realistic-samples feature: implement the
PYAUTO_TEST_MODE_SAMPLESknob soPYAUTO_TEST_MODE=2/3bypass runs write asamples.csvwhose row count and byte size match a production Nautilus SLaM stage (N ~ 10k–100k), making cold SLaM runs instant while keeping resume-overhead profiling honest. The design is locked — implement D1–D4 from the phase 1 issue verbatim: #1378 (comment) (phase 1 record: PyAutoMindcomplete/2026/07/test-mode-representative-samples-phase-1-design.md).Blocked at creation: PyAutoFit is claimed by aggregator-sqlite (#1377). Parked in PyAutoMind
planned.md; starts when the claim frees.Plan
test_mode_samples()accessor inautoconf/test_mode.pynext totest_mode_level()— env varPYAUTO_TEST_MODE_SAMPLES, default 4,N < 4raisesValueError.autofit/non_linear/test_mode.pyshim; extend_build_fake_samples—N == 4keeps today's literal branch byte-identical;N > 4vectorized numpy synthesis (seed 0, prior-median row 0,logL_i = best − i, weights∝ exp(−i/(N/10))normalized) through the productionSample.from_lists → SamplesPDF → write_tablepath.N=3 → ValueError).Detailed implementation plan
Affected Repositories
Branch Survey
aggregator-sqlite(#1377)Branch:
feature/test-mode-representative-samples· Worktree:~/Code/PyAutoLabs-wt/test-mode-representative-samples/(created by/start_libraryonce unblocked)Implementation Steps
autoconf/test_mode.py: addtest_mode_samples()(D1 semantics; docstring in the module's existing register).autofit/non_linear/test_mode.py: add to import +__all__.autofit/non_linear/search/abstract_search.py_build_fake_samples: keep theN == 4literal branch untouched; add theN > 4vectorized branch per D2 (numpy(N, D)scatterp·(1+1e-3·G), zero-handling as today, best-first monotone logL, normalized exp-decay weights,log_prior = 0).test_autofit/non_linear/(numpy-only; no JAX anywhere).Key Files
PyAutoConf/autoconf/test_mode.py— new accessor (D1)PyAutoFit/autofit/non_linear/test_mode.py— shim re-exportPyAutoFit/autofit/non_linear/search/abstract_search.py—_build_fake_samples(D2)Guard-rails from the design (do not re-derive)
samples_above_weight_threshold_fromis updater.py-only); the D2 weight floorw_min ≈ (10/N)e⁻¹⁰ ≥ 4.5e-10keeps threshold-applying loads safe for N ≤ 1e5 (threshold1.0e-10).hst_fastsource_lp[1]).logL_best = -1e99) must work unchanged in both branches.Original Prompt
Click to expand starting prompt
Test-mode representative outputs — Phase 2: core API
Type: feature
Target: autofit
Repos:
Difficulty: medium
Autonomy: supervised
Priority: normal
Status: formalised
Phase 2 of 4 of
draft/feature/autofit/test_mode_representative_outputs_size_realistic.md.Implements the D1–D4 decisions locked in phase 1 (
..._phase_1_design.md) — do notreopen them. Blocked until phase 1's decisions are posted.
Scope
byte-identical when the knob is unset. Touch @PyAutoConf only if D1 placed the
accessor next to
test_mode_level()inautoconf/test_mode.py._build_fake_samplesin @PyAutoFit(
autofit/non_linear/search/abstract_search.py) to synthesize N samples per theD2 recipe. Vectorized numpy — no per-Sample python loops; N=50k must generate
in seconds or the feature defeats its purpose.
samples.summary()quantiles,
result.model/result.instancechaining, multi-batch structuralguarantees; plus default-unset back-compat (exactly today's 4 samples). Library
unit tests are numpy-only — no JAX.
of the ship gate (workspace_test if a library unit test can't cover it cleanly).
Ship
ship_library: PyAutoFit PR (+ PyAutoConf PR if touched, merged first per thedependency graph). The PR's API-change summary unblocks phase 3.