Skip to main content

auditloop

An agent runtime with a ledger. A coding-agent harness that blocks, records, and proves.

ci python runtime deps license

中文文档 · Design · Plan · Roadmap · Decisions

pip install auditloop
auditloop demo          # no API key, no network, 30 seconds
```n
▶ **[Live ledger viewer](https://rezerostarting.github.io/auditloop/)** — click through three real runs (ok / unverified / policy-blocked) in the browser.

---

## The problem

Letting a model edit real code fails in three ways, and none of them is "it can't write code":

| Failure | What it looks like | What auditloop does |
|---|---|---|
| **It acts out** | `rm -rf`, deleting the wrong file, editing outside the repo | A policy layer: hard-deny, read-only, ask-to-approve. Paths outside the workspace are refused. |
| **It lies about being done** | "Fixed it, tests pass" — they were never run | A verification gate: the run is only `ok` if a verification command exits `0`. Otherwise it is `unverified`. |
| **You can't tell what happened** | 20 minutes later the result is wrong and the context is gone | A ledger: every model call, tool call, and denial is appended to JSONL — renderable, replayable, costable. |

> The model saying "I'm done" is not a conclusion. A `rc=0` in the ledger is.

![The same scripted model twice: without the gate it reports ok; with the gate the ledger records rc=1 and the run is unverified](docs/assets/demo-contrast.gif)

*Same script, same repo, same "model". The only difference is whether a verification command
runs at the end. Try it yourself: `auditloop demo --contrast`.*

*The animation is rendered frame-by-frame from the real command output (`tools/make_demo_gif.py`), not a screen recording.*

This is not a smarter agent. It is a runtime that turns agent behavior into auditable facts.

---

## 30 seconds

```bash
# 1. Watch it work (offline, scripted model, identical output every time)
auditloop demo

# 2. Read the ledger
auditloop trace list
auditloop trace show demo --full

# 3. Replay the decisions
auditloop trace replay demo

# 4. Point it at a real model
export AUDITLOOP_BASE_URL=https://api.deepseek.com/v1
export AUDITLOOP_API_KEY=sk-xxxx
export AUDITLOOP_MODEL=deepseek-chat
auditloop run "make divide raise ValueError on zero and prove it with the tests" \
  --verify "python -m pytest -q"

On PowerShell: $env:AUDITLOOP_BASE_URL="...".

Exit codes (CI-ready)

Code Meaning
0 Done, and the verification command exited 0
3 Unverified — the model finished, the proof did not
4 Blocked by policy (the model kept hitting the wall)
5 Budget exhausted (tokens or cost)
6 Step limit reached
7 Upstream model failure (retries and fallbacks exhausted)

What gets recorded

One append-only JSONL file per run. cat works.

▶ run demo · policy ask · model mock · workspace /tmp/auditloop-demo-x
  → model call #1 (2 messages, ~448 tokens)
  ← stop · in 248/out 66 · tools todo_write
  · todo_write(items=[...])
    ↳ ok 59B · 0ms
  ...
  ⊘ denied shell: matched hard-deny rule \bdel\s+/([fqs]|\s)*
  ...
  ⇣ context compacted: dropped 8 messages, ~103 tokens saved
  ...
  ⌘ verify `python -m pytest -q` → rc=0
■ finished: ok · 10 steps · 4829in/350out tokens · $0.0000

Nine event types cover every moment worth asking about later: run.created · model.request · model.response · policy.decision · tool.call · tool.result · context.compacted · verification · run.finished


Six commands

Command Purpose
auditloop run "<task>" Run one task, render the loop live
auditloop demo Offline end-to-end: fix a bug, watch every step
auditloop demo --contrast Same script twice: with and without the verification gate
auditloop trace list / show / replay / verify / resume / otel Inspect, check consistency, resume after a kill, export to OpenTelemetry
auditloop eval run --gate 0.9 Run the task set, exit 1 below the gate
auditloop doctor Nine deterministic self-checks, exit code for CI
auditloop providers list 14 model-platform presets; switch with AUDITLOOP_PROVIDER
auditloop doctor --probe Real call: does this endpoint support tool calls?

