open-standards/wai/extensions/provenance.md
Transaction Science ee44f1871c
Some checks failed
no-vanity-metrics / Scan committed Markdown for vanity metrics (pull_request) Successful in 3s
no-vanity-metrics / WAI public text names no comparison (pull_request) Successful in 4s
no-vanity-metrics / WAI public text names no company or product (pull_request) Successful in 3s
standards workspaces build + test / arl-rs (pull_request) Successful in 1m16s
standards workspaces build + test / eoc-rs (pull_request) Successful in 2m9s
standards workspaces build + test / jcp-rs (pull_request) Successful in 1m32s
standards workspaces build + test / joule-ui-rs (pull_request) Successful in 1m11s
standards workspaces build + test / joulehook-rs (pull_request) Successful in 1m13s
standards workspaces build + test / proof-rs (pull_request) Successful in 1m16s
standards workspaces build + test / sense-rs (pull_request) Successful in 1m13s
standards workspaces build + test / sandbox-rs (pull_request) Successful in 2m21s
standards workspaces build + test / smart-byte-rs (pull_request) Successful in 4m6s
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Successful in 17s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 7m25s
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Successful in 8s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 25s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 46s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 1m53s
wai-pack / wai-pack · does this change touch it (pull_request) Successful in 4s
WAI section references / cited sections exist (pull_request) Successful in 10s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 4m30s
wai-web reach builds / wai-web reach · does this change touch it (pull_request) Successful in 4s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 14m56s
workflow hygiene / every workflow supersedes its own queue (pull_request) Successful in 5s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 2m48s
wai-pack / wai-pack · linux (pull_request) Successful in 1m6s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 23s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 2m4s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m23s
wai-web reach builds / wai-web reach builds · the package of record, every output as recorded (pull_request) Successful in 2m44s
wai-web reach builds / wai-web reach builds · this tree's wai-web, every rung on its engine line (pull_request) Successful in 4m1s
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 4m36s
standards workspaces build + test / aac-rs (pull_request) Successful in 1m48s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 47s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 30s
standards workspaces build + test / map-rs (pull_request) Successful in 29s
standards workspaces build + test / mesh-rs (pull_request) Successful in 28s
standards workspaces build + test / openpay (pull_request) Successful in 1m30s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 5m46s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 24s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 1m54s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 1m6s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 2m52s
standards workspaces build + test / macOS energy backends (pull_request) Failing after 4m59s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 10m6s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 29s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 3m14s
wai-pack / wai-pack · macos (pull_request) Successful in 2m12s
wai-web reach: the provenance vector's signer id is a label
The reach receipt workloads verified a receipt copied from the site, written by
wai_prov before its signer id became a label: it named a domain under did:web,
which signer_ids_are_labels refuses (jwp-receipts §7.1, §7.8).

wai_prov gains --carry <receipt.json>: it measures nothing, carries each
step's figure and label from an earlier receipt for the same lineage, and signs
them with its published test seed (0x70 x 32) under its label
did:example:wai-prov. It refuses a receipt that does not verify or whose steps
are not this run's (operations, input and output hashes, work), and writes no
report. The vector is regenerated with it: the envelope is unchanged, the
figures are the ones wai_prov first measured for these bytes, and carrying the
receipt onto itself writes both files again byte for byte. The vector's README
states how it is made and the command.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-10 04:27:29 -04:00

5.2 KiB

WAI Extension: Asset Provenance

Status: Draft. Lever 4 — content-addressing + receipts + measured energy for content that cannot be reduced to instructions. WAI does not reconstruct the asset; it carries the opaque bytes and a signed, energy-accounted lineage. Conformance is content-hash-equivalence (recompute, compare) + signature validity. Reference impl: the provenance feature of wai-rs; tooling: wai_prov; live sink: wai.transaction.science/provenance. Keywords MUST, MUST NOT, SHOULD, MAY are RFC 2119/8174.

