Skip to main content
A proof pack is the unit of audit. Every governed action — a delivery event, a rights state transition, a policy change, a metering projection, a settlement reconciliation — eventually appears, signed, in a proof pack.

Shape

A proof pack is a SignedProofPack envelope (envelope.v1) carrying an ordered array of signed, hash-chained records. Each record holds the proof receipt payload, the per-record Ed25519 signature over its payloadCanonical, and the chain anchors beforeHash / afterHash.
A pack may also carry optional metering and settlement summaries the auditor reconciles against the records.

Canonical-JSON serialisation

Each record’s signature is computed over the canonical-encoded payloadCanonical string for that record’s payload (the auditor re-derives payloadCanonical from the wire payload and asserts byte-equality). Canonical means:
  • Object keys sorted lexicographically.
  • No whitespace between tokens.
  • Integers serialised without trailing .0.
  • Floats serialised in their shortest round-trip form.
  • Strings serialised with the minimum-escape set per RFC 8785.
The auditor library reproduces this serialisation deterministically across TypeScript, Python, and Rust.

Chain semantics

Each record carries beforeHash (the previous record’s afterHash) and afterHash (the SHA-256 of its own payloadCanonical). The genesis record has beforeHash: null. The auditor walks the records in issuance order and asserts three invariants: genesis-null, link continuity (records[i].beforeHash === records[i-1].afterHash), and non-decreasing payload.issuedAt. When verifying a later pack in a tenant’s chain, pass the previous pack’s tail afterHash so cross-pack continuity is checked rather than falsely rejected. A break is reported with a stable reason code (CHAIN_LINK_MISMATCH, GENESIS_BEFORE_HASH_NOT_NULL, or CHAIN_OUT_OF_ORDER).

Envelope versioning

envelopeVersion identifies the proof-pack envelope (envelope.v1). The auditor refuses to verify a pack whose envelope version it doesn’t recognise (UNSUPPORTED_ENVELOPE_VERSION). The record-level payload.version ("1") identifies the receipt payload schema.

Records

The records array is ordered by issuance within the pack. Each record is independently signed (its own per-record Ed25519 signature over payloadCanonical), so a single record remains independently verifiable when extracted from a pack for a regulator request.

Where to find a sample

The conformance fixture set under packages/sdks/auditor-ts/__tests__/fixtures/ in the open-source auditor repo includes worked examples — valid packs, intentionally-broken packs, chain-break scenarios — used as fixtures by all three language ports (sdk-auditor-ts, sdk-auditor-py, sdk-auditor-rs). The sample above is the valid-proof-pack.json fixture (signature, payloadCanonical, and afterHash shown as placeholders).