Shape
A proof pack is aSignedProofPack 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.
metering and settlement summaries the
auditor reconciles against the records.
Canonical-JSON serialisation
Each record’ssignature 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.
Chain semantics
Each record carriesbeforeHash (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 overpayloadCanonical), 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 underpackages/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).