1. Scope and model

A wai.asset.provenance object is not a content capability — it is a JWP receipt profile about a carried asset, the way jwp-receipts is. The asset itself declares an ordinary capability (wai.image.jpeg, wai.audio.flac, …) and WAI carries it unchanged; the provenance receipt adds three things the carried bytes do not have on their own:

  1. Tamper-evidence — the asset is content-addressed (asset_content_hash, BLAKE3 over the complete WAI envelope); a verifier recomputes it and compares.
  2. Lineage — an ordered chain of processing steps, each binding its input and output content hashes, signed as one group.
  3. Energy accounting — each step carries its measured/declared microjoules; the receipt totals them.

This is the "verifies whatever it carries" half of the thesis, for the content the reconstruct half cannot touch. WAI never decodes the asset — a sink hands the bytes to whatever native element renders that media.

In scope: the step model, the AssetReceipt group, the verification obligations. Out of scope: a transport; a capture device; the asset's own codec (it is opaque here).

2. The step

A ProvStep is one transformation in the asset's lineage:

field meaning
op operation, e.g. "origin.synthesize", "encode.jpeg", "derive.thumbnail"
input_hash content hash of the input (all-zero for an originating step)
output_hash content hash of the output
work exact deterministic work (pixels, samples)
joules_micro measured/carried microjoules; 0 is the unmetered marker, never 0 J (energy-measurement §2)

Step content hash: BLAKE3("wai:prov-step\x01" || op_len | op | input | output | work | joules).

3. The receipt (AssetReceipt)

A JWP group: the asset's content hash is the identity, the per-step hashes are the Merkle leaves (JWP's exact moq-jwp:merkle-{leaf,node} domains), and one Ed25519 signature covers a profile payload carrying the asset hash, the declared media + capability, the Merkle root, the step chain, and the total joules. It chains across edits via parent_receipt_hash, like the worlds / audio / haptic / splat receipts.

4. Conformance

A conforming verifier MUST: (a) recompute the asset's content hash and require it equal the receipt's asset_hash; (b) require the step chain be linked — each step's input_hash equals the previous step's output_hash, and the final output_hash equals asset_hash; (c) recompute the Merkle root from the step hashes; (d) verify the Ed25519 signature as SPEC §7 Signatures requires. A failure at any point is a failure — the asset is reported unverified, never "probably fine".

There is no tolerance parameter: the content hash matches or it does not.

5. Energy is measured, never invented

joules_micro per step is carried from a meter, exactly as the other receipts carry it: wai_prov measures the real CPU energy of each encode (IOReport via macmon, no sudo) and signs the figure. An unmetered step carries the unmetered marker 0, which a reader presents as unmetered and never totals as zero joules. The receipt never derives energy it did not measure.

Each step's figure carries its acquisition class as an optional label (energy-measurement §2.8), because the steps of one lineage can be metered by different parties in different ways. A labelled step binds its class into its leaf hash; a step with no label keeps its legacy leaf and its figure is unlabelled. wai_prov labels each encode it measures OnChipCounter, with its declared uncertainty, and records an encode whose measurement fails the §4 ratio or the power reader's liveness (§3.1) as unmetered, and writes a measurement report for each step it measured (energy-measurement §6). With --carry it measures nothing: it carries each figure, and its label, from an earlier receipt for the same lineage, which must verify and whose steps must have the same operations, hashes and work, and writes no report. total_joules_micro carries no class of its own, and a total over steps that include an unmetered one covers only the measured steps (Partial).

Appendix

The reconstruct classes prove WAI can ship a world, a sound, a body, a volume as instructions and have every sink rebuild them identically. Provenance proves the complement: for the photograph that is just a photograph, WAI still adds something a bare file cannot — a tamper-evident identity, a signed lineage, and an honest energy ledger — without ever pretending to understand the pixels. Carries whatever it can reconstruct; verifies whatever it carries.