wai: staged measurement and the session claim in the browser; a session bound to the envelopes it names (W5-4) #187

Merged
dcharlot merged 25 commits from wai/w5-4-measure-web into main 2026-10-08 09:58:09 -04:00

2026-10-08

Transaction Science
ci: wai-web's native test count is 24, with the WAI2 classical-length test
Some checks failed
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 6m34s
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Successful in 13s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 12m7s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 1m2s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 13m5s
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 26s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 45s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 3m24s
wai-pack / wai-pack · linux-arm64 (pull_request) Failing after 36s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 1m40s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 47m29s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 10m1s
wai cross-architecture byte-equality / macos-arm64 (reference) (pull_request) Successful in 3m19s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 19m50s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 35s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 3m37s
wai-pack / wai-pack · macos (pull_request) Failing after 6s
WAI HTTP delivery / HTTP corpus · falsification and differential (pull_request) Successful in 1h19m12s
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Successful in 1m4s
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Successful in 1m0s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 1m6s
wai-pack / wai-pack · linux (pull_request) Failing after 13s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Failing after 52s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 25s
wai-pack / wai-pack · dependency licences (pull_request) Failing after 1m7s
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 4m17s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 2m44s
workflow hygiene / every workflow supersedes its own queue (pull_request) Successful in 4s
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 07:42:21 -04:00
Transaction Science
wai: state the ranged-WAI2 classical length as a limitation of this revision
Some checks failed
standards workspaces build + test / sense-rs (pull_request) Successful in 1m6s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 8m7s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 35s
standards workspaces build + test / smart-byte-rs (pull_request) Successful in 3m39s
wai cross-architecture byte-equality / linux-x86_64 (pull_request) Successful in 27s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 2m41s
wai-pack / wai-pack · linux-arm64 (pull_request) Failing after 59s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 6m36s
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Successful in 13s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 12m59s
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 24s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 45s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 1m40s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 31m50s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 2m3s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 10m46s
wai-pack / wai-pack · macos (pull_request) Failing after 16s
WAI HTTP delivery / HTTP corpus · falsification and differential (pull_request) Successful in 1h19m18s
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Successful in 1m4s
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Successful in 1m5s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 1m10s
wai-pack / wai-pack · linux (pull_request) Failing after 15s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Failing after 55s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 20s
wai-pack / wai-pack · dependency licences (pull_request) Failing after 1m8s
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 4m22s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Failing after 2m24s
workflow hygiene / every workflow supersedes its own queue (pull_request) Successful in 3s
jwp-receipts §2.4.12 (classical_declared and rule 9), the CHANGELOG and the
claim-conformance README (the envelopes context and the sweep table's SPEC §6.4 row,
the one that cites rule 9): this revision derives the classical length from the WAI2
envelopes held in full; a sink that received a WAI2 only as byte ranges holds its head,
not the envelope, and cannot yet state its classical rendition. Recording such a
session is HTTP session work still to come.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 05:23:56 -04:00
Transaction Science
wai: HTTP reports a refinement by its refines.base alone; a conforming envelope's refinement tested
- §7 step 4 as the text stands: a refinement of the pick is one whose refines.base, read
  on its own, is the pick's id (container::refinements_naming, refinements_naming in
  http_verify.py), so one whose refines is otherwise malformed is reported dropped
  (components_nonconforming). Of a conforming envelope the set is the same as before.
- Objects OCF (ONC's conforming twin: refinements [2], dropped []), ONM (refines
  {base: b} alone: reported) and ONX (refines {base: x}: not reported), on the whole and
  the range paths; fetch_OR_malformed_refines now reports its refinement; the generator
  checks each outcome.
- falsify: conforming-withheld and refines-read-whole, each with an http_verify.py
  --mutate, wired into falsify/run.sh; nonconforming-offered's must-fail list extended.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 03:11:46 -04:00
Transaction Science
wai: the recorder derives the classical length; a malformed sha256 refused behind encryption
- SessionRecorder states classical_declared from the WAI2 envelopes it holds, readable or
  encrypted, as rule 9 counts them (claim_receipt::session::classical_length, which rule 9
  now calls); SessionRecorder::classical is removed. A page that receives a WAI2 it does
  not decode seals its session. counting/ gains wai2-classical.wai and its encrypted twin;
  verify_measure seals a session over each in wasm32 and checks the length against the
  table, and the native and Python verifiers agree.
