# How the Checkpoint and Rewind System Works Without Git in DeepSeek-Reasonix

> Discover DeepSeek-Reasonix's checkpoint and rewind system. Restore code and chat history with JSON snapshots, bypassing Git for seamless version control.

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

---

**DeepSeek-Reasonix implements a snapshot-based checkpoint system that captures file states and conversation boundaries in JSON files before each edit, enabling full restoration of code and chat history without Git commands or repository initialization.**

The **DeepSeek-Reasonix** agent provides a **git-free checkpoint and rewind system** that persists session state using minimal JSON snapshots rather than repository commits. This allows users to roll back both code files and conversation history to any previous turn, even in directories that have never been initialized with Git. The system operates through three coordinated components: a snapshot store for file content, turn-boundary tracking for conversation state, and an orchestration layer that handles restoration logic.

## Core Architecture of the Snapshot System

The checkpoint system rests on three pillars that work together to provide atomic rollback capabilities without version control dependencies.

### The Checkpoint Store

At [`internal/checkpoint/checkpoint.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/checkpoint/checkpoint.go), the **Store** struct manages persistence of file snapshots. Each turn generates a new JSON file (`turn-<n>.json`) in a `*.ckpt/` directory adjacent to the session file. The `Store.Snapshot` method (lines 29–55) captures the pre-edit content of every file before modifications occur, storing data in a `FileSnap` struct that preserves the original encoding and content.

### Turn Boundaries for Conversation Rewind

The system tracks conversation state through **message indices** stored in checkpoint metadata. When a turn begins, `Controller.beginCheckpoint` in [`control/controller.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/control/controller.go) records the current message count (`MsgIndex`) in the checkpoint. This boundary marker allows the system to truncate the in-memory message log to the exact length it had at the start of any historical turn.

### Rewind Orchestration

The `Controller.Rewind` method in [`control/controller.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/control/controller.go) (lines 1560–1595) coordinates the restoration process. It accepts a target turn number and a **RewindScope** (`RewindCode`, `RewindConversation`, or `RewindBoth`), then executes the appropriate restoration logic without invoking external version control commands.

## How Checkpoints Are Created

Checkpoints are generated automatically through a pre-edit hook mechanism that intercepts file changes before they reach the filesystem.

### The Pre-Edit Hook

When the controller initializes, it installs a hook via `c.executor.SetPreEditHook` in [`control/controller.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/control/controller.go):

```go
c.executor.SetPreEditHook(func(ch diff.Change) {
    c.checkpoints.snapshot(ch)
})

```

This hook fires for every file modification, forwarding a `diff.Change` struct containing the file path, change kind, and original content to the checkpoint manager.

### Snapshot Deduplication and Persistence

The `checkpointManager` delegates to `Store.Snapshot`, which performs several critical operations under a mutex lock:

1. **Path validation**: Ignores empty paths
2. **Encoding detection**: Preserves the original file encoding (unless the file is new)
3. **Deduplication**: Uses a `seen` map to ensure only the first change to a file in a given turn is recorded
4. **Content capture**: Stores the old content (or `nil` for new files) in a `FileSnap`

The resulting checkpoint persists to disk as atomic JSON, ensuring that corruption of one checkpoint never affects others.

## The Rewind Process

Rewinding involves three coordinated steps that restore the workspace to a previous state while maintaining session integrity.

### Parsing Rewind Requests

User commands flow through `parseRewind` in [`control/controller.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/control/controller.go) (lines 3066–3100), which converts string arguments or HTTP JSON payloads into structured targets:

```go
func parseRewind(args string, cps []checkpoint.Meta) (int, RewindScope, error) {
    // Defaults to latest checkpoint with RewindBoth scope
    // Validates turn numbers and scope strings
}

```

### Restoring Code Snapshots

When `RewindCode` or `RewindBoth` is requested, `Store.RestoreCode` walks the checkpoint history to find the earliest snapshot for each modified path at or after the target turn. The restoration logic handles two cases:

- **Existing files**: Writes back the captured content using the original encoding
- **New files**: Removes files that did not exist at the target turn (indicated by `nil` content in the snapshot)

### Truncating Conversation History

For conversation rewinds, the system retrieves the stored `MsgIndex` from the checkpoint manager's boundary map. The `Controller.truncateHistory` method then slices the session's message array to this index, effectively removing all messages from subsequent turns. Finally, `checkpointManager.truncateFrom` renumbers future turn counters and cleans up stale boundaries.

## Using the Checkpoint System

DeepSeek-Reasonix exposes checkpoint functionality through multiple interfaces: CLI commands, HTTP endpoints, and direct Go API calls.

### CLI Usage

The desktop and terminal interfaces accept rewind commands:

```bash

# Restore both code and conversation to turn 2

reasonix /rewind 2

# Restore only code state, keep conversation history

reasonix /rewind 3 code

# Restore only conversation, keep current files

reasonix /rewind 5 conversation

# Shortcut to latest checkpoint with both scopes

reasonix /rewind

```

### HTTP API

The server implementation in [`internal/serve/serve.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/serve/serve.go) (lines 610–632) exposes a REST endpoint:

