How Checkpoint and Rewind Functionality Work in DeepSeek-Reasonix for Long Autonomous Runs
Reasonix uses snapshot-based checkpoints written after every visible user turn, combined with a transactional rewind subsystem that atomically restores both conversation state and file system to any previous turn.
DeepSeek-Reasonix is an autonomous coding agent capable of executing extended multi-turn sessions where each turn may modify files, execute tools, or send messages. To keep these long runs safe and fully reversible without polluting Git history, the engine implements a robust checkpoint and rewind functionality that persists session snapshots to disk and allows precise undo operations.
Checkpoint Creation and Storage Architecture
After every visible user turn, Reasonix writes a complete snapshot of the session state to a dedicated checkpoint directory named <session-id>.ckpt. This operation ensures that no matter how many autonomous steps execute, the user can always revert to a known good state.
The checkpoint structure is defined in internal/checkpoint/checkpoint.go, where the snapshot stores three critical components: the event log (.jsonl), the current turn counter, and a snapshot of the file system relevant to the session. The controller persists the checkpoint location in SessionCheckpointDir, as implemented in internal/store/session.go at line 153.
// Create a checkpoint after a user turn (internal/control/turn_orchestrator.go)
func (o *Orchestrator) finalizeTurn(turn *Turn) error {
// ...execute tools, update files...
// Write a checkpoint for the visible user turn
if err := c.session.Checkpoint(turn.ID); err != nil {
return err
}
return nil
}
The Controller maintains a monotonic turn counter and an in-memory map from turn numbers to checkpoint IDs. This indexing mechanism, found in internal/control/turn_orchestrator.go at lines 138-139, enables the UI to display a "rewind picker" where each user turn is labeled with its original prompt and timestamp.
The Rewind Subsystem and Atomic Restoration
When a user invokes /rewind (or uses the double-Esc UI shortcut), the server calls Controller.rewind from internal/control/rewind.go. This function first validates that no turn is currently executing to prevent race conditions, then loads the chosen checkpoint and restores both the conversation transcript and the file system to that exact snapshot.
The restoration process is transactional: if any part of the file system or state recovery fails, the operation aborts and the session remains unchanged. Error handling is centralized in the rewindFail function, located in internal/control/controller.go at lines 3263-3268, which ensures atomicity and prevents partial rewinds from corrupting the session.
// Rewind to checkpoint #7 (internal/control/rewind.go)
func (c *Controller) Rewind(turn int, mode RewindMode) error {
plan, err := c.prepareRewind(turn, mode)
if err != nil { return err }
// Apply the snapshot stored in the checkpoint
if err := c.session.RestoreFromCheckpoint(plan.CheckpointID); err != nil {
return c.rewindFail(err)
}
c.notice("rewound to turn %d", turn)
return nil
}
Users can specify the rewind mode to restore "code only", "conversation only", or "both", allowing granular control over which aspects of the session revert.
Undoing Rewinds and Transaction Safety
After a successful rewind, Reasonix records a rewind transaction that itself can be undone using the "undo-rewind" command. This functionality uses the same checkpoint mechanism: the previous checkpoint is re-applied, effectively moving the session forward again to its pre-rewind state.
The UndoRewind implementation in internal/control/rewind.go at lines 179-188 demonstrates this bidirectional capability, ensuring that even the rewind operation itself is reversible without data loss.
# CLI usage examples
$ reasonix /rewind 14 both # rewind turn 14, restoring code and conversation
$ reasonix /undo-rewind # undo the last rewind operation
Persistence Across Restarts
Because checkpoints are stored on disk outside of Git history, the checkpoint and rewind functionality remains available across application restarts. A user can close Reasonix, reopen it later, and still access the full checkpoint list from previous sessions.
The web UI fetches available checkpoints via the /checkpoints endpoint, implemented in internal/serve/serve.go at lines 1234-1235. This endpoint serves the checkpoint metadata to the frontend, allowing the rewind picker to display historical turns even after the engine reboots.
User Interface and Experience
The web UI displays a picker listing each checkpoint with timestamps and a brief summary of changes made during that turn. According to docs/CHECKPOINTS.md, users interact with this system through intuitive controls that distinguish between rewinding code changes, conversation history, or both simultaneously.
This design ensures that long autonomous runs—potentially involving hundreds of file edits and tool executions—remain fully navigable and reversible through a visual timeline interface.
Summary
- Snapshot-based checkpoints are written to disk after every visible user turn in
internal/checkpoint/checkpoint.go, storing the event log, turn counter, and file system state. - Atomic rewinds in
internal/control/rewind.govalidate session state, restore snapshots transactionally, and handle errors viarewindFailto prevent partial state corruption. - Bidirectional undo allows users to reverse a rewind operation using
UndoRewind, treating rewinds as reversible transactions. - Disk persistence outside Git history enables checkpoint survival across application restarts, served via the
/checkpointsAPI ininternal/serve/serve.go. - Granular control lets users rewind code, conversation, or both, managed by the turn orchestrator in
internal/control/turn_orchestrator.go.
Frequently Asked Questions
How does Reasonix ensure data integrity during a rewind operation?
Reasonix treats rewinds as atomic transactions. The Controller.rewind function in internal/control/rewind.go validates that no turn is currently running before initiating restoration. If RestoreFromCheckpoint fails at any point, the error propagates to rewindFail in internal/control/controller.go (lines 3263-3268), which aborts the operation and leaves the session in its original state without applying partial changes.
Can I undo a rewind if I restore the wrong checkpoint?
Yes. After a successful rewind, Reasonix records a rewind transaction that can be reversed using the /undo-rewind command. As implemented in internal/control/rewind.go at lines 179-188, this reapplies the previous checkpoint, effectively moving the session forward again to its state before the rewind occurred.
Where are checkpoints stored and do they persist after closing the application?
Checkpoints are stored in a dedicated directory named <session-id>.ckpt on disk, referenced by SessionCheckpointDir in internal/store/session.go (line 153). Because these snapshots exist outside of Git history and in persistent storage, they survive application restarts. The UI retrieves historical checkpoints via the /checkpoints endpoint defined in internal/serve/serve.go (lines 1234-1235).
What is the difference between rewinding code versus conversation?
The rewind subsystem supports three modes controlled by the RewindMode parameter: "code" restores only file system snapshots, "conversation" restores only the event log and transcript, and "both" restores the complete session state. This granularity allows users to revert buggy code changes while preserving discussion context, or vice versa, as documented in docs/CHECKPOINTS.md.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →