Star on GitHub ★
Billions of agents in production · zero behavioral guarantees

Software has contracts.
Your agents have
a paragraph of hope.

Types, assertions, APIs — every reliable system you have ever shipped was reliable because something checked it. AI agents handle money, health records, and legal decisions on the strength of a prompt. Agent Behavioral Contracts give them runtime enforcement, < 10 ms inline invariant checks, and a mathematical theorem that bounds their drift.

0.9541
RELIABILITY Θ
< 0.27
BOUNDED DRIFT D★
< 10 ms
PER ACTION CHECK
18,000
MISSIONS PREREG.
Write your first contract ABC I — the framework & theorem (71 pp.) ↗
arXiv:2602.22302 · 71 pages · 14 tables
arXiv:2608.12895 · 49 pages · 18 theorems
The same agent, run 34 times · drag to set recovery rate γ
α 0.031 γ 0.118 band D★ 0.263
LEFT — no contract. Nothing corrects the agent, so deviations accumulate. Every run ends somewhere different, and no run comes back.
RIGHT — same agent, under contract. Recovery pulls it back every time it slips. The runs stay inside a band you can compute in advance ($\pm D^\star$).
Mathematical Foundation · Drift Bounds Theorem

Geometric Convergence to Invariant Boundary

For any autonomous AI agent with stochastic perturbation rate α and contract recovery rate γ > α, expected trajectory drift concentrates within the bounded envelope D = α / γ.

Ornstein-Uhlenbeck Stochastic Drift Convergence Diagram
Act I · Specify ABC I §3 · arXiv:2602.22302

A contract is four clauses:
C = (P, I, G, R)

Each clause is checked at a different moment in the agent's life. Everything else in both papers — every bound, every certificate — is a direct mathematical consequence of this tuple.

P BEFORE
Preconditions
Unauthenticated user, unapproved compliance state, missing consent — the agent never gets to start.
I DURING
Invariants
Held on every single action. SSN patterns, card numbers, spend ceilings — evaluated inline in under 10 ms.
G AFTER
Governance
Policy that outranks the prompt. Disclaimer present, PII redacted, audit record written — before anything ships.
R ON VIOLATION
Recovery
The clause that earns the theorem. Without a recovery rate γ, there is nothing to compare drift α against — and no bound exists.
Hard clauses — never negotiable
A breach is not a warning, it is a hard block. The action is intercepted before it reaches the user. Measured compliance across 7 LLMs: 88–100%.
Soft clauses — graded, logged, bounded
Tone, scope creep, unhelpfulness. Contracted agents surface 5.2–6.8 violations per session that uncontracted baselines miss entirely (p < 0.0001, d = 6.7–33.8).

One file. The agent cannot ignore it.

The contract lives beside the agent, not inside its prompt. Enforcement is code, so it does not depend on the model choosing to cooperate.

financial-advisor.yaml
# Agent Behavioral Contract
agent: financial-advisor
version: "1.0"

before:            # P (Preconditions)
  - user must be authenticated
  - compliance status must be approved

during:            # I (Invariants - inline < 10ms)
  - responses must not contain SSN patterns
  - responses must not contain credit card numbers
  - session cost must stay under $5.00
    severity: critical
    action: block

after:             # G (Governance - post-action)
  - response must include regulatory disclaimer
  - all PII references must be redacted

on_failure:        # R (Recovery - γ parameter)
  retries: 3
  fallback: escalate_to_human
  message: "Connecting you with a human advisor."
PII blocked at source
The SSN never leaves the process. Invariant fires mid-generation, response is withheld and redacted.
Spend capped strictly
A hard ceiling terminates runaway token spend at $5.00. No prompt phrasing raises it.
Disclaimer enforced
Governance checks the finished answer. Missing disclaimer means the answer does not ship.
Recovery, then human handoff
Three attempts to satisfy the clause, then escalation. This is the γ in the theorem — it is a number you configure.
Theorem 1 · Drift Bounds ABC I §4

Correct it faster than it wanders,
and it can never wander far.

Drift is the distance between what the agent is doing and what the contract says. Each step, the world pushes it out by α and recovery pulls it back by a fraction γ of wherever it currently is. Those two forces settle at exactly one place.

Figure 2 · Drift dynamics — drag horizontally to change γ
γ 0.118 D★ = α/γ 0.263 STABLE
In plain words
Think of a boat drifting on a current with someone rowing back. If the rowing is stronger than the current, the boat settles at a fixed distance from the dock and stays there. That distance is the current divided by the rowing.
Formally
𝔼[D(t+1)] ≤ (1 − γ)·𝔼[D(t)] + α  ⟹  𝔼[D(t)] → D = α/γ for γ > α
In your code
m = Monitor(contract)
m.metrics.drift      # 0.263
m.metrics.recovery   # 0.118
# measured: D★ < 0.27 across extended sessions
Video Masterclass

Why 90% of Multi-Agent Systems Fail

Watch author Varun Pratap Bhardwaj break down the mathematical proofs behind Agent Behavioral Contracts, the 18,000-mission co-failure trap, and the convex moment polytope certifier.

Definition · (p, δ, k)-satisfaction

"It complied" is the wrong question.

A model that samples cannot promise you certainty, so demanding it is theatre. What you can demand is this: on at least p of sessions, every clause is satisfied within k recovery attempts — and we are confident of that to within δ.

