Repository navigation
Closed
Description
Symptom
Turn-scoped diffs don't show what actually changed in that turn. Observed variants:
- sometimes only 1 file,
- sometimes only the
.gedstate files, - sometimes ~500 files (everything).
Mechanism (verified)
Turn diffs are checkpoint-pair diffs: CheckpointReactor captures git refs refs/t3/checkpoints/<base64url(threadId)>/turn/<n> per turn (Utils.ts:6-10, CheckpointReactor.ts:317,597,679 — including placeholder captures). CheckpointDiffQuery.getTurnDiff diffs checkpoint N-1 → N (Layers/CheckpointDiffQuery.ts:101-134); turn 0 uses a synthetic base ref. The client picks the range from per-turn summaries' checkpointTurnCount with an inferred fallback when absent (DiffPanel.tsx:225-251).
Root-cause hypotheses (ranked)
- Missed/placeholder-only capture for a turn → the adjacent checkpoint pair straddles only orchestration state writes (
.ged/**files change every turn), producing the "only .ged files" / "1 file" variants. Capture happens on turn completion plus placeholder paths (CheckpointReactor.ts:441-506,850-876); a race between stage settlement commits and capture could attribute content to the wrong pair. - Wrong turn-0 baseline → the "500 files" variant: if the turn-0 base ref is missing/stale (e.g. after worktree recreation the refs don't exist in the fresh clone), the diff runs against an empty or wrong tree and everything appears new.
- Client-side inferred turn→count mapping selecting the wrong pair when summaries lack
checkpointTurnCount.
Fix plan
- Reproduce each variant; instrument capture (log ref, turn count, dirty state at capture).
- Fix capture timing/attribution so each checkpoint pair brackets exactly one turn's content changes (decide policy for mid-turn commits and
.gedstate writes — consider excluding orchestration-internal paths from turn attribution). - Ensure turn-0 base ref exists in every workspace where diffs are computed; fail loudly (not "everything changed") when it doesn't.
- Replace or harden the client's inferred mapping so a missing count surfaces an explicit state instead of a wrong range.
Acceptance criteria
- For a scripted multi-turn session with known per-turn file changes, each turn chip shows exactly that turn's files.
- First-turn diff never shows the whole repo when the baseline ref is absent — explicit error or correct baseline.
- Regression tests for capture attribution (mid-turn commit, .ged writes, worktree recreation).
Size: M
Metadata
Metadata
Assignees
Labels
No labels
Activity
fix(checkpointing): fail loudly on dangling checkpoint refs instead o…
Merge fix/7781-turn-diff-correctness: loud failures for dangling chec…
t3dotgg commentedon Sep 6, 2026
Note
🤖 Claude Fable 5.1 responding on behalf of Theo
#10347 landed. The PR status refresh now runs on its own worker in CheckpointReactor, so a fast follow-up message can no longer edit files before the previous turn's checkpoint is captured. That covers the 1-file and only-.ged attribution race. Still open here: the whole-repo variant from a missing turn-0 base ref after worktree recreation, and the client's inferred turn mapping when checkpointTurnCount is absent.