feat(chat): optional background rollback checkpoint at agent-run start#91
Merged
Zeus-Deus merged 2 commits intoJun 10, 2026
Conversation
Snapshot the working tree when an agent-chat session starts so the user can roll back everything the run changed (issue #80). - Checkpoint runs in a spawned background task AFTER the provider session is up — no git work (or even the settings-cache read) sits on the latency-to-first-token path - Non-destructive snapshot: stage tracked + untracked changes into a temporary GIT_INDEX_FILE, write-tree + commit-tree onto HEAD, anchor at refs/codemux/checkpoints/<thread>; the user's index, worktree, and stash list stay untouched and no hooks fire - Record per thread in agent_chat_checkpoints (FK cascade with the session row) and emit agent_chat_checkpoint so the pane header can reveal the restore affordance without polling - Restore: pre-restore safety snapshot, read-tree --reset -u, clean -fd (ignored files spared), reset --mixed to the pre-run HEAD — undoes run commits, deletes run-created files, brings pre-run changes back as unstaged edits; refuses on branch mismatch or a pruned snapshot - Opt-in via Settings → Agent → "Checkpoint before agent runs" (synced agent_chat.checkpoints_enabled, default off) - Prune both refs/codemux namespaces to the 20 newest refs per create and drop the matching bookkeeping rows - Restore button (history icon) in the chat pane header with confirm dialog, disabled while a turn is running; dev-mock handlers for the browser-pane smoke flow - Tests: git helper round trips incl. linked-worktree case, DB CRUD + cascade, settings serde defaults, integration create/restore against real repos, mock-runtime background-spawn e2e (event + DB), header component tests for the restore flow
…tional-background-rollback-checkpoint-at-agent # Conflicts: # src-tauri/src/lib.rs # src/tauri/commands.ts # src/tauri/events.ts
This was referenced Jun 10, 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.
Closes #80
Summary
When an agent-chat session starts, take an opt-in, background snapshot of the workspace working tree so the user can roll back everything the run changed. The snapshot adds zero latency to the first token and does not disturb the user's index, worktree, or stash list.
How it works
Snapshot (non-destructive, shadow ref) —
git stash createignores untracked files, sogit_checkpoint_createinstead stages the worktree (tracked + untracked,.gitignorerespected) into a temporaryGIT_INDEX_FILE, runswrite-tree+commit-treeonto HEAD (plumbing — no hooks fire), and anchors the commit atrefs/codemux/checkpoints/<thread>so gc can't reap it. The user's real index/worktree/stash are byte-identical afterwards. Non-repos and unborn-HEAD repos are silently skipped.Background, never on the first-token path —
agent_chat_start_sessionspawnstauri::async_runtime::spawn+spawn_blockingafter the provider session is up and the session row is persisted; even the settings-cache read happens inside the spawned task. Failures are logged, never surfaced — a checkpoint must not break (or slow) the chat it protects.Recorded per run — new
agent_chat_checkpointstable (schema v7, FK cascade withagent_chat_sessions) stores snapshot commit, pre-run HEAD, branch, repo path, ref name. On success the backend emitsagent_chat_checkpointso the pane header reveals the restore affordance without polling.Restore — confirm dialog →
agent_chat_restore_checkpoint:refs/codemux/pre-restore/<thread>(keeps even run-made commits reachable)read-tree --reset -u <snapshot>+clean -fd(ignored files spared) +reset --mixed <pre-run HEAD>Result: run commits undone, run-created files deleted, pre-run changes back as unstaged edits, formerly-untracked files untracked again. Known, documented loss: the pre-run staged/unstaged split flattens to unstaged.
Opt-in — Settings → Agent → "Checkpoint before agent runs" (
agent_chat.checkpoints_enabled, synced settings, default off; legacy settings blobs deserialize to off).Pruning — each create prunes both
refs/codemux/namespaces to the 20 newest refs and drops the matching bookkeeping rows, so shadow refs can't grow unboundedly.UI
Acceptance criteria (issue #80)
git status --porcelainbyte-identical before/after)Testing
tests/agent_chat_commands.rs): create→restore round trip through the same blocking helpers the commands call, against real temp repos + in-memory DB; mock-Tauri-runtime e2e of the actual background spawn path (async spawn → blocking pool → real git snapshot → DB write through managed state →agent_chat_checkpointevent), plus the gate-off no-op casetsccleanupdate_settingagent-browserbinary,codemuxMCP entry in the real~/.claude.json, flaky port-reuse test) — none in files this PR touches; each passes with a cleanHOME/ re-runDocs
docs/plans/agent-run-checkpoint.md(incl. follow-ups: checkpoint continuity across silent restarts, socket/MCP exposure, per-turn history — out of scope per the issue)docs/features/agent-chat.md§ Run checkpoints,docs/core/STATUS.md,docs/INDEX.md