Tasks — Mission A — P0 Read/Write Consistency

Mission: mission-a-p0-consistency-01KZWHY1 | Branch: fix/mission-a-p0-consistency Planning base: fix/mission-a-p0-consistency | Merge target: fix/mission-a-p0-consistency

Four independent, module-local P0 fixes — one WP per issue (C-001 non-goal: no shared helper). WP01–WP03 are independent (parallel-capable); WP04 (#3311) is sequenced LAST (highest blast radius) via a dependency on the other three. Every WP carries its product fix, non-fakeable green-wash guard tests, and the NFR-005 regression-exit (relocate/replace the repro, drop the marker, canonical marks + guard docstring).

Subtask Index

IDDescriptionWPParallel
T001Read-back merged record; build counts/JSON/event from itWP01
T002On-disk emit-spy guard testWP01[P]
T003Relocate #3320 repro → tests/cli/commands/; canonicalizeWP01
T004ruff/mypy + targeted retrospect suiteWP01
T005overall_verdict exempts only empty placeholder (description==MARKER)WP02
T006Guard tests: partial-authoring, all-scaffold, real-AC-001-no-markerWP02[P]
T007Relocate #3231 repro → tests/acceptance/; canonicalizeWP02
T008Touched-consumer check (incl. acceptance_verdict.py) + ruff/mypyWP02
T009ProjectMetadata round-trips schema_version (load+save); drop mask entryWP03
T010Verify runner success-path stamp + dry_run-writes-nothing; keep 2nd writer consistentWP03
T011Round-trip unit test (load→save preserves schema_version)WP03[P]
T012REPLACE #3334 repro: real MigrationRunner.upgrade(), STALE fixture, 4 post-condsWP03
T013ruff/mypy + targeted upgrade suiteWP03
T014Execution-begun signal via resolved coord-aware surfaceWP04
T015Gate _compute_and_write_lanes: preserve planning_commit_sha or refuseWP04
T016Guard tests: non-None-tip preservation; observable regeneration (benign)WP04[P]
T017Relocate #3311 repro → tests/specify_cli/cli/commands/agent/; canonicalizeWP04
T018ruff/mypy + targeted finalize suite (serial if daemon)WP04

Work Packages

WP01 — #3320 retrospect --update reports/emits the persisted record (P1, land first)

the merged on-disk record, not the pre-merge generated one.

ran_no_findings generator; assert JSON and an emit-spy match on-disk.

  • Goal: report counts/findings_status and emit RetrospectiveCaptured from
  • Independent test: seed has_findings+1 gap; create --update with a
  • Subtasks: T001, T002, T003, T004.
  • Dependencies: none.
  • Prompt: tasks/WP01-retrospect-update-persisted.md (~280 lines).

WP02 — #3231 acceptance verdict scaffold discriminator (P1)

(description==SCAFFOLD_TODO_MARKER); seeded-pending FR rows + all-scaffold stay pending.

/ real-AC-001-no-marker row sets.

  • Goal: overall_verdict exempts only the contentless empty placeholder
  • Independent test: verdict over partial-authoring / all-scaffold / empty-only
  • Subtasks: T005, T006, T007, T008.
  • Dependencies: none.
  • Prompt: tasks/WP02-acceptance-verdict-scaffold.md (~300 lines).

WP03 — #3334 failed upgrade recoverability (save() root fix) (P2)

strips it; a failed upgrade stays recoverable; genuine pre-3.x stays blocked.

migration; STALE fixture; assert stamp==pre_schema, gate no SystemExit, dry_run byte-identical, genuine-pre-3.x still SystemExit(4).

  • Goal: ProjectMetadata round-trips schema_version so no save() caller
  • Independent test: real MigrationRunner.upgrade() with a stub failing
  • Subtasks: T009, T010, T011, T012, T013.
  • Dependencies: none.
  • Prompt: tasks/WP03-upgrade-schema-roundtrip.md (~360 lines).

WP04 — #3311 re-finalize preserves provenance (P3, LAST — highest blast radius)

status surface); preserve planning_commit_sha or refuse; pre-execution re-finalize still regenerates.

pre-execution re-finalize observably regenerates.

  • Goal: gate finalize recompute on "execution begun" (resolved coord-aware
  • Independent test: execution-begun re-finalize preserves a non-None SHA;
  • Subtasks: T014, T015, T016, T017, T018.
  • Dependencies: WP01, WP02, WP03 (sequences #3311 last).
  • Prompt: tasks/WP04-finalize-provenance-guard.md (~340 lines).

Sequencing

WP01 ∥ WP02 ∥ WP03 (independent lanes) → WP04. MVP slice: WP01 (lowest risk). Regression-exit (NFR-005/SC-006) is each WP's DoD; at completion pytest tests/ -m regression shows none of the four green.