Summary
Forking a session while a turn is still streaming works (the daemon accepts it, the parent keeps streaming, the fork is created and focused), but the fork branches at the last completed turn — the response currently being generated is not carried into the fork.
Why
The assistant turn is only committed to a session's canonical history on turn_done. session.fork snapshots parent.canonicalHistory at fork time, so mid-turn that snapshot ends at the user prompt of the in-flight turn (the streaming assistant reply isn't in it yet). forkedFrom.atTurn reflects committed user turns.
Verified during the fork-while-mid-turn investigation:
So this is a product/UX decision about the branch point, not a bug in the fork path.
Options to decide later
- Leave as-is, document it. Fork = "branch from the last settled point." Simple, predictable; the streaming answer lives only on the parent.
- Wait-for-settle. If the parent is mid-turn, defer the fork until the current turn completes, then branch (so the fork includes the just-finished response). Needs a UX affordance (spinner / "forking after this turn").
- Snapshot the partial. Commit the in-flight assistant text into the fork's seed history at fork time. Most faithful to "branch from what I'm looking at," but the partial turn has no
turn_done/usage and may be truncated mid-tool — messiest.
Leaning toward (1) + a clear affordance, but revisit with fresh eyes.
Not blocking
Fork-while-running itself is functional; this only concerns which point it branches from. Tracked separately so it doesn't hold up the current integration-test work (#165, #166).
Summary
Forking a session while a turn is still streaming works (the daemon accepts it, the parent keeps streaming, the fork is created and focused), but the fork branches at the last completed turn — the response currently being generated is not carried into the fork.
Why
The assistant turn is only committed to a session's canonical history on
turn_done.session.forksnapshotsparent.canonicalHistoryat fork time, so mid-turn that snapshot ends at the user prompt of the in-flight turn (the streaming assistant reply isn't in it yet).forkedFrom.atTurnreflects committed user turns.Verified during the fork-while-mid-turn investigation:
response.ok, fork insession.list, parent goesthinking → idleuninterrupted.So this is a product/UX decision about the branch point, not a bug in the fork path.
Options to decide later
turn_done/usage and may be truncated mid-tool — messiest.Leaning toward (1) + a clear affordance, but revisit with fresh eyes.
Not blocking
Fork-while-running itself is functional; this only concerns which point it branches from. Tracked separately so it doesn't hold up the current integration-test work (#165, #166).