open-standards/wai/extensions/transparency.md
Transaction Science 5ee4c7e28b
Some checks failed
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 1m39s
standards workspaces build + test / aac-rs (pull_request) Successful in 32s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 1m8s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 37s
standards workspaces build + test / map-rs (pull_request) Successful in 40s
standards workspaces build + test / mesh-rs (pull_request) Successful in 35s
standards workspaces build + test / openpay (pull_request) Successful in 2m53s
wai cross-architecture byte-equality / linux-aarch64 (pull_request) Successful in 24s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Failing after 42s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 26s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 50s
no-vanity-metrics / Scan committed Markdown for vanity metrics (pull_request) Successful in 3s
standards workspaces build + test / eoc-rs (pull_request) Successful in 1m48s
standards workspaces build + test / jcp-rs (pull_request) Successful in 1m17s
standards workspaces build + test / proof-rs (pull_request) Successful in 1m12s
standards workspaces build + test / sandbox-rs (pull_request) Successful in 2m6s
standards workspaces build + test / arl-rs (pull_request) Successful in 1m48s
standards workspaces build + test / smart-byte-rs (pull_request) Successful in 2m34s
wai cross-architecture byte-equality / linux-x86_64 (pull_request) Successful in 22s
standards workspaces build + test / joule-ui-rs (pull_request) Successful in 2m0s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 2m20s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 26s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 1m58s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 44s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 44s
standards workspaces build + test / joulehook-rs (pull_request) Successful in 2m5s
standards workspaces build + test / sense-rs (pull_request) Successful in 1m53s
wai formal verification (integer core) / kani (pull_request) Successful in 4m4s
standards workspaces build + test / macOS energy backend (jcp-energy) (pull_request) Successful in 1m50s
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Successful in 54s
wai cross-architecture byte-equality / macos-arm64 (reference) (pull_request) Successful in 22s
WAI neural decoders end-to-end / synthetic fixtures → Rust decode → reference (±4) (pull_request) Failing after 1m11s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 26s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 2m29s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 22s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 58s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 2m35s
wai cross-architecture byte-equality / windows-x86_64 (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · windows (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · windows (pull_request) Has been cancelled
wai: typed receipt classes and the soft binding class, reading OER through the OER module
A JWP receipt says what was delivered, by whom and at what energy cost, and
binds to its object one way. Other statements about the same objects had
nowhere to go, and energy-measurement §2 requires an acquisition class beside
every non-zero figure, which the object receipt has no member for.
jwp-receipts §2.4.3-§2.4.7 adds a `claim` kind with one envelope, one
canonical form (RFC 8785) and one signature rule for the classes energy,
lawful-basis and log-inclusion. §2.6 and §3.2 add a second, deliberately
weaker binding class: a publisher-signed soft binding with a resolution
endpoint, under the ancestor rule. §3.1 step 3 fixes a strict Ed25519 rule. A
declaration that a decision or a recovery record is checked against is
verified before anything is compared with it (`context_invalid`).

OER as settled on main is authoritative: this adds no second OER reader and
changes no OER rule, vector, verifier or document. An OER receipt an energy
claim names is read by oer::load under the document profile, verified by
oer::verify_receipt, and its figure read by the exact quantity reader the
composition checks use, through a new crate-private oer::rounds_to_micro.
claim_verify.py does the same with the OER reference's load, verify_receipt
and dec. The claim envelope keeps its own step-1 reader (claim_text.rs),
which reads claims only.

- Acquisition classes are the refined ones. The energy body carries the class
  as energy-measurement §2.7 writes it in JSON (energy_provenance,
  energy_uncertainty, energy_counter_filtering, energy_calibration_ref),
  present and null where a class has none, so a claim keeps one canonical
  form. Legacy HwShunt is refused, since no claim predates the refinement
  (energy_legacy_acquisition); missing, misplaced or sub-floor evidence is
  energy_acquisition_evidence. The grade correspondence is oer-receipts §2's,
  an exhaustive match over all five variants.
- §3.1 step 2's member tables give exactly the type step 2 checks, and step 2
  lists what the class rules add to a type as step 4's, never field_type. Both
  verifiers read a declaration in its table's order (they had read purposes
  before vocabulary and fragment, and every encoding after every member, so a
  declaration with two defects gave another reason than the text).
- oer::py_float_repr writes a double at a tie between two shortest decimals as
  CPython's repr does (round half to even at the shortest length). No content
  address or verdict depended on it: main's number profile keeps floats out of
  every receipt body. It changed the printed name of a vector named by such a
  number, which both OER verifiers print and the OER fuzzer compares. Fourteen
  doubles CPython 3.14.7 wrote are pinned.
- claim-conformance/: 154 vectors covering all 40 reasons, the canonical
  fixture recomputed by claim_verify.py and pinned, a second verifier
  (claim_verify.py) that shares no code with wai-rs, and differential.py,
  which runs both on inputs the corpus does not hold. receipt_claims joins the
  conformance library tests and both corpus loops.

Checked on this machine (macOS arm64) on the stream's tree:
- library tests with receipt_claims (dev; oer + receipt_claims also release);
- wai_claim_vectors and wai_oer_vectors verify their corpora;
- claim_verify.py reports every vector's declared outcome;
- differential.py: its default families and 20,000 random inputs (seed 7):
  no verdict differs and nothing crashes;
- oer2_verify.py passes every OER vector file and refuses every unreadable
  document, the C kernel's output equals firmware_vectors.json, and
  fuzz_differential.py (seed 1, 20,000 documents) finds no divergence.
And on this commit's tree, the per-link gate: build, library tests,
carriage, every corpus in the conformance loop, byte-exact, wasm32.

Not run here: the Linux and Windows legs (CI runs Linux; the Windows runner
is offline). The Python scripts are run by hand, not in CI.
Not done: key discovery (every claim signature presumes the verifier holds
the key), an authority class for who may sign which class, region- or
time-scoped soft bindings, and checking a log's receipt under its profile.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 01:42:45 -04:00

5.5 KiB

WAI Extension: Transparency Emission

Status: Draft. Adds an external encoding for WAI receipts so a party with no WAI tooling can check them, and a registration profile so a receipt's existence is independently witnessed. Strictly additive: the JWP receipt chain is unchanged, and nothing here replaces it. Keywords MUST, MUST NOT, SHOULD, MAY are RFC 2119/8174.

1. What is actually missing

Not verifiability. An Ed25519 signature over a group Merkle root is checkable by anyone holding the publisher key, and jwp-receipts §3 specifies exactly how. Three properties are missing, and none of them is a signature property:

  • Non-equivocation. Nothing prevents a publisher showing one receipt chain to one party and a different chain to another. Both verify.
  • Independent timestamping. A receipt says when the publisher says it was made.
  • Detectability of suppression. A receipt that was never shown to anyone leaves no trace of its absence.

These are log properties, not envelope properties, and they are why this extension exists.

2. The move, and its shape

The family already owns both halves: a transparency log with consistency proofs exists, and JCR-1 (deterministic CBOR + COSE_Sign1, RFC 9052) is already the canonical receipt envelope across sibling standards. What nothing in the family has is a standardised external encoding that an outside auditor's off-the-shelf tooling can verify with no bespoke verifier.

So the sequence is: bring WAI's receipts onto JCR-1 as its siblings already are, then emit in the standardised encodings on top.

  • A WAI receipt SHOULD be expressible as a JCR-1 envelope. This is alignment with the family, not a new format.
  • An implementation MAY additionally emit an RFC 9942 (COSE Receipts) encoding of a group receipt, and MAY use the RFC 9995 COSE Hash Envelope form where the payload is carried by hash rather than by value.
  • These emissions are additional encodings of the same facts. An implementation MUST NOT let the JWP chain and an emitted encoding disagree, and where they do, the JWP chain is authoritative and the emission is in error.

3. What is registered, and what is not

SCITT registers per-artifact Signed Statements over an HTTP API. WAI emits per-object receipts at media-group cadence. These cadences do not match, and forcing them together would put a registration round-trip in the per-object path.

  • An implementation MUST NOT register per-object receipts individually.
  • An implementation SHOULD register the group receipt, or periodic checkpoints over the receipt chain, leaving the per-object receipt exactly where it is.
  • Registration MUST NOT be a precondition for a receipt being valid. An unregistered receipt is a receipt whose existence is unwitnessed, not a receipt that is wrong.
  • A registration MAY be recorded on the receipt chain as a log-inclusion claim (jwp-receipts §2.4.7): its subject is the registered receipt's link hash, and its body carries the Transparency Service's receipt verbatim with the profile it was registered against. Accepting that claim is not verifying the inclusion (§6).

The checking party is the Relying Party in the terminology of the SCITT architecture; this extension uses that term rather than coining another.

4. The hash-algorithm constraint

RFC 9995's payload_hash_alg takes an identifier from the COSE Algorithms registry. BLAKE3 — which jwp-receipts §2.1 uses throughout — does not appear in that registry.

This is a real constraint, not a detail to be waved through:

  • An implementation MUST NOT emit a COSE Hash Envelope naming BLAKE3 by an unregistered or invented identifier. An identifier a Relying Party cannot resolve defeats the entire purpose of emitting in a standard encoding.
  • Until a registration exists, an implementation MUST either omit the hash envelope form, or carry a second digest under a registered algorithm alongside the BLAKE3 commitment, stating plainly that the two cover the same bytes.
  • A dual-hash carry MUST NOT be presented as evidence that BLAKE3 is registered.

Registering BLAKE3 in the COSE Algorithms registry is a separate action with its own process, and this extension does not assume its outcome.

5. Stage discipline

The referenced work is at mixed maturity, and an implementation MUST NOT present any of it as more settled than it is:

document status
SCITT architecture (RFC 9943) Standards Track, published
COSE Receipts (RFC 9942) Standards Track, published
COSE Hash Envelope (RFC 9995) published
SCRAPI (registration/resolution API) approved, in the RFC Editor queue
a concrete log profile Working Group Last Call — not ratified

An implementation MUST NOT describe the log profile as ratified, and SHOULD state which profile it registered against, since a Relying Party cannot check a proof without knowing the log's rules.

6. What this does not do

  • It does not replace the JWP receipt chain, and it does not move the per-object commitment anywhere.
  • It does not make registration a trust anchor. A Transparency Service witnesses that a receipt existed at a time; it does not attest that the receipt is true, and an implementation MUST NOT report registration as verification.
  • It does not solve key discovery. That is jwp-receipts §7, and a log entry naming a key the Relying Party cannot resolve is still unresolvable.