Docs ledger

Read a receipt

Rendered from docs/guide/04-read-a-receipt.md.

Read a receipt

Goal: produce and read the receipt for any one session — the newest, or a specific one you pick.

The default: your newest session

aireceipts

With no arguments, aireceipts computes the observable Standard-API floor for your most recently ended session across every supported agent and prints its receipt:

- - - - - - - - - - - - - - - - - - - - - - - - -
                    AIRECEIPTS                    
 “Add email format validation to the signup for…” 
 Claude Code · Jun 18 2026 09:30:30 UTC · 10m 30s 
    claude-opus-4-8 87% · claude-sonnet-5 13%     
         cache served 85% of input tokens         

Bash..........................≥ $0.0517  (3 calls)
Edit..........................≥ $0.0455  (2 calls)
(thinking/reply)..............≥ $0.0310  (2 turns)
Write.........................≥ $0.0290  (2 calls)
Read...........................≥ $0.0192  (1 call)
--------------------------------------------------
TOTAL....................................≥ $0.1764
standard API-equivalent floor; not an invoice
same tokens on claude-haiku-4-5..........≥ $0.0392
  (78% lower observable floor)
  (arithmetic, not a prediction)
- - - - - - - - - - - - - - - - - - - - - - - - -
                npx aireceipts-cli                
         github.com/anandgupta42/receipts
- - - - - - - - - - - - - - - - - - - - - - - - -

Reading it top to bottom: the title is your opening prompt; the header line gives the agent, start time, and duration; then the model mix (share of tokens per model) and how much of the input was served from cache. The body lists the observable floor per tool, highest first. (thinking/reply) is the model's own output on turns that called no tool. The raw TOTAL is additive; same tokens on … re-prices those exact tokens on a cheaper model as a reference point — the percentage note compares the two observable floors, never predicts completion.

Each human ≥ $X is rounded down. The additive tool ledger uses one adaptive precision: two decimal places for exact cents, normally four when fractional cents remain, and up to twelve for tiny positive evidence. Its displayed rows sum exactly to TOTAL, and neither a row nor TOTAL exceeds the corresponding raw machine value. If IEEE-754 addition serializes just below the exact row-unit sum, the largest row is lowered by the excess unit(s); no row is ever rounded upward. Use --json or --csv for raw precision and explicit lower-bound semantics.

A few lines appear only when they have something to say:

  • a pre-edit linepre-edit: 11% of priced floor (1/10 turns) — the share of the session's observable priced floor before the first named edit-tool call, and how many turns that covered. It's a shape fact, not a verdict: a hard bug can deserve a high share, and a routine edit usually doesn't — a share that surprises you is worth a look;
  • a stuck-loop pattern line names where to look — at turns 1-5 — so you can jump straight to the loop in your own transcript;
  • a coverage caveatcaveat: 2 of 3 usage turns include unpriced tokens — TOTAL excludes those tokens — whenever a session mixed a priced model with one that has no cited price row, so a partial TOTAL never poses as a complete one;
  • an unattributed-usage caveat — Claude id-less response snapshots, Codex request streams that fail reconciliation, and componentwise-dominating opencode session aggregates can expose tokens without a trustworthy request/model join. They remain tokens-only instead of being assigned a fake dollar. A partial turn slice excludes session-level residuals; crossed opencode aggregate/itemized vectors keep the itemized total and report the positive conflict as excluded evidence;
  • time-integrity caveats (inconsistent timestamps, skipped records) as before.

If the parent session has no matching price row but a readable subagent does, aireceipts does not throw away either fact. The child keeps its SUBAGENTS (N) ≥ $X row, while the tail shows KNOWN PRICED SUBTOTAL ≥ $X and KNOWN UNPRICED TOKENS N tok on separate lines, followed by partial pricing coverage; invoice total unknown. The token line is the exact observable usage excluded from the dollar subtotal; unreadable or missing transcripts remain a separate unknown caveat.

The --details section

When the one question you have is "what's inside that number?", ask for it:

aireceipts --details
DETAILS
tokens in / out..........................20k / 897
cache read / write.....................124k / 2.1k
turns / tool calls..........................10 / 8
peak turn.........................24k tok (turn 7)
same reads at uncached input rate..........≥ $0.51
  (arithmetic, not a prediction)
BY MODEL
claude-opus-4-8......................87% · ≥ $0.16
claude-sonnet-5......................13% · ≥ $0.01

