Quickstart: reproduce at base, verify after the fix
Audience: the implementer and reviewer of this Mission. Base revision: ecb5dd914a. Every command runs in a throwaway repository, never in this checkout.
0. Throwaway fixture
S=$(mktemp -d) && cd "$S"
git init -q -b main && git config user.email t@t && git config user.name t
echo x > README.md && git add . && git commit -qm init
spec-kitty init . --ai claude --non-interactive && git add -A && git commit -qm "spec-kitty init"
git checkout -qb topic
spec-kitty agent mission create demo --topology coord --branch-strategy already-confirmed --json > create.json
M=$(python3 -c 'import json;print(json.load(open("create.json"))["mission_slug"])')
C=$(python3 -c 'import json;print(json.load(open("create.json"))["coordination_branch"])')
Run the same steps with --topology lanes_with_coord, and with --pr-bound --start-branch topic from main.
1. #5440: create commits status to the target branch (US1, FR-001/002)
git show --stat HEAD # base: lists kitty-specs/$M/status.events.jsonl
git ls-tree -r --name-only "$C" | grep "$M" # base: empty (coordination branch born without the Mission dir)
git worktree list # base: no coordination worktree
After the fix:
- the target scaffold commit has
meta.jsonandtasks/*but nostatus.events.jsonl; $Ccarrieskitty-specs/$M/status.events.jsonlholdingMissionCreatedandSpecifyStarted;- the coordination worktree exists;
spec-kitty doctor coordination --jsonreports noCOORDINATION_BRANCH_DIVERGED_VS_TARGET.
Tests: R1, R1b, R1c, R20.
2. #5519: fork and clock restart (US2)
spec-kitty agent decision open --mission "$M" --flow specify --slot-key s.a --input-key a --question "A?" --json
# append a tracer entry through the tracer writer (retrospect tracer append, or the
# library append_tracer_finding), which creates the coordination Mission dir at base
spec-kitty agent decision open --mission "$M" --flow specify --slot-key s.b --input-key b --question "B?" --json
wc -l kitty-specs/$M/status.events.jsonl .worktrees/*/kitty-specs/$M/status.events.jsonl
- At base: two logs. The second
event_lamportrestarts. - After the fix: one log on the coordination surface, and
lamport2 > lamport1.
Pre-fix healing: run the base CLI to create the Mission and open the first decision, then run the fixed CLI for the tracer append. The root records are carried over exactly once, and the root copy is restored.
Tests: R4, plus the seed tests in IC-03.
3. #5519: destructive repair (US4)
Build the fork fixture from step 2 (at base), then:
python3 -c 'import json;print(len(json.load(open("kitty-specs/'"$M"'/decisions/index.json"))["entries"]))'
spec-kitty doctor decisions --mission "$M" --repair --json
python3 -c 'import json;print(len(json.load(open("kitty-specs/'"$M"'/decisions/index.json"))["entries"]))'
spec-kitty agent decision verify --mission "$M" --json; echo "exit=$?"
- At base: the entry count drops, and verify exits 0.
- After the fix: the count is unchanged, the output has
forked: trueand the reconcile steps, and verify exits 1 withDECISION_LOG_FORKED. - Fresh clone:
git clone "$S" c2 && cd c2 && spec-kitty doctor decisions --mission "$M" --jsonreports the fork from refs.
Tests: R3, R14, R15, R16.
4. #5513: router reports "unchanged" for a dirty coordination copy (US3)
# make the status log dirty ONLY in the coordination worktree, then:
python3 - <<'EOF'
from pathlib import Path
from specify_cli.coordination.commit_router import commit_for_mission
# call with files=(repo_root/"kitty-specs"/M/"status.events.jsonl",), kind=STATUS_STATE
EOF
- At base:
status == "unchanged",reason == "no_op_already_committed". - After the fix:
committedon$C,surfaceslists the coordination outcome, and the clean-copy control still reportsunchanged.
Tests: R2, R2b.
5. #5501: spec-commit drops the status log (US3.4)
spec-kitty spec-commit --mission "$M" -m "spec batch" \
kitty-specs/$M/spec.md kitty-specs/$M/decisions/index.json kitty-specs/$M/traces/approach.md kitty-specs/$M/status.events.jsonl --json
- At base:
success: true; the status log is silently dropped anddecisions/is re-routed to the coordination branch. - After the fix:
arguments[]names every path's fate. The ledger andspec.mdare on the target; traces and the status log are on$C.
Test: R5.
6. accept (US3.5-3.7)
Create two fixtures: a COORD record dirty in the root checkout, and one dirty only in the coordination worktree. Run spec-kitty accept --mission "$M" --json against each.
- At base: the first fixture's record is committed to
topic; the second fixture's record is skipped or overwritten. - After the fix: the first is reported
COORD_RECORD_IN_ROOT_CHECKOUT(never ontopic); the second is committed on$C.
Tests: R7, R8, R9.
7. finalize, planning pin, receipts (US3.8, US5, US6)
finalize-taskswith coordination-only dirt: at base "no changes"; after the fix, committed on$C(R10).finalize-tasks, then a planning commit, thenfinalize-tasksagain:lanes.jsonplanning_commit_shais refreshed with no flag (R17).spec-kitty agent action implement WP01 --json: everycommits[].shais non-null and contained in itsdestination_ref(R18).
7b. Consolidation and materialize writers (IC-18, ruling Q4)
- Pre-fix EMPTY Mission plus
spec-kitty consolidate. At base, thedoneevents land in the repository root checkout's log. After the fix: one seed commit on$Clands before the merge, and thedoneevents are in the coordination log (R22). - UNMATERIALIZED with a local branch. Remove the coordination worktree (
git worktree remove), then runspec-kitty consolidate. At base it exits 1 with "Merge aborted before any state change". After the fix it materializes the surface and proceeds. A remote-only branch still aborts (R23). spec-kitty materialize(no--mission), on a MATERIALIZED coordination Mission whose root copy is stale. At base,status.jsonis written in the root dir from the stale log. After the fix it is written on the coordination surface (R24).- Guards. Run the consolidation guard files listed in plan IC-18, each by name.
8. Gate and end-to-end
pytest tests/architectural/test_no_write_side_rederivation.py -q # R19: red at base on real offenders
pytest tests/integration/test_coord_single_home_workflow.py -q # FR-015, both topologies + moved merge base
9. NFR-001 timing
scratchpad/nfr001/bench.sh coord topic; scratchpad/nfr001/bench.sh lanes_with_coord prbound
The baseline medians are about 2.64 s (research.md). After the fix, record the medians in the PR. Each must stay within baseline + 1.0 s; there is no absolute bound (ruling Q2).
Test policy (C-006)
Run the targeted test files above, the owning-module test directories of each changed file, and the named architectural gate files:
test_no_write_side_rederivation.pytest_write_surface_placement_guard.pytest_merge_reconciliation_class_guard.pytest_layer_rules.pytest_status_events_writes_gate.pytest_status_state_read_dir_single_authority.py
Never run the full tests/architectural/, the e2e suite as a whole, or make test-full locally.