Skip to content
680 changes: 680 additions & 0 deletions complete/2026/06/jax-substructure-simulator.md

Large diffs are not rendered by default.

87 changes: 87 additions & 0 deletions complete/2026/07/latent-samples-none-on-resumed-fit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# latent-samples-none-on-resumed-fit

- shipped: 2026-07-25 (the same day the prompt recorded the finding)
- library-pr: https://github.com/PyAutoLabs/PyAutoFit/pull/1418 (merged) — "fix: raise SamplesException from latent computation when samples is None (resumed fits)"
- repos:
- PyAutoFit

## Summary

The prompt was filed from the 2026-07-25 full health sweep and fixed upstream the
same day. Nothing in PyAutoMind recorded it, so the prompt sat in `draft/` for two
weeks looking like open work.

Recorded 2026-08-09 by the draft/ sweep. No work is owed.

## Verified against PyAutoFit main (`3b960609`), 2026-08-09

The prompt's § Task offers two options — (a) reload persisted samples on the
resume path, or (b) raise a clear guarded error. **Option (b) is what landed**,
and its § Acceptance is met exactly: "either computes latent samples or fails with
an intentional, documented message — never an `AttributeError` from inside
`latent_samples_from`."

`autofit/non_linear/analysis/latent.py` now opens `latent_samples_from` with an
explicit `if samples is None:` guard raising `exc.SamplesException`, and the
message names the cause and both remedies — samples output disabled via
`output.yaml`'s `samples: false` or `general.yaml`'s `samples_to_csv: false`, so
`result.samples` comes back `None` on the reload; enable samples output and re-run
from cleared output, or pass a `Samples` object explicitly. It also states why
`samples_summary.json` is not a substitute (latents are per-posterior-sample).

The function's `Raises` docstring carries the same diagnosis the prompt reached
independently — that a completed fit short-circuits to
`NonLinearSearch.result_via_completed_fit`, which reloads from `samples.csv`.

The prompt's open sub-question ("May be test-mode-specific — check whether a real
non-bypass resumed fit also returns samples=None") was answered by the fix taking
the general path: the guard is unconditional, not gated on `PYAUTO_TEST_MODE`.

## Why it was missed

This is the one class of drift the Mind cannot see by itself. Unlike the
PyAutoArray k×s finding, there is **no completion record for #1418 anywhere in
`complete/`** — the fix went in upstream without a Mind entry, so no amount of
cross-referencing draft prompts against the ledger would surface it. Only reading
the prompt's acceptance criteria against the upstream tree finds this shape.

## Original prompt
# compute_latent_samples crashes on a resumed completed fit (samples is None)

Type: bug
Target: autofit
Repos:
- @PyAutoFit
Difficulty: medium
Autonomy: supervised
Priority: low
Status: draft

## Finding (2026-07-25 full health sweep)

Running `autolens_workspace_test` `misc/latent/latent_variables_smoke.py` (and
`latent_nan_robustness.py`) twice in the same output tree fails on the second
run: the search resumes ("Fit Already Completed: skipping non-linear search"),
`result.samples` comes back `None` on the resume path (PYAUTO_TEST_MODE=2
bypass), and

autofit/non_linear/analysis/latent.py:113 latent_samples_from
-> samples.model -> AttributeError: 'NoneType' object has no attribute 'model'

A fresh run (output cleared) passes. So the latent pipeline works, but the
resume/load path hands `compute_latent_samples` a `None` samples object
instead of the persisted samples (or a clear error).

## Task

Determine whether the resume path should (a) reload persisted samples so
latent computation works on resumed results, or (b) raise a clear, guarded
error from `compute_latent_samples` when samples are unavailable. May be
test-mode-specific — check whether a real (non-bypass) resumed fit also
returns samples=None.

## Acceptance

Second invocation of the latent smoke scripts in an existing output tree
either computes latent samples or fails with an intentional, documented
message — never an AttributeError from inside latent_samples_from.
Original file line number Diff line number Diff line change
@@ -1,3 +1,74 @@
# oversampling-kxs-coupling

- shipped: 2026-07-09 (series closed; the prompt never left `draft/`)
- issue: https://github.com/PyAutoLabs/PyAutoArray/issues/362 (CLOSED — "series complete")
- prs: PyAutoArray#363, #364, #365 · PyAutoGalaxy#486, #489 · autolens_workspace#236 · autolens_workspace_test#154 (all merged)
- repos:
- PyAutoArray, PyAutoGalaxy
- autolens_workspace, autolens_workspace_test
- phase-records: [[kxs-design]] [[kxs-core]] [[kxs-cache]] [[kxs-workspace-tests]] [[kxs-refactor]] [[kxs-surface-refactor]]

## Summary

This is the **source prompt** for the k×s coupling series — the five-phase plan
it lays out was executed in full over 2026-07-08/09 and the series tracker
PyAutoArray#362 was closed as "series complete". Six dated completion records
already existed for the individual phases; only the prompt they all came from
was never advanced out of `draft/feature/autoarray/`.

Recorded 2026-08-09 by the draft/ sweep. No work is owed.

## Verified against PyAutoArray main (`efaf3041`), 2026-08-09

Graded against the prompt's own § Scope, not inferred from the phase records:

1. **§1 relax the coupling rule — SHIPPED.**
`_validate_convolve_over_sample_size` (`autoarray/dataset/imaging/dataset.py:23`)
accepts any `over_sample_size` (int or adaptive `Array2D`) whose every entry
is divisible by `convolve_over_sample_size`, and raises `DatasetException`
naming the rule otherwise. Its docstring states the mechanism in the prompt's
own words — "the k x s coupling, whereby values evaluated at per-pixel sizes
k_i * s are partially binned to the uniform s the convolution requires".
The pre-change equality rule is gone.

2. **§2 partial pre-bin — SHIPPED**, as
`over_sample_util.binned_to_convolve_size_from`
(`autoarray/operators/over_sampling/over_sample_util.py:205`). The placement
fork the prompt required a design paragraph for was settled and is recorded in
[[kxs-design]]. Covered by `test_over_sample_util.py` on both legs the prompt
asked for — `binned_to_convolve_size_from__uniform_k__equals_manual_reshape_mean`
and `__adaptive_k__and_identity_fast_path`.

3. **§3 PyAutoGalaxy callers — SHIPPED** via PyAutoGalaxy#486 ([[kxs-core]]).

4. **§4 tests — SHIPPED.** Library numpy-only tests as above; the
`convolution_over_sampled.py` adaptive + s=2 `FitImaging` leg the prompt
specifies landed as autolens_workspace_test#154 ([[kxs-workspace-tests]]:
lp round trip chi2=0, adaptive pixelized 6.6e-5, divisibility guard,
adaptive simulate→fit 1.1e-29).

5. **§5 simulator adoption — DELIBERATELY RE-SCOPED, not skipped.**
[[kxs-core]] records the fork resolved as option (c): executed simulators stay
at `s=1`, and option (a) was split out as
`draft/feature/autolens_workspace/oversampled_psf_dataset_adoption.md`. That
prompt is correctly still a live draft — it is the residue of this §5, and is
NOT covered by this record.

6. **Phase-5 refactor exercise — SHIPPED** as PyAutoGalaxy#489
([[kxs-surface-refactor]]), plus the extra [[kxs-cache]] and [[kxs-refactor]]
legs the series added on top of the original plan.

## Why it was missed

Nothing upstream drifted — the trackers were right the whole time, exactly as in
the 2026-08-08 `planned.md` prune. The prompt is stale purely because `draft/` is
graded by no check, and slug-similarity is too weak to catch it: this file's stem
against `kxs-core` scores a Jaccard of 0.25, well under any workable threshold.
What found it was reading the prompt's acceptance criteria against the tree — and
it was provable from PyAutoMind alone, since the six phase records were already
sitting in `complete/2026/07/`.

## Original prompt
# Oversampled PSF: k×s evaluation/convolution coupling + simulator adoption

Type: feature
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,80 @@
# rectangular-adapt-constant-split-guard

- shipped: 2026-07-28 (phase 1 of the @rhayes777 audit epic; the prompt never left `draft/`)
- epic: https://github.com/PyAutoLabs/PyAutoArray/issues/415 (open — phases 2-4 remain)
- issue: https://github.com/PyAutoLabs/PyAutoArray/issues/332 (the reporter's finding), tracker #416 closed
- prs: PyAutoArray#417 (`9411904d`) + PyAutoLens#662 (`2a3f1a63`), both merged
- repos:
- PyAutoArray
- see-also: `draft/bug/autoarray/rhayes_audit_validation_and_crashes.md` § "Phase 1 completion record — 2026-07-28"

## Summary

A duplicate prompt for work that shipped as phase 1 of the @rhayes777 API-audit
epic. The Mind already held the completion record — inside the *sibling* prompt
`rhayes_audit_validation_and_crashes.md`, which planned.md tracks — but this
second, independently-filed prompt for the same surface never learned about it.

Recorded 2026-08-09 by the draft/ sweep. No work is owed on the library leg;
one leg of the prompt's § Verification is noted below as unconfirmed.

## Verified against PyAutoArray main (`efaf3041`), 2026-08-09

The prompt asks for "an explicit validation guard which rejects this unsupported
configuration early, with an error message that tells users what to do instead".
That guard is on main:

