From 37d9f8b0b57b3d7745c825c6faa618e97cd48764 Mon Sep 17 00:00:00 2001 From: Jammy2211 Date: Thu, 16 Jul 2026 09:50:42 +0100 Subject: [PATCH] =?UTF-8?q?refactor:=20retire=20complete.md=20=E2=80=94=20?= =?UTF-8?q?the=20dated=20complete/=20records=20are=20the=20ledger=20(#81)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - backfill the 8 ledger entries that had no dated record (parity proven before deletion); keck-ao also recovers its stranded active/ prompt - lifecycle.py: record --date --from-file (ship skills supply the rich body; no complete.md parsing), move infers the bucket from an existing record, check gains post-retirement invariants, spent one-time subcommands (split-complete, migrate) deleted - git rm complete.md (history in git); index regenerated (594 records) - status.sh counts + recent-5 from complete/ records; README/AGENTS/REFERENCE/ OWNERSHIP/complete-AGENTS/parked/prompt_sync wording updated - scripts/spawn.py deliberately untouched (memory-structure-cleanup rewrites it in parallel; 1-line rider recorded on #81) Co-Authored-By: Claude Fable 5 --- AGENTS.md | 4 +- README.md | 13 +- REFERENCE.md | 27 +- complete.md | 6280 ----------------- complete/2026/07/eceb-editorial-revision.md | 7 + complete/2026/07/ep-analytic-updates-scope.md | 5 + .../2026/07/ep-deterministic-reconcile.md | 5 + complete/2026/07/ep-priors-fable-reassess.md | 6 + .../2026/07/keck-ao-acceptance-checks.md | 8 + .../07/morning-status-release-rehearsal.md | 6 + .../2026/07/release-profile-jax-default.md | 10 + complete/2026/07/slacs1430-acs-parity.md | 6 + complete/AGENTS.md | 21 +- complete/archive/README.md | 2 +- complete/index.md | 17 +- parked.md | 4 +- scripts/lifecycle.py | 287 +- scripts/prompt_sync.sh | 2 +- scripts/status.sh | 24 +- skills/OWNERSHIP.md | 2 +- 20 files changed, 193 insertions(+), 6543 deletions(-) delete mode 100644 complete.md create mode 100644 complete/2026/07/eceb-editorial-revision.md create mode 100644 complete/2026/07/ep-analytic-updates-scope.md create mode 100644 complete/2026/07/ep-deterministic-reconcile.md create mode 100644 complete/2026/07/ep-priors-fable-reassess.md rename active/keck_ao_acceptance_checks.md => complete/2026/07/keck-ao-acceptance-checks.md (53%) create mode 100644 complete/2026/07/morning-status-release-rehearsal.md create mode 100644 complete/2026/07/release-profile-jax-default.md create mode 100644 complete/2026/07/slacs1430-acs-parity.md diff --git a/AGENTS.md b/AGENTS.md index 15168262..818499a9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -42,8 +42,8 @@ For the full workflow narrative, conventions, and registry schemas, read prompts + dev notes). The old `z_features/`, `z_vault/` and `autoprompt/` top-level folders were retired here on 2026-07-13. - **Registry** — root-level markdown files, each with one job: `active.md` - (in-flight tasks), `planned.md` (scoped, not started), `complete.md` - (shipped), `parked.md` (started but not in flight), `queue.md` (ordered + (in-flight tasks), `planned.md` (scoped, not started), `parked.md` (started + but not in flight), `queue.md` (ordered input for `register_and_iterate --queue`), `ideas.md` (raw inbox swept by `$intake`, `/intake` in Claude). Mutate these only via the skills in `skills/` so commit messages stay consistent. diff --git a/README.md b/README.md index 98cacf2d..9d94b398 100644 --- a/README.md +++ b/README.md @@ -22,20 +22,21 @@ What lives here: | `ideas.md` | raw incubating ideas, no structure required | | `draft///*.md` | scoped prompts, **not started** (`feature/`, `bug/`, `docs/`, …) | | `active/.md` | **issued** prompts — an open issue, in flight | -| `complete///.md` | **shipped** — the rich completion record (`complete/AGENTS.md`) | -| `active.md`, `planned.md`, `complete.md` | the task ledger: in flight, queued, done | +| `complete///.md` | **shipped** — the rich completion record IS the ledger (`complete/AGENTS.md`) | +| `active.md`, `planned.md` | the live task ledger: in flight, queued | | `repos.yaml` | the body map — the single source of repo identity | | `scripts/` | registry sync + drift checks (`repos_sync.py`, `lifecycle.py`) | A prompt flows through three file states that mirror the ledger: idea → `draft/…` → `/start_dev` → GitHub issue + `active/` + `active.md` entry → -worktree development → PR → merge → `complete///` + -`complete.md`. `scripts/lifecycle.py` advances the file and drift-checks the -invariant. The registry is shared state, so any machine or session can pick up +worktree development → PR → merge → the dated record +`complete///.md` (the sole completion ledger; the monolithic +`complete.md` was retired 2026-07-16, issue #81). `scripts/lifecycle.py` +advances the file and drift-checks the invariant. The registry is shared state, so any machine or session can pick up an in-flight task. The schemas and conventions — prompt taxonomy, prompt file format, the -`active.md` / `complete.md` schemas, epic trackers, bootstrap on a new +`active.md` / completion-record schemas, epic trackers, bootstrap on a new machine — are in [REFERENCE.md](REFERENCE.md). How agents should operate this repo is in [AGENTS.md](AGENTS.md). diff --git a/REFERENCE.md b/REFERENCE.md index 3763ab38..869fb934 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -3,7 +3,7 @@ The registry schemas, prompt conventions, and workflow detail for this repo. Moved verbatim from `README.md` on 2026-07-10 — agent docs that point at README sections ("Prompt taxonomy", "Prompt file format", the `active.md` / -`complete.md` schemas) resolve here, one link from the README. +completion-record schemas) resolve here, one link from the README. --- @@ -111,9 +111,9 @@ fine — write naturally, the AI fills in the rest. /ship_workspace │ ▼ - PR merged ── post-merge cleanup deletes the worktree, moves the - │ active.md entry to complete.md, and advances the prompt - │ file active/ → complete/// (lifecycle.py move) + PR merged ── post-merge cleanup deletes the worktree, drops the + │ active.md entry, and writes the dated completion record + │ complete///.md (lifecycle.py record) ▼ done ``` @@ -122,7 +122,7 @@ The slash commands above are skills hosted across the organism (Brain, Heart) bu all read/write Mind's registry via workspace-root-anchored paths. One operates over the registry without starting work: -- `/health status` — dashboard of `active.md`, `planned.md`, `complete.md` +- `/health status` — dashboard of `active.md`, `planned.md`, `complete/` (a PyAutoHeart status view, reached through the single `/health` door). Continuity across execution environments needs no special step — any environment reads `active.md` and resumes an in-flight task. @@ -138,7 +138,6 @@ PyAutoMind/ ├── .gitignore │ ├── active.md ← tasks currently in progress (one ## section per task) -├── complete.md ← finished tasks (most recent first) ├── ideas.md ← raw incubating ideas, no structure required ├── parked.md ← started/scoped but not in flight (stashes, orphan worktrees, deferred) ├── planned.md ← issued tasks blocked from starting (created on demand) @@ -192,7 +191,7 @@ environments — see `OWNERSHIP.md`). General PyAuto tooling (release prep, dependency audits, smoke tests, lint sweeps) lives in `admin_jammy/skills/`. `scripts/prompt_sync.sh` is sourced by skills that mutate registry files -(`active.md`, `complete.md`, etc.) to commit and push back to origin. It +(`active.md`, `planned.md`, etc.) to commit and push back to origin. It replaces a now-removed `admin_sync.sh` helper that formerly operated on `admin_jammy/prompt/`. @@ -343,7 +342,12 @@ Each task is an H2 section: Free-form summary of progress and next steps. ``` -### `complete.md` schema +### Completion record (`complete///.md`) schema + +The dated records are the completion ledger (`complete/AGENTS.md`; the +monolithic `complete.md` was retired 2026-07-16, issue #81). Each record opens +with the same fields the old ledger entries carried, then the rich narrative +and, appended by `lifecycle.py record`, the original prompt: ```markdown ## @@ -351,8 +355,11 @@ Each task is an H2 section: - completed: YYYY-MM-DD - library-pr: [, ] - workspace-pr: [, ] -- notes: | - Long-form description of what landed, gotchas, follow-ups. +- summary: + +## Original prompt + + ``` ### Epic trackers (retired 2026-07-13) diff --git a/complete.md b/complete.md deleted file mode 100644 index a753d5e9..00000000 --- a/complete.md +++ /dev/null @@ -1,6280 +0,0 @@ -## heart-state-clobber -- issue: https://github.com/PyAutoLabs/PyAutoHeart/issues/78 -- completed: 2026-07-16 -- library-pr: https://github.com/PyAutoLabs/PyAutoHeart/pull/79 (merged) -- summary: PyAutoHeart test suite clobbered live ~/.pyauto-heart state; run() made side-effect-free in test_run + version_skew (sibling found by empirical sweep), persist moved to main() (tick unchanged), suite-wide HEART_STATE_DIR conftest sandbox + regression tests. Build-chain umbrella Phase 0a (epic PyAutoBuild#155). Shipped under human-authorized corrective-PR exception (Heart RED). - -## pyautolens-assistant-joss-paper (JOSS paper #2 scaffolded next to the software — SHIPPED) -- issue: https://github.com/PyAutoLabs/autolens_assistant/issues/69 (CLOSED) -- completed: 2026-07-15 -- workspace-pr: https://github.com/PyAutoLabs/autolens_assistant/pull/71 — MERGED (fa1aaa6, merge commit 3b5349f). wiki-currency CI green. -- summary: created `autolens_assistant/paper/` (paper.md 1309 words, paper.bib, README.md, .gitignore), mirroring the `PyAutoLens/paper_jax/` sibling. The author's four drafted sections (Summary / Statement of need / software design / benchmarks) existed ONLY inside the Mind prompt file — this consolidated them into a real manuscript. Title: "PyAutoLens-Assistant: Using Natural Language and AI to Analyse Gravitational Lenses". -- unblocked: had sat in planned.md since 2026-07-14 blocked-by benchmark-calibration (#59) holding the autolens_assistant repo claim. #59 closed → claim released → shipped from its own worktree. The block was recorded as an issue comment, which is where the resume context lived. -- bibliography provenance (REUSABLE PATTERN): extracted all 6 entries VERBATIM from `wiki/literature/bibliography/autolens_literature.bib` (1037 entries) via a brace-matching python extractor, rather than writing bib entries from memory. Fabricated/mistyped citations are the one failure mode a paper cannot absorb, and the repo already had verified entries. Cited: Nightingale2021 (PyAutoLens JOSS), Casey2023 (COSMOS-Web), EuclidCollaboration2025 (Q1 lensing), LSSTDarkEnergyScienceCollaboration2012, Vegetti2010 + Minor2021 (SDSSJ0946+1006 subhalo + high-concentration claim). -- decisions: benchmarks framed "three representative examples" (repo ships 4 prompts; hard_group_multi deliberately undescribed — author chose reframe over a 4th paragraph; framing recorded in paper/README.md so prose+prompt set can't drift). Author block mirrors the JAX paper (sole corresponding author). Renamed SLACS0946+1006 → SDSSJ0946+1006 to match the cited papers + the literature wiki. -- contract deviations (both surfaced, both evidence-backed): (1) NO pending-release label — it does not exist on autolens_assistant, ensure_workspace_labels.sh does not cover the repo, and PRs #70/#68/#66 all merged unlabelled. It guards the library-first merge gate, meaningless for a docs-only PR with no upstream library PR. Creating it would have invented a convention. (2) NO smoke tests — ship_workspace's smoke step assumes a workspace repo with scripts/; this repo has none and the change touches no code. Ran the repo's OWN gates instead: `make validate-literature-citations` + `audit_skill_apis.py`. -- verified: citations resolve 1:1 (6 cited / 6 defined / 0 missing / 0 unused); body 1309 words inside JOSS 750-1750; YAML front-matter parses with all required keys; audit 58 files/120 symbols/0 broken. NOT verified: Inara PDF build (docker not installed locally) — left unchecked on the PR Test Plan rather than claimed. -- trap avoided: `audit_skill_apis.py` writes a dated report to `autoassistant/audit/` as a side effect, which `git add -A` would sweep up — already gitignored (.gitignore:30), commit stayed clean. See [[feedback_ship_workspace_binary_leak]]. -- heart: shipped at YELLOW score 55 (no RED), author-acknowledged; both reasons ("workspace validation not passing (3 failed, 2026-07-09)"; "58 stale parked script(s)") pre-date the branch and are unrelated to a docs-only change. Ack recorded verbatim on the issue + in active.md. -- OPEN / needs author: `State of the field` + `Research impact statement` are commented stubs (JOSS requires both; neither draftable without author judgement). Benchmark-results prose stays FUTURE-TENSE because benchmarks/RESULTS.md records ZERO runs for all 4 benchmarks — despite #59 (first calibration campaign) being CLOSED. Either results exist un-ingested or the campaign closed without producing them; worth a look before submission. - -## release-profile-jax-default (delete the JAX override-list trap — SHIPPED) -- issue: https://github.com/PyAutoLabs/autofit_workspace_test/issues/46 (CLOSED) -- completed: 2026-07-15 -- pr: https://github.com/PyAutoLabs/autofit_workspace_test/pull/47 — MERGED (e97d71e, squash). -- summary: follow-on to [[multistart-adam-release-jax]] (#44/PR#45). PR#45 fixed the SYMPTOM (added 3 missing `set: {PYAUTO_DISABLE_JAX: "0"}` overrides); this removed the REASON the override list exists. `PYAUTO_DISABLE_JAX` is read in exactly one place that matters to autofit_workspace_test — `af.Analysis.__init__` — and `af.Analysis` defaults `use_jax=False`. So the release profile's `"1"` default was a NO-OP for ~35 of 42 scripts (already numpy) and SABOTAGE for the 7 that opt in. Zero speed benefit; its only effect was a hand-maintained "remember to add your script" list = the trap. Pinned `"0"`, `overrides: []`, -31 lines of config, bug class gone. Matches sibling autofit_workspace which always pinned "0". -- KEY LESSON (drove the design): a memory note recording this EXACT trap already existed, written the DAY BEFORE, and I walked into it anyway. Documentation does not fire at the moment of the mistake. Delete the thing-to-remember. See [[feedback_delete_the_trap_dont_document_it]]. -- rejected on evidence (do not redo): smoke_tests.txt promotion (per-PR gate hardcodes ENV_VARS_FILE=env_vars.yaml, never reads the release profile); static config guard (naive `use_jax=True` string rule false-positives on simulator_use_jax_parity.py which uses SimulatorImaging, unaffected by the env var); loud warning in af.Analysis (BUILT then KILLED by adversarial review — al flips use_jax BEFORE super().__init__() so it never fires for 54 autolens scripts, and ag/al default use_jax=True so it fires on default constructions claiming JAX "was requested"). Nothing pushed from that branch. -- verified: resolver sweep over all 42 scripts both profiles (31 change 1->0, 11 unchanged); latent_nan_robustness.py (opts in, JAX half ran for the FIRST time) exit 0 — no hidden bug; Nautilus/Emcee/latent/model_composition identical exit 0 under DISABLE_JAX=1 and =0. -- DO NOT COPY to autolens/autogalaxy_workspace_test: ag/al analyses default `use_jax=True`, so "1" is NOT a no-op there — flipping it is a real behaviour change across the whole surface. Open question filed: whether their mode=release validating numpy for most of the surface is intended. -- follow-ups: PyAutoFit#1372 (OPEN, retitled) = use_jax/PYAUTO_DISABLE_JAX inconsistent across af (default False, reads env) / ag (default True, doesn't) / al (default True, reads env EARLY, duplicating af). Fable research brief filed: draft/research/workspaces/env_profile_and_validation_gate_redesign.md. - -## arxiv-digest-announcement-window (#papers digest silently dropped papers — window anchored to submission, not announcement — SHIPPED) -- issue: https://github.com/PyAutoLabs/PyAutoMind/issues/79 (CLOSED) -- completed: 2026-07-15 (user reported the miss; diagnosed, fixed, backfilled + merged same session) -- pr: https://github.com/PyAutoLabs/PyAutoMind/pull/80 — MERGED (7d4e92d, squash). -- summary: user reported the #papers digest missing two strong-lensing papers announced 2026-07-15 (2607.12129 arc candidate in MACS J0308.9+2645; 2607.12209 NGC 6505 Einstein ring). The keyword query was NOT at fault — a 72h re-run returned both. `.github/scripts/arxiv_fetch.py` filtered on `` (v1 SUBMISSION) within a rolling 24h window (72h Mondays), but the arXiv API only indexes a paper once ANNOUNCED, 1–3 days after submission. Any paper whose announcement lag pushed its v1 timestamp outside the window was unseeable: not yet indexed on the run covering its submission, too old by the run that could first see it. Both papers were submitted Mon 20:24/23:18 UTC (after the Mon 14:00 ET cut-off) → announced Tue 20:00 ET = Wed 00:00 UTC; Wednesday's run looked back 24h to Tue 02:00 UTC and missed them by ~3h. Fix = anchor the window to arXiv's ANNOUNCEMENT BANDS (20:00 ET announce Sun–Thu; 14:00 ET deadlines Mon–Fri), derived from run time via `zoneinfo` so the ET→UTC offset tracks DST. Mon–Fri runs now take bands Thu→Fri, Fri→Mon, Mon→Tue, Tue→Wed, Wed→Thu = exactly one week, disjoint, gapless, still stateless. `LOOKBACK_HOURS` retained as the rolling escape hatch. -- the docstring lied, and that mattered: it claimed consecutive runs "cover disjoint day-bands (gapless)". True ONLY if papers are searchable at submission. They are not. Monday's 72h "weekend sweep" was the bug at its worst — it queried three days of submissions arXiv had not yet announced (weekend submissions announce Mon 20:00 ET, AFTER Monday's run), and Tuesday's 24h window had already moved past them. -- TRAP (cost me a failed CI run): `claude-code-action` REFUSES to run from a branch that edits its own workflow file — "Workflow validation failed... must have identical content to the version on the repository's default branch". Its guard against untrusted workflow edits running with repo secrets. So a workflow-editing PR CANNOT be smoke-tested end-to-end in real CI pre-merge; the first scheduled run on main is the first live outing. The workflow's own error message misleadingly fingers an expired CLAUDE_CODE_OAUTH_TOKEN first. I dispatched from the branch trying to backfill AND smoke-test in one shot; it died at the Claude step (nothing reached Slack — POST failed with no payload, so no harm). Re-fired from main and it worked: the backfill only needs the LEGACY rolling window, which main already had, so it never needed this PR at all. -- TRAP 2 — a green run is not evidence the window is right: a broken window yields count=0 → the "no new papers" heartbeat posts and the run goes GREEN. The design intent was "silence in #papers always means a broken run"; in practice a broken window is indistinguishable from a quiet day. Today's 02:00 scheduled run was exactly this: green, while dropping both papers. -- backfill: human chose a narrow window over the full 168h sweep. Reconstructing what each broken run EFFECTIVELY saw (its window ∩ the index frontier at that moment) showed the weekend region was empty — the only real gap was Mon 18:00 → Tue 02:00 UTC, holding exactly 3 papers (the 2 reported + 2607.12081 MOA microlensing, a keyword false-positive). Last already-posted paper was Mon 13:40, first gap paper Mon 18:58 → that 5.3h dead zone let a rolling W=40 hit the gap with ZERO duplicates. Run 29398900801 from main: count=3, Slack POST ok, Claude highlighted both lensing papers and dropped the MOA one. -- verified: `--selftest` (15 assertions: both DST regimes — EDT 14:00 ET=18:00 UTC / EST=19:00 UTC — all five run weekdays, the Fri→Mon weekend seam, 3h cron-slip stability, and both dropped papers pinned as a regression case) passes locally, on the branch CI runner, and on main post-merge. Live API run at a simulated Wed 02:00 UTC computes band 2026-07-13T18:00Z..2026-07-14T18:00Z and recovers BOTH papers, correctly excluding Monday's earlier ones (they belong to the previous band, which Tuesday's run owns). Override path re-checked: LOOKBACK_HOURS=72 still yields mode=lookback. -- design: kept the stateless band rather than a cross-run "seen IDs" store — exact disjointness instead of dedup-after-overlap, no committed state file to drift. Human accepted. Residual: papers announced out of band (submission held, cross-list added late) are still missed; a seen-ID store is the only real fix and is not worth it yet. -- NOT test-fired post-merge on purpose: at merge time the band computes to Mon 18:00→Tue 18:00 UTC — the exact 3 papers just backfilled — so a dispatch would have re-posted them. First live outing = the Thu 02:00 UTC scheduled run (band Tue 18:00..Wed 18:00). -- process note: the Brain Bug Agent misrouted this — it keyword-matched "lens/Einstein" from the PAPER TITLES into lensing_wiki, left the owner unresolved, called it `large`/library work, and asked for a reproduction already in hand. Overrode it and used the WORKFLOW.md emulation path. PyAutoMind is neither a library nor a workspace repo in the owner map; a worktree was used deliberately so Mind's main checkout stayed on main for registry ops (prompt_sync_push does `git add -A` on the current branch). -- process note 2: a staged `git mv` of the prompt got swept into a CONCURRENT session's `prompt_sync_push` commit (d1d2a0b, "route multistart-adam-release-jax"). Content landed correctly but under a misleading message — the `git add -A` trap now bites across parallel sessions sharing Mind's checkout, not just across branches. - -## multistart-adam-release-jax (release profile disabled JAX, breaking MultiStartAdam — nightly-release RED 5 nights — SHIPPED) -- issue: https://github.com/PyAutoLabs/autofit_workspace_test/issues/44 (CLOSED) -- completed: 2026-07-15 (found by /morning, fixed + merged same session) -- pr: https://github.com/PyAutoLabs/autofit_workspace_test/pull/45 — MERGED (ad95dd8, squash). -- summary: `nightly-release` failed 2026-07-11→07-15; Stage 3 (release-fidelity integrate) dispatched Heart workspace-validation mode=release and exactly ONE shard failed — autofit_test/searches. Cause: `autofit_workspace_test/config/build/env_vars_release.yaml` pins PYAUTO_TEST_MODE="0" (real sampler, so `_fit` runs — no bypass) AND PYAUTO_DISABLE_JAX="1" (forces use_jax=False). MultiStartAdam is JAX-native and hard-raises when `analysis._use_jax` is falsy (multi_start_gradient/search.py:120-126), so it raised. Regression from the multi-start promotion (PyAutoFit#1370 / this repo's #43, merged 2026-07-14) — NOT the perf-flake tail of the release-tail epic. Fix = 3 `set: {PYAUTO_DISABLE_JAX: "0"}` overrides (MultiStartAdam + Dynesty_jax + Nautilus_jax) + 1 smoke `unset: [PYAUTO_TEST_MODE, PYAUTO_DISABLE_JAX]` for MultiStartAdam. -- TRAP (cost me a plausible-but-wrong first fix): TWO env profiles. `env_vars.yaml` = the `smoke` profile; `env_vars_release.yaml` = mode=release. Reading the wrong one yields a fix that changes nothing. Sibling `autofit_workspace/scripts/searches/mle.py` uses the same search and passes ONLY because that workspace's release profile pins DISABLE_JAX="0"; the autolens/autogalaxy `guides/modeling/searches.py` construct MultiStartAdam but never `.fit()`, so never reach the guard. -- TRAP 2 (a claim I shipped wrong, then corrected): "smoke" is two things. The PER-PR gate is `.github/workflows/smoke_tests.yml` running the curated `smoke_tests.txt` (11 scripts; contains NEITHER MultiStartAdam NOR BlackJAXNUTS). `env_vars.yaml` instead feeds Heart's workspace-validation mode=smoke, which runs EVERY script weekly (Mon 03:00 UTC). So the smoke-profile override buys a WEEKLY net on the JAX path, not a per-PR one. I asserted per-PR in the PR body + commit message + code comment before checking; corrected in cb1b8f1 and in the squash message. Caught it only by verifying the change was real rather than trusting green checks — the PR's own smoke checks pass but never run the script. -- Dynesty_jax/Nautilus_jax were passing VACUOUSLY: they declare use_jax=True but were absent from the release overrides, so they validated the NumPy path while presenting as JAX tests. No backend guard = no loud failure. Both verified exit 0 with JAX on, so no bug was hiding behind them. -- verified: MultiStartAdam exit 0 recovering 50.156/25.196/9.858 vs truth 50/25/10 (release env AND smoke-resolved env); Dynesty_jax exit 0 (~10s); Nautilus_jax exit 0 (~25s). Env resolution driven through `autobuild.env_config.build_env_for_script` over the real configs for every scripts/searches/*.py — `_pattern_matches` substring-matches the full path INCLUDING extension, so `searches/Nautilus` would also catch `Nautilus_jax.py`; confirmed Nautilus.py + DynestyStatic/Dynamic.py correctly stay at DISABLE_JAX=1. -- residual: genuine PER-PR coverage would need MultiStartAdam.py promoted into the curated `smoke_tests.txt` — deliberately NOT done (cuts against "smoke tests are a small curated subset"); left as an open decision for the human. -- follow-on: tonight's nightly-release reaching Stage 3 clean is the actual proof; issue closed on merge with that stated. - -## slacs1430-acs-parity (SLACS1430+4105 ACS reduction vs legacy — pixel parity PASS — SHIPPED) -- issue: https://github.com/PyAutoLabs/PyAutoReduce/issues/17 (STAYS OPEN for the optional model-parity fit leg) -- completed: 2026-07-10 (pixel parity verdict + scripts); active.md entry retired 2026-07-14 (/morning, human-directed) -- pr: https://github.com/PyAutoLabs/PyAutoReduce/pull/23 — MERGED (0face12, squash). -- summary: PyAutoReduce production reduction of slacs1430+4105 reproduces the trusted legacy dataset up to fully-understood differences (astrometry: legacy is rot270 of north-up; photometry flux ratio 1.040; noise ratio ≈1.35=R, legacy family internally inconsistent on the correlated-noise correction; PSF tier-1 ePSF 0.129″ vs 0.120″). Acquire dup-product bug independently fixed on main by #18's is_direct_product. Full verdict table: issues/17 close-out comment 2026-07-10. -- residual (not blocking retirement): the optional model-level parity fits are checkpointed/OOM'd (NOT RUN) — #17 stays OPEN with that as its last checklist item (resume: `prototypes/slacs1430_parity_fit.py autoreduce`/`legacy`, serially on a quiet machine). Methodology notes seed the queued PJ011646 WFC3 follow-up. - -## keck-ao-acceptance-checks (Keck-AO checks 3–4 — plate-scale finding delivered — INTERIM, retired) -- issue: https://github.com/PyAutoLabs/PyAutoReduce/issues/13 (STAYS OPEN — real finding + resumable fit) -- completed: interim 2026-07-09; active.md entry retired 2026-07-14 (/morning, human-directed — no longer actively tracked) -- summary: Check 3 delivered a concrete result — the adapter's narrow-camera `native_scale` (9.942 mas) is wrong for both epochs; truth is 9.952 mas pre-2015 (Yelda 2010; B1938 raw PIXSCALE 0.009952 agrees) / 9.971 mas post-2015 (Service 2016), so shipped phase-4 mosaics read θ_E ~0.10% low. Proposed fix (gated on review): epoch-aware `native_scale` selected with the distortion solution. Check 4 lens fit (SIE+shear+Sersic, Nautilus) ran ~1h CPU, not converged, 94MB checkpoint. -- residual (not blocking retirement): the epoch-aware `native_scale` fix + the check-4 θ_E-vs-0.45″ convergence are documented on #13 with resume commands; #13 stays OPEN as the backlog anchor. The 94MB checkpoint was on a laptop that reset — may need re-running from scratch on a quiet machine. - -## ep-analytic-updates-scope (EP phase 6 — scope analytic conjugate updates — plan DELIVERED) -- issue: https://github.com/PyAutoLabs/PyAutoFit/issues/1337 (CLOSED — research deliverable done) -- plan: https://github.com/PyAutoLabs/PyAutoFit/issues/1338 (STAYS OPEN — implementation backlog, 4 WPs) -- completed: 2026-07-08 (scoping/plan); active.md entry retired 2026-07-14 (/morning, human-directed) -- summary: Read-only research phase 6 scoped analytic (conjugate) likelihood updates for the EP framework and delivered a four-work-package implementation plan on #1338 (exact PriorFactors, projection contract, linear-Gaussian, conjugate table) — plan-only per human direction (no implement). Backlog anchor: feature/autofit/ep_analytic_updates.md. #1337 (the research task) closed as its deliverable lives on #1338, which stays open for future implementation. - -## ep-priors-fable-reassess (priors/messages — 9 bugs fixed + 5 decisions resolved — SHIPPED) -- issue: https://github.com/PyAutoLabs/PyAutoFit/issues/1330 + decision hub #1331 (both stay OPEN for parked design work only) -- completed: 2026-07-10 (fixes shipped); active.md entry retired 2026-07-14 (/morning, human-directed after verification) -- prs: PyAutoFit#1345 (batch + decisions 1/3/4) + PyAutoFit#1348 (decisions 2/5) — both MERGED 2026-07-10. -- summary: The Fable audit of autofit/mapper/prior + autofit/messages found 9 confirmed bugs. All fixed, all 5 open decisions resolved, verified live on origin/main 2026-07-14. #1345: LogGaussianPrior.with_limits crash, UniformPrior.logpdf array input, TruncatedNormalMessage.log_partition (integrated to 2.27 → 1.0), FixedMessage.logpdf_cache aliasing; D1 Beta clamp → raises ValueError; D3 Gamma from_mode → match mean+variance (α=m²/V); D4 normalisation → drop constants + Prior.log_normalisation() hook. #1348: D5 RelativeWidthModifier → abs(mean) + optional absolute_floor, raises on ≤0 width; D2 NormalMessage → σ<0 rejected, σ=0 permitted. -- key trap: **D2 deviated from the strict recommendation to the permissive σ=0-preserving variant** — strict σ≤0 broke 20 tests across latent (simple_model_for_kwargs), from_mode(covariance=0), and model_centred_relative: the load-bearing σ=0 point-mass idiom [[sigma_zero_point_mass_idiom]]. Regression tests: test_priors_messages_fixes_1331.py + test_prior_width_safety.py. #1330/#1331/#1332 remain OPEN as umbrella hubs for parked design work (property-based tests, TransformedMessage docs, density refactor, hierarchy collapse, bijector migration) — NOT the fixed bugs. - -## ep-deterministic-reconcile (EP phase 5 — three deterministic-variable mechanisms — DECIDED) -- issue: https://github.com/PyAutoLabs/PyAutoFit/issues/1336 (CLOSED 2026-07-10) -- completed: 2026-07-10 (decided); active.md entry retired 2026-07-14 (/morning, human-directed) -- decision: **Recommendation A adopted** (human) — keep both composition paths (factor_out deterministic variables AND compound/shared-variable arithmetic), document the trade-off; no unification, no deprecation. The model. sugar from #1153 stays retired (reverted be6411755). Seam tests + lowering table shipped via #1334 (6803441); IC50 needs no migration. Remaining README §6 doc edit rides with the in-flight EP statistics PR. -- worktree: none (read-only research). - -## morning-status-release-rehearsal (morning Slack digest + release rehearsal — RESOLVED) -- issue: https://github.com/PyAutoLabs/PyAutoHeart/issues/39 (STAYS OPEN for the RELEASE_MODE=live leg) -- completed: 2026-07-09 (resolved); active.md entry retired 2026-07-14 (/morning, human-directed) -- prs: PyAutoBuild#119 + PyAutoHeart#40 + PyAutoMind#41 — all MERGED. -- summary: Morning-status Slack digest + health webhook restored and delivering. User re-set both May-17 secrets (webhook + CLAUDE_CODE_OAUTH_TOKEN); morning_health dispatched → Slack POST success. Digest needed 3 further Mind-main CI fixes (checkout, show_full_output, allowedTools Write; 51e869e/d042289/0b78d5f) → fully green. Resolution detail: issues/39#issuecomment-4924031684. -- residual (not blocking retirement): PyAutoHeart#39 intentionally stays OPEN for the human-gated `vars.RELEASE_MODE=live` flip on PyAutoBuild (TestPyPI → live PyPI), to be flipped when the maintainer is satisfied with the release train. The tracking entry is retired because the rehearsal/Slack scope is done and no repo claim remains. - -## eceb-editorial-revision (ECEB wiki rules — EC A&A template assets — MERGED) -- issue: https://github.com/Jammy2211/euclid_assistant/issues/6 (CLOSED) -- completed: 2026-07-14 (human-directed PR + merge in /morning session; docs-only) -- pr: https://github.com/Jammy2211/euclid_assistant/pull/8 — MERGED (squash, 2f4f2ee) 2026-07-14; branch deleted. -- summary: Editorial revision of `wiki/rules/acknowledgements.md` and `wiki/rules/references.md` to reference the bundled official EC A&A template assets under `knowledge/sources/euclid_assets/`. acknowledgements.md documents `\AckDatalabs` (ESA Datalabs macro) and replaces the stale "euclid.sty not present" open question with guidance to use the macros + refresh the style file from the ECEB template. references.md documents the A&A acknowledgements → references → appendices ordering. -- validation: both factual claims verified against the tracked assets before shipping — `\AckDatalabs` at `euclid.sty:361`, appendix-after-references at `blank.tex:529`. Docs-only prose; no code paths touched. -- note: the private manuscript companion (`/mnt/c/Users/Jammy/Science/euclid/paper`) is a separate deliverable outside this repo and was not part of this PR. - -## pyautolens-jax-joss-paper (PyAutoLens-JAX JOSS paper scaffold — MERGED) -- issue: https://github.com/PyAutoLabs/PyAutoLens/issues/608 (CLOSED) -- completed: 2026-07-14 (supervised; human acknowledged Heart YELLOW and directed merge) -- library-pr: https://github.com/PyAutoLabs/PyAutoLens/pull/609 — MERGED (merge commit eab44c046730bba72442b7c57896a1bf6bedad56) -- summary: Added `paper_jax/` alongside the published `paper/`, with the exact PyAutoLens-JAX title, author-supplied Summary and Statement of need, end-to-end benchmark draft, current JOSS section scaffold, bibliography, build instructions, and AI disclosure. The existing paper was unchanged. -- validation: 381 PyAutoLens tests passed; four GitHub Python 3.12/3.13 jobs passed; downstream smoke gate passed 53 checks across six workspaces with 0 failures and 2 configured skips. Docker was unavailable locally, so the documented Inara PDF command was not executed. - -## corrective-pr-heart-red (human-authorized corrective-PR exception for Heart RED — MERGED) -- completed: 2026-07-14 -- issue: https://github.com/PyAutoLabs/PyAutoBrain/issues/112 (CLOSED) -- prs: PyAutoBrain#113 (AUTONOMY.md exception + ship-skill links + contract test; main 1ae5ec8) + PyAutoMind#78 (- corrective-red: active.md schema note; main 66eb361) — both MERGED (squash) 2026-07-14. -- summary: Resolved the Heart-RED ship deadlock — RED forbids commit/push/PR-open at every autonomy level, but Heart can't clear a RED until the fixing source reaches main + wheels rebuild + release-integration validation passes, so the fix for the named RED defect couldn't ship. Added a narrow, auditable, HUMAN-AUTHORIZED corrective-PR exception to `AUTONOMY.md`: trigger (RED + a source fix repairing a named reason); contemporaneous human authorization quoting the exact RED reason + approving the specific corrective issue; permits ONLY commit/push/one pending-release PR mapped to that reason; forbids automatic merge/close/release/rehearsal/unrelated-scope (merge stays human, every release blocked while RED); four record sinks (issue, PR body, active.md `- corrective-red:` block, autonomy_log.md `corrective` row); names one reason when RED has several; parks without shipping on mixed-scope/stale-reason/missing-evidence/not-causal; recovery = human merge → fresh wheels + release-integration validation → new Heart verdict. Ship skills (ship_library/ship_workspace/WORKFLOW) link the exception, no policy duplication. Follow-up (same PR): the AGENT provides the quote — surfaces the exact RED reason string(s) verbatim from `pyauto-heart readiness` so the human authorizes what's shown, not a reconstructed string. 12-test deterministic contract test (`tests/test_corrective_red_exception.py`); 59 tests pass. -- key traps / findings: Design decisions (confirmed with human): HUMAN-ONLY (never under --auto; the invariant "Heart YELLOW/RED is never acknowledged autonomously" stays verbatim) + NAME-ONE-OF-SEVERAL RED reasons (PR scopes which reason it clears; siblings remain, release blocked until all clear). IRONY: this PR *builds* the corrective mechanism but doesn't qualify for it (repairs none of the named RED reasons) — so it shipped through organism-scoped Heart RED under the human's pre-existing "nothing branch-related" judgment (same call as the jax-gradient-optimizer-benchmark PR), authorized in-session ("Ship through the RED"). API Changes: none (doctrine/docs + tests). Contract-test seam: ship skills legitimately reference `autonomy_log.md` (calibration append) — the no-duplication test pins only exception-distinctive tokens (`- corrective-red:`, "park without shipping", "recovery sequence"). - -## lifecycle-state-split (draft/active/complete prompt-file lifecycle + archive wiki — MERGED) -- completed: 2026-07-13 -- issue: https://github.com/PyAutoLabs/PyAutoMind/issues/71 -- prs: PyAutoMind#72 (structure+engine+rewire) + #73 (557 dated records, active/ 440→7, complete.md kept+paired) + #74 (lifecycle.py record) + #75 (Phase-2 index wiki) + PyAutoBrain#109 (skills) + #110 (ship_* record hook) — all MERGED (squash) 2026-07-13. -- summary: Split the flat 444-file issued/ pile into a draft/ -> active/ -> complete// prompt-FILE lifecycle mirroring the active.md -> complete.md ledger. scripts/lifecycle.py (stdlib) owns move/record/split-complete/migrate/index/check. complete.md split into 557 dated rich records under complete/YYYY/MM (kept + paired 1:1 by slug, check-enforced); active/ pruned 440->7 in-flight (287 done/legacy dropped, git-recoverable). Phase-2: generated token-light complete/index.md (curated Highlights band + per-bucket links/hooks), lifecycle_drift.yml CI (check + index --check). create_issue -> active/, ship_* -> lifecycle.py record. Templates republished. TRAP: spawn.py template coupling forces structural+spawn+republish atomic; docs/ mixed prompts+specs (only Type:-headed moved to draft/docs/); #74/#75 both touched lifecycle.py subparser -> rebased #75. - -## refactor-post-phase3 (PyAutoReduce post-phase-3 refactor — MERGED) -- issue: https://github.com/PyAutoLabs/PyAutoReduce/issues/8 (CLOSED) -- completed: 2026-07-09 (present-and-wait; human-directed merge in the keck-ao session). Retired to complete.md 2026-07-13 (/morning; worktree was already released). -- pr: https://github.com/PyAutoLabs/PyAutoReduce/pull/10 — MERGED (squash, 371721f) 2026-07-09. -- summary: behaviour-preserving PyAutoReduce refactor; witnesses byte-identical output on both paths. 2 disclosed fix riders (CPDIS fobj, ePSF window +20) caught by baseline capture. - -## rect-adapt (rectangular adaptive-mesh edges — MERGED) -- issue: https://github.com/PyAutoLabs/PyAutoArray/issues/372 (CLOSED) -- completed: 2026-07-10 (--auto chain; human-directed merge via the kernel-cdf session; coordinated order #375→#374). Retired to complete.md + worktree/branch cleaned 2026-07-13 (/morning). -- pr: https://github.com/PyAutoLabs/PyAutoArray/pull/375 — MERGED (squash) 2026-07-10. -- summary: rectangular adaptive-mesh `edges_transformed` fix. Consumers `plot/inversion.py` (pcolormesh) + `mesh_geometry/rectangular_rotated.py` both inherit it. Verification upthread on #372. Follow-up mcmc-corner-smoke (a nightly blocker) was queued in planned.md on autofit_workspace/PyAutoFit claims. - -## ep-negative-sigma-crash (EP hierarchical factor sigma<0 — MERGED) -- issue: https://github.com/PyAutoLabs/PyAutoFit/issues/1363 (CLOSED) -- completed: 2026-07-13 (--auto; effective supervised = min(safe header, bug cap); human ship sign-off + YELLOW-ack + merge at the checkpoint) -- pr: https://github.com/PyAutoLabs/PyAutoFit/pull/1364 — MERGED (squash) 2026-07-13 (main 301c0a2fa). -- summary: nightly `workspace-validation` RED on `autolens/guides` — the EP guide crashed intermittently with `NormalMessage sigma cannot be negative`. Root cause: the guide's `HierarchicalFactor` draws `mass.slope` from `GaussianPrior(mean, sigma)` whose `sigma` is a truncated hyper-prior (`lower_limit=0`); the factor's **Laplace/Newton** optimiser overshoots below 0 (scale posterior at `mean≈0.0005`, hard against the boundary), so `Factor.__call__` built `GaussianPrior(sigma<0)` and tripped the strict `NormalMessage` guard. Fix (`graphical/declarative/factor/hierarchical.py`): `Factor.__call__` catches `exc.MessageException` → returns `-inf` (out-of-support = zero density, correct EP semantics). Strict guard untouched; stale `RelativeWidthModifier` hint in `messages/normal.py` corrected. Deterministic regression test `test_autofit/graphical/hierarchical/test_negative_scale.py`. Guide untouched (no autoimmunity). API Changes: none (internal). Option (iii) no workspace impact. -- key traps / findings: **smoke guide-script crashes in the nightly's test-mode env** (`PYAUTO_TEST_MODE=1 PYAUTO_SMALL_DATASETS=1 PYAUTO_FAST_PLOTS=1` — fast, reduced *real* sampler), NOT full mode (a full-mode run took hours and never reached the crash locus). Base + test-mode crashed on run 1 (`sigma=-0.07…` via `graphical.laplace.newton`); fix + test-mode ran clean. `TEST_MODE=1`=reduced real sampler, `=2`=sampling bypassed. Gate: full `test_autofit/` 1473p/1s; graphical in-order 218p. Rider: `test_full_hierachical` is order/RNG-flaky pre-existing on main (passes in-order, fails isolated — identical value with fix stashed); unrelated. Worktree removed + branches deleted post-merge. - -## autofit-navigator-catalogue-staleness (regenerate — MERGED) -- completed: 2026-07-13 (filed + fixed same session; no GH issue — trivial) -- pr: autofit_workspace#93 — MERGED (squash) 2026-07-13. -- summary: autofit_workspace `navigator / Catalogue staleness` CI was red on main (surfaced merging Group B #151). Cause: a stale `Search: NSS` entry in `workspace_index.json`/`llms-full.txt` left after the NSS sampler removal. Fix: `PyAutoBuild/autobuild/regenerate_navigator.py autofit` → only the 2 catalogue files changed (no incidental churn). CI green post-merge (navigator staleness + smoke). Recurrence note (from the prompt): consider auto-regenerating the catalogue in pre_build/pre-commit so it can't drift on main again. - -## release-datasets-group-b (bare-`dataset/` repos — purged & MERGED) -- issue: https://github.com/PyAutoLabs/PyAutoBuild/issues/151 (CLOSED) -- completed: 2026-07-13 (--auto continuation; user directed "do group b"; merges human-directed) -- prs: autofit_workspace#92 + HowToFit#19 + HowToGalaxy#22 + HowToLens#31 — all MERGED (squash) 2026-07-13. -- summary: Group B of the release-dataset `-f` leak (companion to Group A #126). The 4 bare-`dataset/` repos had ALL their simulated data force-committed. Resolution = **b1 purge** (not b2 allowlist): investigation showed all four already self-provision via `if not dataset_path.exists(): subprocess.run([sys.executable, ".../simulator.py"])` (autofit/HowToFit `path.exists()`+`from_json` toy 1D-Gaussian; HowToGalaxy/HowToLens `dataset_path.exists()`+`from_fits` tutorial imaging) — the prompt's "no should_simulate idiom" was true of the *string* only. No real data committed → full `dataset/` purge, bare `dataset/` intent preserved. Smoke all green (10/10, 10/10, 4/4, 6/6). Purged 408+408+21+27 files via PyAutoGut (condemned.md; pre-purge SHAs 1254a2fe/ccc19584/caf1657c/554be8b4). Leg 1 (`-f` drop) prevents recurrence; leg-4 guard skips bare-`dataset/` repos. **Whole leak now resolved across all 6 workspace repos.** -- rider found: autofit_workspace `navigator / Catalogue staleness` CI is red on **main** (pre-existing since ≤2026-07-12, unrelated — catalogue doesn't reference dataset/); autofit#92 merged despite it (not a required check). Filed `bug/autofit_workspace/navigator_catalogue_staleness_on_main.md`. - -## release-ships-simulated-datasets (Group A — all 4 legs complete & MERGED; Group B separate) -- issue: https://github.com/PyAutoLabs/PyAutoBuild/issues/126 (CLOSED) -- completed: 2026-07-13 (--auto supervised; user greenlit "go" + route purges via PyAutoGut; merges human-directed) -- prs: PyAutoBuild#150 (leg1 `-f` drop + leg4 `autobuild/check_dataset_allowlist.py`) + autolens_workspace#272 (~207 files purged) + autogalaxy_workspace#129 (~107) — all MERGED (squash) 2026-07-13. Merged workspaces-first, guard-last (nightly-release safety). -- summary: `pre_build.sh`'s `git add -f dataset/` force-committed simulated datasets against each workspace `.gitignore` allowlist (the disproven "15×15 smoke" framing of #126). Fix: **leg 1** drop `-f`; **leg 2** MOOT (workspaces already self-provision via the older `not dataset_path.exists(): subprocess.run([...simulator...])` idiom — 130+ scripts; the prompt's "7 unguarded" and an interim "16 needs-guard" were both wrong, keyed on the `should_simulate` string); **leg 3** purge every non-allowlisted regenerable dataset via **PyAutoGut** (`condemned.md` type:file, sweep-after 2026-08-13, archive-ref = pre-purge fork SHA 8625a1de/e940f8cd, in main history); **leg 4** allowlist-based guard in pre_build (allowlist-presence-gated so bare-`dataset/` Group-B repos skip). Final smoke autolens 9/9 + autogalaxy 8/8 (re-run after every purge). -- key traps / findings: guard signal is the simulator-subprocess, NOT the `should_simulate` string (topic-namespaced dataset_names; `samples` is `dataset_label="samples"`+`dataset_sample_name`, nested → guarded by advanced graphical/hierarchical/EP guides). Leg-4 guard **caught a leak the manual audit missed** — `dataset/imaging/los_halos` mixed real-looking `.npy` + simulated `.fits`; on inspection simulator.py `np.save()`s the `.npy` too (output, nothing reads them) so BOTH purged + de-allowlisted. User calls: `interferometer/simpleold` killed (dead); `interferometer/many_visibilities` kept→allowlisted (active); autogalaxy `database/simple__{0,1,2}` kept→allowlisted (committed-by-design aggregator = Group-B b2). `interferometer/dark_matter_subhalo` (sim-only, no consumer) purged. gh traps hit: `gh pr edit` fails Projects-classic (use `gh api PATCH`); `sed s///` breaks on `9/9` slash (use python). -- Group B: `bug/pyautobuild/release_datasets_group_b_policy.md` (autofit/HowToFit/HowToGalaxy/HowToLens bare-`dataset/`; leg-4 guard skips them until they adopt allowlists). -- worktree ~/Code/PyAutoLabs-wt/release-ships-simulated-datasets — safe to remove (all merged; PyAutoHeart branch unused). - -## lenstool-scaling-reference-magnitude (PR1 cluster + PR2 group/imaging — complete; PR3 SLaM deferred) -- issue: https://github.com/PyAutoLabs/autolens_workspace/issues/265 -- completed: 2026-07-10 (registry reconciled 2026-07-13) -- prs: autolens_workspace#267 (PR1 cluster) + autolens_workspace#268 (PR2 group+imaging) — both MERGED 2026-07-10 (squash). Both on main (cd0a965a/0f941072/99999a3f). -- summary: LensTool reference-magnitude (mag0) scaling-relation convention — explicit fixed reference luminosity (not max-of-sample), fixed exponent 0.5, full dPIE r_core/r_cut/b0 scaling (added ra_ref). Delivered as 2 of a planned 3 sequential PRs: cluster examples (#267) then group + imaging feature examples (#268). PR3 (SLaM pipelines) was scoped but never started; deferred to planned.md as lenstool-scaling-slam. Gotcha (recorded for the follow-up): notebook regen via generate.py autolens surfaces PRE-EXISTING catalogue drift (multi/features notebooks + llms-full.txt/workspace_index.json) that must be reverted so only the scaling-scoped files are staged. -- close-out 2026-07-13: registry entry was stale (active.md still read "PR1 #267 OPEN/unmerged" though both PRs merged 2026-07-10). Freed the autolens_workspace claim on user request — worktree ~/Code/PyAutoLabs-wt/lenstool-scaling-reference-magnitude removed (clean, no unmerged/uncommitted/gitignored work; the slam branch sat 0 commits ahead of main), local branches feature/lenstool-scaling-{reference-magnitude,slam} deleted. Merged remote branches origin/feature/lenstool-scaling-{reference-magnitude,group-imaging} left for routine remote cleanup. - -## manifest-drift-organ-registration (firewall + spawn spec + pointer sweep — complete) -- completed: 2026-07-13 -- prs: PyAutoMind#68 (fbf1055) + Jammy2211/euclid_assistant#7 — both MERGED 2026-07-13 (squash); PyAutoMind-template + PyAutoMemory-template republished (spawn regenerate from fbf1055). -- summary: cleared the manifest drift surfaced by the 2026-07-13 /morning (/health Heart YELLOW tenant-firewall 12 mismatches + failing spawn_drift + one CLAUDE→AGENTS pointer miss), all fallout from recent work (the /morning bin scripts, hygiene conductor, perf Heart legs, PyAutoGut condemned.md, skill-wrapper symlinks) landing without manifest registration. **repos_sync.py**: registered the 12 new organ-code files in FIREWALL_ALLOWLIST → tenant-firewall OK (Heart's manifest_drift.py shells out to repos_sync --check, so this directly cleared the YELLOW). **spawn.py + spawn_spec.md**: registered the 7 new PyAutoMind paths — condemned.md→EMPTY (registry file like parked.md), policy/**→KEEP (org-agnostic safety), .claude/** + .codex/**→DROP (installer artifacts); excluded the generator's own scripts/spawn.py from canary_scan (it defines CANARY_TOKENS as machinery). **Template republish**: spawn --write + normal-push sync of both -template repos (they were significantly stale) → spawn_drift red→green (run 29245239306). **euclid_assistant#7**: CLAUDE.md→content-free @AGENTS.md pointer + canonical AGENTS.md header — finished the Jammy2211 tail of the AGENTS.md standardization epic (maintenance/jammy2211/agents_md_pointer_sweep.md, now Status: complete; autofit_workspace_developer already compliant, admin_jammy AGENTS-less record-only). Also housekeeping: got PyAutoMind's primary checkout back on main (freed main from a stale codex worktree, ff'd 91 commits d58127f→704b667, deleted stray tmp-land-navigator). - -## pyautogut-organ (Gut organ + hygiene drive seam — complete) -- completed: 2026-07-12 -- prs: PyAutoMind#65 (2e12e85) + PyAutoBrain#104 (4e4258d) — both MERGED 2026-07-12 (squash); PyAutoGut repo bootstrapped on main (c0dd6ee). Decision: research/pyautobrain/pyautogut_organ_decision.md (decided). Prompts: issued/pyautogut_repo_skeleton.md + issued/hygiene_pyautogut_drive_seam.md. -- summary: grew the sixth organ, **PyAutoGut** (the Gut) — owns the lifecycle of condemned self-material (stale branches, stashes, dead code/tests) as durable, recoverable git refs until voided on a sweep; the storage mirror of Memory (retention vs release). Passes the persistent-reusable-artifact-lifecycle test hygiene failed → consistent doctrine, not a reversal; organ settled by elimination (gut owns voiding, not the spleen). **Repo**: bin/pyauto-gut (archive/recover/list/void; void gated behind --yes), AGENTS.md boundaries (vs Immune/hygiene/Memory/Heart), condemned.md manifest in the Mind (symmetric to parked.md). Registered as a peer organ in repos.yaml + ORGANISM.md (organism-map blocks regenerated → 6 organs). **Drive seam** (mirrors Heart↔vitals; the conductor stays a planner, never mutates): hygiene `tidy` is now PyAutoGut-aware — enumerates 95%-sure debris and emits an async condemnation plan (proposed condemned.md entries + exact `pyauto-gut archive` calls + computed sweep-after), no synchronous per-item repo_cleanup interrogation, merged branches skip the pen; new `sweep` mode reads condemned.md via stdlib _hygiene_condemned.py, classifies by transit clock (due/pending/undated), emits the batch void plan (`pyauto-gut void`) behind the existing repo_cleanup gates (no second gate). Tests: test_hygiene_conductor 14p (added tidy async-condemn + sweep transit-clock, incl. HTML-comment exclusion). **Namespace revision** (implementation finding, recorded in the decision doc): the archive namespace is refs/heads/archive/condemned/ (a pushable branch prefix), NOT the decided custom refs/archive/* — GitHub only accepts pushes to refs/heads/* and refs/tags/*. Env caveats (cloud session): PyAutoGut created via the GitHub UI by the user (org repo-creation not permitted to the integration); ref-deletes / `void` are proxy-blocked from the session, leaving one stray test branch `archive/condemned/__selftest_branch__` on the PyAutoGut remote for manual deletion. - -## restore-truncated-howto-tutorials - -## howto-markdown-resync -- issue: https://github.com/PyAutoLabs/HowToLens/issues/28 (closed) -- completed: 2026-07-11 -- prs: HowToLens#29 (ab01aaca) + HowToFit#17 (e738b085) + HowToGalaxy#20 (442db308) — all MERGED 2026-07-11 -- summary: re-synced 4 stale HowTo ch1 markdown pages after the truncation-restore work merged post-batch-2b. HowToLens tutorial_1+tutorial_2 re-rendered from restored scripts (were truncated → now full, 16+14 imgs); HowToFit tutorial_5 re-render; HowToGalaxy tutorial_4_methods dropped (stub). markdown/+1 config entry only, no scripts/CI. Calibration merged-unchanged. - -- issue: https://github.com/PyAutoLabs/HowToLens/issues/26 (CLOSED) -- prs: HowToLens#27 + HowToGalaxy#19 + HowToFit#16 — all MERGED 2026-07-11 (docs-only, library-free) -- completed: 2026-07-11 -- summary: /intake → --auto supervised. HowToLens ch1 tutorial_1/tutorial_2 were cut off mid-docstring — an LLM output-token cutoff during the workspace bootstrap (frozen at the truncated length since commit #1, original source gone). Restored tutorial_1 (429→672, log10+Galaxies+Units+WrapUp adapted from the complete 654-line HowToGalaxy sibling) and tutorial_2 (214→391, ray-tracing grids/images/Galaxies/Tracer/Mappings/WrapUp from guides/tracer.py). These two were the ONLY genuine truncations across all three HowTo repos. Prevention: .github/scripts/check_tutorials_complete.py + a `tutorials-complete` CI job in all 3 repos requiring every non-stub tutorial to reach a terminal __Wrap Up__/__Summary__ section (a truncation never does). Also filled HowToGalaxy's empty tutorial_4_methods (0 bytes since bootstrap → not-written stub) + normalized 12 complete-but-unmarked tutorials across the 3 repos. Smoke 6/6 + 4/4 + 10/10; all CI green incl the new check. Heart YELLOW (6 ambient reasons) acked in-session at each ship; merges human-approved. Worktree + branches cleaned. Traps in [[project_howto_truncation_restore]] (linter must live in .github/scripts not scripts/, else notebook-gen converts it; revert dataset/ before staging; single-backslash LaTeX in docstrings). - -## hygiene-file-modes (crlf / config / artifacts — complete) -- issue: PyAutoBrain#96 (closed) ; prompt issued/hygiene_file_hygiene_modes.md -- completed: 2026-07-11 -- prs: PyAutoBrain#97 — MERGED 2026-07-11 (squash), --auto supervised, live sign-off -- summary: three cheap org-specific hygiene conductor modes, added on demonstrated recurring need (grounded 2026-07-11: no lint/ruff in CI; documented CRLF, config-drift, output-leak gotchas — nothing else catches them). Conductor-only, NO Heart legs (point-in-time debris/surface, cheap file/git scans in the fast default scan). **crlf** (debris→/refactor): `git grep -Il $'\r$' -- '*.py'` — LIVE FOUND 649 CRLF .py files (PyAutoArray 224, PyAutoGalaxy 223, PyAutoFit 96, PyAutoLens 77, PyAutoConf 28, PyAutoBuild 1). **config** (surface→/refactor): agents/conductors/hygiene/_hygiene_config.py (stdlib+PyYAML, graceful degrade) recursive key-path diff of each library config/*.yaml vs matching workspace config — LIVE FOUND 17 keys missing downstream (autogalaxy 13/autofit 3/autolens 1). **artifacts** (debris→/repo_cleanup): tracked files under outputs?/ (EXCLUDING output_test fixture) + stray data-ext outside dataset/test — low-FP, LIVE FOUND 4 (PyAutoFit 2, autogalaxy_workspace 2). Default ranking now picks highest-count debris (tidy/crlf/artifacts). User decision: NOT normalizing the 649 CRLF files yet (library-touching, big diff — separate task; would pair with a .gitattributes `* text=auto` guard). Candidate future checks discussed + deferred (demonstrated-need doctrine): lint/dead-code (better as pre-commit), coverage + flaky-test (heavy/off-tick). Tests: config helper recursive-diff fixture; PyAutoBrain 42p. - -## hygiene-perf-phase4 (unit-test / workspace-testmode / function profiling — complete) -- issues: PyAutoHeart#63 (4a) + PyAutoHeart#65 (4b) closed; prompts issued/hygiene_{unit_test_timing,workspace_testmode_timing,function_profiling}.md -- completed: 2026-07-11 -- prs: PyAutoHeart#64 (4a unit_test_timing) + PyAutoHeart#66 (4b workspace_testmode_timing) + PyAutoBrain#94 (perf aggregates all timing legs) + PyAutoBrain#95 (4c perf --profile) — all MERGED 2026-07-11 (squash), --auto supervised, live sign-off -- summary: reopened + closed the hygiene perf scope. The originally-shipped perf mode covered only import timing; the original prompt also asked for unit-test speed, workspace-scripts-in-TEST_MODE speed, and non-likelihood function profiling (user caught the narrowing). Built all three: **4a** heart/checks/unit_test_timing.py (parses `pytest --durations`, validated vs real output), **4b** heart/checks/workspace_testmode_timing.py (`PYAUTO_TEST_MODE=2`+`SMALL_DATASETS`; curated start_here scripts), **4c** agents/conductors/hygiene/_hygiene_profile.py + `perf --profile