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.
show is for.
--run that matches nothing is a
named thing that is not there, so it is refused and names the runs the store does
hold:
--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:
--run to reach an older one:
--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.
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:
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 inreceipts/ 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
--jsonstays parseable and a redirect still shows the damage on your terminal. - It also appears in the
unreadablearray of both commands’ JSON, carrying therunandoperationits file name records alongside thepathand thereason— 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
--runor--statusquery 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.