The mechanism: small records, one chain, an independent check.
Everything the product pages say rests on this page. The record is a published format, the verifier trusts none of the code that wrote the record, and each verdict has a narrow, stated meaning.
1 · The receipt
Each stage writes one receipt, in canonical JSON.
A stage is one logical step of a run. Its receipt (stage-receipt/0.2) is canonical JSON: UTF-8 with no byte-order mark, sorted keys, no incidental whitespace, and no JSON numbers, so numeric-looking values are decimal strings. The same content always yields the same bytes, and so the same digest.
| Member | What it records |
|---|---|
format, run_id, stage | The format version, the run, and which stage this is. |
prev | The digest of the previous receipt, or null for the first. This is the link in the chain. |
inputs, outputs | Each artifact read or written, by digest and byte count, with a trust class: operator-authored, model-generated or externally-sourced. |
instrument | The tool that did the work: name, version and a digest of its configuration. |
assertions | Named constants and measured values the stage states. |
outcome | ok, refused or error. |
time | started and ended, each with an explicit zone. |
coverage, emission, anchor | Declared versus observed stages; how the receipt was produced; whether the run is anchored. |
A run folder holds MANIFEST.json, a receipts/ folder and an artifacts/ folder with the bytes the digests name. Artifacts can include documents, prompts and answers, so treat run folders like logs that may hold sensitive data.
2 · The chain
Receipts are hash-chained into a manifest.
Each receipt names the digest of the one before it. MANIFEST.json (format stage-receipt-chain) lists every receipt's file and digest in order and ends in a chain_head: the digest of the last receipt. Change, remove or reorder a receipt and the links no longer match.
Digests above are illustrative. Pipelines that branch are recorded as a graph: a stage's inputs can name the earlier receipts it read. Per-document stages carry two roots: receipts_root over the receipt bytes, and outputs_root over document id and output digest pairs, which is what comparison uses.
Signatures, beside the chain
An Ed25519 signature over the chain head, by a key you hold. It sits in signatures/ and changes no existing byte. It shows that the key's holder signed; it doesn't say who the holder is.
Anchors, beside the chain
A timestamp proof over the chain head from an outside party, in anchors/. It shows the record existed by a time, under that party's trust assumptions, not when the run happened.
3 · The verifier
A separate program decides, from bytes alone.
onetrace-verify is the reference verifier. It uses only the Python standard library, makes no network call, and doesn't trust the SDK that produced the record: a record from any other emitter is checked the same way.
Canonical form first
Each receipt's bytes must equal its own canonical serialisation. A receipt that doesn't is refused before anything else is read.
Every link, and the head
Each prev and the chain_head must match. A break is reported at its exact place.
Every output file
With --require-artifacts, each artifact must exist and match its digest. A missing or edited file fails, by name.
Each check prints PASS, FAIL or NOT-RUN. A format version the verifier doesn't implement is refused by name, never guessed at, and reported as not verified (exit 2) rather than as a pass or a fail.
4 · The verdicts
Comparison: one verdict per stage, about its output.
diff refuses to compare a run the verifier refuses. It then compares each stage's output digest in chain order (for a per-document stage, its outputs_root) and gives exactly one verdict.
| Verdict | Rule |
|---|---|
same | The output digest matches on both sides. |
FIRST DIFFERENCE | The first stage, in chain order, whose output digest differs. At most one per comparison. |
downstream | After the first difference, and still different. |
reconverged | After the first difference, but matching again: different computations, same output. Reported, not hidden. |
COULD NOT CHECK | The stage can't be evaluated, for example an unimplemented format version or an unreadable file. Never treated as a pass. |
Annotations never change a verdict
A changed instrument name, version, configuration digest or asserted constant is reported as an annotation. So a stage can be same and still show that how its output was produced changed.
Localise and read the text
localize names the first point of divergence and its cause, or in one run the first stage that didn't end cleanly. diff --text shows what the recorded outputs contained, checked against the receipts first, in a published text-diff format.
5 · The evidence ladder
In the console, each question is its own rung.
The console never collapses a run into one score. Each rung is a separate question with its own evidence, and each answer says what was and wasn't checked. None of them says the output was correct.
Records agree
The verifier's checks held, with the output files required.
Signed by a known recorder
A signature over the chain head by a key on your trust list.
Nothing declared is missing
Every declared stage left a receipt.
Re-runnable stages reproduced
Stages re-run from recorded inputs gave the recorded outputs.
Committed by a known time
An anchor fixes when the record existed.
6 · The limits
What the mechanism does not establish.
Stated in full in what onetrace does not claim. The ones a reviewer most needs:
Not a truth oracle
A faithfully recorded wrong answer verifies. Trust classes say where bytes came from, not whether they're right.
Not proof against a writer
Someone who can rewrite storage and recompute every digest isn't stopped by verification alone. Hold the chain head somewhere independent, or anchor it.
Not bit-exact everywhere
Reproduction isn't claimed across machines for numeric stages, and unseeded model calls are reported as could not check, with their originals kept.
Read the source material
The format is published, and still version 0.
The record format is written up as an Internet-Draft so that something other than the program that wrote a record can read it. It may change before version 1; every record carries its version, and a verifier refuses versions it doesn't implement.
Stage receipts
The normative format, chain and verification rules.
Datatracker → ReferenceThe record format
Every member, the two roots and the graph form.
Read → ReferenceText-diff format
What diff --text writes, with its schema.
The five verdicts
The exact comparison rules.
Read → ReferenceThe manual
From basics to signing, anchoring and comparison.
Read → ReferenceNon-claims
Every limit, stated before you find it.
Read →