Skip to content

Add fx session fork and fx session rewind (stack 1/2) - #1

Draft
Aarya2004 wants to merge 7 commits into
mainfrom
aarya/session-fork-rewind
Draft

Add fx session fork and fx session rewind (stack 1/2)#1
Aarya2004 wants to merge 7 commits into
mainfrom
aarya/session-fork-rewind

Conversation

@Aarya2004

Copy link
Copy Markdown
Owner

Review mirror of vercel-labs#560, the durable half of vercel-labs#537.

This PR exists so the stack renders with true per-PR diffs, which the upstream pair cannot do because GitHub requires a PR's base branch to live in the base repository. Review and discussion belong on the upstream PR; do not merge this one.

Aarya2004 added 7 commits August 31, 2026 23:47
The staging lock, staging root, staged-session start, promotion, and
discard helpers are generic. Session fork will call them too, so the
`recovery` prefix would misdescribe them. The on-disk directory and lock
file names are unchanged.

Claude-Session: https://claude.ai/code/session_01Hjm7J6N3SL5Y62TJ3bPxwD
A fork writes its history into a brand-new session, so its cache
publication cannot be deferred. A rewind rewrites the same session in
place and follows compaction.

Claude-Session: https://claude.ai/code/session_01Hjm7J6N3SL5Y62TJ3bPxwD
`forkSessionCopy` stages a new session holding the first N turns of a
healthy source, copies only the artifacts those turns reach, and commits
the branch history as a `fork` state replacement. The source is opened
under its writer lock and read through the read-only replay, so it is
never rewritten.

`rewindSession` truncates the same session in place under a `rewind`
state replacement. Artifacts for the dropped turns are left on disk.

Claude-Session: https://claude.ai/code/session_01Hjm7J6N3SL5Y62TJ3bPxwD
Both verbs render text and JSON from one snapshot, following the session
recovery contract.

Claude-Session: https://claude.ai/code/session_01Hjm7J6N3SL5Y62TJ3bPxwD
`fork --at <turn>` names an absolute boundary read straight off the
`[turn N]` labels `fx session <id>` prints. `rewind --by <count>` names a
relative one, which is how undoing the last turns is asked for. The CLI
resolves both to the absolute retained-turn count the store takes, and
reports an out-of-range request with the session's real turn count.

Claude-Session: https://claude.ai/code/session_01Hjm7J6N3SL5Y62TJ3bPxwD
The e2e suite drives the built binary against a fake gateway: it seeds a
multi-turn session, forks it, resumes the branch, and checks the source
directory is byte-identical afterward. Classified verification-only in
the PGSO corpus, since branching and undo are deliberate rare operations
that must stay correct without being made hot.

Claude-Session: https://claude.ai/code/session_01Hjm7J6N3SL5Y62TJ3bPxwD
A recovery checkpoint describes an in-flight turn that sits past the last
committed one, so any rewind that drops turns leaves it describing work the
session no longer has. Keeping it let `--continue-recovery` resume a response
for a turn that was removed.

`forkSessionCopy` already cleared it. A no-op rewind still keeps it, because
that path drops nothing and commits nothing.

Claude-Session: https://claude.ai/code/session_01Hjm7J6N3SL5Y62TJ3bPxwD
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant