Selective Checkpoint Restore Across Code and Conversation State¶
When code state and conversation state are stored separately, restore is three actions — keep the mental model, keep the edits, or full reset.
Selective checkpoint restore is the affordance a harness exposes when its checkpoint primitive captures code state and conversation state in separate stores: the user (or the agent) can rewind one without the other. Claude Code's /rewind menu names three: "Restore code and conversation", "Restore conversation" (keep current code), and "Restore code" (keep the conversation) (Claude Code: Checkpointing). Each axis matches a different failure mode; conflating them wastes the affordance.
When each restore action fits¶
| Restore | What it keeps | Use when |
|---|---|---|
| Code only | The conversation (the agent's analysis, the plan, your back-and-forth) | The agent's reasoning is still useful but the edits are wrong — try the same plan again with the agent's accumulated context. |
| Conversation only | The files on disk | The edits landed correctly but the next planning step poisoned itself — drop the bad reasoning, keep the work. |
| Both | Nothing from the restored range | Full reset of a short, low-value detour. For longer side-quests, fork the session instead so the dead-end is preserved off-thread. |
The three actions map to three recovery goals: preserve debugging context, keep partial work, or clean slate.
How it works¶
Claude Code keys file backups by the UUID of each user message (Claude Agent SDK: File Checkpointing). The transcript and file backups are independent stores with independent identifiers, so the harness composes three restore actions from two:
graph LR
A[user prompt] --> B[checkpoint UUID]
B --> C[file backup store]
B --> D[conversation transcript]
C -.code only.-> E[files at UUID,<br>conversation unchanged]
D -.conversation only.-> F[transcript at UUID,<br>files unchanged]
C & D -.both.-> G[full state at UUID]
Granularity is per user prompt — "Every user prompt creates a new checkpoint" (Claude Code: Checkpointing) — with no sub-prompt rewind. The SDK exposes only the code-only axis: rewind_files() (Python) / rewindFiles() (TypeScript) restore files but "does not rewind the conversation itself" (Claude Agent SDK: File Checkpointing). No primitive rewinds conversation alone, so agent-driven restore is one-sided today.
Why it works¶
Selective restore is possible because the two state stores carry independent identifiers and independent restore operations. Where a harness serializes checkpoint state as a single transaction — Cursor zips the pre-change files and treats the chat as a forward-only continuation thread (Steve Kinney: Cursor Checkpoints) — the selective axis is architecturally unavailable. The unit of restorable state is a harness design decision; the three-way split is what that decision enables. Rollback-First Design lists checkpoints as one reversible primitive, and selective restore is what makes them more reversible than an all-or-nothing snapshot.
When this backfires¶
The three-way affordance carries costs the docs do not surface.
- Rewind always forks the session. Every restore creates a new conversation branch in Claude Code, so heavy use clutters
--resumehistory; the fourth "rewind without fork" option was requested and closed not-planned (anthropics/claude-code #9279). For short sessions the fork tax dominates. - Bash edits are outside the safety net. "Checkpointing does not track files modified by bash commands" (Claude Code: Checkpointing). A code-only restore on a session where
make,sed -i, ormvdid the real work produces silent inconsistency — the backup restores some files, the bash-side changes survive untouched. - Code-only restore can desync the agent's mental model. When files revert but the conversation still references the rewound edits, the agent operates against state it only thinks exists — the drift surface Cursor's single restorable unit avoids by design.
- Short sessions where nothing was learned. Picking among three options is overhead;
/clearorclaude --continue --fork-sessionis cheaper when the rewound range held no useful context. - Teams that commit every agent turn. Git already gives per-file restore (
git restore --source=<sha>) with the same selectivity; the harness checkpoint adds a parallel rollback channel, doubling cognitive load for the same capability. - Code-only restore plus re-execution can replay irreversible side effects. A code-only restore invites the agent to retry the failed step — but an LLM agent re-synthesizes a subtly different request rather than replaying the identical call. When that retry hits an external system, the restore can produce duplicate charges or reused credentials instead of a clean rollback — the "semantic rollback attack" of ACRFence: Preventing Semantic Rollback Attacks in Agent Checkpoint-Restore. Gate restore-then-retry behind idempotency keys when the rewound range touched a stateful external call.
The pattern earns its keep when the session is long enough that learned context is valuable, the harness separates the two state stores, and bash-driven file modification is bounded.
Example¶
A common selective-restore flow: the agent spent an hour analyzing a flaky integration test, identified the race condition correctly, then proposed a fix that broke a different invariant.
Restore code only. The diagnosis is correct; only the patch was wrong.
/rewind
→ Select the prompt where the fix was proposed
→ Choose: Restore code
→ Files revert; the conversation still contains the diagnosis
→ Type: "That fix broke X. Try a different patch that preserves Y."
The agent re-attempts the fix with the analysis still loaded — no re-investigation from scratch — because the Claude Code Restore code action reverts files while leaving the conversation intact.
Restore conversation only. The patch was right but the agent then proposed a follow-up refactor based on a misread of an unrelated file.
/rewind
→ Select the prompt where the bad refactor proposal started
→ Choose: Restore conversation
→ Conversation rewinds; the patch files stay edited
→ Type: "Don't refactor that module — it's owned by another team."
The work is preserved; only the planning thread is rewound.
Key Takeaways¶
- Three restore actions match three recovery goals — code-only keeps the mental model, conversation-only keeps the work, both is full reset.
- The split exists because Claude Code stores file backups and the conversation transcript as independent UUID-keyed stores; harnesses that don't separate them (Cursor) cannot offer it.
- The SDK exposes code-only restore programmatically (
rewind_files()); conversation-only restore has no SDK primitive today. - Every rewind forks the session — heavy selective use clutters
--resumehistory. - Bash-edited files are not checkpointed; selective restore on a bash-heavy session produces silent inconsistency.