-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Checkpoint diffs never resolve: ProviderRuntimeIngestion placeholder preempts CheckpointReactor git capture #585
Description
Bug
Turn diffs ("Loading checkpoint diff…" / "Filesystem checkpoint is unavailable for turn N") never resolve after a Codex turn completes, even when the project is a valid git repository.
Root cause
There is a race between two independent event handlers that both react to turn completion:
-
ProviderRuntimeIngestionhandlesturn.diff.updatedevents and immediately dispatchesthread.turn.diff.completewith a placeholder checkpoint entry:checkpointRef: "provider-diff:<eventId>"(not a real git ref)status: "missing"files: []
(
apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts, lines 1064-1083) -
CheckpointReactorhandlesturn.completedevents and is supposed to capture a real git-ref-based checkpoint viaCheckpointStore.captureCheckpoint, then dispatchthread.turn.diff.completewith the actual diff data.(
apps/server/src/orchestration/Layers/CheckpointReactor.ts, lines 150-298)
The problem: ProviderRuntimeIngestion wins the race and inserts the placeholder into thread.checkpoints first. When CheckpointReactor later processes turn.completed, it checks:
if (thread.checkpoints.some((checkpoint) => checkpoint.turnId === turnId)) {
return; // ← early exit, real capture never happens
}(line 169)
Since the placeholder already has the same turnId, the real git checkpoint is never captured. The DiffPanel then tries to resolve provider-diff:UUID via git rev-parse, which fails because it's not an actual git ref.
Observed behavior
- Server logs show
thread.turn-diff-completedevents withcheckpointRef: "provider-diff:..."andstatus: "missing" - DiffPanel shows "Loading checkpoint diff..." indefinitely, then "Filesystem checkpoint is unavailable for turn N"
- No
refs/t3/checkpoints/git refs are created for the affected turns
Reproduction
- Add any git-initialized project
- Send a message that triggers file changes (e.g., "add a comment to README")
- Wait for turn to complete
- Open the diff panel → stuck on "Loading checkpoint diff..."
Suggested fix
The dedup check in CheckpointReactor (line 169) should either:
- Only skip if an existing checkpoint has a non-placeholder status (i.e., skip
"missing"entries), or - Replace/upgrade placeholder checkpoints with the real git-based checkpoint when one becomes available
Additionally, there is a secondary CWD inconsistency worth noting: CheckpointReactor turn-completion capture prefers sessionRuntime.cwd while CheckpointDiffQuery only uses resolveThreadWorkspaceCwd. If these ever diverge, refs would be written to one repo but looked up in another.
Environment
- T3 Code dev (main branch)
- Codex provider with GPT-5.4
- Linux (Arch)