27 lines
1.4 KiB
Markdown
27 lines
1.4 KiB
Markdown
# 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.
|