Run ledger
The run ledger is BMO’s persistence and observability surface for runs: the durable lifecycle records of agent spawns, mesh delegations, A2A invocations, OpenAI-compat chat completions, and any other long-running operation that should survive restart and be auditable later.
It is two ledgers behind one read model:
agent_runs(durable) — SQLite-backedagent_runsandagent_run_eventstables, owned by the daemon and present whenever the agent runtime is wired.- OpenAI-compat (in-memory) — gated by
options.openai_compat.enabled; bounded run history exposed by the in-process HTTP server. A sticky-degraded tracker promotes any persistence failure to the operator surfaces and only clears on the next successful op.
When to enable
Section titled “When to enable”The durable agent ledger is always on when the daemon is running. It is
required for bmo agents history, the agent debugger, and resumable spawn
inspection. There is no config knob.
The OpenAI-compat ledger is off by default. Enable in bmo.toml:
[options.openai_compat]enabled = truetool_policy = "chat_only" # or "auto_approve"ambiguity_policy = "ask"model_override_policy = "reject"Pair with bmo serve to expose the OpenAI-compat HTTP surface.
Operator surfaces
Section titled “Operator surfaces”| Surface | Purpose |
|---|---|
bmo config show-run-ledger | Posture summary: agent_runs state, OpenAI-compat state plus sticky-degraded flag, ring capacity and saturation, action/outcome histogram, recent ring entries |
/run-ledger (TUI slash; aliases /run_ledger, /runledger, /ledger) | Same posture in the chat transcript, sharing the CLI formatter |
Runs sidebar chip | Live status badge: ready, enabled, degraded, server idle, store off |
run_ledger_status (agent tool) | Read-only posture as JSON for agents |
runledger.BuildSnapshot | Library accessor used by every surface above |
The same runledger.PostureSnapshot flows through CLI, slash, sidebar, and
agent-tool layers. This is the formatter-divergence mitigation called out in
the maturity-iteration plan: one read model, one renderer, every surface
byte-matches.
Structured logs
Section titled “Structured logs”Each operation emits a paired record into the bounded process-global ring (capacity 32):
run_ledger.fired— one per op entry, before the action runs.run_ledger.action— boundedledger,action, andoutcomeenum after the op completes.
Filter examples:
run_ledger.firedrun_ledger.actionrun_ledger.action ledger=openai_compat outcome=failedrun_ledger.action error_category=persist_failedField discipline (KTD-5): records carry only FNV32-hashed run/session
prefixes, bounded scalar metadata (action, outcome, error_category,
latency_ms, level), and timestamps. Raw run IDs, request IDs, session
IDs, message bodies, and stack traces never reach the log layer or the
posture surfaces.
Sticky-degraded contract
Section titled “Sticky-degraded contract”When the OpenAI-compat run store fails to persist, the in-process tracker:
- Sets a sticky
degraded=trueflag, visible immediately in CLI, slash, sidebar, and therun_ledger_statustool. - Publishes a
runevents.SubsystemDegradedevent. - Clears the flag and publishes
runevents.SubsystemRecoveredon the first subsequent successful op.
This is intentional: a one-off persist failure stays visible long enough for an operator to notice, but recovers automatically on its own. The flag is process-scoped; restarting the daemon clears it.
Tracing recipe
Section titled “Tracing recipe”Walk a single OpenAI-compat run end-to-end without leaving the operator seat:
/run-ledger— confirm the ledger is enabled and not sticky-degraded.bmo openai-compat runs list --limit 10— find the recent request ID.bmo openai-compat runs events <request_id>— print the per-event timeline, fromchat_startedthrough tool-call events tochat_done.- If
run_ledger.action ... outcome=failed error_category=persist_failedappears in step 1’s recent ring, the ledger has been degraded; check theservelogs and theagent_run_eventstable. The sticky flag will clear on the next success.
Agent tools
Section titled “Agent tools”run_ledger_status— read-only posture as JSON, covering durable and in-memory ledgers, histogram, and KTD-5-redacted recent ring. It is safe on every OS, requires no permission prompt, and matches the CLI/slash surfaces.
Related
Section titled “Related”- Agent debugger — durable run inspection UI.
- Terminal browser — paired posture/ring pattern donor.
- Tools reference