- Rule 4: of an encrypted envelope, a rendition's sha256 is still required absent or well
  formed (RenditionMeta::digest_well_formed, digest_well_formed in Python): a malformed one
  matches no payload. jwp-receipts rule 3 narrowed to whether a payload matches a
  well-formed sha256. Twelve vectors, by rendition and by exploded hash; the differential's
  encrypted family mutates the named rendition's sha256.
- Stale docs: rule 3 and rule 9 in session.rs, the Python docstring, the received doc, the
  corpus comments.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 03:02:27 -04:00
Transaction Science
wai: the HTTP plan follows SPEC §7.1's offer rule
http-delivery §7 step 4: an envelope offers its refinements only when every
component conforms, which the verified head's manifest decides. Where one does
not, each refinement component of the picked entry is dropped
(components_nonconforming) and never requested, one stating no sha256 dropped
for that too (step 5); the base's path does not change. §10.3 and §13 say so,
and the status block no longer states a limitation.

http_binding: plan.rs gains WhyWhole::ComponentsNonconforming; session.rs gates
the range path and the whole-object path alike, so the dropped report stays
complete on both: digest-absent drops first, then the nonconforming ones.
http_verify.py does the same with staged_verify.component_roles, which now holds
the Python port of check_component_roles that claim_verify.py and http_verify.py
both read (registry-based; wai-http.yml's paths add the registry).

Corpus: object ONC (a base, a companion bound to nothing, a refinement with its
sha256) and fetch_ONC_whole / fetch_ONC_ranged; fetch_ORN_* now report the
refinement dropped for both reasons. Falsify: nonconforming-offered.patch and
http_verify.py --mutate nonconforming-offered; whole-applies-no-digest.patch
re-targeted at the moved digest-absent drop.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 01:38:05 -04:00
Transaction Science
wai: stage explode gates on capability; the §4.1 sentence scoped; the caller-offers case named
- wai stage explode refuses a component of a nonconforming WAI2 that is of a
  refinement-only capability or marked a refinement, not only one marked a
  refinement: a role-less wai.video.int_refine component, with refines or
  without, no longer explodes into a layer stage apply would route as one.
  tests/cli_stage.rs: explode_gives_no_layer_of_a_nonconforming_envelope, over
  refinement_before_selectable.wai, refinement_only_as_component.wai and
  ok_explode.wai with its refinement's role taken away; bases and conforming
  layers still explode.
- staged-delivery §4.1: an envelope whose capability is not refinement-only
  reaches step 1 only through a caller's offer, and step 1 refuses it as it
  refuses a refinement-only envelope with a fallback.
- staged-conformance: capability_not_refinement's about and the README say the
  case tests the caller-offers path.
- codecs::is_companion_only's comment no longer calls every other registered
  capability standalone media.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 01:27:23 -04:00
Transaction Science
wai: an encrypted envelope's clear parts checked; a record or derivation is no component
§2.4.12, against the envelopes:
- An encrypted envelope (SPEC §6.4) is held: its manifest and rendition table
  are in the clear, so rules 4-9 read them as any held envelope's — the
  rendition an entry names, its capability, the component rules, a base's
  layer count, a companion-only capability, a fallback, a layer's refines and
  span — and leave to the signer only what needs a payload: its digests, a
  base's units and a layer's WIR1 payload. Rule 9 reads the classical length
  every well-formed WAI2's table declares, encrypted or not.
  Vectors: the review's three probes (rendition 9 of two, a relabelled
  rendition, the WAI2 named with no rendition), a base at two layers, a
  companion-only capability, a nonconforming refinement, an encrypted layer
  over an encrypted base (accepted). Re-derived, outside the pinned prefix:
  session_envelope_encrypted (390) now accepts; the classical-null case is
  session_envelope_encrypted_classical_unstated (389); session_envelope_inert_
  unnamed_accept (397) states the classical length the encrypted table adds.
- §2.4.12's signer's statements name whether a refinement's exploded envelope
  held as its own bytes was received on its own.

SPEC §7.1: a component whose capability is a record or a derivation does not
conform, in any role (record-or-derivation-as-component), in check_component_
roles and claim_verify.py; pin-conformance/selection.json gains a record and a
derivation rendition, and its two companion cases take the new finding.
session_roles_record_rendition pins it in the claim corpus. 555 vectors.

staged-measurement's countability is cited by its heading (§3), so the
section-refs check passes. differential.py adds an encrypted-envelope family.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 01:24:50 -04:00
Transaction Science
wai: a record or a derivation is no companion; the HTTP plan's limitation stated
SPEC §7.1 companion rule 1 now says it outright: a capability registered in a
kind other than companion — a payload, a record or a derivation (§5, Kinds of
registered string) — is not a companion. The reference read rule 1 from
codecs::is_known_capability, which leaves records and derivations out, so it
admitted them as if unregistered; check_component_roles now reads the registry
(capability_kind) and refuses them as standalone-as-companion. claim_verify.py
reads the registry the same way.

