lifecycle: validate the registry files in check, reconcile planned.md - #158
Merged
Conversation
planned.md holds 12 entries, 8 of them wrong, and `lifecycle.py check` reports OK through all of it — cmd_check never opens planned.md or parked.md and never resolves a prompt: path. Found while task-selecting: the two highest-leverage planned entries (notebook-kernel-cwd-auto-simulate, auto-simulate-guard-wrong-simulator-target) are both already fixed on main. Verified rather than assumed — PyAutoHands build_util.py now routes through run_notebook.py, and an audit of all 246 should_simulate guards in autolens_workspace against the 54 simulators' declared outputs found 236 resolvable and 0 mismatches. Scopes an offline-only check plus the reconciliation of the 8 drifted entries and the first test for lifecycle.py. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GW2wFpSkZtXr8VzM5w8MpX
`check` reported OK over a planned.md in which 9 of 13 entries were wrong,
because cmd_check never opened planned.md or parked.md and never resolved a
`prompt:` path. It validated only two conditions, both about active.md and
the state folders.
Adds three registry checks: every `prompt:` path resolves, exactly rather
than via the legacy fallback; it resolves into a state folder its registry
implies (planned -> draft, active -> active, parked -> either, since parked
holds both scoped and started-then-parked tasks); and no slug is listed in
two registries.
Reconciles what it found. Six of the thirteen entries were work that had
already shipped -- verified on each upstream main, not inferred:
notebook-kernel-cwd-auto-simulate PyAutoHands build_util.py routes through
run_notebook.py, setting the kernel path
auto-simulate-guard-wrong-target autolens_workspace: 236 resolvable
guards audited, 0 mismatches
build-testpypi-rehearsal-mode (M1) PyAutoHands release.yml `rehearsal` input
heart-ci-linkage (M0) PyAutoHeart heart/checks/ci_status.*
heart-release-validation (M2) PyAutoHeart heart/validate.py + ingest
heart-release-profile-wheel (M3) PyAutoHeart named `release` profile
The entire M0-M3 release-validation chain shipped without one entry being
retired. Removed rather than given fabricated complete/ records: they
shipped under other tasks' PRs, and dated records nobody verified would put
a worse lie somewhere more trusted. Three legacy PyAutoMind/<type>/<target>/
paths normalised to draft/.
First test for lifecycle.py: fictional, hermetic fixtures per the
KEEP-copied-into-the-template rule, each leg driven with input that trips
it. Two checks were themselves wrong before these tests pinned them -- the
parked.md state rule and the trailing-parenthetical path form.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GW2wFpSkZtXr8VzM5w8MpX
Jammy2211
pushed a commit
that referenced
this pull request
Aug 8, 2026
Three follow-ups to the registry-integrity work (#158). 1. `lifecycle.py orphans` — the mirror of the checks added there. Those validate registry -> prompt; this validates prompt -> registry, listing active/ prompts that no entry claims. A prompt counts as claimed by a resolving `prompt:` path or by an entry whose slug matches its stem, since many entries predate the `prompt:` convention. Report-only, NOT wired into `check`: 8 of 10 active/ prompts are currently unclaimed, and a gate nobody can turn green gets disabled. `--check` exits non-zero for once that backlog is clear. 2. complete/2026/06/build-testpypi-rehearsal-mode.md — the M1 release-rehearsal task, which shipped 2026-06-30 as PyAutoHands #111 (71936fb) and left its prompt stranded in active/ for six weeks. Reconstructed after the fact and labelled as such; the merge body itself names unblocking the Heart release-validation gate (M2). This is the record #158 declined to write before the upstream evidence existed. Folds and removes the active/ prompt. 3. draft/maintenance/pyautomind/active_prompt_orphan_triage.md — the remaining 7 orphans, with per-outcome disposal and the steps to turn `orphans` into a gate afterwards. One is pre-diagnosed: ep_optimise_expose_updater_delta.md belongs to an active.md entry already marked COMPLETE with both PRs merged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GW2wFpSkZtXr8VzM5w8MpX
Jammy2211
added a commit
that referenced
this pull request
Aug 8, 2026
…ge (#159) Three follow-ups to the registry-integrity work (#158). 1. `lifecycle.py orphans` — the mirror of the checks added there. Those validate registry -> prompt; this validates prompt -> registry, listing active/ prompts that no entry claims. A prompt counts as claimed by a resolving `prompt:` path or by an entry whose slug matches its stem, since many entries predate the `prompt:` convention. Report-only, NOT wired into `check`: 8 of 10 active/ prompts are currently unclaimed, and a gate nobody can turn green gets disabled. `--check` exits non-zero for once that backlog is clear. 2. complete/2026/06/build-testpypi-rehearsal-mode.md — the M1 release-rehearsal task, which shipped 2026-06-30 as PyAutoHands #111 (71936fb) and left its prompt stranded in active/ for six weeks. Reconstructed after the fact and labelled as such; the merge body itself names unblocking the Heart release-validation gate (M2). This is the record #158 declined to write before the upstream evidence existed. Folds and removes the active/ prompt. 3. draft/maintenance/pyautomind/active_prompt_orphan_triage.md — the remaining 7 orphans, with per-outcome disposal and the steps to turn `orphans` into a gate afterwards. One is pre-diagnosed: ep_optimise_expose_updater_delta.md belongs to an active.md entry already marked COMPLETE with both PRs merged. Claude-Session: https://claude.ai/code/session_01GW2wFpSkZtXr8VzM5w8MpX Co-authored-by: Claude <noreply@anthropic.com>
This was referenced Aug 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
scripts/lifecycle.py checkreported OK over aplanned.mdin which 9 of 13 entries were wrong.cmd_checkvalidated only two conditions, both aboutactive.mdand the state folders — it never openedplanned.mdorparked.md, and never resolved a singleprompt:path.The registry is the first thing a task-selection pass reads, so the rot has a measured cost: a session picked the two highest-leverage
planned.mdentries and spent most of itself discovering both were already fixed on main.What this adds
Three registry checks over
active.md/planned.md/parked.md:prompt:path resolves — and resolves exactly, not via the pre-lifecyclePyAutoMind/<work-type>/<target>/fallback;planned→draft/,active→active/,parked→ either, sinceparked.mdholds both scoped and started-then-parked tasks;Output shape and the exit-code contract (
0OK,1drift) are unchanged.What this reconciles
Six of the thirteen entries were work that had already shipped — verified on each upstream
main, not inferred:notebook-kernel-cwd-auto-simulatebuild_util.py:302routes throughrun_notebook.py, settingresources['metadata']['path']auto-simulate-guard-wrong-simulator-targetshould_simulateguards audited against the 54 simulators' declared outputs, 0 mismatchesbuild-testpypi-rehearsal-mode(M1)release.yml—rehearsaldispatch input,resolve_modejob, downstream jobs gatedif: rehearsal != 'true'heart-ci-linkage(M0)heart/checks/ci_status.{sh,py}; the script's own comment says it "replaces the oldgh run list --limit 1" — verbatim the defect the entry describedheart-release-validation(M2)pyauto-heart validate --ingest→heart/validate.py,validation_report.json,release-integrate.ymlheart-release-profile-wheel-integration(M3)heart/validate.pycarries the namedreleaseprofile and gates fidelity onprofile == releaseThe entire M0–M3 release-validation milestone chain shipped without one registry entry being retired.
These are removed rather than given fabricated
complete/records — they shipped under other tasks' PRs, and dated records with merge evidence nobody verified would put a worse lie somewhere more trusted. Three legacy paths normalised todraft/.planned.mdgoes 13 → 7 entries, all paths exact.Tests
tests/test_lifecycle_check.py— the first test forlifecycle.py. Fictional, hermetic fixtures per the KEEP-copied-into-the-template rule (test_spawn_privacy.py), with every leg driven by input that must trip it. Mutation-checked: reverting either fix fails the specific test guarding it.Two checks were themselves wrong before these tests pinned them — the
parked.mdstate rule, and the trailing-parenthetical path form (- prompt: ....md (carries the phase table)).python3 scripts/lifecycle.py check→ OK.pytest tests/→ 99 passed.Known limitation
A local check cannot catch the class that cost the most. All six shipped entries were found by reading upstream code; five were catchable here only because their prompt files happened to be missing. Had those files existed,
checkwould still print OK. Catching that class needs each entry'sissue:cross-checked against GitHub, which makeschecknon-hermetic — deliberately out of scope, recorded in the prompt.Prompt:
draft/maintenance/pyautomind/registry_integrity_check.mdGenerated by Claude Code