Skip to main content

DEPRECATED — merged into aegis-hooks (aegis.grounding). Hard gate that forces AI agents to back every claim with evidence.

Project description

Receipts

⚠️ Deprecated — merged into Aegis. This engine now ships inside aegis-hooks as aegis.grounding, alongside Aegis's hook-boundary enforcement — so the same tool governs what an agent does and what it claims. receipts-gate is frozen at 0.1.x and won't get further updates.

pip install aegis-hooks
from aegis.grounding import Ledger, Gate, Answer, Claim, ClaimKind  # same API

New in Aegis: ledger_from_audit() grounds an answer against Aegis's own audit trail, and aegis grounding audit is the folded-in CLI. See the Grounding section.

Force AI agents to back every claim with evidence — or declare it an assumption.

Agents lie about the research they did and quietly base conclusions on guesses, because there's no cost to either. Receipts adds the cost. Every claim an agent makes must point at a tamper-evident log of what it actually did. Claims that can't be grounded are illegal — they must be surfaced as explicit assumptions, not buried in the answer.

You can't fix this with prompting ("don't assume, don't lie"). Receipts doesn't ask the model to be honest — it measures honesty against ground truth, with deterministic checks the model can't game.

Install

pip install receipts-gate

Zero dependencies. The distribution is receipts-gate (the bare name was taken); the import and the CLI are plain receipts.

The three rules

Every claim is checked against the Ledger (the captured execution log):

Rule Kills How
Binding guesses stated as fact A claim must cite real evidence in the ledger, or be demoted to an assumption.
Effort honesty "I reviewed the entire codebase" Effort claims must cite evidence of a matching kind; words like all / entire / thoroughly require machine-checkable coverage proof.
Support citing a source that doesn't say it Cited evidence must actually back the claim (deterministic heuristic by default; pluggable LLM/NLI judge for production).

Two modes, one engine

  • Live gate (Gate.finalize) — runs inside the agent loop and blocks ungrounded output before the user ever sees it, handing the agent a precise list of what to fix.
  • Post-hoc auditor (audit) — ingest a finished trace and get a Verdict. Same engine, no runtime coupling. Drop it in CI to fail PRs from ungrounded agent runs.

Quick start

from receipts import Ledger, Gate, Answer, Claim, Assumption, ClaimKind

# 1. Evidence is captured from real work, not self-reported.
ledger = Ledger()
ev = ledger.record("file_read", "config.py", "PORT = 8080")

# 2. The agent emits claims that point at evidence.
gate = Gate(ledger)  # hard gate by default
answer = Answer(
    summary="The service listens on port 8080.",
    claims=[Claim("The port is 8080", evidence_ids=[ev.id], kind=ClaimKind.FACT)],
    assumptions=[
        Assumption("The paid tier is higher", reason="not verified",
                   impact="capacity planning wrong if false"),
    ],
)

# 3. The gate renders the answer, or raises UngroundedAnswerError with a fix list.
print(gate.finalize(answer))

Capture evidence automatically by wrapping tools:

from receipts import track

@track(ledger, kind="web_fetch", source=lambda url: url)
def fetch(url): ...

Or audit an existing run:

from receipts import ingest_trace, audit
ingest_trace(ledger, my_logged_events)   # [{"kind","source","content"}, ...]
verdict = audit(answer, ledger)
print(verdict.report())

Semantic support via an LLM

The default support check is token overlap — transparent, but shallow. For real grounding (catching a claim that cites evidence which is related but doesn't say what the claim asserts), swap in the LLM judge. The gate stays deterministic for binding and effort; only the support check calls the model, so the thing being audited can't game the structural rules.

from receipts import Gate, AnthropicLLM, LLMSupportVerifier

gate = Gate(ledger, verifier=LLMSupportVerifier(AnthropicLLM()))  # needs receipts-gate[anthropic]

LLM is a one-method protocol — drop in any backend (NLI model, embeddings, a different vendor) or FakeLLM for tests.

Free-text extraction (no structured claims required)

Agents don't have to emit Claim objects by hand. Give Receipts the prose answer and the ledger, and it produces a structured Answer for the gate to check. The extraction is LLM-driven and advisory — every binding it produces is still re-verified deterministically, so a hallucinated citation surfaces as a gate failure, not a silent pass.

from receipts import extract_claims, Gate, AnthropicLLM

answer = extract_claims(free_text_answer, ledger, AnthropicLLM())
print(Gate(ledger).finalize(answer))   # checks the extracted claims

CLI / CI gate

receipts audit trace.json exits non-zero when any claim is ungrounded — a drop-in CI gate on agent output. Deterministic by default (no API key); --llm turns on the semantic judge.

receipts audit trace.json          # exit 1 if blocked
receipts audit trace.json --json   # machine-readable

Trace format and a copy-into-your-repo GitHub Action are in examples/ci/receipts-example.yml. Claims reference evidence by a local label, list index, or real id — see trace.py.

Framework adapters

Capture is framework-agnostic; these map specific ecosystems onto the Ledger.

OpenAI / Anthropic / Claude Agent SDK traces — ingest a finished transcript, recording each tool result as evidence (pure Python, no SDK needed):

from receipts.adapters import from_openai_messages, from_anthropic_messages

from_openai_messages(ledger, openai_messages)       # OpenAI chat format
from_anthropic_messages(ledger, anthropic_messages) # Messages API / Claude Agent SDK

LangChain / LangGraph — capture tool results live via a callback handler, no change to your tool code:

from receipts.adapters import langchain_handler

handler = langchain_handler(ledger)
agent.invoke(inputs, config={"callbacks": [handler]})

Layout

src/receipts/
  models.py      data model — Evidence, Claim, Assumption, Answer, Verdict
  ledger.py      append-only, hash-stamped evidence log (the ground truth)
  instrument.py  capture: @track decorator + ingest_trace()
  verify.py      pluggable support check — HeuristicVerifier + LLMSupportVerifier
  llm.py         LLM protocol + AnthropicLLM / FakeLLM backends
  extract.py     free-text answer -> structured Answer
  trace.py       load a portable trace file -> (Ledger, Answer)
  cli.py         `receipts audit` command
  gate.py        the three rules + Gate + audit()
  adapters/      OpenAI trace, Anthropic/Claude-Agent-SDK trace, LangChain callback
examples/        research_agent.py (gate), agent_loop.py (capture->extract->gate)
tests/           pytest suite

Develop

python -m pytest -q
python examples/research_agent.py

Status / roadmap

v0.1 — core engine, hard gate, post-hoc auditor, framework-agnostic capture, LLM support verifier, free-text extraction, OpenAI adapter, receipts audit CLI

  • CI action.

Adapters: OpenAI trace, Anthropic / Claude Agent SDK trace, LangChain/LangGraph callback.

Next candidates:

  • NLI / embeddings SupportVerifier backends (no LLM call)
  • Live in-loop gate wrappers for popular agent runtimes
  • Published package on PyPI

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

receipts_gate-0.1.1.tar.gz (25.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

receipts_gate-0.1.1-py3-none-any.whl (26.3 kB view details)

Uploaded Python 3

File details

Details for the file receipts_gate-0.1.1.tar.gz.

File metadata

  • Download URL: receipts_gate-0.1.1.tar.gz
  • Upload date:
  • Size: 25.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for receipts_gate-0.1.1.tar.gz
Algorithm Hash digest
SHA256 63b12316f0bfe5719f4cf2035ec9534eb1b9e9211710145dde7fe50adb071ee8
MD5 a17c4894510cece977672c46cc076f57
BLAKE2b-256 872b88a9b47952dd3a1d21ecdd3ee41c9ae1d043334f5f090ecafea49b89dadb

See more details on using hashes here.

Provenance

The following attestation bundles were made for receipts_gate-0.1.1.tar.gz:

Publisher: publish.yml on Thepizzapie/Receipts

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file receipts_gate-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: receipts_gate-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 26.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for receipts_gate-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8002e0db9a2bebf10cb8c23c4cc8f594a315038d36935f1dce9d4dbb3029f3a6
MD5 9c8dd5d9e9f3d1f0bb2fd7a0d4777e53
BLAKE2b-256 970b7f6958ff4bb2193c0db23e5ead3a1626b12e97f1333fac19b60c0e2e6e63

See more details on using hashes here.

Provenance

The following attestation bundles were made for receipts_gate-0.1.1-py3-none-any.whl:

Publisher: publish.yml on Thepizzapie/Receipts

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page