Vectors: session_roles_record_companion and session_roles_derivation_companion
(rule 5's whole-envelope check; 547 vectors), and pin-conformance/selection.json's
record_as_companion and derivation_as_companion (check_component_roles alone).

http-delivery's status block and the CHANGELOG state the limitation of this
revision: the HTTP binding's plan does not yet withhold refinements of a
nonconforming envelope.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 00:45:55 -04:00
Transaction Science
wai: the HTTP fetch plan keeps its own drop reporting; the CLI replay knows the tool routes by capability
Reverts the HTTP binding's gate from the previous commit: http-delivery's fetch
plan reports a refinement with no digest among the components it drops, and the
whole-envelope gate hid it (http-conformance's fetch_ORN cases). Bringing the
HTTP plan under SPEC §7.1's offer rule needs http-delivery's text, http_verify.py
and its corpus together; it is left as an open item.

tests/cli_stage.rs: the corpus case capability_not_refinement offers an envelope
of a capability that is not refinement-only to §4 directly; the tool routes it
as a base by its capability, and the test checks that it does.
staged-delivery §4.1 says where such an envelope reaches step 1.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 00:24:32 -04:00
Transaction Science
wai: one verdict for either name, layers by capability, a key holder's session, §7.1's offer rule
§2.4.12, against the envelopes:
- An entry naming a held WAI2 rendition by its exploded envelope's content hash,
  with no rendition, is read as naming the rendition by rules 4-8 (it skipped
  them before); the exploded envelope's own bytes, held, are a separate
  delivery, read as the WAI1 they are.
- A manifest or rendition is a layer only when its capability is
  refinement-only; any other is a base and a refines it carries is ignored, as
  dispatch, selection and staged::decode_base already treat it. wai stage apply
  routes by capability. The stray-refines bases X1-X3 now accept.
- An encrypted envelope an entry names is admitted by rule 3: a sink holding
  its key decrypts and dispatches it (SPEC §6.4 step 3), so what the entry
  states of it is the signer's statement. session_envelope_encrypted (index
  390, outside the pinned prefix) now rejects only for the classical length the
  verifier cannot read; session_envelope_encrypted_named_accept accepts.
- Rule 5 offers a WAI2 refinement only from an envelope every component of
  which conforms, as SPEC §7.1 now states the reference sink's rule:
  check_component_roles moves to ManifestV2, the HTTP session applies an
  envelope's refinements only when it passes, and wai stage explode refuses a
  refinement of an envelope that does not. claim_verify.py ports the whole
  check; a differential sweep over every registered capability as a companion
  confirms the two agree.

Vectors for Y1, Y2, Y5, Y7 (entries by exploded hash), X1-X3 (accepted), X4
exploded and X4b delivered alone, F1, F2, G1, two companion-and-refinement
accepts, and S1/S2 (a span past the base with the payload's count right).
545 vectors; the pinned prefix unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 00:18:54 -04:00

2026-10-07

Transaction Science
wai: a vector for base admission where no entry names the base
The round-5 falsification found no vector that reached the held base's own
admission alone: with an entry naming the base, the applied-over check refuses
first. session_layer_base_not_admitted_unnamed does.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-07 23:30:23 -04:00
Transaction Science
wai: one base in either form, units in the payload's magic, every sink refusal accounted for
§2.4.12, against the envelopes:
- A WAI2 rendition and its exploded envelope are one base (staged-delivery §9):
  rules 5, 6 and 8 read a layer's base, and the entries naming it, in either
  form, so a WAI1 layer over a component, or a refinement component whose base
  an entry names as its exploded envelope, is tied to the base's first unit
  and its units.
- A WAI1 base's units are read in the format whose magic the payload starts
  with, of its capability's and its fallback's pinned formats.
- Rule 5 (now session_layer_not_applicable) holds every refusal of
  staged-delivery §4.1 steps 1-4 and 6 and SPEC §7.1's refinement conformance:
  capability-not-refinement, refines malformed or absent, a nonconforming
  refinement component, a base that is not a base or a selectable rendition, a
  base the layer does not admit, a base decoded only through its fallback, a
  span or runs outside a held base, and a payload that is not WIR1 with a unit
  for each unit covered. Rule 6 ties a layer only to the entries it is applied
  over.
- Rule 4 refuses an entry naming a WAI2 companion, a rendition or refinement
  whose payload does not match its sha256, a capability that is not
  dispatchable, or the fallback of a WAI1 whose capability is companion-only.
- §2.4.12 names each refusal it leaves to the signer's statement.

The claim-conformance README's table lists every sink refusal that decides
whether a presentation can happen, each with its rule and vectors or the
sentence that leaves it to the signer. New vectors from the review's probes
(A1-A4, B1-B2, H0, H2, H4, H5, R0/R1) and for every row the table closes;
525 vectors, the pinned prefix unchanged. claim_verify.py agrees on every
vector and probe; differential.py adds bases named by exploded envelopes,
fallbacks of another format, admission, digests and refinement conformance.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-07 23:26:55 -04:00
Transaction Science
wai: a vector for a WAI2 refinement component whose base is another refinement
The round-4 falsification of the WAI2 base-is-a-base rule found no vector that
reached it; session_wai2_refines_base_is_a_refinement does. 497 vectors.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-07 22:37:19 -04:00
Transaction Science
ci: wai-web-wasm runs when int-payload-conformance changes
verify_measure.sh's checks import int_payload_verify (through claim_verify.py).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-07 22:34:55 -04:00
Transaction Science
wai: the session accounts for every byte; decoderFor requires first_unit
SessionRecorder::received_envelope records any bytes received whole: bytes that
are not an envelope are an inert object, its content hash and path, counted
null, not presented, held, so the claim's transferred is every byte the sink
received and a verifier holding them accepts it while no entry names them.
RecorderError::NotAnEnvelope is gone. The binding's received never refuses
such bytes, and decoderFor requires the decoder's first_unit (no default of 0).
verify_measure_wasm.mjs checks both, and that the session's transferred is the
sum over every object.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-07 22:34:55 -04:00
Transaction Science
wai: a held layer is one a sink can apply, at its base's first unit; units in the payload's own format
§2.4.12, against the envelopes, three holes closed and the rules renumbered:
- A held layer an entry names must be one a sink can apply as its refines
  states (staged-delivery §3, §4.1 steps 1-2): refines that reads as §3 defines
  it, present on a refinement-only capability; a WAI2 base that is a rendition
  of the same envelope; a base, where held, that is a base; and, where the
  base's units are read, a span within them and runs that sum to them
  (session_refines_malformed). A malformed refines no longer leaves its
  presentations unchecked.
- A held layer's entry states the first_unit of an entry naming its base, a
  WAI1 base by content hash, a WAI2 one by envelope and rendition; and, against
  the stage claims, an entry naming a claim's base or a layer it lists states a
  unit stage_sets names that claim at (session_first_unit_mismatch).
- A WAI1 base's units are read in its payload's own format: its capability's
  pinned format, or its fallback's where the capability pins none, whichever
  capability the entry names. Naming the fallback no longer skips the check.

Vectors from the review's probes: layer and WAI2 refinement-component
first_unit mismatches, a base and its layer shifted together (accepted), the
fallback base in range and past it, refines at layer 0, a span past or empty
over a held base, refines absent, a base that is a layer, WAI2 components
through the layers and units rules, a WAI2 base that is no rendition or no
component id, a held inert envelope listed with counted 0, and a stage set's
base and layer entries off its unit. session_stage_unit_not_presented moves its
entries with the set, so it still rejects with session_stage_disagrees. The
pinned prefix is unchanged; 496 vectors.

claim_verify.py implements every rule as wai-rs does; differential.py extends
session_held to WAI2 refinement components, fallback bases and layers a sink
cannot apply, and perturbs first_unit across base, layer and stage set.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-07 22:34:55 -04:00
Transaction Science
Merge origin/main (1cf132ec) into wai/w5-4-measure-web
The staged-measure-conformance README takes main's provenance paragraph: the
int_codec audio is now coded on a generated signal, so the branch's note that it
codes a recorded sound is dropped, here and in the CHANGELOG.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-07 21:32:49 -04:00
Transaction Science
wai: a session's objects, layers and units are what its envelopes give
The objects: no (content hash, path) is listed twice (session_object_duplicate),
and the recorder merges a re-fetch into one listing whose transferred bytes are
every byte. After the sums, an object is presented exactly when a decoder entry
names it (session_presented_mismatch). With the envelopes, an object listed with a
held envelope's content hash states its counted bytes, null exactly when it is
not countable (session_counted_mismatch).

Inert envelopes: an encrypted envelope, or bytes of neither magic, is refused as
unreadable only where a decoder entry names it; one no entry names is a received
object, uncounted and not presented. SessionRecorder::received_envelope refuses
bytes that are not a WAI1 or WAI2 envelope at once (NotAnEnvelope), and
received(ObjectSeen) is gone: an object not held is received_unheld, its
figures derived.

Layers and units: a decoder entry states first_unit. With the outputs and the
envelopes, each presentation through a held entry is at the layer count its
envelope gives (session_layers_mismatch) and of a unit it covers
(session_unit_outside_object); a re-decode decodes unit - first_unit. The
generator builds the model base as a four-frame WIV1 clip and the WAI2
rendition as a one-frame clip, so a verifier counts them and reads their units;
the session vectors are regenerated, the pinned prefix unchanged.

jwp-receipts §2.4.12 states each rule, its step, order and contexts.
claim_verify.py agrees on every vector; differential.py adds random sessions
holding a base's and its layers' envelopes and object defects to the random
sessions. verify_measure_wasm.mjs requires the browser claim's build profile to
be release.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-07 21:29:32 -04:00
Transaction Science
2026-10-07 15:04:34 -04:00
Transaction Science
wai: review fixes for W5-4 — envelopes checked at seal, the build profile by opt-level, the audio title's provenance
- A recorder that holds the envelopes checks the claim against them.
  SessionRecorder::received_envelope takes an object's bytes and derives its
  content hash, counted and transferred bytes, and (at the tally) whether any
  of its outputs was presented; seal_checked takes the envelopes the recorder
  holds and runs check_session_envelopes, so an entry naming a capability its
  envelope does not give is refused before it leaves the sink
  (session_source_mismatch). stage_measure::session::recorder_of hands the
  title's envelopes to the recorder.
- wai-web's SessionHandle: received(envelope) takes the bytes alone and the
  recorder derives `presented`; decoderFor refuses a via that is neither the
  manifest's capability nor its fallback; verifyClaim takes the envelopes;
  presented's layers and decoder and qualityRgb8's w and h are read as JS
  numbers and refused unless whole and in range (int_in), never truncated or
  wrapped.
- build_info::profile_label decides on OPT_LEVEL alone: 2, 3, s and z are
  release, 0 and 1 (or an unreported level) debug; cargo's PROFILE is not
  read. BuildProfile's doc and jwp-receipts §2.4.8's `build` row say so. A
  size-optimised WebAssembly build is release.
- staged-measure-conformance/README.md no longer calls every title synthetic:
  the wai.audio.int_codec vector codes a recorded sound.

Tests: session_recorder::a_recorder_holding_its_envelopes_checks_them; the
fixture session test requires the envelopes held and checked; build_info's
literals; measure::a_decoder_is_named_through_its_envelopes_capability and
integers_from_js_are_whole_and_in_range (wai-web native count 21 -> 23).
verify_measure_wasm.mjs adds envelope verdicts (wasm32, native and Python
agree), the via refusal, derived `presented`, and the JS integer cases.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-07 09:26:06 -04:00

2026-10-06

Transaction Science
wai-web: staged measurement and the session claim in the browser (W5-4)
wai-web binds wai::stage_measure, the code wai_stage_measure runs, compiled to
wasm32 (src/measure.rs): evaluateTitle gives the text `eval --json` prints for a
title, simulate and simulateModel the text `sim` prints, countObject one
envelope's counted bytes or the code it is not countable with, qualityRgb8 one
picture pair's integers (sums of squares as decimal strings), outputRoot the
output tree's root. A title is read from a map of files; titleMissing names the
next file it needs, so a page fetches them one at a time.

receipt_claims builds and runs for wasm32 with stage_measure, so signing is
exposed: sessionBegin records a session at its entry object
(SessionRecorder), decoderFor/presented/received record what the page did,
finish seals the reconstruct-session claim with a page-supplied seed (energy
null), and verifyClaim runs the claim-conformance runner against the outputs
and the objects. CI builds receipt_claims,stage_measure for wasm32 beside the
stage_measure guard.

demo/verify_measure_wasm.mjs requires, from the wasm32 build, every golden,
refusal title, counted object, quality pair and simulator result of
staged-measure-conformance/ byte for byte, and a page-recorded session per
fixture equal to the native tool's claim byte for byte. demo/verify_measure.sh
adds the native `eval --json` of every fixture (cmp against the wasm32 text)
and the native and Python claim verifiers' verdicts on every browser-sealed
session. wai-web-wasm.yml runs it (the W17 line).

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