open-standards/wai/pin-conformance
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Transaction Science 7ca9e889b9 SPEC §3.1: pin by default; wai verify reports an unpinned envelope, and a decode's record names the set it read
An encoder SHOULD pin the parameter set a payload was coded against wherever a
capability that decodes it is registered as decoding against one, whatever the
intent (SPEC §3.1, Pin by default).
An envelope that pins nothing there still conforms in 1.x; a verifier reports it
(prior_unpinned), informatively: Wai::check_unpinned, WaiMulti::check_unpinned and
codecs::pin_by_default. wai verify now reads the envelopes under each path, refusing
one whose pin breaks SPEC §3.1 and noting prior_unpinned; wai inspect and wai wrap note
it too. pin-conformance/unpinned.json holds the vectors, reached by wai_pin_vectors and
by pin_verify.py, which reads the classes from the published registry export.

A reconstruct-session decoder entry's pin (jwp-receipts §2.4.12) now names the set an
unpinned decode read, by the digest a pin over those bytes names, with the tier none.
The reference sink's base decode gives it (staged::BaseDecode::set, from
IntParams::read_pin), and stage_measure's sessions carry it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-04 12:29:01 -05:00
..
listings wai: the parameter-set pin, component identity, pin-aware selection 2026-10-01 05:51:50 -04:00
sets wai: the parameter-set pin, component identity, pin-aware selection 2026-10-01 05:51:50 -04:00
.gitattributes wai: the parameter-set pin, component identity, pin-aware selection 2026-10-01 05:51:50 -04:00
cases.json wai: the parameter-set pin, component identity, pin-aware selection 2026-10-01 05:51:50 -04:00
pin_verify.py SPEC §3.1: pin by default; wai verify reports an unpinned envelope, and a decode's record names the set it read 2026-11-04 12:29:01 -05:00
README.md SPEC §3.1: pin by default; wai verify reports an unpinned envelope, and a decode's record names the set it read 2026-11-04 12:29:01 -05:00
selection.json wai: an encrypted envelope's clear parts checked; a record or derivation is no component 2026-10-08 01:24:50 -04:00
static.json wai: the parameter-set pin, component identity, pin-aware selection 2026-10-01 05:51:50 -04:00
unpinned.json SPEC §3.1: pin by default; wai verify reports an unpinned envelope, and a decode's record names the set it read 2026-11-04 12:29:01 -05:00

pin-conformance — the parameter-set pin

Vectors for the parameter-set pin (SPEC.md §3.1, §4, §7, §7.1).

Provenance. Generated here by wai_pin_vectors; the parameter-set files under sets/ are stand-in bytes written for the corpus. No media.

Reason-equivalence. A conforming verifier reports exactly the declared outcome for every case:

  • cases.json — given a pin, a capability, the forms the sink reads (default wai.prior.set) and the artifacts it holds, the outcome ok or the one reason SPEC §3.1 names: pin_malformed, form_not_registered, form_unreadable, form_required, prior_not_held, digest_superseded, set_malformed, part_mismatch. A held artifact is a file, or a listing together with the root its paths are read below. Paths are relative to this directory. The cases model a sink that holds no key log, so check 5 (prior_revoked, prior_not_authorised) does not run; it is covered by the parameter-set vectors of ../signer-conformance/ and the key_log library tests.
  • selection.json — given a WAI2 manifest, its payloads, the capabilities the sink advertises and the one-file parameter sets it holds, the rendition SPEC §7.1 picks and the reason for each entry it skips (not_selectable, missing_capability, component_digest_mismatch, or a pin reason); when nothing is picked, the reason for every entry. Where stated, also the companions applied with the pick, and the first component-role finding. Selection walks the entries in the table's order, a deployer policy SPEC §7.1 step 2 allows: the cases are about pins, and SPEC §4's default energy order would walk a classical entry before the learned ones that carry the pins, and reach no pin while it is advertised.
  • static.json — the first finding a verifier makes about a manifest's pins without holding a parameter set (prior_not_applicable, pin_malformed, tier_unregistered, supersedes_malformed, form_not_registered, form_required, tier_exceeds_class, a replicate_* reason), or ok. For a WAI2 manifest the finding is [entry index, reason].
  • unpinned.json — the report a verifier makes about a manifest that pins no parameter set where a capability it decodes through is registered as decoding against one (SPEC §3.1, Pin by default): prior_unpinned, or none. It is informative, and made whatever static.json finds. For a WAI2 manifest, the index of each entry it is made about.

Listings. Every listings/<name>.sha256 is, byte for byte, the listing of sets/<name>/: regular files, names that begin with . left out, sorted by path as bytes. A common checksum utility checks a set against its listing (cd sets/demo && sha256sum -c ../../listings/demo.sha256). Every file under listings/bad/ breaks one listing rule and is set_malformed.

Files are compared as bytes; .gitattributes turns off line-ending conversion.

Verifiers.

  • wai_pin_vectors verify pin-conformance (wai-rs) runs every file through the reference implementation's in-memory pin core (wai::pin::verify_bytes), its selection (WaiMulti::pick), its static checks (Wai::check_pin, WaiMulti::check_pins) and its report (Wai::check_unpinned, WaiMulti::check_unpinned). It runs in both corpus loops of the conformance workflow. wai_pin_vectors generate pin-conformance rewrites the listings from the sets.
  • pin_verify.py checks cases.json, unpinned.json and listings/ with the Python standard library alone, re-implementing the listing rules, the ordered checks and the report from the SPEC text, and reading which capabilities decode against a parameter set from the published registry export (../registry/capabilities.json). It shares no code with wai-rs.