Metadata-Version: 2.4
Name: receipts-gate
Version: 0.1.1
Summary: DEPRECATED — merged into aegis-hooks (aegis.grounding). Hard gate that forces AI agents to back every claim with evidence.
Project-URL: Homepage, https://github.com/Thepizzapie/receipts
Project-URL: Repository, https://github.com/Thepizzapie/receipts
Project-URL: Issues, https://github.com/Thepizzapie/receipts/issues
Author: Adrian Melendez
License-Expression: MIT
License-File: LICENSE
Keywords: agents,ai,evaluation,grounding,guardrails,provenance
Classifier: Development Status :: 7 - Inactive
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Typing :: Typed
Requires-Python: >=3.10
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.40; extra == 'anthropic'
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == 'dev'
Description-Content-Type: text/markdown

# Receipts

> **⚠️ Deprecated — merged into [Aegis](https://github.com/Thepizzapie/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.
>
> ```bash
> pip install aegis-hooks
> ```
> ```python
> 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](https://github.com/Thepizzapie/AEGIS#grounding-gate-what-an-agent-claims).

**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

```bash
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

```python
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:

```python
from receipts import track

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

Or audit an existing run:

```python
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.

```python
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.

```python
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.

```bash
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`](examples/ci/receipts-example.yml).
Claims reference evidence by a local label, list index, or real id — see
[`trace.py`](src/receipts/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):

```python
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:

```python
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

```bash
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
