For AI agents and the humans reviewing them

At which rung did your agent verify?

An AI agent reports "verified" the same way whether it read the diff or ran the changed code and watched it work. rung grades that claim on two axes, how real the verification was and who checked it, then a deterministic gate turns (bundle, policy) into a ship / no-ship verdict. It works for any producer, agent or human.

$ pip install rung-ai
How it works

Evidence in, verdict out

Three steps, one JSON document between them. The bundle is portable: any tool can produce it, any tool can read it.

1

Produce an evidence bundle

Run the change at its real surface, or let rung run witness it, and record what happened as one evidence-bundle/v1: the rung reached, who checked, content-addressed artifacts.

2

Gate it against a policy

The policy sets the floor: which rung and which context each risk tier requires. rung gate reduces (bundle, policy) to a verdict, deterministically.

3

Ship or block

Exit 0 ships, 30 blocks with reasons, 2 means the input could not be evaluated. Wire it into CI and fail the build on anything but 0.

The two-axis model

How real, and who checked

"Verified" gets used for two different things. "The tests pass" reads the same as "I ran the real thing and watched it work." "I checked it" reads the same as "someone independent checked it." rung pulls them apart into two axes you grade separately.

RUNG: how real (0 to 4)
0Read-only reasoning about the code
1Import the unit and call it
2Test suite green
3Drove the real surface and observed it
4Drove it before and after, and compared the two runs (S0 vs S1)
CONTEXT: who evaluated
authorThe producer of the change
fresh-blindAn independent reviewer with no producer state
cross-labAn independent reviewer at a different lab
rung ↓ · context → author fresh-blind cross-lab
2 · tests green generic CI
3 · drove the surface runtime-verification tools
4 · drove + S0/S1 diff real and independent: what rung targets

The axes are independent: "drove it blind, cross-lab" is not a higher rung, it is a different cell. The right-hand column, real verification done by someone other than the producer, is where almost nothing lives today. That is the cell rung is built to name and reward.

Why not just CI?

Green tests are one rung, in one context

A passing suite proves the suite ran. It does not prove the change works at its real surface, and it does not mean anyone but the author looked. On the two axes that is rung 2, author context: the right floor for low-risk work, not evidence for a high-risk change.

rung does not replace your tests and never runs them. It records where a claim sits and refuses to let it read higher than the evidence supports. A policy can then require, say, cross-lab context at rung 4 before a critical change ships.

The gate

A deterministic gate that can't be talked into a pass

The gate is a pure function of (bundle, policy): it reads those two files, re-hashes each artifact they reference to confirm it matches, and returns a verdict. A declared pass grants nothing, and every check it adds is a reason to block, never a reason to pass. Same bundle and policy, same verdict, every run.

# the smallest bundle that runs: one low-tier claim, no artifacts
{
  "schema": "evidence-bundle/v1",
  "change": { "producer": { "lab": "your-lab" } },
  "claims": [
    { "id": "c1", "risk_tier": "low", "rung": 2, "context": "author", "verdict": "pass" }
  ]
}
$ rung gate bundle.json      # prints a JSON verdict, exits on the contract below
0 pass 30 block 2 unreadable or malformed input

Portable evidence bundle

One evidence-bundle/v1 JSON document per change: the rung reached, the context, content-addressed artifacts, the S0/S1 differential, a verdict, and any cross-lab attestation.

Stdlib-only, no build step

The runtime is dependency-free and targets Python 3.9+. The gate reads and hashes as one auditable module. Vendor the single file, or pip install rung-ai.

Fails closed

Unknown or missing policy keys, an unknown schema major, or malformed input each block or exit 2. Never a silent pass, never an uncaught traceback. Only exit 0 is pass.

Earn the rung, don't type it

Witness a run with rung run

An agent's cheapest path to a rung claim should be to run the surface, not to hand-type a hash for bytes that were never produced. rung run executes the probe, captures the exact bytes off the child's own stdout/stderr, writes the bundle, then gates it and exits with the gate's verdict.

# drive a CLI surface, declare rung 3, let the tool witness and gate it
$ rung run --rung 3 --surface cli -- mytool --check

# rung 4: a before/after differential, split on ':::'
$ rung run --rung 4 --diff --surface cli -- mytool --old ::: mytool --new

--rung and --surface are required: the tool witnesses bytes, never a rung, so it never mints one for you. A witnessed hang blocks; a non-deterministic differential blocks; an oversized capture is truncated and flagged. It only ever records honest gaps, never a silent pass.

It is all one rung command with a small verb set. run witnesses and gates; gate (alias check) grades an already-authored bundle; both print the JSON verdict and exit 0, 30, or 2. doctor is a read-only preflight that re-hashes the pinned gate, and version reports the schema major it speaks and that same hash.

Install

Get rung

The distribution is rung-ai on PyPI; the installed command and import package are both rung. The runtime is stdlib-only and dependency-free.

Python (pip / pipx / uv)

pip install rung-ai
pipx install rung-ai
uv tool install rung-ai

Homebrew

brew tap rung-dev/tap
brew install rung

Container

docker run --rm -v "$PWD:/w" -w /w \
  ghcr.io/rung-dev/rung:0.2.0 gate bundle.json

GitHub Actions

- uses: rung-dev/rung@v0.2.0
    with:
      bundle: bundle.json
FAQ

Questions

Does rung run my tests?

No. rung grades and gates the claim about a verification; it never runs your suite. rung run can witness a surface you point it at and record the exact bytes, but it does not author or execute your tests.

Does it sign anything or hold keys?

No. Signing, identity, and trust roots belong to your ecosystem. A bundle has a slot to carry a signature and a verified identity, and a policy can require that an external verifier already checked it; the gate only reads that result.

Python only?

The runtime is stdlib-only Python 3.9+, but it gates any producer's evidence-bundle/v1, written in any language. It also ships as a container image and a GitHub Action.

Is it only for AI agents?

No. Agents are the sharpest case, since they over-claim verification, but any producer, human or machine, and any judge composes the same way.