Add fx session fork and fx session rewind (stack 1/2) - #1
Draft
Aarya2004 wants to merge 7 commits into
Draft
Conversation
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
This was referenced Sep 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.