# How Checkpoints and Rewind Work for Reasonix Session State Recovery

> Discover how DeepSeek Reasonix uses checkpoints and rewind for session state recovery. Learn about its git-free snapshot system and three-phase workflow for deterministic code and chat state management.

- Repository: [YHH/DeepSeek-Reasonix](https://github.com/esengine/DeepSeek-Reasonix)
- Tags: internals
- Published: 2026-08-08

---

**DeepSeek-Reasonix implements a git-free, snapshot-based checkpoint system that captures file states and conversation history at each turn, enabling deterministic rewinding of code and chat state via a three-phase prepare-apply-persist workflow.**

DeepSeek-Reasonix provides robust session state recovery through an integrated checkpoint and rewind mechanism that operates independently of version control. This system records the complete state of edited files alongside conversation metadata at every user turn, storing them as JSON files in session-specific directories. By leveraging this architecture, Reasonix enables developers to safely roll back both code modifications and dialogue history to any previous point without touching the underlying git repository.

## The Snapshot-Based Checkpoint Architecture

Reasonix employs a **git-free checkpoint model** that lives alongside session data, mirroring the deterministic safety found in Claude Code’s rewind feature. Each checkpoint represents a complete snapshot of the workspace state at a specific turn, capturing not just file contents but also the conversation context that produced them.

### Checkpoint Data Structure

Every checkpoint is stored as a JSON file containing a `Checkpoint` struct with the following components:

- **Turn metadata**: Turn number, timestamp, and the prompt that triggered the edit
- **FileSnap entries**: A list of file snapshots capturing pre-edit content, file mode, SHA-256 fingerprint, and capture source (previewer, before-mutation, or after-mutation)
- **Coverage information**: Indicators showing which files were captured and any gaps in the snapshot

The `FileSnap` struct, defined in [`internal/checkpoint/checkpoint.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/checkpoint/checkpoint.go) lines [33‑46]【/cache/repos/github.com/esengine/DeepSeek-Reasonix/main-v2/internal/checkpoint/checkpoint.go#L33-L46】, provides the granular state capture necessary for deterministic restoration.

### Storage and Persistence

The `Store` struct manages checkpoint persistence in a dedicated directory named `<session>.ckpt/`. According to the implementation in [`internal/checkpoint/checkpoint.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/checkpoint/checkpoint.go) lines [40‑65]【/cache/repos/github.com/esengine/DeepSeek-Reasonix/main-v2/internal/checkpoint/checkpoint.go#L40-L65】, the system maintains:

- An in-memory slice of completed checkpoints (`done []*Checkpoint`)
- A content-addressed `BlobStore` for large file payloads
- Session-specific isolation ensuring checkpoints never interfere with the user's repository

## How Session Rewind Works

The rewind mechanism follows a strict three-phase workflow designed to ensure safety and consistency when recovering previous states.

### Phase 1: Preparation and Validation

Before any state changes occur, `Controller.PrepareRewind(turn, scope)` validates that the rewind operation can proceed safely. As implemented in [`internal/control/rewind.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/control/rewind.go) lines [95‑129]【/cache/repos/github.com/esengine/DeepSeek-Reasonix/main-v2/internal/control/rewind.go#L95-L129】, this function:

1. Verifies the requested checkpoint exists
2. Ensures no turn is currently running
3. Confirms the conversation boundary is still present
4. Returns a `RewindPlan` describing what can be rewound (code, conversation, or both) and any disabling conditions

### Phase 2: Applying the Rewind

The `Controller.Rewind(turn, scope)` method, exposed via the HTTP endpoint `POST /rewind` registered in [`internal/serve/serve.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/serve/serve.go) line [408]【/cache/repos/github.com/esengine/DeepSeek-Reasonix/main-v2/internal/serve/serve.go#L408】, executes the actual restoration:

**Code Restoration**: The checkpoint store restores each file to its captured pre-edit content, or deletes the file if it did not exist at the checkpoint time.

**Conversation Truncation**: The `conversationApplier.ApplyConversationTruncate` function, found in [`internal/control/rewind.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/control/rewind.go) lines [34‑56]【/cache/repos/github.com/esengine/DeepSeek-Reasonix/main-v2/internal/control/rewind.go#L34-L56】, truncates the event-log up to the checkpoint’s `MsgIndex`. If the conversation was compacted past this index, the operation fails with a "conversation rewind unavailable" error.

### Phase 3: Persistence

After restoration, the controller writes a new session snapshot so future runs see the rewound state. The checkpoint store updates its internal turn counter and boundary map to reflect the new current position in the session history.

## Automatic State Capture with MutationObserver

Checkpoints are populated automatically through the `MutationObserver`, which intercepts tool-generated edits before they modify the filesystem. As shown in [`internal/checkpoint/observer.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/checkpoint/observer.go) lines [196‑234]【/cache/repos/github.com/esengine/DeepSeek-Reasonix/main-v2/internal/checkpoint/observer.go#L196-L234】, the observer invokes:

- `CaptureBefore`: Records the pre-mutation state of files
- `CaptureAfter`: Records the post-mutation state

This hook-based approach ensures every tool-generated edit is recorded without requiring manual checkpoint creation.

## Using the Checkpoints API

### Listing Available Checkpoints

The HTTP endpoint `GET /checkpoints` returns a list of `Meta` objects for UI selection. Implemented in [`internal/serve/serve.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/serve/serve.go) line [1072]【/cache/repos/github.com/esengine/DeepSeek-Reasonix/main-v2/internal/serve/serve.go#L1072-L1076】, this endpoint provides:

```json
[
  {
    "Turn": 1,
    "Time": "2024-08-05T12:34:56Z",
    "Prompt": "Add new utils",
    "Paths": ["utils.go"],
    "CanUndoFiles": true,
    "Legacy": false
  }
]

```

### Executing a Rewind via HTTP

To programmatically trigger a rewind, send a `POST` request to the rewind endpoint:

```http
POST https://<reasonix-server>/rewind
Content-Type: application/json

{
  "turn": 3,
  "scope": "both"
}

```

The **rewind scope** accepts three values:
- `"code"`: Restore only file states
- `"conversation"`: Truncate only the dialogue history
- `"both"` (default): Restore both code and conversation

The server responds with **204 No Content** on success or **500** if the checkpoint is unavailable.

### Programmatic Rewind in Go

For direct integration with the Go controller:

```go
import (
    "reasonix/internal/control"
)

func rewindExample(ctl *control.Controller, turn int) error {
    // Validate and obtain a plan
    plan, err := ctl.PrepareRewind(turn, control.RewindBoth)
    if err != nil {
        return fmt.Errorf("cannot prepare rewind: %w", err)
    }
    if !plan.OK {
        return fmt.Errorf("rewind disabled: %s", plan.DisabledReason)
    }

    // Perform the rewind
    if err := ctl.Rewind(turn, control.RewindBoth); err != nil {
        return fmt.Errorf("rewind failed: %w", err)
    }
    return nil
}

```

## Summary

- **Git-free isolation**: Checkpoints stored in `<session>.ckpt/` directories never interact with the user's git repository
- **Complete state capture**: `FileSnap` entries record SHA-256 hashes, file modes, and content for deterministic restoration
- **Three-phase safety**: The prepare-apply-persist workflow ensures rewinds only occur when valid and safe
- **Flexible scope**: Rewind operations can target code, conversation, or both states independently
- **Automatic instrumentation**: `MutationObserver` hooks capture all tool-generated edits without manual intervention

## Frequently Asked Questions

### What storage format does Reasonix use for checkpoints?

Reasonix stores checkpoints as JSON files in session-specific directories named `<session>.ckpt/`. Each file contains turn metadata, `FileSnap` entries with SHA-256 fingerprints, and coverage information. Large file payloads are stored in a content-addressed blob store to optimize disk usage.

### Can I rewind only the conversation without affecting code?

Yes. The rewind scope parameter accepts `"conversation"` to truncate only the dialogue history using `ApplyConversationTruncate`, `"code"` to restore only file states, or `"both"` to perform both operations simultaneously. This granular control allows you to revert chat context while preserving recent code changes.

### What happens if the conversation history was compacted?

If the conversation was compacted past the checkpoint's `MsgIndex`, the rewind operation fails with a "conversation rewind unavailable" error. The system validates the conversation boundary during the preparation phase to prevent partial or inconsistent rewinds.

### Is the checkpoint system dependent on git?

No. Reasonix checkpoints are completely **git-free** and operate alongside session data. While the tool may run in a git repository, the checkpoint store in [`internal/checkpoint/checkpoint.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/checkpoint/checkpoint.go) manages its own persistence layer, ensuring that session recovery works regardless of the repository's git state or history.