The section slots between the price-delta line and the footer. When supported TypeScript tool results and chronology are captured, recorded verification evidence appears at its end, after BY MODEL if present. Line by line: tokens in / out is the raw prompt/completion split; cache read / write shows whether caching is actually working (when the transcript reports the cache-write TTL tiers, a writes: 5m … · 1h … sub-line appears — absent data renders nothing, never a fabricated 0); turns / tool calls is the session's shape; peak turn is the single most context-heavy request; same reads at uncached input rate re-prices your cache-read tokens at the plain input rate — a lower-bound counterfactual on the same cited price rows as everything else; BY MODEL splits the parent session's observable floor per model. It is a secondary parent-only partition with no displayed subtotal, so it does not purport to decompose a TOTAL that may also include subagents. Every line renders only when its data exists in the transcript. --details composes with the default template only; it also works with --svg.

Recorded verification evidence

aireceipts --details can show a recorded TypeScript command followed by a TypeScript edit, or a command whose tool result was an error:

VERIFICATION EVIDENCE
npx tsc --noEmit..........tool result ok (turn 2)
TS edit after it........................turn 3
no later matching result recorded
(recorded calls only; external checks unknown)

This is a transcript inspection aid. It reports the linked tool result and captured turn numbers, so you can inspect the command before relying on it. Displayed turns start at 1; the JSON indices start at 0 (displayed turns 2 and 3 are JSON indices 1 and 2). “Tool result ok” is not a compiler exit-code certificate or proof of any project's correctness. A tool error can mean a missing compiler or a permission problem as well as a type error. No output prose is interpreted as success. For a tool error, the command row says tool result error (turn N) and there is no TS edit after it row. Both cases end with the same two notes: no later recognized invocation has a recorded result, and external checks are unknown.

The first version recognizes only foreground Claude Code parent-session Bash calls whose entire command is npx tsc --noEmit and which were not requested to run in the background. Outer whitespace is allowed; extra flags, chaining, pipes, wrappers, background requests, other commands and other agents are outside this slice. TypeScript edits are successful named Edit or Write calls to .ts, .tsx, .mts, or .cts paths in later captured turns. Paths never appear in the evidence block or its JSON. The check and edit need not cover the same project; the receipt makes no such claim.

Turn order supplies the chronology; recorded timestamps must also agree. Unknown or running tool statuses, dropped records, absent timing or ambiguous ordering suppress the relevant finding. A docs-only edit or a failed edit does not produce the typed-edit line. A later recognized completed invocation becomes the latest observation; this does not certify that an earlier problem was repaired. External CI, shell-based edits and child sessions remain unknown.

No block means no supported finding, not that no verification happened. The block appears only in classic --details text/SVG/PNG. Receipt/compare JSON includes the evidence field whenever a supported finding exists; it needs no additional opt-in flag. It does not change default receipts, handoffs, pricing, flagged-pattern subtotals, budgets or telemetry.

Pick a different session

First, list what's on disk — newest first:

aireceipts --list
1. [claude-code] Read config.yaml and check whether the port is set.  ·  Jun 25 2026 14:00:00 UTC  ·  2 tool calls
2. [claude-code] What HTTP status code should a successful DELETE return?  ·  Jun 24 2026 10:00:10 UTC  ·  0 tool calls
3. [codex] Run the flaky login test until it's green.  ·  Jun 23 2026 09:00:00 UTC  ·  3 tool calls
4. [codex] What does the --frozen-lockfile flag do in pnpm install?  ·  Jun 22 2026 16:00:06 UTC  ·  0 tool calls
5. [codex] The build fails because of a broken import in src/utils/formatDate.ts — can you fix it?  ·  Jun 20 2026 11:00:04 UTC  ·  3 tool calls
6. [claude-code] Add email format validation to the signup form and add a unit test for it. The signup form is in src/components/SignupF…  ·  Jun 18 2026 09:30:30 UTC  ·  8 tool calls
7. [claude-code] Can you fix the flaky login test in src/auth/login.test.ts? It's failing intermittently in CI.  ·  Jun 15 2026 14:00:25 UTC  ·  5 tool calls

Then select one three ways — a 1-based index from the list, a session id, or a substring of the title:

aireceipts 6                    # the sixth session listed
aireceipts "email format"       # matched by title substring

Both print the same receipt shown above. If a substring matches nothing, you get no session matched "…" (see Troubleshooting).

The six-line version

For a glance instead of the full ledger:

aireceipts --mini "email format"
aireceipts · session receipt
Claude Code · claude-opus-4-8 · 10m 30s
total  ≥ $0.1767
top    Bash · ≥ $0.0517 (3 calls)
no flagged pattern detected
run  aireceipts  for the full receipt

This is exactly what the SessionEnd hook prints. The mini total floors the raw session value directly (here ≥ $0.1767), so it can sit a fraction of a cent above the full ledger's TOTAL — which is derived from the displayed rows so that they always sum exactly. Both are true floors of the same session.

When there's no price

If a session ran on a model with no cited price row, the receipt shows tokens, never guessed dollars — a deliberate honesty rule, not a failure. See How pricing is estimated for why, and what it looks like.

Next