Skip to main content
build assembles receipts and writes them under the Trace root; these two read them back. list answers what is in the store? with one line per receipt, and 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.

receipt list

Every receipt in the store, grouped by the run it came from, oldest run first.
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 the verdict are what show is for. Narrow it with either filter:
A --run that matches nothing is refused and names the runs the store does hold: it means you asked for something absent, and silence would read as “that run went fine”. 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.

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, and add --run to reach an older one:
The run is printed either way, because it is implicit unless you gave --run — and two runs of one program yield receipts with identical operation ids and different verdicts. 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 non-zero rather than printing nothing. An unknown operation names what the run does hold.
show is more than cat. An operation id that isn’t 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 — by reading the directory, so that every lookup can also report any damage it passed over.

Options

JSON output

list emits an index, not whole receipts — it says what is in the store, so it carries the fields a reader scans or filters on:
An entry in unreadable carries the run and operation its file name records alongside the path and the reason, so a consumer can tell whether the damage is in the run it just built or in an old one kept as evidence. That index carries the completeness an agent decides on, so a spend policy can read the store through one command rather than 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.
A file in receipts/ that cannot be parsed — truncated mid-write, hand-edited, written by an older CLI — is reported, not skipped: on stderr in every case, and in the unreadable array of both commands’ JSON. A store that is partly damaged must never present as intact, so this holds even when a query is refused, and a run whose receipts are all unreadable is still counted as the most recent run rather than passed over for an older one. Files the CLI didn’t write are passed over in silence.
The warning goes to stderr, never stdout. It is a diagnostic about the store rather than part of the answer, so receipt list --json | jq . stays valid with a damaged file present, and receipt show --json > out.json still shows the damage on your terminal.