# Receipt Canonicalization (v1) This locks the bytes that `blake3` and `sha256` cover for every receipt envelope across vm-cloud, vaultmesh-mcp, command-center, and civilization-ledger. ## Canonical JSON - Start from the JSON object defined in `receipt_v1.schema.json` **excluding signature metadata** (`sig_alg`, `signer_pub`, `signature`, `signed_at`). - Remove any fields whose value is `undefined` (nulls are allowed and kept). - Recursively sort object keys lexicographically. - Arrays keep order; elements are canonicalized recursively. - Serialize with JSON `UTF-8` bytes, no trailing newline. (Equivalent to `JSON.stringify(canonicalize(obj))` in vm-cloud.) ## Hash inputs - `blake3` = `BLAKE3(canonical_json_bytes)` hex-encoded (lowercase). - `sha256` = `SHA-256(canonical_json_bytes)` hex-encoded (lowercase). - `hash_alg` MUST be the literal string `"blake3+sha256"` to prevent algorithm drift. ## Excluded from hash - `sig_alg`, `signer_pub`, `signature`, `signed_at` are **not** part of the hashed body. They are attached after hashing and do not change the receipt body digest. ## File naming & storage (non-binding but recommended) - Store receipts under `outputs/receipts/` (vm-cloud) or `receipts/mcp/` (vaultmesh-mcp) using timestamped filenames, e.g., `YYYYMMDD-HHMMSS-action-target.json`. - Maintain a `HEAD.json` (or similar) that tracks the latest `{ blake3, file, created_at }` to support chain continuity checks.