Fix cycle stage detection breaks on multi-phase builds

After a FAIL verification on a multi-phase build, the fix cycle gets permanently stuck at `needs-fixes` even when the fix build completes successfully. AnaVerify reports "nothing to verify." The pipeline is dead until a human manually intervenes. This happened on `configurability-improvements` — the first real multi-phase build to go through a FAIL-fix-re-verify cycle. It will happen to every customer who hits a verify rejection on any multi-phase work item, and the single-spec path has the same underlying fragility.

verdict PASSscore 19 / 19findings 6 (1 risk · 1 debt · 4 obs)duration 1h 26mrejection cycles 0shipped May 12, 2026surface cli

Pipeline timeline

Intent to proven code in 1h 26m across Think, Plan, Build, and Verify.

Think
12m
Plan
21m
Build
31m
Verify
5m

Assertion ledger

19 claims, each independently verified. Showing 8 — show all →

IDSaysMatcher
A001A fix build on phase 2 transitions the stage to ready-for-re-verifyverifiedok
A002A fix build on a single-spec item transitions the stage to ready-for-re-verifyverifiedok
A003Stage stays needs-fixes when no fix build has been savedverifiedok
A004When both numbered and unnumbered report files exist, save renames the unnumbered to numberedverifiedok
A005Companion data files are renamed alongside their report filesverifiedok
A006Auto-rename works for verify reports the same way as build reportsverifiedok
A007Stage detection reads timestamps from saves.json instead of git logverifiedok
A008Multi-phase stage detection reads phase-numbered saves.json keysverifiedok

Findings 6 total

debtpackages/cli/src/commands/work.tsclosed
A013/A014 completeWork backward compat assertions have no tagged tests — verified by source inspection only
obsclosed
A015/A016/A017 template content assertions have no tagged tests — verified by source inspection only
riskpackages/cli/src/commands/work.tsclosed
completeWork fallback lets two multi-phase specs share one unnumbered saves.json entry — phase 2 passes if phase 1's unnumbered key exists
obspackages/cli/tests/commands/work.test.tsmonitor
Stage detection tests use hardcoded timestamps with 1-hour gaps — no boundary test for equal timestamps
obspackages/cli/src/commands/artifact.tsclosed
Auto-rename overwrites numbered file unconditionally — if the unnumbered file is stale or corrupt, the good numbered version is destroyed
+1more findings

Integrity seal

scopesha256:b322a9ccb963d...
contractsha256:e191bd3ec9fcd...
plansha256:6765a3db4c853...
specsha256:8df906375b9c8...
build-reportsha256:716856600a75a...
build-datasha256:f29ea33658b3c...
verify-reportsha256:95990c75b9efe...
verify-datasha256:58ebb35df6c65...
audit cmd$ ana proof audit fix-cycle-stage-detection   → all hashes match