Skip to main content

Circuit breaker for AI agents. Predict what should happen, compare against reality, and block the next mutation when they diverge.

Project description

Expectation Ledger

Tests Python 3.10+ License: Apache 2.0 Status: Alpha

A circuit breaker for AI agents: predict what should happen, compare against what did, and block the next mutation when they diverge.

Expectation Ledger is a zero-dependency Python library that runs inside an AI agent's control loop. Before each action the agent records what it expects; after the action, the result is classified against that prediction; when a high-stakes action contradicts its prediction, a circuit breaker opens and blocks further mutations until a verification step passes.

Most agent safeguards are perimeter controls — ask a human first, or run it in a sandbox. Both limit what an agent can reach. Neither stops an agent from compounding a mistake inside the boundary it was already allowed to operate in, because the agent doesn't know its last action failed. Expectation Ledger closes that gap, in-process, with no model retraining, no prompt engineering, and no external service.

This is not "AI safety" in the alignment sense. It's engineering safety, in the reliability sense — the same principle as a circuit breaker in your house: when something goes wrong, stop the current before it does more damage.

pip install expectation-ledger

How it works

  ┌──────────────┐     ┌───────────────┐     ┌──────────────┐
  │ 1. PREDICT   │ ──▶ │ 2. ACT        │ ──▶ │ 3. COMPARE   │
  │ Derive what   │     │ Run handler,  │     │ Classified    │
  │ should happen │     │ get result    │     │ vs expected   │
  └──────────────┘     └───────────────┘     └──────┬───────┘
                                                    │
                                     ┌──────────────▼──────────────┐
                                     │ 4. ENFORCE                  │
                                     │ Low severity → log/continue │
                                     │ High severity → open breaker│
                                     │ Breaker open → block mutate │
                                     │ Verify pass  → close breaker│
                                     └─────────────────────────────┘

Four concepts, zero dependencies:

Concept What it is
Prediction What the agent expects to happen — an invariant + success evidence + known failure modes
PredictionOutcome What actually happened — classified as matched, contradicted, or unknown
PolicyRule What to do for each severity × stakes combination (continue, log, board, force-verify)
BreakerState An open/closed circuit breaker — blocks new mutations until verified safe

Quick start

from expectation_ledger import (
    Prediction,
    BreakerState,
    compare_prediction,
    update_breaker,
    breaker_blocks,
)

# 1. Before acting: state what you expect
prediction = Prediction(
    prediction_id="apply-config-1",
    transition="apply_config:nginx",
    expected="config file is written and nginx reload succeeds",
    invariant="existing unrelated config files are unchanged",
    success_evidence="handler returns ok=True with verification status",
    failure_modes=["permission denied", "syntax error", "reload failed"],
)

# 2. Act — your agent does something here...
result = {"ok": False, "status": "syntax_error", "error": "unexpected '}' on line 12"}

# 3. Compare
stakes = "high"
outcome = compare_prediction(prediction, result, stakes)
# outcome.result → "contradicted", outcome.severity → "high"

# 4. Enforce
breaker = BreakerState()
breaker = update_breaker(breaker, "apply_config", "nginx", [outcome], None)
# breaker.state → "open"

# 5. Breaker blocks the next mutation
if breaker_blocks(breaker, "apply_config", {"apply_config", "deploy"}):
    print("blocked — must verify before mutating again")

# 6. After verification passes, breaker closes
verify_result = {"ok": True, "status": "syntax_check_passed"}
verify_outcome = compare_prediction(
    Prediction("verify-1", "verify:dashboard", "syntax check passes", "", "", []),
    verify_result,
    "high",
)
breaker = update_breaker(breaker, "verify", "nginx", [verify_outcome], None)
# breaker.state → "closed" — agent can mutate again

How it compares

Capability Expectation Ledger Prompt-based guardrails External approval Sandbox
Runs in-process (no network, no service)
Structured pass/fail comparison
Severity routing (low/medium/high)
Self-blocking (agent stops itself on failure)
Verified recovery path
Audit trail (every prediction/outcome recorded)
Framework-agnostic

Expectation Ledger vs. prompt-based guardrails

Prompt-based guardrails ("think step by step," "verify before answering") are cheap and easy but have no enforcement mechanism — the model can ignore them under pressure or in long contexts. Expectation Ledger is structural: it compares structured output against structured predictions, and the breaker is code, not prose.

Expectation Ledger vs. external approval

Asking a human to approve every action works for low-frequency changes but doesn't scale to an agent that runs dozens of operations per minute. Expectation Ledger is designed for agents that already have operator approval for the category of work they're doing — it catches the unexpected failures inside approved operations, not the decision to operate at all.

