haia-trace reads a run of recorded events and assembles Operation
Receipts — one verdict per payment operation — rendering them in the terminal
or as JSON.
Local-first: it reads and writes a project-local .trace/ directory. No daemon,
no database, no network.
Install
haia-trace command. Requires Node ≥ 22.
Commands
sample
Assemble receipts from bundled fixtures — no setup required.
build
Assemble one receipt per operation from a run’s events.
receipt
List the receipts
build has written; show one verdict in full.template
List the templates you can build against; scaffold your own.
The .trace/ directory
build is “rebuild”.
A receipt’s file name carries both the run and the operation, because an
operation id is only guaranteed unique within its run — an adapter is free to
number operations per session. receipt reads the store back, so
nothing outside the CLI needs to know how the name is built.
Moving the root
--dir <path> relocates the whole root — haia-trace build --dir .my-trace —
for a second project in one checkout, or a scratch run that should not touch the
committed tree. What is inside the root never changes: events/, receipts/,
templates/.
--templates-dir <path> moves templates alone and outranks --dir. Every
command that resolves a template takes both; receipt reads the
store only, so it takes --dir alone.
The recorder is the one thing --dir cannot reach: it names its own directory
(createRunEventWriter(".trace/events")), so point it at events/ under
whatever root you build with.
git
events/ and receipts/ are recorded and derived; templates/ is source you
author. Ignore the two subdirectories, not the root:
Output formats
Every command renders to the terminal by default.build, receipt list and
receipt show also take --json and write a document to stdout instead;
template list and template new do not.
Diagnostics never go to stdout. A warning about receipt files that could not be
read is written to stderr, so haia-trace receipt list --json | jq . stays
valid and > out.json still shows the damage on your terminal.
Colour and glyphs come from the terminal’s own capabilities and degrade to ASCII
where Unicode is unsupported. A spinner appears only on an interactive terminal
and only while build is actually folding events.
Exit codes
A verdict is an answer, not a failure.
build exits 0 on a PARTIAL
receipt — read --json and branch on completeness to gate on one. receipt list on an empty store is an answer too and exits 0, while receipt show with
nothing to show is a failure and exits 1.
Templates that ship
Four:x402-buyer, x402-seller and x402-facilitator for the three sides of
an x402 payment, and escrow-arc for an escrow on Arc. template
lists what each one expects, and scaffolds your own for anything else.