Preflight Checklist
Problem Statement
Claude Code has /branch, --fork-session and /rewind. Related requests exist: #32631 (fork/merge/tree spec), #69712 (branches in agent view, merge-back), #150 (forks as git branches, locked), #16236, #19286, #12629. This is not another "please add branching" — it identifies a specific limitation shared by all of the above: the conversation timeline and the code timeline can only move together.
The primary case: executing an agreed plan
A session goes like this. Five to ten messages of discussion — constraints, tradeoffs, rejected approaches — converge on a plan with ten items. That message is the single most valuable artifact of the session: it encodes not just the ten items but everything that justified them.
Then the items get executed. Each is largely independent. Item 4 does not need the debugging transcript from item 3, the file it tried and abandoned, or the test output it printed. What item 4 needs is exactly two things: the conversation state as it was at the plan, and the code state as it is now, after items 1–3 landed.
Today those two cannot be requested together. /rewind restores conversation and code as a linear pair — restoring the conversation to the plan throws away the code from items 1–3, and restoring code only doesn't move the conversation. /branch copies the conversation forward from the current point, carrying all the accumulated noise, and both branches then operate on the same working tree.
So execution proceeds linearly instead, and by item 7 the context is dominated by the residue of items 1–6: the plan is far behind, /compact has fired at least once, and the model's grip on the original constraints has measurably decayed.
The current workaround is to serialise the plan to a file, /clear, and re-read it per item. This is what people actually do, and it is a poor trade. The file contains the ten items, not the reasoning behind them — the discussion of why option B was rejected, or which constraint made item 6 depend on item 2, is gone, and re-establishing it costs either tokens or accuracy. It is manual bookkeeping: write the file, update it, remember to update it, keep it consistent with what actually got done. And it works around something the session already contains — the plan message is sitting right there in the transcript; the problem is purely that there is no way to re-enter at it.
The secondary case: reversing a key decision
Some messages are decision points — an architectural choice, an answer to a clarifying question from Claude, a "yes, do it that way." When one turns out wrong, the desirable action is "return to that decision and take the other path," where both conversation and code go back. /rewind does this once, linearly. What's missing is the ability to treat such a point as a durable, named location you can return to more than once and branch from repeatedly — and to keep the abandoned attempt around rather than losing it.
The two situations are structurally different
They are not points on a scale of "how far back do I go." They differ in what the branches are to each other.
In the parallel case — items 4 and 5 of a single plan — the branches are complementary. All of them are meant to land. The conversation must diverge, because each item deserves a clean thread starting from the plan, but the code must not: item 5 has to see the files item 4 wrote. When the last item is done there is nothing to merge, because nothing ever diverged.
In the alternative case — Redis versus an in-process cache — the branches are mutually exclusive. Exactly one survives. Here both the conversation and the code must diverge, and the isolation has to be real: approach A must never see files written by approach B, or the comparison is meaningless. At the end one branch is adopted and the others are discarded.
So the axis that matters is not depth of rewind. It is whether the code state is shared and accumulating, or separate and disposable — and that follows directly from whether the branches complement each other or compete.
Claude Code today implements only the second case. /branch and --fork-session always duplicate the session, and the working tree is then shared by accident rather than by design — so the parallel case gets done with a tool built for the alternative case, producing merges that shouldn't exist and file states that match neither branch's transcript. The parallel case has no expression at all.
Both cases need the same missing primitive: a message you can name, return to repeatedly, and re-enter with an explicit statement of how this branch relates to its siblings.
Proposed Solution
Make the branch mode explicit, and let one anchor mechanism serve both.
- Anchors — named, re-enterable points in a conversation
/anchor plan
Marks the current point (or a selected earlier message) as a named, durable location. Anchors persist with the session and survive /compact — a compaction may summarise messages, but must not destroy the ability to re-enter at an anchor.
Plan mode should create one automatically: when plan mode exits with an approved plan, that message becomes an anchor named plan by default. This makes the primary case work with zero extra user action.
- Two branch modes, chosen at re-entry
/from plan # parallel: conversation <- anchor, code <- current (default)
/from plan --alt # alternative: conversation <- anchor, code <- anchor, isolated
Parallel mode is the default because it is the common case and the one with no workaround today. The conversation rewinds to the anchor; the working tree is untouched and keeps accumulating. There is exactly one code state on disk. Nothing is duplicated, so nothing is merged. Ten plan items become ten short threads sharing one carefully-built prefix, over one continuously advancing codebase.
Alternative mode rewinds both. Each --alt branch gets its own code state, isolated from its siblings, so approach A never sees files written by approach B. At the end one branch is adopted and the others are discarded or archived.
Users shouldn't have to reason about which files travel where — they state the relationship between the branches, and the tool derives the rest.
- What isolation means, and where git comes in
Isolation is only needed in alternative mode. Parallel mode requires no snapshotting whatsoever — worth stating explicitly, because it means the common case is cheap to implement.
For alternative mode the code state has to live somewhere, and the backend should be configurable rather than baked into the user-facing model. Three options, in increasing order of fidelity:
The existing checkpoint mechanism already works and restores in place, but it misses anything the edit tools didn't do — rm, mv, code generators, build output — so a restored state can be incomplete.
Git worktrees give real isolation, since each branch gets its own directory, at the cost of a second working directory on disk and slower switching.
Shadow refs — snapshot commits stored under something like refs/claude// — cover everything git covers, including bash-made changes and deletions, while keeping the user's own git log clean. They are inspectable with ordinary git tooling and can be garbage-collected along with the existing 30-day session retention.
{ "branching": { "altBackend": "worktree" } }
Git is worth supporting because it already solves snapshotting correctly and is sitting right there in every project — but it is an implementation option for one of the two modes, not the concept. Parallel mode, which is the more valuable half of this request, works with no version control involvement at all.
- A ledger for parallel branches
Re-entering an anchor in parallel mode injects a compact, auto-generated status note:
[From anchor "plan" — 3 of 10 items completed]
[done] 1. Extract config loader -> src/config.rs, src/main.rs
[done] 2. Add retry middleware -> src/http/retry.rs (+ tests)
[done] 3. Replace panic with Result -> 6 files
[here] 4. Migrate cache layer
This is the plan file people currently maintain by hand, generated instead, and carrying provenance rather than just item text. It tells the model what state the code is actually in without spending the context that the full transcript would.
- A return path for alternative branches only
/merge try-redis --summary # inject the branch's conclusions into the current conversation
/merge try-redis --diff # offer its file changes for review and application
Conflicts are surfaced as a diff for the user to resolve, never silently reconciled by the model. Parallel branches need no merge command at all — by construction there is nothing to merge, and that absence is a property of the design rather than a gap in it.
- Navigation
/anchors lists the anchors in a session and, for each, the branches taken from it, their mode, their status and the files they touched.
A session tree view shows anchors as nodes and branches as edges, with parallel and alternative branches rendered distinctly and the current position highlighted. Without it, a session with three anchors and eight branches becomes unnavigable.
Branches should also be reachable from the same place other work is: per #69712, they currently appear only in the /resume picker and not in the agent view.
- Mode can be promoted
Sometimes a parallel item turns out to need isolation halfway through — it starts rewriting a file another item owns. /isolate should convert the current parallel branch into an alternative one from the same anchor, snapshotting its current code state rather than forcing the user to start over.
- Backward compatibility and minimal version
Sessions with no anchors behave exactly as today; /rewind and /branch keep their current semantics. /from --alt is a repeatable, named form of what /branch already does, not a replacement for it.
If the full proposal is too large, the smallest genuinely useful slice is anchors plus parallel mode: /anchor, /from, the ledger, and automatic anchoring of approved plans. That requires no snapshotting, no git integration and no merge machinery, and it solves the case that has no workaround. Alternative mode is largely a formalisation of /branch plus a code backend, and can follow.
Alternative Solutions
Serialising the plan to a file and /clear. The current standard workaround. Loses the reasoning behind the plan, requires manual upkeep, and re-reads a document instead of resuming a state.
/compact with a focus argument. Lossy and non-deterministic. The user cannot specify precisely what survives, and what survives is a summary, not the original messages.
/branch per plan item. This is the alternative-mode tool applied to a parallel-mode problem. It copies the conversation forward with all of the current item's noise, and the isolation it implies is fictional — both branches write to the same working tree. Users then either merge things that were never meant to diverge, or end up with a working tree matching no branch's transcript.
/rewind per item. Linear and single-shot. Restoring the conversation to the plan discards the code from completed items; restoring code only leaves the conversation where it was.
Subagents or /fork per item. The closest existing fit, and genuinely good for delegable work — but a subagent gets a fresh context window, so it doesn't inherit the plan discussion, and the user supervises a delegate rather than working at the anchor themselves.
Manual git worktree plus a session per item. Solves code state, but each session starts with no shared conversation context — paying, per item, the exact cost the anchor exists to avoid.
Priority
Medium - Would be very helpful
Feature Category
Configuration and settings
Use Case Example
Ten-item refactor (parallel)
After a plan-mode session, plan is anchored automatically. For each item: /from plan, do the item, verify it, then /from plan again for the next one.
Every item starts with the full reasoning behind the plan in context and none of the previous item's debugging noise, while the code accumulates normally in a single working tree. Item 10 is executed with the same context quality as item 1. No plan file, no /clear, no /compact, no merge.
An item that goes wrong
Item 6 turns out to be a bad idea once implemented. /from plan --alt returns both conversation and code to the plan state, while items 1–5's work stays recorded in their own branches — recoverable, unlike a linear rewind.
Genuine alternatives (alternative mode)
Before a caching decision: /from plan --alt twice, one branch per approach, each with its own code state. Benchmark both, /merge redis-approach --summary --diff, discard the other. Here divergence is the point, and a git backend earns its keep.
Long sessions generally
Re-entry at an anchor is also the cheapest available fix for context decay in long agentic sessions: instead of one 200-message thread compacted twice, it becomes ten short threads sharing one carefully-built prefix.
Additional Context
This overlaps with #32631, and I'd be glad to see it folded in there — but the two model different things. #32631 treats a branch as a full fork of a session and focuses on the tree and the return path. This proposal's central claim is narrower: that conversation state and code state should be selectable independently at re-entry, and that the most common case — "conversation back, code forward" — needs no merge, no duplication and no version control to implement, yet no existing command expresses it.
Preflight Checklist
Problem Statement
Claude Code has /branch, --fork-session and /rewind. Related requests exist: #32631 (fork/merge/tree spec), #69712 (branches in agent view, merge-back), #150 (forks as git branches, locked), #16236, #19286, #12629. This is not another "please add branching" — it identifies a specific limitation shared by all of the above: the conversation timeline and the code timeline can only move together.
The primary case: executing an agreed plan
A session goes like this. Five to ten messages of discussion — constraints, tradeoffs, rejected approaches — converge on a plan with ten items. That message is the single most valuable artifact of the session: it encodes not just the ten items but everything that justified them.
Then the items get executed. Each is largely independent. Item 4 does not need the debugging transcript from item 3, the file it tried and abandoned, or the test output it printed. What item 4 needs is exactly two things: the conversation state as it was at the plan, and the code state as it is now, after items 1–3 landed.
Today those two cannot be requested together. /rewind restores conversation and code as a linear pair — restoring the conversation to the plan throws away the code from items 1–3, and restoring code only doesn't move the conversation. /branch copies the conversation forward from the current point, carrying all the accumulated noise, and both branches then operate on the same working tree.
So execution proceeds linearly instead, and by item 7 the context is dominated by the residue of items 1–6: the plan is far behind, /compact has fired at least once, and the model's grip on the original constraints has measurably decayed.
The current workaround is to serialise the plan to a file, /clear, and re-read it per item. This is what people actually do, and it is a poor trade. The file contains the ten items, not the reasoning behind them — the discussion of why option B was rejected, or which constraint made item 6 depend on item 2, is gone, and re-establishing it costs either tokens or accuracy. It is manual bookkeeping: write the file, update it, remember to update it, keep it consistent with what actually got done. And it works around something the session already contains — the plan message is sitting right there in the transcript; the problem is purely that there is no way to re-enter at it.
The secondary case: reversing a key decision
Some messages are decision points — an architectural choice, an answer to a clarifying question from Claude, a "yes, do it that way." When one turns out wrong, the desirable action is "return to that decision and take the other path," where both conversation and code go back. /rewind does this once, linearly. What's missing is the ability to treat such a point as a durable, named location you can return to more than once and branch from repeatedly — and to keep the abandoned attempt around rather than losing it.
The two situations are structurally different
They are not points on a scale of "how far back do I go." They differ in what the branches are to each other.
In the parallel case — items 4 and 5 of a single plan — the branches are complementary. All of them are meant to land. The conversation must diverge, because each item deserves a clean thread starting from the plan, but the code must not: item 5 has to see the files item 4 wrote. When the last item is done there is nothing to merge, because nothing ever diverged.
In the alternative case — Redis versus an in-process cache — the branches are mutually exclusive. Exactly one survives. Here both the conversation and the code must diverge, and the isolation has to be real: approach A must never see files written by approach B, or the comparison is meaningless. At the end one branch is adopted and the others are discarded.
So the axis that matters is not depth of rewind. It is whether the code state is shared and accumulating, or separate and disposable — and that follows directly from whether the branches complement each other or compete.
Claude Code today implements only the second case. /branch and --fork-session always duplicate the session, and the working tree is then shared by accident rather than by design — so the parallel case gets done with a tool built for the alternative case, producing merges that shouldn't exist and file states that match neither branch's transcript. The parallel case has no expression at all.
Both cases need the same missing primitive: a message you can name, return to repeatedly, and re-enter with an explicit statement of how this branch relates to its siblings.
Proposed Solution
Make the branch mode explicit, and let one anchor mechanism serve both.
/anchor plan
Marks the current point (or a selected earlier message) as a named, durable location. Anchors persist with the session and survive /compact — a compaction may summarise messages, but must not destroy the ability to re-enter at an anchor.
Plan mode should create one automatically: when plan mode exits with an approved plan, that message becomes an anchor named plan by default. This makes the primary case work with zero extra user action.
/from plan # parallel: conversation <- anchor, code <- current (default)
/from plan --alt # alternative: conversation <- anchor, code <- anchor, isolated
Parallel mode is the default because it is the common case and the one with no workaround today. The conversation rewinds to the anchor; the working tree is untouched and keeps accumulating. There is exactly one code state on disk. Nothing is duplicated, so nothing is merged. Ten plan items become ten short threads sharing one carefully-built prefix, over one continuously advancing codebase.
Alternative mode rewinds both. Each --alt branch gets its own code state, isolated from its siblings, so approach A never sees files written by approach B. At the end one branch is adopted and the others are discarded or archived.
Users shouldn't have to reason about which files travel where — they state the relationship between the branches, and the tool derives the rest.
Isolation is only needed in alternative mode. Parallel mode requires no snapshotting whatsoever — worth stating explicitly, because it means the common case is cheap to implement.
For alternative mode the code state has to live somewhere, and the backend should be configurable rather than baked into the user-facing model. Three options, in increasing order of fidelity:
The existing checkpoint mechanism already works and restores in place, but it misses anything the edit tools didn't do — rm, mv, code generators, build output — so a restored state can be incomplete.
Git worktrees give real isolation, since each branch gets its own directory, at the cost of a second working directory on disk and slower switching.
Shadow refs — snapshot commits stored under something like refs/claude// — cover everything git covers, including bash-made changes and deletions, while keeping the user's own git log clean. They are inspectable with ordinary git tooling and can be garbage-collected along with the existing 30-day session retention.
{ "branching": { "altBackend": "worktree" } }
Git is worth supporting because it already solves snapshotting correctly and is sitting right there in every project — but it is an implementation option for one of the two modes, not the concept. Parallel mode, which is the more valuable half of this request, works with no version control involvement at all.
Re-entering an anchor in parallel mode injects a compact, auto-generated status note:
[From anchor "plan" — 3 of 10 items completed]
[done] 1. Extract config loader -> src/config.rs, src/main.rs
[done] 2. Add retry middleware -> src/http/retry.rs (+ tests)
[done] 3. Replace panic with Result -> 6 files
[here] 4. Migrate cache layer
This is the plan file people currently maintain by hand, generated instead, and carrying provenance rather than just item text. It tells the model what state the code is actually in without spending the context that the full transcript would.
/merge try-redis --summary # inject the branch's conclusions into the current conversation
/merge try-redis --diff # offer its file changes for review and application
Conflicts are surfaced as a diff for the user to resolve, never silently reconciled by the model. Parallel branches need no merge command at all — by construction there is nothing to merge, and that absence is a property of the design rather than a gap in it.
/anchors lists the anchors in a session and, for each, the branches taken from it, their mode, their status and the files they touched.
A session tree view shows anchors as nodes and branches as edges, with parallel and alternative branches rendered distinctly and the current position highlighted. Without it, a session with three anchors and eight branches becomes unnavigable.
Branches should also be reachable from the same place other work is: per #69712, they currently appear only in the /resume picker and not in the agent view.
Sometimes a parallel item turns out to need isolation halfway through — it starts rewriting a file another item owns. /isolate should convert the current parallel branch into an alternative one from the same anchor, snapshotting its current code state rather than forcing the user to start over.
Sessions with no anchors behave exactly as today; /rewind and /branch keep their current semantics. /from --alt is a repeatable, named form of what /branch already does, not a replacement for it.
If the full proposal is too large, the smallest genuinely useful slice is anchors plus parallel mode: /anchor, /from, the ledger, and automatic anchoring of approved plans. That requires no snapshotting, no git integration and no merge machinery, and it solves the case that has no workaround. Alternative mode is largely a formalisation of /branch plus a code backend, and can follow.
Alternative Solutions
Serialising the plan to a file and /clear. The current standard workaround. Loses the reasoning behind the plan, requires manual upkeep, and re-reads a document instead of resuming a state.
/compact with a focus argument. Lossy and non-deterministic. The user cannot specify precisely what survives, and what survives is a summary, not the original messages.
/branch per plan item. This is the alternative-mode tool applied to a parallel-mode problem. It copies the conversation forward with all of the current item's noise, and the isolation it implies is fictional — both branches write to the same working tree. Users then either merge things that were never meant to diverge, or end up with a working tree matching no branch's transcript.
/rewind per item. Linear and single-shot. Restoring the conversation to the plan discards the code from completed items; restoring code only leaves the conversation where it was.
Subagents or /fork per item. The closest existing fit, and genuinely good for delegable work — but a subagent gets a fresh context window, so it doesn't inherit the plan discussion, and the user supervises a delegate rather than working at the anchor themselves.
Manual git worktree plus a session per item. Solves code state, but each session starts with no shared conversation context — paying, per item, the exact cost the anchor exists to avoid.
Priority
Medium - Would be very helpful
Feature Category
Configuration and settings
Use Case Example
Ten-item refactor (parallel)
After a plan-mode session, plan is anchored automatically. For each item: /from plan, do the item, verify it, then /from plan again for the next one.
Every item starts with the full reasoning behind the plan in context and none of the previous item's debugging noise, while the code accumulates normally in a single working tree. Item 10 is executed with the same context quality as item 1. No plan file, no /clear, no /compact, no merge.
An item that goes wrong
Item 6 turns out to be a bad idea once implemented. /from plan --alt returns both conversation and code to the plan state, while items 1–5's work stays recorded in their own branches — recoverable, unlike a linear rewind.
Genuine alternatives (alternative mode)
Before a caching decision: /from plan --alt twice, one branch per approach, each with its own code state. Benchmark both, /merge redis-approach --summary --diff, discard the other. Here divergence is the point, and a git backend earns its keep.
Long sessions generally
Re-entry at an anchor is also the cheapest available fix for context decay in long agentic sessions: instead of one 200-message thread compacted twice, it becomes ten short threads sharing one carefully-built prefix.
Additional Context
This overlaps with #32631, and I'd be glad to see it folded in there — but the two model different things. #32631 treats a branch as a full fork of a session and focuses on the tree and the return path. This proposal's central claim is narrower: that conversation state and code state should be selectable independently at re-entry, and that the most common case — "conversation back, code forward" — needs no merge, no duplication and no version control to implement, yet no existing command expresses it.