@@ -12,6 +12,9 @@ title: "Forking of existing sessions"
1212We propose adding the ability to "fork" a new session based on an existing one.
1313This will allow us to use the current conversation as context to generate pull
1414request descriptions, summaries, etc. without polluting the user history.
15+ Additionally, agents may optionally support forking at a specific message
16+ boundary by accepting a ` messageId ` , allowing clients to branch the conversation
17+ from an earlier point instead of only from the current session head.
1518
1619## Status quo
1720
@@ -25,7 +28,8 @@ Therefore we want to be able to fork a session, issue additional messages, and t
2528
2629> What are you proposing to improve the situation?
2730
28- To add a "session/fork" method.
31+ To add a ` session/fork ` method, with an optional ` messageId ` branch point when
32+ the agent advertises support for message-scoped forks.
2933
3034## Shiny future
3135
@@ -34,17 +38,35 @@ To add a "session/fork" method.
3438We will be able to implement functionality that requires using the current chat
3539without polluting its history, ranging from summaries to potentially subagents.
3640
37- I can also see this feature being extended in the future to support an optional
38- message ID, so the fork happens at a specific message, allowing clients to implement
39- functionality like editing previous messages and similar.
41+ When message-scoped forks are supported, clients will also be able to branch an
42+ existing session from a specific message boundary. That makes features such as
43+ "edit and retry from here", alternate continuations, and what-if exploration
44+ possible without mutating the original session.
4045
4146## Implementation details and plan
4247
4348> Tell me more about your implementation. What is your detailed implementation plan?
4449
45- We propose to add a new "session/fork" method. Agents must declare this option is
46- available by returning ` session: { fork : {} } ` in its capabilities. The object is reserved
47- to declare future capabilities, such as forking from a specific message, a tool call, or similar.
50+ We propose to add a new ` session/fork ` method. Agents must declare this option
51+ is available by returning ` session: { fork: {} } ` in its capabilities.
52+
53+ Agents that additionally support forking from a specific message boundary
54+ advertise:
55+
56+ ``` json
57+ {
58+ "agentCapabilities" : {
59+ "session" : {
60+ "fork" : {
61+ "messageId" : {}
62+ }
63+ }
64+ }
65+ }
66+ ```
67+
68+ Clients MUST send ` messageId ` on ` session/fork ` only when
69+ ` session.fork.messageId ` is present.
4870
4971Then the client would be able to request a fork of the given session:
5072
@@ -68,6 +90,63 @@ Similarly, the agent would respond with optional data such as config options, th
6890Agents may reply with an error if forking of that specific session or with the given options is not supported,
6991for example if the agent does not support forking with a different working directory than the initial session.
7092
93+ ### Message-scoped forks
94+
95+ When the agent advertises ` session.fork.messageId ` , the client may include an
96+ optional ` messageId ` field in ` session/fork ` :
97+
98+ ``` json
99+ {
100+ "jsonrpc" : " 2.0" ,
101+ "id" : 2 ,
102+ "method" : " session/fork" ,
103+ "params" : {
104+ "sessionId" : " sess_789xyz" ,
105+ "messageId" : " 4c12d49b-729c-4086-bfed-5b82e9a53400" ,
106+ "cwd" : " ..." ,
107+ "mcpServers" : [... ]
108+ }
109+ }
110+ ```
111+
112+ The ` messageId ` identifies the first message that is ** not** copied into the
113+ forked session. In other words, the fork branches immediately before the
114+ referenced message:
115+
116+ - if ` messageId ` is omitted, the fork is created from the current head of the
117+ source session;
118+ - if ` messageId ` is present, the fork contains all replayable conversation
119+ state before that message boundary and excludes the referenced message and all
120+ later history from the new session.
121+
122+ This semantics is chosen because it composes cleanly with the
123+ [ ` messageId ` RFD] ( /rfds/message-id ) and directly supports edit-style workflows:
124+ a client that wants to replace a previously sent message can fork at that
125+ message's ID, then send the replacement prompt into the new session.
126+
127+ Agents that support ` messageId ` -scoped forking:
128+
129+ - SHOULD accept ` messageId ` values that were previously surfaced in the source
130+ session as ` userMessageId ` acknowledgments or replayed/emitted
131+ ` user_message_chunk ` and ` agent_message_chunk ` IDs;
132+ - MUST treat the ID as a message-boundary selector for the whole message, not
133+ for an individual chunk;
134+ - MUST reject unknown or unsupported ` messageId ` values with an error;
135+ - SHOULD NOT treat ` agent_thought_chunk ` IDs as valid fork anchors unless they
136+ intentionally expose thought history as replayable branch points.
137+
138+ The ` session.fork.messageId ` capability is intentionally coarse-grained. It
139+ means the agent can evaluate message-scoped fork requests, but it does not
140+ guarantee that every surfaced message is a valid fork anchor. Agents MAY reject
141+ individual message IDs when their history cannot be replayed safely from that
142+ point. A future extension may allow agents to advertise or stream per-message
143+ forkability.
144+
145+ Clients MUST follow the ` messageId ` acknowledgment rules from the
146+ [ ` messageId ` RFD] ( /rfds/message-id ) : if a prompt response omitted
147+ ` userMessageId ` , the client MUST assume that user message ID was not recorded
148+ and MUST NOT use it as a ` session/fork ` anchor.
149+
71150## Frequently asked questions
72151
73152> What questions have arisen over the course of authoring this document or during subsequent discussions?
@@ -79,6 +158,28 @@ For example, "session/new" has options such as capabilities and MCP which are no
79158recommended to be set when forking, as the context being forked was built with other
80159tools, and forking may accept a messageId for checkpoints.
81160
161+ ** Q: Why use ` messageId ` instead of a numeric message index?**
162+
163+ ` messageId ` builds directly on the draft message-identification work and avoids
164+ index drift across streaming, replay, deduplication, and partial history
165+ loading. A stable message identifier is also easier for clients to persist than
166+ an implementation-defined ordinal.
167+
168+ ** Q: Why does ` messageId ` mean "branch before this message" instead of "include this message"?**
169+
170+ This choice makes the feature immediately useful for editing and retry flows.
171+ If a client wants an alternate continuation from after a given message, it can
172+ use the next message's ID as the branch point, or omit ` messageId ` entirely when
173+ branching from the current session head.
174+
175+ ** Q: Does advertising ` session.fork.messageId ` mean every message is forkable?**
176+
177+ No. The capability only means the agent understands message-scoped fork
178+ requests. Agents MAY still reject specific ` messageId ` values if replaying from
179+ that point would be unsafe, lossy, or otherwise unsupported. This keeps the
180+ initial proposal simple while leaving room for a future per-message forkability
181+ signal.
182+
82183** Q: Should fork only accept the ` sessionId ` or also other options, similar to ` session/load ` ?**
83184
84185Initially, we proposed to only accept the ` sessionId ` , but this would make it more difficult to
@@ -95,6 +196,9 @@ None. This proposal is inspired by the abilities exposed in Claude Agent SDK. It
95196
96197## Revision history
97198
199+ - 2026-04-10: Added an optional ` messageId ` branch point, capability gating,
200+ branch semantics aligned with the ` message-id ` RFD, and clarified that
201+ message-fork support is coarse-grained rather than guaranteed per message.
98202- 2025-11-17: Mentioned capabilities format, updated FAQ.
99203- 2025-11-20: Added request format and updated capabilities format.
100204- 2025-12-10: Adjust fork options to align with ` session/load ` .
0 commit comments