An AI coding agent can tell you it finished when it did not. Bounded Loops runs your agent until a check it can neither edit nor grade says the work actually passes, and stops at a limit you declared before the run started. Three words carry the whole idea. The gate is the check that decides pass or fail — a command, a test suite, a schema, never the agent; the agent's own "I'm done" is written to the record and ignored. The bound is a limit declared up front: attempts, tokens, wall-clock, laps without progress. The ledger is the append-only, hash-chained file of what happened, and `bl verify` re-checks it, so "it passed" is something you confirm rather than trust. The accompanying paper proves three guarantees — that a run finishes, does not drift, and does not overspend — and then measures the gates themselves against a held-out mutant corpus, because a proof about gates is worth what the gates are worth.
69 shipped loops and 7 reference graphs. Browse independent acceptance gates for engineering, finance, content and operations. Default examples and live execution have different requirements.
Browse loops and graphs →Require a separate acceptance check before completion, with declared limits and a persisted receipt you can verify.
python -m pip install bounded-loops
bl loops install bug-fix-red-green --dest ./loops
bl run loops/bug-fix-red-green --yes --run-id first-proofThe 1 October 2026 keyless demo used a stub worker and a real pytest gate. An ungated false GREEN claim failed its tests; the gated run passed six tests, and the persisted receipt passed chain, separately recorded head, and completeness checks. Not a hosted-agent accuracy or savings benchmark.
Iteration and stall limits, scratch sandbox with symlinks refused, input quarantine excluding key material, output schema gate, per-lap tracing, regression evaluation, token budget, human approval, wall-clock limit. BOUNDED_LOOPS_KILL is checked before every lap; gate commands are tokenized and run without a shell.
The domain rule lives in one file and holds regardless of runner, gate, or storage backend. A gate the worker cannot write to is the only thing that can end a loop — pytest, a JSON Schema, a command, a security scanner. The agent's claim is recorded and ignored.
Finance, legal, retail, operations, enterprise and ERP, security, testing, content, research, business, healthcare, and software. They ship inside the wheel, so `bl loops install` copies one into your project with nothing downloaded — it works offline.
Two defect classes let a sound-looking check pass anything: a check satisfied by the absence of the thing it checks, and a check whose subject supplied the value it is applied to. Turned on its own 69-loop catalogue, the instrument found 47 such gates in code that had shipped and passed review.
The receipt log is the sole durable state; the CLI, monitor, MCP server and Arena report are projections of it and hold none of their own. A third party holding only the run directory can check that no node reached DONE without a gate verdict — and the released verifier does exactly that.
Works with Claude Code, OpenAI Codex, Antigravity, or no agent at all. Ports-and-adapters throughout, with one composition module permitted to wire an adapter to a port — enforced by an import-graph walk that counts function-local and dynamic imports.
Bounded Loops: Pre-Run Spend Bounds, Proved Termination, and Verified Completion for Agent Harnesses
Varun Pratap Bhardwaj, 2026
Read on arXiv →