Snapshots & rollback

Every apply takes a snapshot first. Any apply can be undone.

Snapshots

Before any agent-initiated write, KrowForge calls services/apply_engine.apply() which:

  1. Reads the current state of every file the diff will touch.
  2. Stores a snapshot in services/snapshot_store.py — a per-workspace ring buffer (capacity 100 snapshots).
  3. Then applies the diff.

The snapshot has a stable ID (UUID) and is referenced by the receipt.

Rolling back

Three ways to trigger a rollback:

From the run history drawer

Each completed run shows a Rollback button. Clicking it restores every file the run touched to its pre-run snapshot.

From the receipt

POST /api/agent/rollback with a snapshot ID. Returns the diff that was reversed.

From the Changes panel

A Rollback last apply button at the top of the Changes panel (when there's a recent applied run).

Rollback receipts

Every rollback creates its own receipt. The audit chain is bidirectional:

… → receipt#41 (apply) → receipt#42 (rollback of #41) → …

You can roll forward again — but it's a new apply, not a re-application of the original. The agent re-generates the diff with current context.

Capacity & eviction

The buffer holds 100 snapshots per workspace. When full, the oldest snapshot is evicted. Once a snapshot is evicted, that specific apply can't be rolled back through the UI — but the receipt persists forever, so the audit trail stays intact.

If you anticipate needing very-long-tail rollback (security audits, compliance), pin the workspace into a self-hosted instance with a larger snapshot capacity (SNAPSHOT_BUFFER_SIZE env var).

What snapshots cover

  • Files written by the apply engine.
  • File creates (rollback deletes the file).
  • File deletes (rollback recreates the file with snapshot content).

What snapshots don't cover:

  • Shell command side effects (DB rows, network calls, sent emails).
  • External API calls (cloud deploys, third-party services).
  • Anything outside the workspace root.
If the agent runs psql -c "DROP TABLE users", that's not in any snapshot. Snapshots cover file changes, not arbitrary shell side effects. Use autonomy modes and per-tool guards to constrain side effects upstream.