diff --git a/dashboard.html b/dashboard.html index 1bec66c4..3194c422 100644 --- a/dashboard.html +++ b/dashboard.html @@ -38,9 +38,9 @@

📋 PyAutoMind Dashboard

Every task the Mind is holding. Tap a task's 📋 and its /start_dev command is on your clipboard — paste it into a Claude Code chat to route Claude straight to that task.

-

In flight 2 · Parked 3 · Planned 6 · Backlog 143 · markdown version

+

In flight 2 · Parked 3 · Planned 6 · Backlog 146 · markdown version

Start here

-

Highest priority (filed as high) — showing 12 of 18

+

Highest priority (filed as high) — showing 12 of 19

TRIAGE: needs manual review before routing — medium · safe · high

Numba CPU likelihood phase 1: batched MGE convolution + operated-matrix — autoarray · medium · supervised · high

Rectangular mesh split: Bilinear (fast CPU default) vs RTU (advanced/GPU) — autoarray · medium · supervised · high

@@ -48,11 +48,11 @@

Highest priority (filed as high) — showing 12 of 18

multi_galaxy package: new regime package in autolens_workspace — autolens · large · supervised · high

Profile and speed up JAX likelihood-function compile times (all use — autolens_profiling · large · supervised · high

Give the Profiling Agent a compile-time axis — the arc — profiling · large · supervised · high

+

Stamp the small-datasets regime at the FITS writer funnel — pyautonerves · large · supervised · high

Deep research: Can we speed up Delaunay in PyAutoArray? — autoarray · too-large · supervised · high

Census of priors and messages — confirmed bugs + redesign — autofit · too-large · supervised · high

einstein_radius_jit_from: replace static init_guess with a JAX-native seed finder — autogalaxy · too-large · supervised · high

Split lensing regimes: multi_galaxy / group / cluster (epic plan) — autolens · too-large · supervised · high

-

Re-baseline the MGE imaging JIT profiling regression value — autolens_workspace_developer · too-large · supervised · high

Quick wins (small enough, and safe enough to run unattended)

(none right now)

In flight markdown version

@@ -77,7 +77,7 @@

Planned

latent-nan-guard-honest-run

Backlog markdown version

-

143 filed prompts, not started — sorted most-pickable first (priority, then size). 23 of them belong to an epic and are listed only under Epics below.

+

146 filed prompts, not started — sorted most-pickable first (priority, then size). 23 of them belong to an epic and are listed only under Epics below.

feature — 28

Numba CPU likelihood phase 1: batched MGE convolution + operated-matrix — autoarray · medium · supervised · high

@@ -110,7 +110,8 @@

Backlog

Teach repos_sync --write to stamp organ config surfaces — pyautomind · hard · supervised · low

-bug — 31 +bug — 33 +

Stamp the small-datasets regime at the FITS writer funnel — pyautonerves · large · supervised · high

Fix release JAX runtime compatibility and likelihood parity — health_fixes · too-large · supervised · high

Fix JIT quick-update visualization output regressions — health_fixes · too-large · supervised · high

Fix release-profile numerical inversion failures — health_fixes · too-large · supervised · high

@@ -118,6 +119,7 @@

Backlog

pixel_scales given as an int (or np.float64) is never widened — autoarray · small · supervised · medium

jax 0.11 breaks beta/gamma message log_partition under jit ('tuple' object — autofit · small · supervised · medium

Heart script_timing baselines are orphaned by path moves and filled — pyautoheart · small · supervised · medium

+

should_simulate rmtree's committed, gitignore-allowlisted datasets — autoarray · medium · supervised · medium

Numba PSF gathers derive the y/x kernel shifts from the — autoarray · low · supervised · medium

PyNUFFT dev extra is incompatible with current SciPy on Python — autoarray · small · supervised · normal

LogGaussianPrior misreports its own support as (-inf, inf) — autofit · small · supervised · normal

@@ -163,7 +165,8 @@

Backlog

Adopt Python 3.12 as the PyAuto ecosystem minimum — libraries

-maintenance — 17 +maintenance — 18 +

smoke_install.sh's stale jax<0.7 pin — CI is on the right — ci · low · supervised · medium

autolens_workspace_developer rectangular experiments — Gut stash + rename — autolens_workspace_developer · small · supervised · normal

Mirror drifted library config keys into the workspace configs — workspaces · small · supervised · normal

Un-park imaging/features/scaling_relation/slam once PyAutoArray#431 merges — workspaces · small · supervised · normal

diff --git a/dashboard.md b/dashboard.md index 4abde06b..df646139 100644 --- a/dashboard.md +++ b/dashboard.md @@ -11,11 +11,11 @@ Every task the Mind is holding, on one page: what is in flight, what is parked, | [In flight](#in-flight) (`active/`) | 2 | | [Parked](#parked) (`parked.md`) | 3 | | [Planned](#planned) (`planned.md`) | 6 | -| [Backlog](#backlog) (`draft/`) | 143 | +| [Backlog](#backlog) (`draft/`) | 146 | ## Start here -**Highest priority** (filed as `high`) — showing 12 of 18 +**Highest priority** (filed as `high`) — showing 12 of 19
📋 TRIAGE: needs manual review before routing — medium · safe · high @@ -73,6 +73,14 @@ Every task the Mind is holding, on one page: what is in flight, what is parked,
+
📋 Stamp the small-datasets regime at the FITS writer funnel — pyautonerves · large · supervised · high + +``` +/start_dev draft/bug/pyautonerves/small_datasets_regime_stamp_at_writer_funnel.md +``` + +
+
📋 Deep research: Can we speed up Delaunay in PyAutoArray? — autoarray · too-large · supervised · high ``` @@ -105,14 +113,6 @@ Every task the Mind is holding, on one page: what is in flight, what is parked,
-
📋 Re-baseline the MGE imaging JIT profiling regression value — autolens_workspace_developer · too-large · supervised · high - -``` -/start_dev draft/test/autolens_workspace_developer/mge_jit_regression_rebaseline.md -``` - -
- **Quick wins** (small enough, and safe enough to run unattended) - _(none right now)_ @@ -229,7 +229,7 @@ Scoped but not started; some are not yet prompt files. Full detail in [`planned. ## Backlog -**143** filed prompts, not started. Each section is sorted most-pickable first (priority, then size). **23** of them belong to an epic and are listed only under [Epics](#epics) below. +**146** filed prompts, not started. Each section is sorted most-pickable first (priority, then size). **23** of them belong to an epic and are listed only under [Epics](#epics) below.
feature — 28 @@ -461,7 +461,15 @@ Scoped but not started; some are not yet prompt files. Full detail in [`planned.
-bug — 31 +bug — 33 + +
📋 Stamp the small-datasets regime at the FITS writer funnel — pyautonerves · large · supervised · high + +``` +/start_dev draft/bug/pyautonerves/small_datasets_regime_stamp_at_writer_funnel.md +``` + +
📋 Fix release JAX runtime compatibility and likelihood parity — health_fixes · too-large · supervised · high @@ -519,6 +527,14 @@ Scoped but not started; some are not yet prompt files. Full detail in [`planned.
+
📋 should_simulate rmtree's committed, gitignore-allowlisted datasets — autoarray · medium · supervised · medium + +``` +/start_dev draft/bug/autoarray/small_datasets_rmtree_of_committed_data.md +``` + +
+
📋 Numba PSF gathers derive the y/x kernel shifts from the — autoarray · low · supervised · medium ``` @@ -847,7 +863,15 @@ Scoped but not started; some are not yet prompt files. Full detail in [`planned.
-maintenance — 17 +maintenance — 18 + +
📋 smoke_install.sh's stale jax<0.7 pin — CI is on the right — ci · low · supervised · medium + +``` +/start_dev draft/maintenance/ci/smoke_install_stale_jax_pin.md +``` + +
📋 autolens_workspace_developer rectangular experiments — Gut stash + rename — autolens_workspace_developer · small · supervised · normal diff --git a/draft/bug/autoarray/small_datasets_rmtree_of_committed_data.md b/draft/bug/autoarray/small_datasets_rmtree_of_committed_data.md new file mode 100644 index 00000000..8680fd7e --- /dev/null +++ b/draft/bug/autoarray/small_datasets_rmtree_of_committed_data.md @@ -0,0 +1,84 @@ +# should_simulate rmtree's committed, gitignore-allowlisted datasets + +Type: bug +Target: autoarray +Repos: +- @PyAutoArray +- @autolens_workspace_test +Difficulty: medium +Autonomy: supervised +Priority: medium +Status: formalised + +Tracked as PyAutoArray#470. Found during +`complete/2026/08/jax-grad-local-vs-ci-assertions.md`; **independent of that bug** +and untouched by its fix (PyAutoArray#471). + +`should_simulate` deletes tracked, version-controlled data and replaces it with +capped-simulator output. + +## The defect + +`autoarray/util/dataset_util.py`, small-datasets branch: + +```python +if os.environ.get("PYAUTO_SMALL_DATASETS") == "1": + if Path(dataset_path).exists(): + shutil.rmtree(dataset_path) +``` + +The `rmtree` is unconditional. It never asks whether the directory holds +generated data or committed data. + +## The live case + +In `autolens_workspace_test`: + +- `.gitignore:13` reads `!dataset/point_source/simple/**` — an explicit allowlist + exception, i.e. the directory is **deliberately committed**. `git ls-files` + confirms three tracked JSON files under it. The allowlist comments describe this + class as real/external data that must never be purged. +- `scripts/point_source/visualization/visualization.py:39` calls + `should_simulate("dataset/point_source/simple")`, and that script declares only + `ENV: real_plots` (line 22), so it **keeps** `PYAUTO_SMALL_DATASETS=1` under the + smoke profile defaults. + +So an ordinary smoke run deletes committed data. It is then re-simulated through +`PointSolver.solve`, which under the cap short-circuits to a fixed position pair +(`PyAutoLens autolens/point/solver/point_solver.py:119`) — the replacement is not +merely lower-resolution, it is degenerate. Seven full-regime scripts read that +same directory, one of them in `smoke_tests.txt`. + +## Severity — recoverable, but wrong + +`git checkout -- dataset/point_source/simple` restores it and the deletion shows +as a dirty tree, so this is not unrecoverable data loss. But it silently violates +the invariant the allowlist exists to express, leaves developers with an +unexplained dirty tree after a routine smoke run, and — combined with the seven +full-regime readers — is the same mixed-regime collision class as #260 in a +dataset family the shape-based fix is structurally blind to (JSON, no FITS). + +## Options (a design call is needed — do not just pick one) + +1. **Skip `rmtree` for git-tracked paths.** Cheap, but puts a git dependency in a + library utility: wrong layer. +2. **Have the workspace declare the exception** — give + `point_source/visualization/visualization.py` a `full_datasets`-style profile + entry so it never enters the small regime against committed data. Narrowest + fix; leaves the general footgun armed for the next allowlisted dataset. +3. **Regime path separation** — capped runs write to a separate path so the two + regimes never share a directory. Removes the collision rather than detecting + it, and would also close #260's remaining gaps, but needs a path-rewrite layer + in the IO with real sharp edges (committed read-only inputs like + `uv_wavelengths/sma.fits` need read-fallback; plot outputs; absolute paths). + +(2) unblocks the immediate case; (3) is the architecturally correct shape if this +class keeps recurring. Related: PyAutoNerves#153. + + + + diff --git a/draft/bug/pyautonerves/small_datasets_regime_stamp_at_writer_funnel.md b/draft/bug/pyautonerves/small_datasets_regime_stamp_at_writer_funnel.md new file mode 100644 index 00000000..298c539d --- /dev/null +++ b/draft/bug/pyautonerves/small_datasets_regime_stamp_at_writer_funnel.md @@ -0,0 +1,99 @@ +# Stamp the small-datasets regime at the FITS writer funnel + +Type: bug +Target: pyautonerves +Repos: +- @PyAutoNerves +- @PyAutoArray +Difficulty: large +Autonomy: supervised +Priority: high +Status: formalised + +Tracked as PyAutoNerves#153. Follow-up to +`complete/2026/08/jax-grad-local-vs-ci-assertions.md` (PyAutoArray#471), which +closed the **imaging** manifestation of this bug class and deliberately left the +rest open. + +`PYAUTO_SMALL_DATASETS=1` caps simulated datasets to a reduced resolution, but +**nothing on disk records which regime a dataset was written under**. That gap +lets a capped dataset survive into a later full-resolution run and be loaded +silently. + +## Why the shipped fix is not enough + +PyAutoArray#471 made `should_simulate` regenerate on the small->full transition by +*inferring* the regime from `data.fits`'s shape (the cap emits exactly +`SMALL_DATASETS_SHAPE_NATIVE = (16, 16)`). That inference is structurally blind to +two dataset families: + +- **Point-source and weak-lensing datasets are JSON** — `dataset/point_source/simple/` + holds only `.json`, and weak lensing writes `dataset.json` + (`autolens_workspace/scripts/weak/simulator.py:136`). There is no FITS to infer + from, so `should_simulate` degenerates to existence-only there. +- **Interferometer corruption is shape-invariant.** The visibility count is fixed + by the committed uv file (`sma.fits`, 360 baselines) while the real-space grid + the visibilities are computed from is capped 256x256 -> 16x16 + (`Grid2D.uniform`, `uniform_2d.py:499`). So a capped run writes a `data.fits` + with **identical NAXIS** and garbage values. + +The interferometer case is the reason this is `Priority: high`: unlike the imaging +failure that started all this, it produces **no shape mismatch and trips no +assertion**. It fails silently. A silent wrong answer in a likelihood is worse +than a loud one. + +## The proposal + +Record the regime at **write** time instead of inferring it at read time. + +Every FITS write in the entire stack funnels through **one function** — +`autonerves/fitsable.py:89` `output_to_fits` (verified: it is the only +`output_to_fits` definition across PyAutoNerves, PyAutoArray, PyAutoGalaxy and +PyAutoLens, and is re-exported as `aa.output_to_fits`). A header card written +there when `PYAUTO_SMALL_DATASETS=1` is active is: + +- **truthful by construction** — written by the same call that writes the data, so + it cannot disagree with it, and there is no stamped-but-empty-directory failure + mode (the reason a marker file written by `should_simulate` was rejected: that + function runs *before* simulation and cannot write a truthful marker); +- **zero-call-site** — no changes across the ~420 `should_simulate` sites in the + workspaces; +- **the only discriminant that can catch the interferometer case**, since it does + not depend on shape. + +`PyAutoArray.should_simulate` then prefers the stamp, keeping the existing shape +heuristic as the legacy fallback for datasets already on disk that carry no stamp. + +## Risks to weigh before implementing + +- This changes a header card on **every FITS the stack writes**. Round-trip tests, + file-hash regression pins and golden-file comparisons could be disturbed. This is + exactly why it was kept out of PyAutoArray#471 rather than riding along with it — + it deserves its own deliberate change and its own CI run. +- **JSON datasets need a separate decision.** `autonerves/dictable.py:370` is the + equivalent funnel, but stamping there risks round-trip pollution of the dictable + schema. Point-source and weak lensing stay exposed until that is settled — + decide it explicitly rather than by omission. +- The stamp only helps datasets written *after* it lands, so the shape fallback in + PyAutoArray is not throwaway work and must not be removed. + +## Suggested scope + +1. Add the regime stamp to `output_to_fits`, gated on the env var. Decide the card + name and whether absence means "full" or "unknown". +2. Teach `should_simulate` to prefer the stamp, shape check as fallback. +3. Run the round-trip / golden-file surface deliberately — that is the real risk, + not the logic. +4. Take the JSON decision explicitly (stamp `dictable`, or record why not and + leave point-source/weak-lensing tracked as still-exposed). +5. Validate against the interferometer case specifically: capped run then + full-regime run must now regenerate, where today it silently does not. + + + + diff --git a/draft/maintenance/ci/smoke_install_stale_jax_pin.md b/draft/maintenance/ci/smoke_install_stale_jax_pin.md new file mode 100644 index 00000000..fd1892fc --- /dev/null +++ b/draft/maintenance/ci/smoke_install_stale_jax_pin.md @@ -0,0 +1,68 @@ +# smoke_install.sh's stale `jax<0.7` pin — CI is on the right jax by accident + +Type: maintenance +Target: ci +Repos: +- @autolens_workspace_test +Difficulty: low +Autonomy: supervised +Priority: medium +Status: formalised + +Found 2026-08-22 while building a CI-equivalent environment to reproduce +autolens_workspace_test#260. Latent — CI is green today — but it is green for the +wrong reason. + +## The defect + +`autolens_workspace_test/.github/scripts/smoke_install.sh:9`: + +```bash +pip install "jax<0.7" "jaxlib<0.7" +``` + +Replaying the install script verbatim, that line **downgrades jax to 0.6.2** and +raises a resolver conflict against autonerves' own requirement: + +``` +autonerves 9999.0.0.dev0 requires jax<0.11.0,>=0.7.0; ... but you have jax 0.6.2 +which is incompatible. +Successfully installed jax-0.6.2 jaxlib-0.6.2 +``` + +The install only ends up on the intended **0.10.2** because the *next* line's +`[optional]` extras happen to pull it back up: + +```bash +pip install "./PyAutoArray[optional]" "./PyAutoGalaxy[optional]" "./PyAutoLens[optional]" +``` + +## Why it matters + +The pin no longer expresses the intent it was written for, and the correct +outcome now depends on line ordering rather than on the constraint. Any +reordering of those two lines, or a change to what the `[optional]` extras +resolve, would silently drop the entire smoke suite onto jax 0.6.2 — and because +`autonerves` declares `jax>=0.7`, that is a configuration the stack does not +claim to support. The failure would surface as unexplained smoke breakage, not as +an install error. + +The comment block immediately below that line (about `tfp-nightly` vs +`tensorflow-probability`) is still accurate and should be preserved. + +## Suggested scope + +1. Establish what the `jax<0.7` pin was originally protecting against, and whether + that reason still holds — do not simply delete it because it looks stale. +2. Either remove it (letting `autonerves`' `jax<0.11.0,>=0.7.0` govern) or replace + it with a pin that states the real intended range. +3. Verify by replaying the install from scratch and asserting the resolved jax + version, rather than inferring it from a green run. +4. Check whether sibling workspaces' install epilogues carry the same stale pin. + + + +