That is the whole trick. Non-determinism stops being an excuse and becomes a parameter you set, audit and report.

session( ⋀c∈C sat(c) within k ) ≥ p,  conf. 1 − δ
Figure 3 · 240 sessions — drag horizontally to set k
k 3 0.950
Each square is one session. Green: clause held clean or recovery fixed it within k attempts. Red: needed more than k attempts — a genuine violation counted against the guarantee.
Evidence · ABC I AgentContract-Bench v1

Measured, not claimed.

200
Scenarios
1,980
Sessions
7 / 6
Models / Vendors
0.9541
Reliability Θ
< 10 ms
Per Action
0.98
Financial
0.98
Healthcare
0.98
Support
0.98
Code gen
0.97
Research
0.97
Governance
0.89
Composition

Six domains behave. One does not. Composition — agents handing work to agents — is the weak column, and that gap is exactly where the second paper starts.

Act II · Measure ABC II §3 · arXiv:2608.12895

Two agents are not two chances.

Chain two agents and everyone multiplies their reliabilities — a step licensed by assuming they fail independently. We ran 18,000 preregistered missions, scored by deterministic code with no LLM judge, to check. They do not.

Figure 4 · Co-failure lattice — drag left/right to change φ
φ 0.916 log OR 6.66 co-fail 90.0%
In plain words
Two copies of the same model trip over the same missions. Putting one behind the other looks like a safety net but is closer to one net, doubled — and the arithmetic everyone uses quietly credits you for the second one.
Formally
ℙ(FAFB) ≥ ℙ(FA)·ℙ(FB)   Positive dependence inflates joint failure above the independence product.
In your code
pipeline:
  - agent: model-x   # same model
  - agent: model-x   # redundancy over-credited
# fix: substitute a distinct architecture
WHAT HELPS — 6 OF 6 CONTRASTS
Substituting a different model architecture reduces the association in every single contrast we ran. Diversity is not a slogan here; it is the measured lever.
WHAT DIDN'T — REPORTED AS A NULL RESULT
Substituting a different vendor (e.g. OpenAI Direct vs Azure) for the same underlying foundation model yields zero reduction in co-failure.

The tempting fix makes it worse.

If agents are correlated, why not model the correlation and bootstrap a confidence interval? Because that interval tightens around whatever your model believes — while the truth stays where it always was. More data does not fix it. More data hides it.

Figure 5 · Drag horizontally for more sample data (n)
n 2,000 FITTED: MISSES TRUTH
identification gap = O(1)
bootstrap haircut = O(n−1/2)
One term never shrinks. The other shrinks like the square root of your sample. Eventually the interval is narrower than the error it cannot see.
No visible symptom
Nothing in the output warns you. The certificate looks better every quarter while being wrong the entire time. This is the failure mode ABC II was written to remove.
Act III · Certify ABC II §5 · 18 theorems

Assume nothing. Bound everything.

Take every joint failure distribution consistent with what you actually measured — not one fitted guess, all of them — and ask which is worst. That worst case is the certificate. It cannot be optimistic, because nothing was assumed away.

Figure 6 · LP over the joint — drag up/down for more moments
moments 14 floor 0.4116 interval −85.7%
Convex Optimization · ABC II §5

Non-Parametric LP Certificate over Moments

Rather than fitting a parametric distribution that underestimates co-failure tails, AgentAssert solves an exact linear program over the convex polytope of moment functionals M₁₀ ... M₁₄, guaranteeing anytime-valid Type-I error α ≤ 0.0471.

Convex Optimization Moment Polytope Diagram
In plain words
The shaded shape holds every way your two agents could be failing together that your data cannot rule out. Each new measurement slices a piece off. Whatever corner is left lowest is what we promise — so measuring more can only ever help you.
Formally
minμ∈Mc, μ⟩  s.t.  ∈ BoxBCP(, α), μ ≥ 0   Sound and sharp for the information supplied.
In your code
cert = certify(missions, moments=14, alpha=0.05)
cert.floor    # 0.4116
cert.sound    # True
# anytime-valid: type-I error 0.0471
0.2455 → 0.4116
Certified floor, ten moment functionals enriched to fourteen. The guarantee rises because the evidence did.
85.7%
Narrowing of the identified interval over the same enrichment. Sharpness is earned, never assumed.
0.0471
Type-I error of the anytime-valid companion under optional stopping. You may look at the data whenever you like.
Interactive Optimization Engine · Convex Polytope Slicer (3D)
Interactive 3D Moment Polytope Slicer (ABC II §5)
CERTIFIED FLOOR: 0.4116 INTERVAL SHRUNK: 85.7%
Enrich Moment Functionals:
Optimization Problem: min ⟨c, μ⟩ s.t. Aμ ∈ Box(m̂, α), μ ≥ 0
Anytime Type-I Error: α = 0.0471

Your first contract takes four lines.

Wrap the agent you already have. Nothing about the model changes — what changes is that violations become visible, blockable and countable.

from agentassert_abc import Contract, Monitor

contract = Contract.from_yaml("advisor.yaml")
agent = Monitor(contract).wrap(my_agent)

agent.run("summarise my portfolio")
# → invariant I2 blocked 1 action, recovered in 1