Templates and stages
A template describes an operation as an ordered sequence of milestone stages. For the canonical x402 payment, that’sintent → payment → settlement → paid_action, plus an optional business record.
Each stage’s match is a match-set: any one of its events closes the stage.
This is deliberate — different roles witness the same milestone differently, so
settlement can be closed by a client-side response, a server-side settle, or an
on-chain confirmation:
The verdict
1
Each stage gets a state
confirmed when at least one witness from its match-set was observed;
otherwise not_confirmed. A confirmed stage carries the event_ids of the
witnesses behind it — the evidence.2
Gaps are explained, never hidden
A required stage left unclosed is surfaced under
missing, each with a
plain-language explanation from the template’s missing_explanation.3
Faults surface as exceptions
An event whose type is in the template’s
exceptions (e.g.
x402.settle.failed) does not close a stage — it’s recorded on the
operation as a fault.4
Completeness is decided
full only when every required stage is confirmed, at least one stage
closed, and no fault was observed. Otherwise partial.Deterministic by design
The assembler is a pure function — no LLM, no randomness. The same events and template always yield the same Receipt, byte for byte. That’s the evidence-chain guarantee: a Receipt states absence rather than guessing, so it never invents a milestone it didn’t observe.The Receipt object
Every surface — terminal,receipt.json, markdown — renders the same object:
completeness: "partial" plus missing: [paid_action] is a
machine-readable basis to stop a chain of spending.