open-standards/wai/jwp-conformance/README.md
Transaction Science cc371d815a wai: energy reports, labelled JWP leaves and what signatures cover
Two claim classes report on one energy figure without changing the
receipt that seals it. `measurement` carries a bracket's values as
integers with each bracket's liveness facts, the build and the power
reader, and is accepted only against the receipt that carries its
figure. `operating-point` records the requested, committed and
delivered operating points and a prediction. The ratio, verdict and
residual are derived by every reader, never stated.

energy-measurement §6.2 gives the figure and the least declaration a
report's integers support as exact integer formulas; wai-rs
`energy_report` implements them with no floating-point arithmetic.
§3.1 defines a live power reader: a rail must advance in two
consecutive intervals, in at least five and in at least four of every
five, over at least 300 ms. A frozen or held rail is refused rather than
sealed under a hardware class. An unmetered `0` is never a figure of
zero joules.

A JWP object's figure, class and origin are bound into its Merkle leaf
(`\x02`), and a labelled group payload signs the total's class, its
coverage and the parent link. An object must sit at the position its
inclusion proof walks, and group signatures follow the strict Ed25519
rule claims use. `jwp_delivery` and `energy_figure` implement this in
wai-rs; joule-moq 0.2.0 builds and verifies both labelled forms.

New corpus `jwp-conformance/` with `jwp_verify.py`, more claim vectors
with the earlier ones pinned, and a CI job that runs claim_verify.py,
differential.py and jwp_verify.py. Legacy receipts keep their bytes.
External JWP implementations must adopt the `\x02` leaf and the
labelled group payload before verifying objects or groups that use
them.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-01 06:37:25 -04:00

64 lines
4.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# jwp-conformance
Conformance for the labelled forms of the [JWP delivery receipts](../extensions/jwp-receipts.md)
(§2.2–§2.4.2, §3, §3.3 and §5.7) and for the `WAI_RECEIPT` property's readings
([moq-streaming-format](../extensions/moq-streaming-format.md) §5): an object's figure,
class and origin bound into its Merkle leaf; a group total's class signed under the
labelled group payload; the position an object's inclusion proof must walk; the group
total read from its objects; and a property read as signed only where a signed statement
restates it.
## Files
| file | what it is |
|---|---|
| `vectors.json` | The corpus, generated by `wai_jwp_vectors gen` in `wai-rs` (feature `receipt_claims`). `wai_jwp_vectors verify` requires a byte-identical regeneration and every declared outcome. |
| `jwp_verify.py` | A second verifier, written from the extension text, that shares no code with `wai-rs`. It takes BLAKE3, jwp-receipts §3.1 step 3's Ed25519 rule and the claim verifier from `../claim-conformance/claim_verify.py`, itself independent of `wai-rs`. |
## Procedures
Each vector names one procedure and declares one outcome.
| procedure | input | outcome |
|---|---|---|
| `leaf` | an object receipt | its leaf, in the form its label gives (§2.2) |
| `group` | a group receipt, and optionally the previous one held | `accept` with its link hash and signing payload (§2.3, §3 step 3), or a rejection at a §3 step |
| `object` | a group receipt, an object receipt and the envelope delivered | `accept` (§3 steps 1–5), or a rejection at a §3 step |
| `total` | a group receipt and the objects delivered with their envelopes | the total's reading — `unmetered`, `unlabelled`, `weakest` (a legacy group whose every non-zero part is labelled: a class name only), or `signed` (a labelled group's own class, `checked` against every object or `unchecked`) — or a rejection |
| `property` | a `WAI_RECEIPT` property, with the object, its group and its envelope, or with an `energy` claim | the property's reading — `unmetered`, `unsigned`, or `signed` with the class and the key that signed it (the group's for a leaf, the claim's for a claim) — or a rejection |
A rejection names its reason (§3.3), and its §3 step where it has one; the group total
and a property are not steps of §3.
## What the corpus holds
Leaves in both forms, the labelled one with tags 0, 2, 4 and 5. A group in the legacy
payload whose objects mix the forms, and a group in the labelled payload chained to it,
with their signing payloads, signatures and link hashes. Every way a label, a figure or
an origin can be restated, stripped or added, and which of them the legacy leaf leaves
unbound. Labels that break their rules in correctly built trees. Objects presented at
another object's position — including the duplicated last leaf of an odd level, and a
duplicate that would hide a weaker class from the total. Group labels that break their
rules, correctly signed; a `sign_version` other than 2; and group signatures the strict
Ed25519 rule refuses (`S` ≥ L, a key of small order, a key whose `y` is not reduced). Totals read from complete and incomplete holdings, a total that
does not match its parts, and labelled totals whose class, coverage, declared uncertainty
or window disagree with what their parts compose to. Properties that agree with, and
disagree with, a labelled leaf or an `energy` claim, including a claim signed by a key
other than the publisher's, which reads as signed by that key.
## Synthetic, and what it attests
Keys are Ed25519 from fixed 32-byte seeds — 0x11 the publisher, 0x22 the meter, 0x33 a
relay — and attest nothing. Envelopes, figures, origins and calibration references are invented, and
calibration references use a reserved example domain.
## Running
cargo run --no-default-features --features receipt_claims --bin wai_jwp_vectors -- verify ../jwp-conformance
python3 jwp_verify.py vectors.json
Both run in CI: the Rust verifier on every platform of the conformance matrix, the Python
one on the linux runner (`.github/workflows/wai-conformance.yml`). The Python verifier
needs the `cryptography` package. joule-code's `joule-moq` pins leaves, roots and
signatures from this corpus in its own tests, and its workflow re-runs when the corpus
changes.