diff --git a/active.md b/active.md index 6d4cf305..fb25a165 100644 --- a/active.md +++ b/active.md @@ -13,36 +13,3 @@ - registered: 2026-08-19 by the wake_up session — the issuing session (claude/autofit-priors-messages-audit-ylvenv) filed the prompt + issue but not this entry, tripping Lifecycle Drift on main. - repos-none-claimed: this entry claims NO repos — one line deliberately, not 2-space bullets. - -## organ-repo-spelling-splits -- issue: https://github.com/PyAutoLabs/PyAutoBrain/issues/287 -- issued: 2026-08-26 -- prompt: active/organ_repo_spellings_split_across_keys.md -- status: ready-to-ship — implemented and pushed on both branches; no PR opened - yet (PyAutoMind e160d40b, PyAutoBrain 6329db8). 515 Brain tests pass, - repos_sync --check all 13 legs OK, Heart NOT EVALUATED (web-github). -- worktree: n/a — web-github session; the session's own PyAutoBrain + PyAutoMind - clones are the checkout, on the designated branch below (no - ~/Code/PyAutoLabs-wt/ worktree exists in this environment). -- repos: - - PyAutoBrain: claude/organ-repo-spelling-splits-hbbms0 - - PyAutoMind: claude/organ-repo-spelling-splits-hbbms0 -- summary: | - Infrastructure task (organism repos only). Fourth instance of the - hand-maintained-aliases vs derived-target-set defect class (#267, #269); - this one closes the class. Keying decision taken up front per the prompt: - organs key PREFIXED (`pyautobrain`), extending #271's rule — canonical key - is the bare package name where the repo ships one, the repo name where it - does not. Fix derives the bare/prefixed/package alias join from the body - map (new `package:` identity key in repos.yaml) and adds three coverage - guards to test_policy_seams.py. Sweep also covers PyAutoScientist and - pyautolabs.github.io, both split/unresolvable and not named in the prompt. - Heart unreachable from this environment — ship gate leg 4 records NOT - EVALUATED. - - DEVIATION from the answered scope question: `pyautolabs.github.io` was - deliberately DE-REGISTERED rather than joined. Joining it means aliasing its - truncated head `pyautolabs`, which is the ORG name — `@PyAutoLabs/PyAutoFit` - would then resolve to the static site instead of PyAutoFit. The acceptance - criterion's other branch ("or is deliberately not registered") covers it, and - a guard pins both halves. Raised for review at ship time. diff --git a/active/organ_repo_spellings_split_across_keys.md b/active/organ_repo_spellings_split_across_keys.md deleted file mode 100644 index 45c40534..00000000 --- a/active/organ_repo_spellings_split_across_keys.md +++ /dev/null @@ -1,72 +0,0 @@ -# Organ repo spellings split across two normalised keys - -Type: bug -Target: pyautobrain -Repos: -- PyAutoBrain -Difficulty: large -Autonomy: supervised -Priority: normal -Status: formalised -Filed: 2026-08-24 -Issued: 2026-08-26 - -Found while shipping the refactor witness-map audit (@PyAutoBrain#269 / PR #271). - -## The defect - -The bare spellings of the organ repos do not normalise to the same key as their -repo spellings, so a policy map keyed on one is invisible to the other. - -@PyAutoBrain/agents/faculties/sizing/_sizing.py (`_target_sets.names_for`) -registers BOTH spellings of every `PyAuto*` repo as known targets -(`name.lower()` and `name.lower()[2:]`), but the `repo_aliases` table in -@PyAutoBrain/config/policy.yaml only joins them for the libraries: - -| mention | normalises to | resolves? | -|---|---|---| -| `@PyAutoBrain` | `pyautobrain` | yes | -| `@autobrain` | `autobrain` | no — a known target with nothing filed under it | - -Same for the bare Heart, Memory, Mind and Gut spellings. `@autohands` was joined -in PR #271 because `extra_organism_targets` declares it explicitly and it -reaches real code today; the rest are latent — no prompt in the Mind history -uses them yet. - -## Decide before fixing - -This is NOT a blind alias sweep. Should organs key on the bare form -(`autobrain`) or the prefixed form (`pyautobrain`)? `target_signals` keys the -prefixed form (`pyautobrain`, `pyautomind`, `pyautoheart`, `pyautobuild`), and -after #271 `test_witness` keys organs prefixed but libraries bare. Whichever way -it goes has to hold across both maps at once, so answer the question first and -let the edit follow. - -## The wider question this raises - -Three separate repos have now hit this same defect class — PyAutoNerves -(#267), PyAutoCTI and PyAutoReduce (#269). The shared cause is that -`repo_aliases` is HAND-MAINTAINED while the known-target set is DERIVED from the -body map, so the two drift silently and the gap only ever surfaces as a -wrong-but-plausible conductor message ("strengthen tests first" for a -well-tested repo). - -Guard 2 added in #271 — a witness-map key must be what its repo normalises to — -closes the witness-map instance only. An alias gap in a map with no coverage -guard is still invisible. Consider deriving `repo_aliases` from the body map so -the class closes rather than its fourth instance. - -## Notes on this prompt's header - -`pyauto-brain intake classify` scored this `bug` at high confidence (kept), but -proposed `Target: autocti` — it read the prior-instance history above as the -subject — and `Difficulty: too-large` (score 10), inflated by the repo names and -the design-decision keywords. Corrected to `pyautobrain` / `large` on review. -An alternative classification is `refactor`: the fix is behaviour-preserving for -every spelling that resolves today. `bug` was kept because the Bug Agent's -investigate-first strategy matches the "decide before fixing" requirement above. - -Acceptance: every spelling of every body-map repo that `_target_sets` registers -as a known target resolves to a key the policy maps are actually filed under, or -is deliberately not registered; a guard makes a future alias gap fail loudly -rather than degrade a conductor's advice. diff --git a/complete/2026/08/organ-repo-spelling-splits.md b/complete/2026/08/organ-repo-spelling-splits.md new file mode 100644 index 00000000..d966109f --- /dev/null +++ b/complete/2026/08/organ-repo-spelling-splits.md @@ -0,0 +1,180 @@ +- issue: https://github.com/PyAutoLabs/PyAutoBrain/issues/287 (closed on ship) +- shipped: 2026-08-26 — PyAutoBrain PR https://github.com/PyAutoLabs/PyAutoBrain/pull/288 + and PyAutoMind PR https://github.com/PyAutoLabs/PyAutoMind/pull/333 (Mind merged first) +- classification: bug (PyAutoBrain + PyAutoMind; organism infrastructure — neither + library nor workspace) +- summary: The bare and prefixed spellings of seven repos normalised to two different + keys, so a policy map filed under one was invisible to the other. The keying question + the prompt demanded be answered first was answered — **organs key PREFIXED** — and + then the class was closed rather than its fourth instance: the bare/prefixed/package + alias join now DERIVES from the body map's new `package:` field, and five guards make + the next gap fail loudly. + +## The decision, taken before the edit + +Organs key on the prefixed form (`pyautobrain`). Not a new rule — #269's rule made +executable: *the canonical key is the package the repo SHIPS where it ships one, the +repo name where it does not.* Organs ship no package; Nerves is the one that does and +already keyed bare (`autonerves`). Everything downstream was already filed prefixed for +organs — `test_witness`, `target_signals`, `REPO_DISPLAY`, `target_default_wiki`, and +the Mind's own `draft/*/pyautobrain/` target folders — so keying bare would have rekeyed +five maps for no gain. + +## Shipped changes + +- `PyAutoMind/repos.yaml`: `package:` on the seven repos that ship one (six libraries + + Nerves), documented in the header as identity — the other name a repo is known by. +- `PyAutoBrain/agents/faculties/sizing/_sizing.py`: `_body_map_specs`, `canonical_key`, + `spellings_of`, `unreachable_repos`, `_derived_aliases`, `_repo_aliases`; the alias + table is now derived ∪ hand, with a conflict between them raising rather than one + quietly winning. +- `PyAutoBrain/config/policy.yaml`: `repo_aliases` trimmed to what a body map cannot + know, with the canonical-key rule written where the maps live. + `extra_organism_targets` emptied — `autohands` is derived now. +- `PyAutoBrain/agents/conductors/intake/_intake.py`: `REPO_DISPLAY` derived too. +- `PyAutoBrain/tests/test_policy_seams.py`: five guards (below). + +## What the reproduction found beyond the prompt + +The prompt named five organs. Sweeping every body-map repo found seven splits — the five +organs, PyAutoHands (joined only by a policy literal), and **PyAutoScientist** — plus one +repo that could never resolve at all. + +**`pyautolabs.github.io` was DE-REGISTERED, not joined.** This is a deliberate deviation +from the scope answered at plan time ("join both"). `normalise_repo` truncates at the +first `.`/`/`, so no mention can reach a dotted repo name. The obvious fix — alias the +truncated head — is *worse* than the gap: that head is `pyautolabs`, the ORG name, so +`@PyAutoLabs/PyAutoFit` would have started resolving to the static site instead of +PyAutoFit. The acceptance criterion's other branch ("or is deliberately not registered") +covers it. The exclusion derives from the names themselves (any name carrying a +separator), not a hand-kept list, and a guard pins both halves: the repo is out of the +known targets AND its truncated head still resolves to nothing. + +## Guards, each mutation-tested + +| Guard | Mutation that proves it | +|---|---| +| no repo splits across two keys | removing the derived join names all seven affected repos | +| no alias points at a key nothing is filed under | — | +| body map `package:` agrees with the witness map | mis-keying one `package:` value raises at import | +| unreachable repos excluded, and their head resolves to nothing | forcing the dotted repo back into the set | +| canonical keys survive a body map with no `package:` | deleting the pre-package fallback rows | + +## Traps and findings + +- **The cross-repo CI pinning is the trap this task turns on.** `tests.yml` checks the + sibling Mind out at `main`, pinned, so a Brain half that REQUIRED the Mind half would + sit red until Mind merged. `canonical_key` falls back to the hand table's library rows + when no `package:` is declared, giving identical keys either way — and a test pins that + property so the fallback is not an unexercised path. The corroboration guard did NOT + have that tolerance on first push and **failed CI for exactly this reason**; the fix + made it all-or-nothing (a map declaring no package has nothing to corroborate; one + declaring *some* must declare all), which is a stronger guard than the one it replaced, + not a weakened one. +- **The tenant firewall rejected two drafts of the prose**, for naming PyAutoCTI, + PyAutoReduce, PyAutoScientist and PyAutoLabs in comments — the third consecutive task + where it caught the agent's own drift (cf. #267, #269). The comments read generically + because of it. +- **Behaviour preservation was measured, not asserted.** An A/B over every spelling in + the alias table and target sets shows exactly six resolutions changed, all intended + joins; libraries, short forms, renames, workspaces and org-qualified paths byte-identical. +- **`REPO_DISPLAY` had the beginnings of the same drift** — reachable keys (`pyautohands`, + the CTI/Reduce libraries, the HowTos) carried no row, so a header rendered + `Target: pyautohands`. Newly-reachable keys would have inherited it, so it was derived + in the same pass rather than special-cased. +- **A `git checkout --` during the mutation sweep clobbered the implementation** and it + had to be reapplied. Worth naming: mutation-testing a file you are also editing needs a + file backup, not a git restore. + +## Gate + +Brain tests 515 pass (510 baseline + 5 guards), on both matrix legs in CI, and locally +against BOTH body-map states — the branch's Mind with all seven packages declared, and a +Mind checkout at `origin/main` with none. `repos_sync --check` all 13 legs OK. Smoke n/a +(organism repos). **Heart NOT EVALUATED** — `pyauto-heart` is unreachable from a +web-github session, so leg 4 of the ship gate never ran; recorded that way rather than +claimed clean. Effective autonomy `supervised`; the run took its plan checkpoint (two +scope questions put to the human) and proceeded on the answers. + +## Follow-ups + +- The seven pre-package library rows in `repo_aliases` are the fallback for a body map + without `package:`. Now that PyAutoMind#333 has merged they are dead weight and can be + deleted, which also fully arms the corroboration guard's strict path. +- `normalise_repo` still passes `maxsplit` positionally (a DeprecationWarning on 3.13). + The copy this task introduced was fixed; the pre-existing one was left alone. + +## Original prompt + +# Organ repo spellings split across two normalised keys + +Type: bug +Target: pyautobrain +Repos: +- PyAutoBrain +Difficulty: large +Autonomy: supervised +Priority: normal +Status: formalised +Filed: 2026-08-24 +Issued: 2026-08-26 + +Found while shipping the refactor witness-map audit (@PyAutoBrain#269 / PR #271). + +## The defect + +The bare spellings of the organ repos do not normalise to the same key as their +repo spellings, so a policy map keyed on one is invisible to the other. + +@PyAutoBrain/agents/faculties/sizing/_sizing.py (`_target_sets.names_for`) +registers BOTH spellings of every `PyAuto*` repo as known targets +(`name.lower()` and `name.lower()[2:]`), but the `repo_aliases` table in +@PyAutoBrain/config/policy.yaml only joins them for the libraries: + +| mention | normalises to | resolves? | +|---|---|---| +| `@PyAutoBrain` | `pyautobrain` | yes | +| `@autobrain` | `autobrain` | no — a known target with nothing filed under it | + +Same for the bare Heart, Memory, Mind and Gut spellings. `@autohands` was joined +in PR #271 because `extra_organism_targets` declares it explicitly and it +reaches real code today; the rest are latent — no prompt in the Mind history +uses them yet. + +## Decide before fixing + +This is NOT a blind alias sweep. Should organs key on the bare form +(`autobrain`) or the prefixed form (`pyautobrain`)? `target_signals` keys the +prefixed form (`pyautobrain`, `pyautomind`, `pyautoheart`, `pyautobuild`), and +after #271 `test_witness` keys organs prefixed but libraries bare. Whichever way +it goes has to hold across both maps at once, so answer the question first and +let the edit follow. + +## The wider question this raises + +Three separate repos have now hit this same defect class — PyAutoNerves +(#267), PyAutoCTI and PyAutoReduce (#269). The shared cause is that +`repo_aliases` is HAND-MAINTAINED while the known-target set is DERIVED from the +body map, so the two drift silently and the gap only ever surfaces as a +wrong-but-plausible conductor message ("strengthen tests first" for a +well-tested repo). + +Guard 2 added in #271 — a witness-map key must be what its repo normalises to — +closes the witness-map instance only. An alias gap in a map with no coverage +guard is still invisible. Consider deriving `repo_aliases` from the body map so +the class closes rather than its fourth instance. + +## Notes on this prompt's header + +`pyauto-brain intake classify` scored this `bug` at high confidence (kept), but +proposed `Target: autocti` — it read the prior-instance history above as the +subject — and `Difficulty: too-large` (score 10), inflated by the repo names and +the design-decision keywords. Corrected to `pyautobrain` / `large` on review. +An alternative classification is `refactor`: the fix is behaviour-preserving for +every spelling that resolves today. `bug` was kept because the Bug Agent's +investigate-first strategy matches the "decide before fixing" requirement above. + +Acceptance: every spelling of every body-map repo that `_target_sets` registers +as a known target resolves to a key the policy maps are actually filed under, or +is deliberately not registered; a guard makes a future alias gap fail loudly +rather than degrade a conductor's advice. diff --git a/complete/index.md b/complete/index.md index bfad2dbe..84c66e86 100644 --- a/complete/index.md +++ b/complete/index.md @@ -6,7 +6,7 @@ Token-light navigation over the finished-work records (schema: only then grep a dated bucket. Curators: edit the band between the CURATED markers; everything below GENERATED is rebuilt. -1141 records across 7 buckets. +1142 records across 7 buckets. ## Highlights @@ -159,6 +159,7 @@ _(curate hard-won records here — survives regeneration.)_ - [numerical-inversion-failures](2026/08/numerical-inversion-failures.md) - [one-tap-dashboard-rollout](2026/08/one-tap-dashboard-rollout.md) — the pattern (a generated page + one-tap 📋 copy-for-Claude payloads, phone - [optional-dependency-skip-guards](2026/08/optional-dependency-skip-guards.md) — `test_nautilus.py::test__single_core_builds_no_pool` had no skip guard +- [organ-repo-spelling-splits](2026/08/organ-repo-spelling-splits.md) — closed on ship - [organism-board-final-readmes](2026/08/organism-board-final-readmes.md) — close on record - [paper-management-pipeline](2026/08/paper-management-pipeline.md) — auto-closed on merge - [per-parameter-step-scaling](2026/08/per-parameter-step-scaling.md) diff --git a/dashboard.html b/dashboard.html index f3e997ba..f1fa40b3 100644 --- a/dashboard.html +++ b/dashboard.html @@ -185,7 +185,7 @@

