From 00110fb3c3713a2f304be17df321db448b5b5cee Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Mon, 16 Mar 2026 04:56:22 -0700 Subject: [PATCH] docs: update checkpoint/rollback docs for new features - Reflect that checkpoints are now enabled by default - Document /rollback diff for previewing changes - Document /rollback for single-file restore - Document automatic conversation undo on rollback - Document terminal command checkpoint coverage - Update listing example to show change stats - Fix config path (checkpoints.enabled, not agent.checkpoints_enabled) - Consolidate features/checkpoints.md to brief summary with link --- .../user-guide/checkpoints-and-rollback.md | 175 ++++++++++-------- .../docs/user-guide/features/checkpoints.md | 99 ++-------- 2 files changed, 115 insertions(+), 159 deletions(-) diff --git a/website/docs/user-guide/checkpoints-and-rollback.md b/website/docs/user-guide/checkpoints-and-rollback.md index a7a34115f..f81a7d4f8 100644 --- a/website/docs/user-guide/checkpoints-and-rollback.md +++ b/website/docs/user-guide/checkpoints-and-rollback.md @@ -6,10 +6,28 @@ description: "Filesystem safety nets for destructive operations using shadow git # Checkpoints and `/rollback` -Hermes Agent can automatically snapshot your project before **destructive operations** (like file write/patch tools) and restore it later with a single command. +Hermes Agent automatically snapshots your project before **destructive operations** and lets you restore it with a single command. Checkpoints are **enabled by default** — there's zero cost when no file-mutating tools fire. This safety net is powered by an internal **Checkpoint Manager** that keeps a separate shadow git repository under `~/.hermes/checkpoints/` — your real project `.git` is never touched. +## What Triggers a Checkpoint + +Checkpoints are taken automatically before: + +- **File tools** — `write_file` and `patch` +- **Destructive terminal commands** — `rm`, `mv`, `sed -i`, `truncate`, `shred`, output redirects (`>`), and `git reset`/`clean`/`checkout` + +The agent creates **at most one checkpoint per directory per turn**, so long-running sessions don't spam snapshots. + +## Quick Reference + +| Command | Description | +|---------|-------------| +| `/rollback` | List all checkpoints with change stats | +| `/rollback ` | Restore to checkpoint N (also undoes last chat turn) | +| `/rollback diff ` | Preview diff between checkpoint N and current state | +| `/rollback ` | Restore a single file from checkpoint N | + ## How Checkpoints Work At a high level: @@ -21,24 +39,11 @@ At a high level: - Stages and commits the current state with a short, human‑readable reason. - These commits form a checkpoint history that you can inspect and restore via `/rollback`. -Internally, the Checkpoint Manager: - -- Stores shadow repos under: - - `~/.hermes/checkpoints//` -- Keeps metadata about: - - The original working directory (`HERMES_WORKDIR` file in the shadow repo). - - Excluded paths such as: - - `node_modules/`, `dist/`, `build/` - - `.venv/`, `__pycache__/`, `*.pyc` - - `.git/`, `.cache/`, `.pytest_cache/`, etc. - -The agent creates **at most one checkpoint per directory per turn**, so long running sessions do not spam snapshots. - ```mermaid flowchart LR user["User command\n(hermes, gateway)"] agent["AIAgent\n(run_agent.py)"] - tools["File tools\n(write/patch)"] + tools["File & terminal tools"] cpMgr["CheckpointManager"] shadowRepo["Shadow git repo\n~/.hermes/checkpoints/"] @@ -50,108 +55,128 @@ flowchart LR tools -->|"apply changes"| agent ``` -## Enabling Checkpoints +## Configuration -Checkpoints are controlled by a simple on/off flag and a maximum snapshot count **per directory**: - -- `checkpoints_enabled` – master switch -- `checkpoint_max_snapshots` – soft cap on history depth per directory - -You can configure these in `~/.hermes/config.yaml`: +Checkpoints are enabled by default. Configure in `~/.hermes/config.yaml`: ```yaml -agent: - checkpoints_enabled: true - checkpoint_max_snapshots: 50 +checkpoints: + enabled: true # master switch (default: true) + max_snapshots: 50 # max checkpoints per directory ``` -Or via CLI flags (exact wiring may depend on your version of the CLI): +To disable: -```bash -hermes --checkpoints -# or -hermes chat --checkpoints +```yaml +checkpoints: + enabled: false ``` When disabled, the Checkpoint Manager is a no‑op and never attempts git operations. ## Listing Checkpoints -Hermes exposes an interactive way to list checkpoints for the current working directory. +From a CLI session: -From the CLI session where you are working on a project: - -```bash -# Ask Hermes to show checkpoints for the current directory +``` /rollback ``` -Hermes responds with a formatted list similar to: +Hermes responds with a formatted list showing change statistics: ```text 📸 Checkpoints for /path/to/project: - 1. a1b2c3d 2026-03-13 10:24 auto: before apply_patch - 2. d4e5f6a 2026-03-13 10:15 pre-rollback snapshot (restoring to a1b2c3d0) + 1. 4270a8c 2026-03-16 04:36 before patch (1 file, +1/-0) + 2. eaf4c1f 2026-03-16 04:35 before write_file + 3. b3f9d2e 2026-03-16 04:34 before terminal: sed -i s/old/new/ config.py (1 file, +1/-1) -Use /rollback to restore, e.g. /rollback 1 + /rollback restore to checkpoint N + /rollback diff preview changes since checkpoint N + /rollback restore a single file from checkpoint N ``` Each entry shows: - Short hash - Timestamp -- Reason (commit message for the snapshot) +- Reason (what triggered the snapshot) +- Change summary (files changed, insertions/deletions) + +## Previewing Changes with `/rollback diff` + +Before committing to a restore, preview what has changed since a checkpoint: + +``` +/rollback diff 1 +``` + +This shows a git diff stat summary followed by the actual diff: + +```text +test.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test.py b/test.py +--- a/test.py ++++ b/test.py +@@ -1 +1 @@ +-print('original content') ++print('modified content') +``` + +Long diffs are capped at 80 lines to avoid flooding the terminal. ## Restoring with `/rollback` -Once you have identified the snapshot you want to go back to, use `/rollback` with the number from the list: +Restore to a checkpoint by number: -```bash -# Restore to the most recent snapshot +``` /rollback 1 ``` Behind the scenes, Hermes: 1. Verifies the target commit exists in the shadow repo. -2. Takes a **pre‑rollback snapshot** of the current state so you can “undo the undo” later. -3. Runs `git checkout -- .` in the shadow repo, restoring tracked files in your working directory. +2. Takes a **pre‑rollback snapshot** of the current state so you can "undo the undo" later. +3. Restores tracked files in your working directory. +4. **Undoes the last conversation turn** so the agent's context matches the restored filesystem state. -On success, Hermes responds with a short summary like: +On success: ```text -✅ Restored /path/to/project to a1b2c3d -Reason: auto: before apply_patch +✅ Restored to checkpoint 4270a8c5: before patch +A pre-rollback snapshot was saved automatically. +(^_^)b Undid 4 message(s). Removed: "Now update test.py to ..." + 4 message(s) remaining in history. + Chat turn undone to match restored file state. ``` -If something goes wrong (missing commit, git error), you will see a clear error message and details will be logged. +The conversation undo ensures the agent doesn't "remember" changes that have been rolled back, avoiding confusion on the next turn. + +## Single-File Restore + +Restore just one file from a checkpoint without affecting the rest of the directory: + +``` +/rollback 1 src/broken_file.py +``` + +This is useful when the agent made changes to multiple files but only one needs to be reverted. ## Safety and Performance Guards To keep checkpointing safe and fast, Hermes applies several guardrails: -- **Git availability** - - If `git` is not found on `PATH`, checkpoints are transparently disabled. - - A debug log entry is emitted, but your session continues normally. -- **Directory scope** - - Hermes skips overly broad directories such as: - - Root (`/`) - - Your home directory (`$HOME`) - - This prevents accidental snapshots of your entire filesystem. -- **Repository size** - - Before committing, Hermes performs a quick file count. - - If the directory has more than a configured threshold (e.g. `50,000` files), - checkpoints are skipped to avoid large git operations. -- **No‑change snapshots** - - If there are no changes since the last snapshot, the checkpoint is skipped - instead of committing an empty diff. - -All errors inside the Checkpoint Manager are treated as **non‑fatal**: they are logged at debug level and your tools continue to run. +- **Git availability** — if `git` is not found on `PATH`, checkpoints are transparently disabled. +- **Directory scope** — Hermes skips overly broad directories (root `/`, home `$HOME`). +- **Repository size** — directories with more than 50,000 files are skipped to avoid slow git operations. +- **No‑change snapshots** — if there are no changes since the last snapshot, the checkpoint is skipped. +- **Non‑fatal errors** — all errors inside the Checkpoint Manager are logged at debug level; your tools continue to run. ## Where Checkpoints Live -By default, all shadow repos live under: +All shadow repos live under: ```text ~/.hermes/checkpoints/ @@ -160,21 +185,19 @@ By default, all shadow repos live under: └── ... ``` -Each `` is derived from the absolute path of the working directory. Inside each shadow repo you will find: +Each `` is derived from the absolute path of the working directory. Inside each shadow repo you'll find: - Standard git internals (`HEAD`, `refs/`, `objects/`) - An `info/exclude` file containing a curated ignore list - A `HERMES_WORKDIR` file pointing back to the original project root -You normally never need to touch these manually; they are documented here so advanced users understand how the safety net works. +You normally never need to touch these manually. ## Best Practices -- **Keep checkpoints enabled** for interactive development and refactors. -- **Use `/rollback` instead of `git reset`** when you want to undo agent‑driven changes only. -- **Combine with Git branches and worktrees** for maximum safety: - - Keep each Hermes session in its own worktree/branch. - - Let checkpoints act as an extra layer of protection on top. - -For running multiple agents in parallel on the same repo without interfering with each other, see the dedicated guide on [Git worktrees](./git-worktrees.md). +- **Leave checkpoints enabled** — they're on by default and have zero cost when no files are modified. +- **Use `/rollback diff` before restoring** — preview what will change to pick the right checkpoint. +- **Use `/rollback` instead of `git reset`** when you want to undo agent-driven changes only. +- **Combine with Git worktrees** for maximum safety — keep each Hermes session in its own worktree/branch, with checkpoints as an extra layer. +For running multiple agents in parallel on the same repo, see the guide on [Git worktrees](./git-worktrees.md). diff --git a/website/docs/user-guide/features/checkpoints.md b/website/docs/user-guide/features/checkpoints.md index a50aca8ff..aed879fc2 100644 --- a/website/docs/user-guide/features/checkpoints.md +++ b/website/docs/user-guide/features/checkpoints.md @@ -1,97 +1,30 @@ # Filesystem Checkpoints -Hermes can automatically snapshot your working directory before making file changes, giving you a safety net to roll back if something goes wrong. +Hermes automatically snapshots your working directory before making file changes, giving you a safety net to roll back if something goes wrong. Checkpoints are **enabled by default**. -## How It Works +## Quick Reference -When enabled, Hermes takes a **one-time snapshot** at the start of each conversation turn before the first file-modifying operation (`write_file` or `patch`). This creates a point-in-time backup you can restore to at any time. +| Command | Description | +|---------|-------------| +| `/rollback` | List all checkpoints with change stats | +| `/rollback ` | Restore to checkpoint N (also undoes last chat turn) | +| `/rollback diff ` | Preview diff between checkpoint N and current state | +| `/rollback ` | Restore a single file from checkpoint N | -Under the hood, checkpoints use a **shadow git repository** stored at `~/.hermes/checkpoints/`. This is completely separate from your project's git — no `.git` directory is created in your project, and your own git history is never touched. +## What Triggers Checkpoints -## Enabling Checkpoints +- **File tools** — `write_file` and `patch` +- **Destructive terminal commands** — `rm`, `mv`, `sed -i`, output redirects (`>`), `git reset`/`clean` -### Per-session (CLI flag) - -```bash -hermes --checkpoints -``` - -### Permanently (config.yaml) +## Configuration ```yaml # ~/.hermes/config.yaml checkpoints: - enabled: true - max_snapshots: 50 # max checkpoints per directory (default: 50) + enabled: true # default: true + max_snapshots: 50 # max checkpoints per directory ``` -## Rolling Back +## Learn More -Use the `/rollback` slash command: - -``` -/rollback # List all available checkpoints -/rollback 1 # Restore to checkpoint #1 (most recent) -/rollback 3 # Restore to checkpoint #3 (further back) -/rollback abc1234 # Restore by git commit hash -``` - -Example output: - -``` -📸 Checkpoints for /home/user/project: - - 1. abc1234 2026-03-10 14:22 before write_file - 2. def5678 2026-03-10 14:15 before patch - 3. ghi9012 2026-03-10 14:08 before write_file - -Use /rollback to restore, e.g. /rollback 1 -``` - -When you restore, Hermes automatically takes a **pre-rollback snapshot** first — so you can always undo your undo. - -## What Gets Checkpointed - -Checkpoints capture the entire working directory (the project root), excluding common large/sensitive patterns: - -- `node_modules/`, `dist/`, `build/` -- `.env`, `.env.*` -- `__pycache__/`, `*.pyc` -- `.venv/`, `venv/` -- `.git/` -- `.DS_Store`, `*.log` - -## Performance - -Checkpoints are designed to be lightweight: - -- **Once per turn** — only the first file operation triggers a snapshot, not every write -- **Skips large directories** — directories with >50,000 files are skipped automatically -- **Skips when nothing changed** — if no files were modified since the last checkpoint, no commit is created -- **Non-blocking** — if a checkpoint fails for any reason, the file operation proceeds normally - -## How It Determines the Project Root - -When you write to a file like `src/components/Button.tsx`, Hermes walks up the directory tree looking for project markers (`.git`, `pyproject.toml`, `package.json`, `Cargo.toml`, etc.) to find the project root. This ensures the entire project is checkpointed, not just the file's parent directory. - -## Platforms - -Checkpoints work on both: -- **CLI** — uses your current working directory -- **Gateway** (Telegram, Discord, etc.) — uses `MESSAGING_CWD` - -The `/rollback` command is available on all platforms. - -## FAQ - -**Does this conflict with my project's git?** -No. Checkpoints use a completely separate shadow git repository via `GIT_DIR` environment variables. Your project's `.git/` is never touched. - -**How much disk space do checkpoints use?** -Git is very efficient at storing diffs. For most projects, checkpoint data is negligible. Old checkpoints are pruned when `max_snapshots` is exceeded. - -**Can I checkpoint without git installed?** -No — git must be available on your PATH. If it's not installed, checkpoints silently disable. - -**Can I roll back across sessions?** -Yes! Checkpoints persist in `~/.hermes/checkpoints/` and survive across sessions. You can roll back to a checkpoint from yesterday. +For the full guide — how shadow repos work, diff previews, file-level restore, conversation undo, safety guards, and best practices — see **[Checkpoints and /rollback](../checkpoints-and-rollback.md)**.