Skip to content

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 = true
require_clean_tree = false
max_commits_per_session = 0
llm_commit_message = false

Requirement: Requires a git repository with at least one existing commit.

OptionDefaultDescription
enabledfalseEnable auto-checkpoint
require_clean_treefalseOnly checkpoint when no untracked/unstaged files unrelated to the edit are present
max_commits_per_session0Cap on remembered checkpoint commits per session (0 = unbounded)
llm_commit_messagefalseWhen true, use the last assistant message as the commit message (sanitized); otherwise use synthetic bmo: apply <tool> ...

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, or the agent tool checkpoint_undo with steps and confirm: true. For example, one step undoes the last commit. Both surfaces run git reset --hard HEAD~N in the repo root. There is still no TUI action for git undo.

BMO also supports session checkpoints: named snapshots of a session’s state (message count and todos) that you can restore later. This is independent of git:

  • 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. Restoring truncates messages and restores todos to that point.
  • CLI: bmo checkpoint create [name], bmo checkpoint list, and bmo checkpoint restore <checkpoint-id> default to the most recently updated top-level session in the active data dir. Pass --session-id to target a different session. Restore still requires --yes to confirm.
  • API: POST /v1/sessions/{id}/checkpoints (create), GET /v1/sessions/{id}/checkpoints (list), POST /v1/sessions/{id}/checkpoints/{checkpointId}/restore (restore).

Session checkpoints do not affect git history; they only affect the conversation and task list 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)

SurfaceEntry point
CLIbmo config show-session-capsules (--json for machine-readable)
HTTPGET /v1/sessions/{id}/checkpoints/posture
TUI slash/session-capsules
TUI sidebarCapsules
Agent toollist_recent_session_capsule_events
MCP toolbmo_get_session_capsules_posture

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 (KTD-5 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 Save returns 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:

Terminal window
bmo logs --tail 500 \
| jq -c 'select(.msg|startswith("session_capsule."))'

Filter to lifecycle failures only:

Terminal window
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.

  • Crash recovery — if the agent goes off track, restore to the last known-good state
  • Audit trail — every file change is a commit with a message describing what the agent did
  • Safe experimentation — let the agent try risky refactors; roll back instantly if it goes wrong