PyAutoMindDashboard

Intent. Priority. Flow.

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. Recent is the same work by date — what has been happening rather than what to do next.

- +

Last updated 2026-08-26. This page is generated from active/, draft/ and the registry files, so it is only as current as they are. dashboard_refresh.yml re-renders it on every push to main — that heals a stale page, but not a stale prompt: a task that shipped without its prompt advancing to complete/ keeps rendering here as pickable backlog. Reconciling those is the refresh below.

@PyAutoFit TransformedMessage.factor_gradient crashes on first callissue #1501 — issued 2026-08-19HOLD — do not start dev. Fix-or-delete hangs off the PyAutoFit#1498 logpdf-contract

-

Organ repo spellings split across two normalised keysissue #287 — issued 2026-08-26ready-to-ship — implemented and pushed on both branches; no PR opened

Parked markdown version

3 task(s) @@ -393,12 +392,6 @@

Backlog The 50 newest things to happen to the work in hand, newest first — issued, parked, filed. Every other section on this page is laid out by state, which is exactly why none of them can answer “what has been happening?”. Shipped work is not here: it is read from complete/index.md, and a thousand records deep it would crowd out everything anyone can still act on. Showing the newest 10; … opens the next 10.

- - - - - - @@ -452,7 +445,7 @@

Backlog Phase 3: stop installing pynufft in Hands/Heart CI and PyAutoCTI…

