Skip to content

feat: filesystem checkpoints and /rollback command#824

Merged
teknium1 merged 1 commit intomainfrom
feat/checkpoint-rollback
Mar 10, 2026
Merged

feat: filesystem checkpoints and /rollback command#824
teknium1 merged 1 commit intomainfrom
feat/checkpoint-rollback

Conversation

@teknium1
Copy link
Copy Markdown
Contributor

Summary

Automatic filesystem snapshots before destructive file operations, with user-facing rollback via /rollback slash command. Inspired by PR #559 (by @alireza78a) — uses their shadow git approach but with a fundamentally different integration.

How It Works

When enabled, Hermes takes one snapshot per conversation turn before the first write_file or patch call. Uses shadow git repos at ~/.hermes/checkpoints/ via GIT_DIR + GIT_WORK_TREE — completely isolated from the user's project git.

Enabling

hermes --checkpoints              # per-session flag
# config.yaml — permanent
checkpoints:
  enabled: true
  max_snapshots: 50

Rolling Back

/rollback          # list checkpoints
/rollback 1        # restore to most recent checkpoint
/rollback 3        # restore further back

Design Decisions

  1. Not a tool — the LLM never sees it. Zero prompt tokens, zero schema overhead.
  2. Once per turn — deduplicates so only the first file-mutating op per turn triggers a snapshot.
  3. Opt-in — disabled by default. No performance impact for users who don't want it.
  4. Never blocks — all checkpoint errors are silently logged; file operations always proceed.
  5. Pre-rollback snapshots — restoring automatically creates a snapshot first, so you can undo your undo.

Files Changed

File Change
tools/checkpoint_manager.py NEW — CheckpointManager class (441 lines)
tests/tools/test_checkpoint_manager.py NEW — 35 tests
run_agent.py Init CheckpointManager + trigger in _execute_tool_calls
gateway/run.py /rollback slash command handler + help text
hermes_cli/main.py --checkpoints CLI flag
website/docs/user-guide/features/checkpoints.md NEW — feature documentation
website/docs/reference/cli-commands.md Added --checkpoints and /rollback
website/docs/user-guide/configuration.md Added checkpoints config section

Note: Changes to cli.py, hermes_cli/config.py, and hermes_cli/commands.py were committed to main already (swept up by a concurrent commit). They include: HermesCLI checkpoints param, config defaults, /rollback handler, and COMMANDS entry.

Test Plan

  • 35 unit tests (all passing)
  • 2798 total suite (0 failures)
  • End-to-end smoke test: create files → checkpoint → modify → rollback → verify content restored
  • Dedup verification: second checkpoint same turn returns False
  • Pre-rollback snapshot verification
  • Disabled manager returns False
  • Root/home dir skip verification
  • Project root resolution (walks up to .git/pyproject.toml)
  • Error resilience: git failure doesn't block file ops

Closes #452.

Automatic filesystem snapshots before destructive file operations,
with user-facing rollback.  Inspired by PR #559 (by @alireza78a).

Architecture:
- Shadow git repos at ~/.hermes/checkpoints/{hash}/ via GIT_DIR
- CheckpointManager: take/list/restore, turn-scoped dedup, pruning
- Transparent — the LLM never sees it, no tool schema, no tokens
- Once per turn — only first write_file/patch triggers a snapshot

Integration:
- Config: checkpoints.enabled + checkpoints.max_snapshots
- CLI flag: hermes --checkpoints
- Trigger: run_agent.py _execute_tool_calls() before write_file/patch
- /rollback slash command in CLI + gateway (list, restore by number)
- Pre-rollback snapshot auto-created on restore (undo the undo)

Safety:
- Never blocks file operations — all errors silently logged
- Skips root dir, home dir, dirs >50K files
- Disables gracefully when git not installed
- Shadow repo completely isolated from project git

Tests: 35 new tests, all passing (2798 total suite)
Docs: feature page, config reference, CLI commands reference
@teknium1 teknium1 merged commit c1775de into main Mar 10, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant