Check the receipts yourself.

Drop an exported audit chain below and this page recomputes every hash in your browser. No account, no install, no upload — the site is a static export with no endpoint to send a file to, so the only way this works at all is locally.

Drop an evidence bundle hereThe NDJSON file from audit-events/export, or paste it below. Nothing leaves this tab — check your network panel.

No export of your own? or and watch the chain break.

Or take the sample away and attack it yourself — , change a single character anywhere in it, and drop it back. This is the frozen vector the control plane and the forensics CLI are both tested against, so an edit that still verifies here is a finding worth sending us.

The chain proves every event links to the one before it. It cannot prove nothing came after the last line, so a bundle with its tail deleted verifies like a whole one. Paste the chain head from a signed checkpoint and the verdict says whether the bundle ends there.

Anchoring a partial export

A full export starts at sequence 1 and anchors itself. An export that starts mid-chain declares its own starting point, which is an assertion the file makes about itself — supply the anchor from somewhere the file cannot reach.

Paste instead

What is being checked

Each audit event is hashed as sha256("trustrail.audit.v1\0" || previous_hash || canonical_event), and every line of the export carries both the event’s own hash and the one before it. The page recomputes each link from the bytes of canonical_event and continues the chain from what the event actually hashes to — not from what the line claims. That distinction is the whole mechanism: a forged event_hash would otherwise relink the chain around its own forgery and every later line would verify.

Three implementations, one rule

The control plane verifies its chain by reading its own tables. The forensics CLI verifies the same rule against a file with no database, because a timeline has to be producible when the control plane is down. This page is the third, and exists because the party who most needs to check a receipt is the one who has no reason to trust a tool written by the party under audit. All three are tested against fixtures derived from the control plane’s own construction, so a change to any one of them fails the others.

Anchors, and why a partial export is refused by default

A full export starts at sequence 1 with an all-zero previous hash and anchors itself. An export that starts mid-chain — the common case during an incident — declares its own starting point, which is an assertion the file makes about itself. Someone who can write the export can write a self-consistent one. So an unanchored bundle is reported as unanchored and refused unless you supply the anchor from a signed checkpoint or a chain head recorded beforehand.

The limit

Verification proves the bundle is internally consistent and unaltered relative to its anchor. It proves nothing about whether the control plane recorded the truth in the first place, and it cannot detect an event that was never written. Nor, on its own, can it detect events that were written and then cut off the end of the export: a bundle missing its tail verifies exactly like a whole one. Supplying the chain head from a signed checkpoint is what closes the end, and the verdict says which of the two you have. “The chain verified” is not “the evidence is complete”, and this page will not say otherwise. See what TrustRail does not do.