- + @@ -692,6 +685,12 @@

Backlog Cluster-scale gradient-search benchmark (Prodigy vs Nautilus…

+ + + + + +
2026-08-26issuedOrgan repo spellings split across two normalised keys
2026-08-24 filed wiki-currency's --check-version gate rots on every library main merge
2026-08-23 filed Brain board follow-ups: what real mornings surface

Epics markdown version

diff --git a/dashboard.md b/dashboard.md index 8d285589..eb8cee04 100644 --- a/dashboard.md +++ b/dashboard.md @@ -42,7 +42,7 @@ anything you could not verify. | Where | Count | |-------|------:| -| [In flight](#in-flight) (`active/`) | 2 | +| [In flight](#in-flight) (`active/`) | 1 | | [Parked](#parked) (`parked.md`) | 3 | | [Planned](#planned) (`planned.md`) | 5 | | [Backlog](#backlog) (`draft/`) | 135 | @@ -163,14 +163,6 @@ Issued — each has an open GitHub issue and usually a branch. The full record f
-
📋 Organ repo spellings split across two normalised keysissue #287 — issued 2026-08-26 — ready-to-ship — implemented and pushed on both branches; no PR opened - -``` -/start_dev active/organ_repo_spellings_split_across_keys.md -``` - -
- ## Parked Started or scoped, not currently in flight — resume by moving the row back to `active.md`. Full detail in [`parked.md`](parked.md). @@ -1188,7 +1180,6 @@ The 50 newest things to happen to the work in hand, newest first — issued, par | Date | Event | Task | |------|-------|------| -| 2026-08-26 | issued | Organ repo spellings split across two normalised keys | | 2026-08-24 | filed | wiki-currency's --check-version gate rots on every library main merge | | 2026-08-24 | filed | interferometer/jax_grad/gradient.py: eager and jitted likelihoods… | | 2026-08-24 | filed | euclid: CRLF has reached the HPC submit scripts AGENTS.md warns about | @@ -1198,12 +1189,12 @@ The 50 newest things to happen to the work in hand, newest first — issued, par | 2026-08-24 | filed | Heart's local smoke runner cannot run any CTI workspace — no autocti… | | 2026-08-23 | filed | pynufft removal: unswept downstream residue (1 hard break + stale… | | 2026-08-23 | filed | Phase 3: stop installing pynufft in Hands/Heart CI and PyAutoCTI… | +| 2026-08-23 | filed | Brain board follow-ups: what real mornings surface |
… 10 more (40 left) | Date | Event | Task | |------|-------|------| -| 2026-08-23 | filed | Brain board follow-ups: what real mornings surface | | 2026-08-22 | filed | smoke_install.sh's stale jax<0.7 pin — CI is on the right jax… | | 2026-08-22 | filed | Untrack the generated FITS test artifacts in autoarray | | 2026-08-22 | filed | The reconstruction noise map describes a different estimator than the… | @@ -1213,12 +1204,12 @@ The 50 newest things to happen to the work in hand, newest first — issued, par | 2026-08-20 | filed | Numba CPU likelihood phase 2: kernel-CDF numba fast path (the 49-88%… | | 2026-08-20 | filed | Numba CPU likelihood phase 1: batched MGE convolution +… | | 2026-08-19 | filed | autolens_workspace_test jax_likelihood pins: 4 scripts fail smoke on… | +| 2026-08-19 | filed | autofit_profiling: bootstrap the repo + general PyAutoFit profiling… |
… 10 more (30 left) | Date | Event | Task | |------|-------|------| -| 2026-08-19 | filed | autofit_profiling: bootstrap the repo + general PyAutoFit profiling… | | 2026-08-19 | issued | @PyAutoFit TransformedMessage.factor_gradient crashes on first… | | 2026-08-19 | filed | Release board: local run_logs enrichment | | 2026-08-19 | filed | RTD organism docs currency: Nerves page, organ-count drift, hands.md… | @@ -1228,12 +1219,12 @@ The 50 newest things to happen to the work in hand, newest first — issued, par | 2026-08-18 | parked | prior-message-collapse-design | | 2026-08-18 | filed | @PyAutoFit TransformedMessage.logpdf/pdf omit the transform… | | 2026-08-17 | filed | Which other searches need prior-support handling — coverage audit… | +| 2026-08-17 | filed | Teach repos_sync --write to stamp organ config surfaces |
… 10 more (20 left) | Date | Event | Task | |------|-------|------| -| 2026-08-17 | filed | Teach repos_sync --write to stamp organ config surfaces | | 2026-08-16 | filed | LogGaussianPrior misreports its own support as (-inf, inf) | | 2026-08-14 | filed | Three jax_likelihood pins are stale by ~1.24e-4 and fail the smoke… | | 2026-08-09 | found | isothermal-ell-sph-oversampling-at-the-cusp | @@ -1243,12 +1234,12 @@ The 50 newest things to happen to the work in hand, newest first — issued, par | 2026-08-06 | filed | Triage: Convolver "No blurring_image provided" warning in canonical… | | 2026-08-06 | filed | Rewrite PyAutoCTI docs/api — 55 of 89 autosummary entries are dead | | 2026-08-06 | filed | Dependency-cap refresh 2026-08: safe bumps, astropy 8 decision, two… | +| 2026-08-05 | filed | Give PyAutoFit searches a seed — today no search can be made… |
… 10 more (10 left) | Date | Event | Task | |------|-------|------| -| 2026-08-05 | filed | Give PyAutoFit searches a seed — today no search can be made… | | 2026-08-04 | filed | dataset/imaging/jwst_lw is untracked because the gitignore was never… | | 2026-08-04 | filed | cosmos_web_ring stores boolean masks as float64, wasting ~3.4 MB of… | | 2026-08-04 | filed | autolens_workspace_developer: broad stale-API rot (56 symbols, no CI) | @@ -1258,6 +1249,7 @@ The 50 newest things to happen to the work in hand, newest first — issued, par | 2026-07-31 | filed | interferometer/start_here.py OOM in nightly release-validation… | | 2026-07-31 | filed | Quick-update plotting cost — minutes per update, and it is not JAX… | | 2026-07-31 | filed | Cluster-scale gradient-search benchmark (Prodigy vs Nautilus… | +| 2026-07-30 | filed | plot coverage — follow-ups deferred from plot-coverage-gaps |