Skip to content

Repository files navigation

Python 3.8+ zero dependencies MIT license Agent Skill ci

receipts

Trust, but verify. A zero-dependency evidence ledger that stops AI coding agents from claiming "done" until they can prove it.

receipts terminal demo

Quickstart · How it works · Agent Skill · CI gate


"All tests pass." (They didn't run the tests.)

Coding agents are confident. They will look you in the eye and say:

"All tests pass. The build is green. The bug is fixed. You're good to merge."

…and they never ran the tests. Or they ran them before the last edit. Or the command failed and they summarized the failure as a success. You find out at 2am when production is on fire.

receipts fixes this with one rule:

No claim without evidence. Every "tests pass" must be backed by a receipt — a captured, tamper-evident record of the command that was actually run, its real exit code, its real output, and a fingerprint of the source tree at that exact moment.

If the code changes after the evidence was captured, the receipt goes stale and the gate fails until the agent re-runs the proof. An agent cannot talk its way past receipts check.

re·ceipts (noun, plural): the evidence you produce when someone says "prove it." Ask any agent that claims it's done.

  • Zero dependencies. One Python file, stdlib only, Python 3.8+. Runs on Linux, macOS, Windows, Termux.
  • Tamper-evident. Output SHA-256 + source-tree fingerprint. Edit the code, old evidence auto-invalidates.
  • Agent-native. Ships as an Agent Skill for Claude Code, Codex, Cursor, and any Skills host.
  • CI-ready. receipts check exits non-zero on any unverified claim — a real merge gate.

Quickstart

# 1. Point your agent at the skill, or symlink the CLI onto PATH:
ln -s /path/to/receipts/bin/receipts ~/.local/bin/receipts

# 2. In your project, initialize the evidence ledger:
receipts init

# 3. Back every claim with the command that proves it:
receipts add "the test suite passes" -- python3 -m pytest -q
receipts add "the build succeeds"    -- npm run build

# 4. Pass the gate before saying "done":
receipts check

# 5. Show your work:
receipts report

A real session (captured from this repo's own demo, not a mockup):

$ receipts init
receipts: initialized evidence ledger at /home/demo/.receipts

$ receipts add "the test suite passes" -- python3 -m unittest discover -s .
receipts: [rcpt-0001] PASS  exit=0  0.19s  python3 -m unittest discover -s .

$ receipts add "calc.py compiles clean" -- python3 -m py_compile calc.py
receipts: [rcpt-0002] PASS  exit=0  0.18s  python3 -m py_compile calc.py

$ receipts check
receipts: PASS   [rcpt-0001] 'the test suite passes'
receipts: PASS   [rcpt-0002] 'calc.py compiles clean'

receipts: VERDICT PASS — all 2 claims backed by fresh evidence.

Now change the source and try to coast on old evidence:

$ echo "def sub(a,b): return a-b" >> calc.py && git commit -am "add sub()"

$ receipts check
receipts: STALE  [rcpt-0001] 'the test suite passes' — source changed after evidence was captured. Re-run it.
receipts: STALE  [rcpt-0002] 'calc.py compiles clean' — source changed after evidence was captured. Re-run it.

receipts: VERDICT FAIL — 2/2 claims not verified. Do not ship.

$ receipts verify        # re-run every recorded command, refresh evidence
receipts: re-run [rcpt-0001] PASS exit=0 0.21s  python3 -m unittest discover -s .
receipts: re-run [rcpt-0002] PASS exit=0 0.19s  python3 -m py_compile calc.py

receipts: VERIFY PASS — all 2 commands still pass.

$ receipts check
receipts: VERDICT PASS — all 2 claims backed by fresh evidence.

The three states

Every receipt is one of three states. receipts check only passes when all are pass.

State Meaning Gate
pass Command exited 0 and the tree hasn't changed since.
fail Command exited non-zero. The claim is false.
stale It passed, but the source changed after capture. Old proof ≠ current code.

Staleness is the whole point. A test that passed before your last edit tells you nothing about the code you're about to ship. receipts fingerprints the tree (git HEAD + meaningful dirty state, or an mtime/size walk for non-git projects) and re-checks it on every check.

Build artifacts (__pycache__, .pytest_cache, node_modules, dist, …) are filtered out of the fingerprint, so running your tests doesn't stale its own receipt.


CLI reference

Command What it does Exit 0 when
receipts init Create .receipts/ ledger + .gitignore entry always (idempotent)
receipts add "<claim>" -- <cmd> Run <cmd>, capture output/exit/fingerprint as a receipt the command passed
receipts check Verify every claim is fresh + passing all receipts pass
receipts verify Re-run every recorded command now, refresh evidence all re-runs pass
receipts report [--out F.md] Emit a Markdown verification report verdict is PASS
receipts list List all receipts always
receipts show <id> Dump one receipt as JSON id exists

Every command accepts --dir <path> to operate on a project elsewhere. add and verify accept --timeout <seconds> (default 600).

The ledger lives at .receipts/ledger.json and is git-ignored by default — evidence is machine-local and regenerated by re-running, never committed. Do not hand-edit it. Evidence you can tamper with is not evidence.


Use it as an Agent Skill

receipts ships with a SKILL.md, so any Skills-aware agent can load the discipline directly. Install it for your agent:

# Claude Code (plugin marketplace)
/plugin marketplace add Kaiser0733/receipts
/plugin install receipts

# Any Skills host via the skills CLI
npx skills add Kaiser0733/receipts

Or just drop SKILL.md + bin/receipts into your agent's skills directory. Once loaded, the agent is instructed to:

  1. run proof commands through receipts add (never bare),
  2. pass receipts check before claiming completion,
  3. re-record on STALE instead of hand-waving,
  4. paste receipts report so a human can audit every claim.

See SKILL.md for the full rule set the agent is held to.


CI gate

Make verification a merge requirement, not a vibe:

# .github/workflows/verify.yml
name: verify
on: [pull_request]
jobs:
  receipts:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: { python-version: "3.12" }
      - name: Verification gate
        run: |
          python3 bin/receipts init
          python3 bin/receipts add "the test suite passes" -- python3 -m pytest -q
          python3 bin/receipts check

This repository dogfoods its own medicine: ci.yml runs the test suite across Python 3.9 / 3.12 / 3.14, then initializes a ledger, records receipts, and gates on receipts check — uploading the report as an artifact.


How it's tamper-evident

Each receipt stores:

  • the claim and the exact command run
  • the exit code, duration, and UTC timestamp
  • a truncated stdout/stderr tail (16 KB) and a SHA-256 of the full output
  • a tree fingerprint — git HEAD + meaningful dirty state (or an mtime/size file walk for non-git projects)

check recomputes the current fingerprint and compares. Any drift → STALE. Any non-zero exit → FAIL. The ledger is append-only through the CLI; there is no delete command on purpose.


FAQ

Does this run my whole test suite again? receipts add runs the command once and stores the result. receipts verify re-runs everything. receipts check re-runs nothing — it only compares fingerprints, so it's instant.

What counts as "the tree changed"? Any change git would report (tracked edits, staged changes, new untracked source files), excluding common build/cache artifacts. In non-git projects, any change to file sizes or mtimes.

Can the agent just lie about the receipt? It could edit ledger.json, but that's a deliberate act of sabotage a human can spot in a diff — the skill's rules forbid it, and the SHA-256 + fingerprint make a forged receipt trivially detectable against a re-run.

Why not just use a test runner? You still do — receipts wraps it. A test runner tells you what happened when you ran it. receipts is the audit trail that the agent actually ran it, on the exact code it's claiming to ship, and didn't touch anything after. "Trust me bro" is not a verification strategy.


Roadmap

  • receipts diff — compare two ledgers across branches
  • signed receipts (ed25519) for supply-chain attestation
  • receipts watch — auto-re-verify on file change
  • first-class JetBrains / VS Code extension

Ideas and PRs welcome — read CONTRIBUTING.md first.

Contributing

Run the tests before you open a PR (and yes, record them as receipts):

python3 -m unittest discover -s tests -v

License

MIT © Kaiser0733

About

Your AI agent says it's done. Show the receipts. — a zero-dependency verification gate that blocks 'done' claims until they're backed by captured, tamper-evident evidence. Agent Skill for Claude Code, Codex, Cursor.

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages