> ## Documentation Index
> Fetch the complete documentation index at: https://docs.enfinitos.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Proof chain

> How EnfinitOS signs and hash-chains every delivery, activity, and operating action — and how the open-source auditor walks the chain offline.

Every governed action in EnfinitOS produces a **proof event**. Proof
events are grouped into **proof packs** — signed, hash-chained
documents that anyone with the published verification key can
verify without contacting EnfinitOS.

## 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`, a per-record Ed25519 `signature` over its
`payloadCanonical`, and the chain anchors `beforeHash` / `afterHash`:

```json theme={null}
{
  "envelopeVersion": "envelope.v1",
  "issuedAt": "2026-04-01T12:00:00.000Z",
  "orgId": "org_test",
  "packId": "pack_001",
  "records": [
    {
      "payload": { "version": "1", "receiptId": "rec_001", "...": "..." },
      "keyId": "fixture_key_v1",
      "algorithm": "ed25519",
      "signature": "<base64url 64-byte Ed25519 signature>",
      "payloadCanonical": "<canonical-encoded payload string>",
      "beforeHash": null,
      "afterHash": "<sha256 hex of payloadCanonical>"
    }
  ]
}
```

A pack may also carry optional `metering` and `settlement` summaries the
auditor reconciles against the records. See
[the proof-pack format reference](/compliance/proof-pack-format) for the
full field listing.

## Canonical-JSON serialisation

Each record's `signature` is computed over the **canonical-encoded**
`payloadCanonical` string for that record's `payload`. Canonical means:
sorted keys, no whitespace, deterministic number formatting. The auditor
library re-derives `payloadCanonical` from the wire `payload` and asserts
byte-equality before checking the signature.

## Hash chain

Each record carries `beforeHash` (the previous record's `afterHash`) and
`afterHash` (the SHA-256 hex of its own `payloadCanonical`). The genesis
record has `beforeHash: null`; when verifying a later pack in a tenant's
chain you anchor it with the previous pack's tail `afterHash`.

A missing or tampered record breaks the chain at the next record's
`beforeHash`. The auditor walks the records in issuance order and
reports the first break with a stable reason code.

## What the auditor does, in code-level detail

1. **Parse** the pack into the `SignedProofPack` envelope and its records.
2. **Re-derive** each record's `payloadCanonical` from its `payload` and
   assert byte-equality.
3. **Check** each record's `afterHash` equals the SHA-256 of its
   `payloadCanonical`.
4. **Verify** each record's Ed25519 `signature` against the key
   identified by its `keyId`.
5. **Walk** the chain: `records[i].beforeHash === records[i-1].afterHash`,
   genesis-null, and non-decreasing `payload.issuedAt`.
6. **Re-project** metering and **re-run** settlement reconciliation
   (when the pack carries those summaries) and assert bit-equality.

If any step fails, verification fails. No partial-credit verdicts.

See [the auditor SDK page](/sdks/auditor) for the open-source
implementation.
