Auto-Checkpoint
Auto-Checkpoint creates a lightweight git commit after successful file
mutations, giving you fine-grained crash recovery and a clear audit trail.
In the current runtime, that follow-up runs after direct-apply mutation tools
such as write, edit, multiedit, and semantic LSP edits, and after
staged_accept / staged_accept_all when staged changes are actually
applied.
[options.auto_checkpoint]enabled = truerequire_clean_tree = falsemax_commits_per_session = 0llm_commit_message = falseRequirement: Requires a git repository with at least one existing commit.
Auto-checkpoint is a git commit. Mutation aftercare
is the change-contract reservation and ingest for the same file effect. The
durable reservation runs whether or not this git commit is enabled. A warning
that begins Auto-checkpoint warning: means the git commit did not land. It
does not say whether the change-contract ingest succeeded. Session checkpoints
are a third surface, described below.
Options
Section titled “Options”| Option | Default | Description |
|---|---|---|
enabled | false | Enable auto-checkpoint |
require_clean_tree | false | Only checkpoint when no untracked/unstaged files unrelated to the edit are present |
max_commits_per_session | 0 | Cap on remembered checkpoint commits per session (0 = unbounded) |
llm_commit_message | false | When true, use the last assistant message as the commit message (sanitized); otherwise use synthetic bmo: apply <tool> ... |
Restoring a git checkpoint (undo)
Section titled “Restoring a git checkpoint (undo)”Safety note: undo uses git reset --hard and discards working-tree changes
that are not preserved elsewhere. Inspect git diff and create a backup or
manual checkpoint before running it.
To undo auto-checkpoint commits, use the CLI: bmo checkpoint undo --steps N --yes, the agent tool checkpoint_undo with steps and confirm: true, or the TUI recovery hub /undo. For example, one step undoes the last commit. All three surfaces use the same destructive git reset --hard HEAD~N behavior in the repo root. They rewind the latest git commit; BMO does not currently verify commit provenance before running the reset.
Session checkpoints (separate feature)
Section titled “Session checkpoints (separate feature)”BMO also supports session checkpoints: named snapshots of a session’s transcript prefix identity, todos, file history, and typed historical read evidence that you can restore later. This is independent of git and does not roll back files on disk. For the full session concept (when to checkpoint vs branch vs new session), see Sessions. For the broader docs taxonomy, see Concept Map.
- TUI: Open the Sessions dialog, select a session, then ctrl+k to create a checkpoint (default name) or ctrl+e to open the Checkpoints list for that session. In the Checkpoints list, select one and press Enter (or r) to restore; confirm with y. A successful restore truncates messages and restores todos and historical file/read evidence to that point; it refuses when retained transcript identity no longer matches.
- CLI:
bmo checkpoint create [name],bmo checkpoint list, andbmo checkpoint restore <checkpoint-id>default to the most recently updated top-level session in the active data dir. Pass--session-idto target a different session. Restore still requires--yesto confirm. - API:
POST /v1/sessions/{id}/checkpoints(create),GET /v1/sessions/{id}/checkpoints(list; bound callers reuse the trusted session),POST /v1/sessions/{id}/checkpoints/{checkpointId}/restore(restore).
Session checkpoints do not affect git history or workspace files on disk; they only restore conversation context and session-scoped historical evidence for that session.
Posture and observability (Session capsules)
Section titled “Posture and observability (Session capsules)”The session-checkpoint surface - internally session capsules - exposes a
single posture read model that powers every operator surface. All six surfaces
report the same Posture snapshot and recent-events ring, so the TUI slash
and sidebar chip, CLI, HTTP, agent, and MCP views never disagree.
Where to read it (6 surfaces, one source of truth)
| Surface | Entry point |
|---|---|
| CLI | bmo config show-session-capsules (--json for machine-readable) |
| HTTP | GET /v1/sessions/{id}/checkpoints/posture |
| TUI slash | /session-capsules |
| TUI sidebar | Capsules |
| Agent tool | list_recent_session_capsule_events |
| MCP tool | bmo_get_session_capsules_posture |
The checkpoint GET reads (list, get, and posture) follow the same
bound-session contract as other parity HTTP reads: a trusted bound caller
inherits its current session, and an unbound caller uses the path session id.
Create and restore remain path-addressed mutations.
Posture states — closed-set, machine-readable. The state field is one of
uninitialized, ready, or degraded. degraded is sticky: it stays
asserted for the configured sticky window after a workspace-snapshot or
store-persist failure so a quiet partial write cannot read as healthy on the
next list/get.
Recent events ring (16 entries, FIFO). The ring stores only bounded
metadata: session-id, checkpoint-id, and checkpoint-name are stored as
FNV32 8-hex hashed prefixes — never as raw values. Raw todos JSON, raw
checkpoint names, and raw session ids never appear in posture output, agent
tool replies, MCP tool replies, or structured logs (field discipline).
Sticky-degraded latch — asserted when:
- a workspace-snapshot capture or restore fails during create/restore (the row is consistent but the snapshot is partial);
- the in-memory checkpoint store’s
Savereturns an error;
cleared automatically when a successful create + workspace-snapshot pair lands inside the sticky window. The latch is process-global and resets on restart (cross-process latch persistence is intentionally out of scope).
Tracing recipe. When you need to correlate a session-capsule episode end to end:
bmo logs --tail 500 \ | jq -c 'select(.msg|startswith("session_capsule."))'Filter to lifecycle failures only:
bmo logs --tail 500 \ | jq -c 'select(.msg=="session_capsule.action" and .action=="workspace_snapshot_failed")'Each session_capsule.fired and session_capsule.action log line carries an
invocation_id that pairs the open and close of one lifecycle episode, plus
the same hashed session_id_hash / checkpoint_id_hash you see in the
posture output and the recent-events ring. Cross-reference any of those three
surfaces by matching the hashes — never the raw ids, which never leave the
process.
Use cases
Section titled “Use cases”- Crash recovery (git) — if the agent goes off track after auto-checkpoint commits, rewind with
bmo checkpoint undo(destructivegit reset --hard) - Audit trail — every file change is a commit with a message describing what the agent did
- Safe experimentation (git) — let the agent try risky refactors; undo the last auto-checkpoint commit(s) if it goes wrong
- Conversation rewind (session) — restore a session checkpoint to rewind chat context without changing files on disk; restore refuses when retained transcript identity no longer matches