```bash
curl -X POST http://localhost:8080/rewind \
  -H "Content-Type: application/json" \
  -d '{"turn":4,"scope":"both"}'

```

The handler unmarshals the request and forwards it to `Controller.Rewind`:

```go
func (s *Server) rewind(w http.ResponseWriter, r *http.Request) {
    var body struct { Turn int; Scope string }
    json.NewDecoder(r.Body).Decode(&body)
    // Scope parsing logic...
    if err := s.ctl().Rewind(body.Turn, scope); err != nil {
        // Error handling...
    }
}

```

### Programmatic Go API

For integration with custom tools or automated testing:

```go
c, _ := control.New(opts)
// ... execute several turns ...
err := c.Rewind(3, control.RewindBoth)
if err != nil {
    log.Fatal(err)
}

```

### Inspecting Checkpoint Metadata

The frontend retrieves checkpoint listings via `Controller.Checkpoints()`, which returns metadata including turn numbers, prompt excerpts, and file counts:

```go
cps := c.Checkpoints()
for _, cp := range cps {
    fmt.Printf("Turn %d – %s (%d files)\n", 
        cp.Turn, cp.Prompt, len(cp.Paths))
}

```

## Summary

- **DeepSeek-Reasonix** implements **git-free checkpoints** using JSON snapshot files stored in `*.ckpt/` directories rather than Git commits.
- The **pre-edit hook** in [`control/controller.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/control/controller.go) captures file states before modifications occur, storing them in [`internal/checkpoint/checkpoint.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/checkpoint/checkpoint.go).
- **Turn boundaries** track conversation length via `MsgIndex`, enabling message log truncation without file system changes.
- The **rewind orchestrator** supports three scopes (`RewindCode`, `RewindConversation`, `RewindBoth`) and handles both file restoration and conversation trimming.
- **Multiple interfaces** expose the functionality: CLI commands (`/rewind`), HTTP POST requests to `/rewind`, and direct Go API calls to `Controller.Rewind`.
- Each checkpoint is stored in an isolated JSON file (`turn-<n>.json`), ensuring that corruption of one checkpoint does not affect the ability to rewind to others.

## Frequently Asked Questions

### Where are checkpoint files stored?

Checkpoint files are stored in a directory named `<session>.ckpt/` adjacent to the session file, with each turn represented by a separate JSON file ([`turn-1.json`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/turn-1.json), [`turn-2.json`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/turn-2.json), etc.). This location is intentionally separate from the workspace root to avoid polluting the user's project directory, and it requires no Git initialization or `.git` directory.

### What happens to files that were created after the target turn?

During a rewind operation, `Store.RestoreCode` checks the snapshot content for each file. If a file was created after the target turn, its earliest snapshot will contain `nil` content, signaling the system to delete the file entirely. If the file existed before the target turn, the system overwrites it with the captured pre-edit content.

### Can I rewind only the conversation without changing files?

Yes. By specifying `RewindConversation` as the scope (or using `reasonix /rewind <turn> conversation`), the system truncates the message log to the stored `MsgIndex` boundary while leaving the current filesystem state untouched. This allows you to retry prompts against your current code without losing recent edits.

### How does this system differ from using Git for version control?

Unlike Git, which requires repository initialization and creates `.git` directories, DeepSeek-Reasonix's system works immediately in any directory without setup. It captures **pre-edit snapshots** rather than post-commit diffs, stores only the files touched in a specific turn (not the entire repository), and maintains conversation state alongside code state. Additionally, checkpoints are stored as simple JSON files that can be manually inspected or deleted without risking repository corruption.