- **Guard**: `Pixelization.__init__` (`autoarray/inversion/pixelization.py:154`)
raises `exc.PixelizationException` when a split regularization meets a mesh
that does not support it. The message names both classes and tells the user
the two ways out — an adaptive mesh (`Delaunay`/`KNNBarycentric`) with the same
regularization, or a non-split scheme (`Constant` for `ConstantSplit`, `Adapt`
for `AdaptSplit`) with the same mesh. Substantively the prompt's suggested text.
- **Mechanism**: two capability flags rather than a type blacklist —
`AbstractMesh.supports_split_regularization` (default `True`, set `False` on
the rectangular family) × `AbstractRegularization.is_split_regularization`
(default `False`, set `True` on `ConstantSplit`/`AdaptSplit`/`AdaptSplitZeroth`).
- **The false pass-through is gone**: `InterpolatorRectangular`'s claim that split
"reuses the same mappings" — the source of the `IndexError: index 4 is out of
bounds for axis 0 with size 4` this prompt reproduces — no longer stands;
`interpolator/rectangular.py:466` now records that the combination is rejected
at construction instead.

Against the prompt's § Verification:

1. **Criterion 1 (concrete construction raises) — MET.**
`test_autoarray/inversion/pixelization/test_split_regularization_support.py`
parametrizes all **9** rectangular × split combinations (the prompt reported
1) and asserts both class names appear in the message.
2. **Criterion 2 (`af.Model` composition form fails before Nautilus starts) —
NOT CONFIRMED.** The guard sits in `Pixelization.__init__`, so it fires
whenever the model is instantiated rather than at composition time. A search
for `supports_split_regularization` in PyAutoLens returns nothing, so no
separate pre-fit model-inspection guard was added. In practice the concrete
guard is reached on the first instantiation, which is early — but that this
precedes sampling was not verified here and would need a run to settle. The
prompt itself allowed this ordering ("add the concrete PyAutoArray guard
first and add a companion AutoLens / analysis guard where the prior model can
be inspected"), so this is a possible residue, not a regression.
3. **Criterion 3 (allowed combinations still work) — MET.** Rectangular +
`Constant`, adaptive + split, and rectangular + no regularization all have
passing parametrized tests.
4. **Criterion 4 (low-level regression test) — MET in the form the fix took.**
Because the capability is deliberately absent rather than repaired, the tests
assert the *clear failure*; the test module says so explicitly. The prompt's
"do not paper over this by clipping indices" instruction was honoured.

## Why it was missed

Two prompts described one surface. `rhayes_audit_validation_and_crashes.md` came
in through the audit and is tracked by `planned.md`, so it was updated when phase
1 shipped; this one came in separately from a user repro
(`z_help/jacob/HerBS-28…`) and, sitting in `draft/`, was graded by nothing. The
related `draft/feature/autoarray/regularization_jax_gradient_gaps.md` § 3 flagged
the same surface a third time and asked "merge at intake if so" — that merge is
now moot, and its leg 3 has been marked done in place.

## Original prompt
# Users keep combining `RectangularAdaptDensity` meshes with `ConstantSplit`

Type: feature
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,45 @@
# test-mode-representative-outputs-size-realistic

- shipped: 2026-07-17 (the epic's own closing condition was met and never actioned)
- issues: PyAutoFit#1378 (phase 1), PyAutoFit#1381 + PyAutoConf#126 (phase 2), autolens_profiling#70 (the closing gate — CLOSED as `completed` 2026-07-17)
- phase-records: [[test-mode-representative-samples-phase-1-design]] [[test-mode-representative-samples-phase-2-core-api]]
- repos:
- PyAutoFit, PyAutoConf (now PyAutoNerves), autolens_profiling

## Summary

An umbrella prompt whose four phases were all resolved, tracked in the prompt's
own status line, and whose stated exit condition then quietly came true.

The prompt is explicit that it is the umbrella — *"issue the phase files, not this
one"* — and its 2026-07-17 status block already recorded:

- phase 1 (design) **COMPLETE**, PyAutoFit#1378, record in `complete/2026/07/`
- phase 2 (core API) **COMPLETE + MERGED**, PyAutoConf#126 + PyAutoFit#1381
- phase 3 **ABSORBED** into slam-resume-profiling (autolens_profiling#70), prompt retired
- phase 4 **ABSORBED** (survey found RTD has no test-mode surface), prompt retired
- *"EPIC CLOSES when #70 ships its recipe leg."*

## Verified 2026-08-09

**autolens_profiling#70 is closed, `state_reason: completed`, closed 2026-07-17 by
Jammy2211** — the same day the prompt's status block was last written. So the only
outstanding condition the umbrella named was satisfied within hours of the note
being taken, and nothing advanced the file.

Recorded by the draft/ sweep. No work is owed.

## Why it was missed

This one needed neither a clone nor a code read — the prompt states its own exit
condition, and one issue-state lookup settles it. That makes it the cheapest class
of draft/ drift to detect and a good argument for extending the advisory
`issues --drafts` pass: #70 is named in the prompt body but is not the kind of
citation that pass currently nets, because the prompt cites it as a *gate* rather
than as its own tracking issue. Worth considering whether an "epic closes when X"
idiom should be machine-readable.

## Original prompt
# Test-mode representative outputs: size-realistic samples for instant pipeline runs

Type: feature
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,71 @@
# normalise-auto-simulate-guard-idiom

- shipped: verified on autolens_workspace main `9974f891` (the prompt never left `draft/`)
- follows: [[auto-simulate-guard-targets]] (autolens_workspace#359 → #364, autogalaxy_workspace#175) and the `should_simulate` migration (autolens_workspace#354)
- repos:
- autolens_workspace

## Summary

The prompt asks for four hand-rolled auto-simulate guards to be converted to
`al.util.dataset.should_simulate`, with one specific caution about not dropping a
stricter check while doing it. All four are converted on main, and the caution was
honoured — more carefully than the prompt asked.

Recorded 2026-08-09 by the draft/ sweep. No work is owed.

## Verified against autolens_workspace main (`9974f891`), 2026-08-09

Against the prompt's § Proposed work:

1. **All four idiom-B sites converted — DONE.** `cluster/likelihood_function.py`,
`interferometer/features/pixelization/many_visibilities_preparation.py`,
`imaging/features/advanced/subhalo/sensitivity/slam_source_parametric.py` and
`…/slam_source_pixelized.py` all call `should_simulate` now. A repo-wide sweep
finds **zero** remaining hand-rolled `data.fits … .exists()` simulator guards
(492 files use the standard idiom).

2. **The `mass.csv` check was preserved — DONE, and better than specified.** The
prompt warned "do not silently drop it" and offered two ways out. The shipped
form takes the first *and* fixes an ordering subtlety the prompt did not raise:

```python
if (
al.util.dataset.should_simulate(str(dataset_path))
or not (dataset_path / "mass.csv").exists()
):
```

with a comment recording that `should_simulate` is evaluated **first** so its
`PYAUTO_SMALL_DATASETS` rebuild always runs. Written the other way round, a
present `mass.csv` would short-circuit past the capped-rebuild side effect —
which is precisely the failure the conversion exists to prevent.

3. **Re-running under the capped profile** — not independently re-run here; that
needs a real execution environment.

4. **`required_files=[...]` on `should_simulate` — NOT taken.** PyAutoArray's
`should_simulate(dataset_path)` still has the single argument. This leg was
explicitly optional in the prompt ("consider whether…", and it would have made
the task library+workspace rather than workspace-only). The `mass.csv` clause
living in the script is the alternative the prompt allowed.

**Not the same class, correctly left alone:** two `if not data_fits_path.exists():`
sites survive, in `multi_dataset/features/imaging_and_point_source/modeling.py:75`
and `cluster/start_here.py:153`. Both guard a one-off `urllib` download of real HST
data (RXJ1131, Abell 2744), not a simulator invocation, so `should_simulate`'s
capped-rebuild semantics would be actively wrong there — it would delete a
downloaded file to re-download it. Converting these would be a regression.

## Note on detection

This is the one finding across three sweeps that `pyauto-brain intake reconcile`
ranked `high` for the right reason: [[auto-simulate-guard-targets]] names the
prompt's path directly in its body. That is signal 3 in
`draft/feature/pyautomind/draft_staleness_detection_signals.md` working as
intended — though it still arrived among 51 other `high`s.

## Original prompt
# Normalise the two auto-simulate guard idioms

Type: maintenance
Expand Down
10 changes: 10 additions & 0 deletions complete/archive/epics/jax_substructure_simulator.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ __What's already done__ (no work needed):

__Outstanding__ (sequenced):

> **CORRECTION 2026-08-09 (draft/ sweep): items 1-4 below are NOT outstanding —
> they SHIPPED on 2026-06-09.** See `complete/2026/06/jax-substructure-simulator.md`
> (PyAutoLens#543 + #544, PyAutoGalaxy direct commits, autolens_workspace_test
> #127/#128/#129), re-verified against upstream `main`. Their four prompt files
> stayed in `draft/` for two months after shipping and were retired into that
> record; the relative links below are therefore dead. The only live work from this
> epic is `draft/feature/jax_substructure/5_prng_key_vmap_noise.md` and
> `6_deflection_equivalence_test.md`, both confirmed still open. This tracker is
> archived material — read the completion record, not this list.

1. [feature/jax_substructure/1_vmap_subhalo_deflections.md](../feature/jax_substructure/1_vmap_subhalo_deflections.md) —
vectorized deflection path: represent N halos as `(max_N, n_params)` arrays,
`jax.vmap` the profile deflection function, sum with mask. Integration test
Expand Down
Loading
Loading