Metadata-Version: 2.4
Name: expectation-ledger
Version: 0.1.0a1
Summary: Circuit breaker for AI agents. Predict what should happen, compare against reality, and block the next mutation when they diverge.
Project-URL: Homepage, https://github.com/tier4research/expectation-ledger
Project-URL: Documentation, https://github.com/tier4research/expectation-ledger#readme
Project-URL: Repository, https://github.com/tier4research/expectation-ledger
Project-URL: Issues, https://github.com/tier4research/expectation-ledger/issues
Project-URL: Changelog, https://github.com/tier4research/expectation-ledger/releases
Author: Tier 4 Research
License: Apache-2.0
License-File: LICENSE
Keywords: agent-reliability,agent-safety,agent-tools,ai-agents,audit-log,circuit-breaker,control-loop,fail-safe,guardrails,llm,local-first,observability,python,python-library
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Provides-Extra: test
Requires-Dist: pytest>=8.0; extra == 'test'
Description-Content-Type: text/markdown

# Expectation Ledger

[![Tests](https://github.com/tier4research/expectation-ledger/actions/workflows/tests.yml/badge.svg)](https://github.com/tier4research/expectation-ledger/actions/workflows/tests.yml)
[![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/)
[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)
[![Status: Alpha](https://img.shields.io/badge/status-alpha-orange.svg)](RELEASE_NOTES.md)

**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.

```bash
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

```python
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:

- **Hermes** — `expectation_ledger.adapters.hermes.build_ledger_context_block()` and `ledger_response_frame_overlay()` for response frame integration
- **OpenClaw / generic** — `expectation_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](https://github.com/tier4research/memorant#suite-workflow), where it works alongside Memorant (trusted long-term claims) and Context Tuner (compression audit) for end-to-end agent memory governance. See [Memorant](https://github.com/tier4research/memorant) and [Hermes Context Tuner](https://github.com/tier4research/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`.