Architecture

                 ┌──────────────────────────────────────────┐
   your task ───▶│              CLI (argparse)              │
                 └───────────────┬──────────────────────────┘
                                 ▼
                 ┌──────────────────────────────────────────┐
                 │            agent loop (core)             │
                 │  budget → compact → llm → policy → tools │
                 └───┬───────────────┬──────────────┬───────┘
                     │               │              │
        ┌────────────▼───┐   ┌───────▼──────┐  ┌────▼──────────┐
        │  context layer │   │ policy layer │  │  tool layer   │
        │  estimate/trim │   │ ask/never/   │  │ fs/shell/grep │
        │  /compact      │   │ auto + HITL  │  │ glob/todo/task│
        └────────────────┘   └──────────────┘  └────┬──────────┘
                                                    │ MCP (stdio, JSON-RPC)
                                             ┌──────▼──────────┐
                                             │ external tools  │
                                             └─────────────────┘

   every action ──▶ ledger (JSONL) ──▶ show / list / replay / otel
                                   └─▶ eval (deterministic checks → gate)

Zero dependencies

The core uses the standard library only: urllib for upstreams, subprocess for tools, json for the ledger, queue + threads for MCP. Not a single third-party package in pip install.

That is not purity, it is installability. An agent tool has to land on someone else's machine and in someone else's CI; every dependency is one more reason to close the tab. The price is writing retries, timeouts, SSE and JSON-RPC by hand — which is the point of the project.


Evaluation

auditloop eval run --mode mock --gate 0.9

Eight tasks. Three of them (t04, t05, t07) assert failure-path behaviour and are mock-only on purpose: a real model refuses to delete the repo instead of tripping the policy, and fixes the failing test instead of dying on it. Scoring a model there produces fake failures.

Mode Result (2026-10-31) What it proves
mock 8/8, $0.0000 plumbing, policy, ledger, failure paths
live · deepseek-chat 5/5, $0.0119, 32.6s model capability on the 5 model-agnostic tasks

A real end-to-end run on a throwaway repo: 15 steps · 18 tool calls · 1 policy denial · verification rc=0 · $0.0127. The denial is real — the model tried rm -f, was blocked, and reported it in its own answer instead of hiding it.


Documentation

Sibling project

  • keepwatch makes sure work is not lost.
  • auditloop makes sure the work is right.

License

MIT

Metadata

Release files for auditloop 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for auditloop 0.2.0
File Size Uploaded Provenance Actions
auditloop-0.2.0.tar.gz 155.9 kB Without provenance Details for auditloop-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for auditloop 0.2.0
File Interpreter ABI Platform Actions
auditloop-0.2.0-py3-none-any.whl Python 3 none any Details for auditloop-0.2.0-py3-none-any.whl

Total release size: 247.5 kB

Release files / auditloop-0.2.0.tar.gz

Download URL auditloop-0.2.0.tar.gz
Size 155.9 kB
Tags Source
SHA-256 checksum
How to use checksums
5f244d3534a4bb5da62ad242a201e98d7390094cbb860fc3daed0bcaa726485c
BLAKE2b-256 checksum
How to use checksums
1f8db0c1b7cdb966b71ccc58a58fe2a88332fcca077121b33dcf1d0ce48630c7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.7

Release files / auditloop-0.2.0-py3-none-any.whl

Download URL auditloop-0.2.0-py3-none-any.whl
Size 91.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e242cf0099f3a342c246d616c0609b09cd5990b138548f950327b295ef14dfae
BLAKE2b-256 checksum
How to use checksums
863d324b52b08709e60a450dda48638af8ef15644b169536391ed9635cff6e57
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.7

Security for auditloop 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page