Fix Multi-Phase Timestamp Poisoning
Fix a state-model bug where `.saves.json` session timestamps are work-item-scoped but the pipeline state machine applies them per-phase. In multi-phase workflows, Phase 1's `verify_started_at` timestamp persists and causes `ana work status` to misclassify Phase 2 as "verify-in-progress" for up to one hour after Phase 1 verification completes. Discovered during the first multi-phase Codex pipeline run (`docs-readme-platform-update`).
verdict PASSscore 27 / 27findings 8 (0 risk · 3 debt · 5 obs)duration 2h 13mrejection cycles 0shipped Jun 1, 2026surface cli
Pipeline timeline
Intent to proven code in 2h 13m across Think, Plan, Build, and Verify.
Think10m
Plan30m
Build28m
Verify6m
Assertion ledger
27 claims, each independently verified. Showing 8 — show all →
| ID | Says | Matcher | |
|---|---|---|---|
| A001 | Phase 2 status is not blocked by Phase 1's verify timestamp | verified | ok |
| A002 | Phase 2 verify start writes a phase-specific timestamp | verified | ok |
| A003 | Phase 2 verify start writes a phase-specific agent key | verified | ok |
| A004 | Phase 2 verify start does not write the generic verify timestamp | verified | ok |
| A005 | Single-spec work still detects verify-in-progress correctly | verified | ok |
| A006 | Phase 1's verify timestamp is ignored when evaluating Phase 2 | verified | ok |
| A007 | Phase 2 re-verify writes the verify timestamp, not the build timestamp | verified | ok |
| A008 | Phase 2 re-verify correctly detects the ready-for-re-verify stage | verified | ok |
Findings 8 total
debtpackages/cli/src/commands/work.ts→ acknowledge
Dead conditional — verifyAgent always equals 'ana-verify' on both branches
debtpackages/cli/src/commands/work.ts→ acknowledge
startBuildPhaseWithKey is an unnecessary wrapper — delegates entirely to startBuildPhase with unused _buildAgentKey param
obspackages/cli/src/commands/work-state.ts→ monitor
resolvePhase returns null for both 'all phases passed' and 'single-spec' — dual-meaning null forces callers to disambiguate
debtpackages/cli/src/commands/work.ts→ scope
getMainTreeResolution re-reads filesystem artifacts via gatherLocalArtifactState even though caller already has hasNumberedSpec/buildReportExists flags
obspackages/cli/tests/commands/work.test.ts→ monitor
A023 test only covers worktree startWork path — doesn't actually compare main-tree vs worktree output as the test title claims
+3more findings
Integrity seal
scopesha256:2cdda3552adbc...
contractsha256:dcd0c02dba63b...
plansha256:ef295e5e990a5...
specsha256:cc483d7adc5f4...
build-reportsha256:49118bd99d357...
build-datasha256:4a64b17dafc26...
verify-reportsha256:9536c4bc91dd9...
verify-datasha256:0799beeb26a94...
audit cmd$ ana proof audit fix-multi-phase-timestamp-poisoning → all hashes match