Repository navigation
refactor: samples adapter and Checkpointer/resume split (search-extensibility A3) #1677
Description
Overview
Phase A3: golden samples.csv fixtures first, then samples/adapter.py (RawSamples, samples_from_raw, sentinel unification), ChainPosterior.thin with the empty-chain fallback, the three archive Checkpointer strategies and a separate resume_state, retention that stops deleting Dynesty's savestate, deletion of the three conf.instance mutations (flipping A0's strict xfails), injected legacy-aware internal-result loading and the D5 design note. No Fitness touch; parallel with A2. Launched --auto by the human on 2026-10-08; effective level safe (refactor cap); Tier: judge.
Plan
"A3 — Samples adapter, Checkpointer/resume split (depends on A1; parallel with A2, no Fitness touch; surveys/01 P3; D5, D8, D13). Repo: PyAutoFit. Scope: golden samples.csv tests on pickled emcee, dynesty, nautilus, NUTS and SMC fixtures, merged before the adapter; samples/adapter.py (RawSamples, samples_from_raw, one log-prior helper, sentinel unification; D13); ChainPosterior.thin, which gives Emcee the empty-chain fallback; base samples_via_internal_from implemented once; the three archive Checkpointer strategies and the separate resume_state; resumable declared honestly; delete the NUTS/SMC duplicate pickle, the Emcee no-op and the three conf.instance mutations; injected internal-result loading with format-aware legacy detection, and the design note on atomic writes, corruption and retention (D5). Risk: medium. Numerical equivalence of samples must hold byte-for-byte against the goldens. Verify: the A0a conf.instance xfails flip to pass; test_emcee/zeus/blackjax_nuts/blackjax_smc.py, nss/test_checkpoint.py; kill-and-resume via MultiStartResurrect.py and a Nautilus kill-and-resume; directory, database, null, zipped and summary-only outputs load; the aggregator loads a pre-A3 folder (Emcee HDF included). Witness: constructing af.Emcee() leaves conf.instance unchanged, the goldens are byte-identical, and a pre-A3 output folder still loads in the aggregator."
Tier: judge — merge mode: human /prm
Detailed implementation plan
Affected Repositories
- PyAutoFit (primary, library,
pending-release)
Branch Survey
All affected canonical checkouts on main, clean (verified 2026-10-08 before the worktree was created).
Suggested branch: feature/search-ext-a3-samples-checkpointer (worktree ~/Code/PyAutoLabs-wt/search-ext-a2-objective-bridge (second PyAutoFit checkout PyAutoFit_a3, branch from main))
Implementation Steps
See the prompt's Pins, Verification and Shape sections (embedded below); commit in the order the Shape names.
Validation checklist (--auto run — plan was not pre-approved)
- Effective level: safe (refactor cap)
- Gate legs recorded in the PR body at ship
Original Prompt
Click to expand starting prompt
Samples adapter and Checkpointer/resume split (epic search-extensibility, phase A3)
Type: refactor
Target: autofit
Repos:
- PyAutoFit
Themes: - searches
- persistence
Difficulty: large
Autonomy: safe
Consequence: judge
Witness: constructingaf.Emcee(),af.BlackJAXNUTS()andaf.SMC()leavesconf.instanceunchanged (the threeCONFIG_MUTATION_XFAILstrict xfails are deleted and pass); goldensamples.csvfixtures for emcee, dynesty, nautilus, NUTS and SMC are byte-identical through the adapter; a pre-A3 output folder (Emcee HDF included) still loads in the aggregator; the two Dynesty A0a(ii) xfails (restored folder falls back to samples.csv) are deleted and pass
Unattended: ready
Priority: high
Epic: search-extensibility
Status: draft
Filed: 2026-10-08
Human launch 2026-10-08: --auto for A2, A3, A3b and B3. Plan draft/research/autofit/search_extensibility_epic_report.md §4 (phase text quoted verbatim below), architecture §3.3–§3.5, decisions in §8. A0, A0c, A1 and B2 are merged (A1: capability attributes, Analysis.is_jax, REQUIRED gate, registry/manifest, docs/design/run_ctx.md frozen). Golden identifiers (A0a(i)) are frozen by human ruling: any identifier change stops the item and is flagged. The nine A0 strict xfails are witnesses: flip only the ones a phase names, never add silent ones. Parallel with A2: this phase does not touch Fitness, parallel/ or the run(ctx) bridge. Implemented on its own branch from main; the main session merges A2 and A3 independently and reconciles any overlap.
Original request (verbatim from the epic plan)
"A3 — Samples adapter, Checkpointer/resume split (depends on A1; parallel with A2, no Fitness touch; surveys/01 P3; D5, D8, D13). Repo: PyAutoFit. Scope: golden samples.csv tests on pickled emcee, dynesty, nautilus, NUTS and SMC fixtures, merged before the adapter; samples/adapter.py (RawSamples, samples_from_raw, one log-prior helper, sentinel unification; D13); ChainPosterior.thin, which gives Emcee the empty-chain fallback; base samples_via_internal_from implemented once; the three archive Checkpointer strategies and the separate resume_state; resumable declared honestly; delete the NUTS/SMC duplicate pickle, the Emcee no-op and the three conf.instance mutations; injected internal-result loading with format-aware legacy detection, and the design note on atomic writes, corruption and retention (D5). Risk: medium. Numerical equivalence of samples must hold byte-for-byte against the goldens. Verify: the A0a conf.instance xfails flip to pass; test_emcee/zeus/blackjax_nuts/blackjax_smc.py, nss/test_checkpoint.py; kill-and-resume via MultiStartResurrect.py and a Nautilus kill-and-resume; directory, database, null, zipped and summary-only outputs load; the aggregator loads a pre-A3 folder (Emcee HDF included). Witness: constructing af.Emcee() leaves conf.instance unchanged, the goldens are byte-identical, and a pre-A3 output folder still loads in the aggregator."
Pins (main 2026-10-08)
conf.instance["output"]["search_internal"] = True at emcee/search.py:131, nuts/search.py:265, smc/search.py:315. Architecture §3.4: DillCheckpointer default, PickleCheckpointer (NUTS, SMC), NativeFileCheckpointer(filename, loader) (emcee HDF, dynesty savestate, nautilus hdf5, NSS pkl); each offers save/load/exists/finalize + retain_after_completion; result_internal (archive) is separate from resume_state (Dynesty, Nautilus, NSS, MultiStart only). The A0a(ii) Dynesty xfails exist because output_search_internal deletes savestate.save after a completed fit: the retention policy fixes that. The A1 checkpointer capability attribute (deferred from §3.1) lands here. Goldens: generate the pickled fixtures + samples.csv from main FIRST (own commit), then the adapter must reproduce them byte-for-byte. Samples weights/representations preserved, no renormalisation (D13). The legacy HDF detection at paths/directory.py:238-246 moves, it is not replaced by a dill-only fallback.
Verification
Full pytest test_autofit (expect 9 → 4 strict xfails: the three CONFIG_MUTATION and the two Dynesty backend xfails deleted; the four Emcee/Zeus/NUTS/SMC import-time-settings xfails are A4 and stay); nojax emulation; afT searches/{Emcee,Zeus,DynestyStatic,Nautilus,BlackJAXNUTS,SMC,MultiStartResurrect}.py under test mode; a Nautilus kill-and-resume script; aggregator load of a pre-A3 folder produced from main.
Shape
One PyAutoFit PR (pending-release), commits: goldens → adapter → thin/empty-chain → Checkpointers + resume_state + retention → conf.instance deletions + xfail flips → legacy loading + design note. Refactor cap safe → ends at PR-open; tier judge.
Activity
Jammy2211 commentedon Oct 8, 2026
Shipped to PR-open under
--auto(2026-10-08): PyAutoFit#1680, stacked on #1679 (A2) with that branch as its base; merge #1679 first. 3531 passed / 1 skipped / 4 xfailed on the integrated head: the threeCONFIG_MUTATION_XFAILand two DynestyDISK_INTERNAL_XFAILstrict xfails are deleted and pass; goldens byte-identical;FitContext.checkpointer/resumewired;docs/design/checkpointing.mdadded. A3b (#1678) is being implemented stacked on this branch.Jammy2211 commentedon Oct 8, 2026
Shipped
Merged 2026-10-08 via
/prm, after A2 (#1679): #1680 (labelpending-release— on main, not yet on PyPI).autofit/non_linear/samples/adapter.py:RawSamples,samples_from_raw, shared log-prior helper, sentinel recognition,ChainPosterior.thin); every search implements oneraw_samples_from.DillCheckpointer,PickleCheckpointer,NativeFileCheckpointer; atomic writes,retain_after_completion), design indocs/design/checkpointing.md(D5); pre-A3 output folders still load in the aggregator.conf.instance. Strict xfails 9 → 4 (three config-mutation + two Dynesty disk-internal flipped as named; the four A4 xfails stay).samples.csvfixtures byte-identical through the adapter (Emcee, Dynesty, Nautilus, NUTS, SMC); golden-test tolerance decision: exact (rtol=1e-12, atol=0); blackjax diagnostic keys checked by shape only.Next in the epic: A3b (#1678, PR #1681 open), then A0a(ii).