Skip to main content
build writes receipts under the .trace/ root; these two read them back. list answers what is in the store? with one line per receipt, show answers what happened in this operation? by rendering the stored verdict in full.
Both are read-only. A receipt is derived from a run’s events, so build is the only thing that creates one — there is no receipt new, unlike template new. To change a verdict, change the template or the events and build again.

Options

receipt list

Every receipt in the store, grouped by run, oldest run first, and within a run in the order the operations started — the same order build reports them in.
Each line carries the operation, its verdict, and the template the verdict was assembled against — two receipts in one run can be judged against different shapes, and a verdict means nothing without knowing which. The stages behind it are what show is for.
The two filters differ in how they fail. A --run that matches nothing is a named thing that is not there, so it is refused and names the runs the store does hold:
A --status that matches nothing is a real answer about the store, so it prints one and exits 0. An empty store is the state every project starts in, so list points at build rather than failing.
Operation ids come from the adapter that recorded the events: the x402 adapter mints a uuid per payment, the Circle adapter uses the escrow contract’s address. The ids in these examples are short to keep the samples readable.

receipt show

With no operation named, the whole of the most recent run — the “how did the run I just built go?” question, which needs no ids to hand. Name an operation for one receipt out of it:
Add --run to reach an older one:
Any leading part of the id works as long as it names exactly one operation in the run. A prefix matching several is refused and lists them, rather than showing you whichever sorted first. An id matching none names what the run does hold:
The run is printed either way, because it is implicit unless you gave --run. Unlike list, having nothing to show is a failure: the caller asked for a verdict and there is none, so an empty store or an unknown operation exits 1.
show is more than cat. An operation id that is not a bare slug — a URL-ish context_id — is escaped into the receipt’s file name, so the file is not nameable by hand. Looking a receipt up by the ids it was written under is the only reliable way to it, and it is what both commands do.

JSON output

list --json emits an index, not whole receipts — it says what is in the store, so it carries only the fields a reader scans or filters on:
It carries the completeness an agent decides on, so a spend policy can read the store through one command instead of globbing the directory and re-deriving how receipts are named. show --json emits the full Receipt objects as { run, receipts, unreadable } — the same shape whether or not you named an operation, so a script consuming it never has to branch on the argument count.

Damaged files

A file in receipts/ that cannot be parsed — truncated mid-write, hand-edited, written by an older CLI — is reported, never skipped. A store that is partly damaged must not present as intact.
  • It goes to stderr in every case, so --json stays parseable and a redirect still shows the damage on your terminal.
  • It also appears in the unreadable array of both commands’ JSON, carrying the run and operation its file name records alongside the path and the reason — enough to tell whether the damage is in the run you just built or in an old one kept as evidence.
  • It still prints when a --run or --status query is refused.
  • A run whose receipts are all unreadable is still counted as the most recent run, rather than passed over for an older one whose verdicts would look clean.
Files the CLI did not write are passed over in silence.