open-standards/wai/jwp-conformance
Repository files (latest commit first)
Filename Latest commit message Latest commit date
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
..
.gitattributes wai: energy reports, labelled JWP leaves and what signatures cover 2026-10-01 06:37:25 -04:00
jwp_verify.py wai: energy reports, labelled JWP leaves and what signatures cover 2026-10-01 06:37:25 -04:00
README.md wai: energy reports, labelled JWP leaves and what signatures cover 2026-10-01 06:37:25 -04:00
vectors.json wai: energy reports, labelled JWP leaves and what signatures cover 2026-10-01 06:37:25 -04:00

jwp-conformance

Conformance for the labelled forms of the JWP delivery receipts (§2.2–§2.4.2, §3, §3.3 and §5.7) and for the WAI_RECEIPT property's readings (moq-streaming-format §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.