Docs · Verify
Verify a
receipt.
Recomputes the chain root from the receipt body, in your browser, and shows you the math. Existence proof for the auditable-labor thesis — dashboards narrate work; a hash chain records it.
What this verifier does
Reads the receipt body, canonicalizes it, hashes the canonical bytes with SHA-256, and compares the computed chain root against the value the receipt claims. The comparison runs entirely in your browser; no network call is made.
A pass means the math you just ran agrees with the math whoever issued the receipt ran. A fail means the receipt body, the claimed chain root, or the canonicalization rule has drifted — and the result panel surfaces all three so you can see where.
The widget
A receipt specimen with an unfilled chain root. Click Verify and the page computes the root from the fields above, in-tab, and reveals the canonical JSON it hashed.
Show the canonical JSON I am hashing
(verify to populate)
The math, step by step
Canonicalization is the entire trick. Two receipts with identical content but different key orderings or whitespace would hash to different roots; the rule below removes every degree of freedom that does not carry meaning.
- 01
Drop
Drop the field being verified
Remove the `claimed_chain_root` field from the receipt body. The chain root is the value the math is going to produce; including it in the input would let any value match itself.
- 02
Sort
Sort all object keys recursively
Walk every object in the receipt tree and emit keys in lexicographic order. Arrays preserve their original order — arrays are sequences, not bags. Determinism lives or dies on this step.
- 03
Encode
JSON-stringify, UTF-8 encode
Serialize with no whitespace, no Unicode escapes, no trailing commas. Encode the resulting string as UTF-8. NaN and Infinity are forbidden by JSON itself; nothing to do here.
- 04
Hash
SHA-256, lowercase hex, sha256: prefix
Hash the UTF-8 bytes with SHA-256. Render as lowercase hexadecimal. Prefix with `sha256:` so the algorithm travels with the value and future migrations are unambiguous.
Reference implementation
The exact JavaScript the widget above runs. Paste this into a console with any receipt object and you reproduce the chain root by hand. The widget is not magic — it is these forty lines.
// Sort all object keys recursively. Drop `claimed_chain_root`
// (the field being verified). Arrays preserve order. Primitives
// serialize normally.
function canonicalize(value) {
if (value === null || typeof value !== "object") return value;
if (Array.isArray(value)) return value.map(canonicalize);
const out = {};
const keys = Object.keys(value)
.filter((k) => k !== "claimed_chain_root")
.sort();
for (const k of keys) out[k] = canonicalize(value[k]);
return out;
}
function canonicalJson(receipt) {
// JSON.stringify with no whitespace, no Unicode escapes,
// no trailing commas. UTF-8 encoding is implicit at the
// TextEncoder step below.
return JSON.stringify(canonicalize(receipt));
}
async function sha256Hex(text) {
const enc = new TextEncoder().encode(text);
const buf = await crypto.subtle.digest("SHA-256", enc);
const bytes = new Uint8Array(buf);
let hex = "";
for (let i = 0; i < bytes.length; i++) {
hex += bytes[i].toString(16).padStart(2, "0");
}
return hex;
}
async function chainRoot(receipt) {
const canonical = canonicalJson(receipt);
return "sha256:" + (await sha256Hex(canonical));
}
Drift between this snippet and the function inside
src/components/ReceiptVerify.astro would be a bug. The
production reference implementation, once published in the RELOS spec, becomes the
single source of truth — both this snippet and the widget derive from it.
Limits
What this page is, and what it is not. No marketing voice — the gap between today and the production verifier is the most useful thing on this surface.
Sandboxed
The widget runs entirely in your browser. It hashes a specimen receipt the page ships with — nothing leaves the tab.
No counter-receipt
A production verifier replays the receipt server-side under a signing key and emits a counter-receipt. That service does not exist yet.
Same math
The canonicalization rule and the SHA-256 step here are the contract the production verifier will run. Today, you audit the math; tomorrow, you audit the counter-signature.
Transparency aid
This page exists so the math is auditable before there is a signed verifier to trust. It is not a replacement for one.
Next
Read the concepts.
The chain root is one field on one receipt. The four mechanisms — identity, leases, evidence, liveness — and the evidence chain itself are the rest of the surface.