Expectation Ledger vs. sandboxing

Sandboxes prevent an agent from reaching beyond a boundary. Expectation Ledger prevents an agent from compounding a mistake inside the boundary. They're complementary — a sandbox limits blast radius; Expectation Ledger stops the agent from chaining errors within that radius.

Using it with your agent

Expectation Ledger is not a service. It's a library you import and call at two points in your agent's control loop:

  1. Before acting: call your prediction source to generate Prediction objects
  2. After acting: call compare_prediction(), then evaluate_policy(), then update_breaker()

Two thin adapters ship in the box:

  • Hermesexpectation_ledger.adapters.hermes.build_ledger_context_block() and ledger_response_frame_overlay() for response frame integration
  • OpenClaw / genericexpectation_ledger.adapters.openclaw.build_context_packet() for pre-model context assembly

For a worked example of wiring Expectation Ledger into a Hermes engineering control loop, see examples/hermes_integration.py.

Expectation Ledger is also available as part of the Memorant suite, where it works alongside Memorant (trusted long-term claims) and Context Tuner (compression audit) for end-to-end agent memory governance. See Memorant and Hermes Context Tuner.

FAQ

What is Expectation Ledger?

Expectation Ledger is an open-source Python library that adds a circuit breaker to an AI agent's control loop. The agent predicts what an action should do, compares the actual result against that prediction, and blocks further mutations when a high-stakes action contradicts what was expected.

How is this different from prompt-based guardrails?

Prompt instructions like "verify before answering" have no enforcement mechanism — a model can ignore them under pressure or in a long context. Expectation Ledger compares structured output against structured predictions, and the breaker is code rather than prose.

Does it replace human approval or sandboxing?

No — it's complementary. A sandbox limits how far an agent can reach; human approval gates whether it acts at all. Expectation Ledger catches unexpected failures inside operations that were already approved, and stops the agent from chaining errors after one.

What is a circuit breaker in this context?

The same pattern used in distributed systems (Hystrix, resilience4j): when an operation fails in a way that suggests further attempts will also fail, the breaker opens and blocks subsequent calls until a health check passes. Here the failure signal is a prediction that was contradicted, and the health check is a verification step.

Does it require an LLM call, a network connection, or a service?

No. Expectation Ledger is a pure-Python library with zero dependencies. It makes no network calls and invokes no model.

Which agent frameworks does it work with?

It's framework-agnostic — two functions called at two points in any control loop. Thin adapters for Hermes and OpenClaw ship in the box; anything else uses the core API directly.

Is Expectation Ledger production-ready?

No. It's alpha (v0.1.0-alpha.x). Core types, severity routing, the policy table, breaker logic, and framework adapters are implemented and tested. Frequency-based prediction sources, similar-prediction retrieval, and breaker persistence are still to come.

Project status

Alpha (v0.1.0-alpha.x). Core types, severity routing, policy table, breaker logic, and framework adapters are implemented and tested. Future work includes frequency-based prediction sources, kNN retrieval for similar-prediction lookup, and breaker persistence backends.

License

Apache License 2.0. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

expectation_ledger-0.1.0a1.tar.gz (17.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

expectation_ledger-0.1.0a1-py3-none-any.whl (15.9 kB view details)

Uploaded Python 3

File details

Details for the file expectation_ledger-0.1.0a1.tar.gz.

File metadata

  • Download URL: expectation_ledger-0.1.0a1.tar.gz
  • Upload date:
  • Size: 17.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for expectation_ledger-0.1.0a1.tar.gz
Algorithm Hash digest
SHA256 2876b07c809aadf667785b3589f3d9eced9228e0ac597e4ba6491a7665f405b0
MD5 5bcf3945ee46eeb15ef228b1cd7ee4b1
BLAKE2b-256 5b55ce679292781b05421444a754fb833b46dbe04db7b04506a871e403162716

See more details on using hashes here.

File details

Details for the file expectation_ledger-0.1.0a1-py3-none-any.whl.

File metadata

  • Download URL: expectation_ledger-0.1.0a1-py3-none-any.whl
  • Upload date:
  • Size: 15.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for expectation_ledger-0.1.0a1-py3-none-any.whl
Algorithm Hash digest
SHA256 04fd44492e2aba73ee24a0c59908bc1254a89f5c9d890a9ee06f7df148f9965d
MD5 6304a5d287758d366ed594624dfc0070
BLAKE2b-256 8c6c94dee50cb718b80d33599730effc33e6a51ab9e21b362a98e7a22c87e3a0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page