wai-ops: the reference crate and conformance vectors for wai-ops/1 (D2a) #206

Merged
dcharlot merged 15 commits from wai/d2a-operators-crate into main 2026-10-10 17:17:02 -04:00

2026-10-10

Transaction Science
ops-conformance: say why the corpus carries no sha256.json
All checks were successful
wai-ops integer operators / wasm32 under Node (pull_request) Successful in 19s
wai-ops integer operators / independent checker (Python) (pull_request) Successful in 11s
wai-pack / wai-pack · does this change touch it (pull_request) Successful in 4s
WAI section references / cited sections exist (pull_request) Successful in 10s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 2m50s
workflow hygiene / every workflow supersedes its own queue (pull_request) Successful in 4s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 14m47s
wai-pack / wai-pack · linux (pull_request) Successful in 1m6s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 1m46s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 19s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m14s
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 20m46s
standards workspaces build + test / aac-rs (pull_request) Successful in 10m39s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 4m15s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 1m29s
standards workspaces build + test / map-rs (pull_request) Successful in 52s
standards workspaces build + test / mesh-rs (pull_request) Successful in 1m15s
standards workspaces build + test / openpay (pull_request) Successful in 5m42s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 13m8s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 56s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 4m22s
wai-ops integer operators / linux-aarch64 (pull_request) Successful in 58s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 1m57s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 2m48s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 7m6s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 10m6s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 29s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 3m11s
wai-ops integer operators / macos-arm64 (pull_request) Successful in 25s
wai-pack / wai-pack · macos (pull_request) Successful in 2m13s
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-10 02:13:04 -04:00
Transaction Science
int_kernels_vectors: ops-conformance states no digest of decoded output
Some checks failed
standards workspaces build + test / macOS energy backends (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · macos (pull_request) Has been cancelled
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Has been cancelled
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Has been cancelled
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · macos (pull_request) Has been cancelled
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Has been cancelled
WAI energy receipts / energy receipts · macos (pull_request) Has been cancelled
wai-ops integer operators / linux-aarch64 (pull_request) Has been cancelled
wai-ops integer operators / linux-x86_64 (pull_request) Has been cancelled
wai-ops integer operators / macos-arm64 (pull_request) Has been cancelled
wai-ops integer operators / wasm32-wasip2 (wasmtime) (pull_request) Has been cancelled
wai-ops integer operators / wasm32 under Node (pull_request) Has been cancelled
wai-ops integer operators / independent checker (Python) (pull_request) Has been cancelled
wai-pack / wai-pack · does this change touch it (pull_request) Has been cancelled
wai-pack / wai-pack · linux (pull_request) Has been cancelled
wai-pack / wai-pack · linux-arm64 (pull_request) Has been cancelled
wai-pack / wai-pack · macos (pull_request) Has been cancelled
wai-pack / wai-pack · independent verifier (Python) (pull_request) Has been cancelled
wai-pack / wai-pack · the floor through a media prober (pull_request) Has been cancelled
wai-pack / wai-pack · dependency licences (pull_request) Has been cancelled
WAI section references / cited sections exist (pull_request) Has been cancelled
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Has been cancelled
workflow hygiene / every workflow supersedes its own queue (pull_request) Has been cancelled
every_decoded_output_states_a_sha256 enumerates every wai/*-conformance/
directory, and the new ops-conformance had neither a sha256.json sidecar nor an
exclusion, so the cargo-class corpora job failed reading the sidecar.

It takes an exclusion, because SPEC §7 *Digests* does not reach it: the rule
binds a vector that states a digest of a parameter-set decode's output, and no
file there states one. Every operator, stage and graph vector, the lower_*
decodes of the sets under sets/ included, states its output integers in full or
its refusal code; certificates/index.json states only each set's SHA-256 (a
parameter-set identity), and the lowered graphs are held as bytes and compared
byte for byte. The output digests a capability decoded through its lowering
must reproduce (integer-operators §14.4) stay in that capability's own corpus,
whose sidecars wai-ops's goldens already read.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-10 01:44:21 -04:00

2026-10-09

Transaction Science
wai-ops.yml: the goldens' digest file in the filter; every test on the 32-bit leg
Some checks failed
WAI conformance / cargo-class corpora · linux (pull_request) Failing after 1m49s
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Successful in 14s
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 30s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 51s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 1m54s
wai-ops integer operators / linux-x86_64 (pull_request) Successful in 21s
wai-ops integer operators / wasm32-wasip2 (wasmtime) (pull_request) Successful in 23s
wai-ops integer operators / wasm32 under Node (pull_request) Successful in 19s
wai-ops integer operators / independent checker (Python) (pull_request) Successful in 11s
WAI section references / cited sections exist (pull_request) Successful in 10s
workflow hygiene / every workflow supersedes its own queue (pull_request) Successful in 4s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 14m13s
standards workspaces build + test / jouleclaw-rs (pull_request) Has been cancelled
standards workspaces build + test / aac-rs (pull_request) Has been cancelled
standards workspaces build + test / joule-code-rs (pull_request) Has been cancelled
standards workspaces build + test / joulecontract-rs (pull_request) Has been cancelled
standards workspaces build + test / jouledesk-rs (pull_request) Has been cancelled
standards workspaces build + test / map-rs (pull_request) Has been cancelled
standards workspaces build + test / mesh-rs (pull_request) Has been cancelled
standards workspaces build + test / openpay (pull_request) Has been cancelled
standards workspaces build + test / macOS energy backends (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · macos (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · macos (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Has been cancelled
WAI energy receipts / energy receipts · macos (pull_request) Has been cancelled
wai-ops integer operators / linux-aarch64 (pull_request) Has been cancelled
wai-ops integer operators / macos-arm64 (pull_request) Has been cancelled
- The goldens compare against wai/neural-conformance/sha256.json, which the
  `paths:` filters did not match (the repo's own matcher said False). Both
  lists now take wai/neural-conformance/**, so a re-pinned digest runs wai-ops.
- The wasip2 leg ran only `vectors verify`, so the unit tests and the goldens
  never ran on a 32-bit target. It now runs `cargo test` under wasmtime in the
  default build (unit and step-8 tests) and with `uncertified` (unit tests,
  goldens, step-8 test), with the wai directory preopened at its own absolute
  path for the files the tests read. Both pass locally under wasmtime.
- The native default-build step runs `cargo test`, not `--lib`, so the step-8
  test and the doc tests that keep an unloaded graph from running are run.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 19:31:39 -04:00
Transaction Science
wai-ops: the interpreter runs only a loaded graph, so step 8 cannot be bypassed
Load step 8 was enforced at `graph::load` only. `interp::run` took any
`&Graph`, and a lowering's graph, a parsed one or a struct literal reached it
without step 8: in the default build, `lower::int_synth` then `run` decoded the
gradient set to its committed digest while `graph::load` of the same bytes
refused it at Load(8).

- `graph::Loaded` holds a graph that passed every load step; its field is
  private and only `graph::load` makes one. `run` takes `&Loaded`.
- A `Graph`, parsed, lowered or built in place, is data. A compile_fail
  example (E0308) on `Loaded` shows a lowered graph cannot be passed to `run`.
- The goldens load every lowered graph from its bytes before running it, so
  their `uncertified` gate now guards something.
- tests/step8.rs, in every build: each lowered int_synth graph is refused at
  Load(8) without the switch and loads with it.
- Cargo.toml says who enables the switch, and that no decoder may.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 19:31:39 -04:00
Transaction Science
wai-ops: a vector for each run and load rule the text now states
A review found rules that only the crate and the README settled, and that no
vector pinned: changing the checker to another reading of each changed no
committed byte. integer-operators now states each one, and each now has a
vector that a different reading fails:

- state: a refused decode changes no state; until a decode completes, a state
  input is `init`, sized by input 0 of the decode being made (§10.3).
- run step 1 runs input by input; an input with a dimension of 0 is
  model_mismatch (§4).
- run step 3: conv_transpose's uncropped output of cout planes is capped, not
  one plane; the caps come before the shape rule, both for that output and for
  an uncropped side; the shape rule comes before max_elems (crop_to) (§4, §5.3).
- crop: a scalar start of −1 is refused though −1 + h ≤ H, and at load a
  scalar start is planned at 0, not at its range's low end (§5.10).
- load step 5: chscale's m_bytes and layernorm_c's g_bytes of 2 are refused,
  and 4 loads (§10.4).

subpos_merge now caps its output sides before its shape rule, in the crate
and the checker, as §4 states for every operator. No input within the caps
can tell the two orders apart.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 19:31:39 -04:00
Transaction Science
wai_ops_check.py: load step 8, profiles recomputed, lowering vectors tied to their roles
The checker copied each vector's `profiles` from the committed line, never ran
load step 8, and took the graph bytes of graphs/lower_*.jsonl as given. So a
regression in the generator's tagger, or a lowering vector whose graph was not
its role as lowered, would have passed.

- A bounds pass and verdict written from integer-operators §8.1–§8.5: every
  +, −, × and floor division saturated at ±2^255 with the node's saturated flag
  (§8.1), the term and partial-sum intervals (§8.2), each operator's rule
  (§8.3), the classes and parameter conditions of §7, and what a node fits and
  the verdict (§8.5). It writes no certificate.
- Load step 8: an empty `check` interval, a lut16 input range past ±32767, or
  a verdict that meets neither profile refuses the graph (model_mismatch).
- `profiles` is recomputed: both profiles for a refused load, else exactly
  those the verdict meets (§14.1). It agrees with all 1,599 committed tags, and
  with Appendix C's predictions for every committed set (int_synth gradient,
  bloom and facade acc32; photo and every WHM1, WAM1 and WMB1 set acc64).
- Each lowering vector's id names <file>/<set>/<role>; its graph must be that
  role as re-lowered, and every role must have one.

The README now points to §14.1 for every field, and lists the coverage classes
of §14.1 item 6 that wait for step 8 in wai-ops: sigmoid and elu at −2^63, and
an rq whose q passes 64 bits while y fits.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 19:31:39 -04:00
Transaction Science
wai-ops: a tensor a ReLU reads inside a WHM1 network is derived, as §13.2 says
§13.2 gives `check` only to an x_ℓ that a layer of tag 0, 1, 2 or 4 reads,
and `check [−2^63, I64]` to a network input that no such layer reads; every
other tensor is `derived`. The lowering and the checker both gave every x_ℓ a
ReLU reads `check [−2^63, I64]`, so a reader of the text could not reproduce
three committed graphs.

Both now follow the text. The checker's `x_record` is rewritten from the
§13.2 wording, not from the crate. Regenerated: the h_s graph of the int_hyper
set 7aceaa1a… and of the int_mlicpp sets 07e1835d… and 7ef44f3b…, and the
lower_whm1 and lower_wmb1 vectors that embed them. No output changes: the
range they drop held every i64.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 19:31:39 -04:00
Transaction Science
wai-ops: rate_predict vectors at the i16 extremes with rates near 2^32
With prev = [−32768, 32767], rate_num = 2^32 − 1 and rate_den = 2^32 − 2,
(b − a)·ρ is 65535·(2^32 − 2), just under 2^48, and rdiv's 2|n| + d passes
2^48 (§5E E12 now states the widths). Three vectors pin the results: both
orders of the extremes, and two channels at rate_den = 2^31.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 19:31:39 -04:00
Transaction Science
wai-ops: residual_step's 32-bit form, with the conditions under which it fits i32
E9's 32-bit form fits i32 only when hi − lo ≤ 65535 and lo − 131070 and
hi + 131070 also fit. At lo = 2^31 − 65536, hi = 2^31 − 1, q = 65535,
pred = hi, r = 2, it formed hi + 131070 and the function overflowed.

- `residual_step_i32` asserts its conditions (`i32_form_fits`) in debug builds.
- `residual_identity_holds` covers the ranges nearest the i32 limits on which
  the form still fits, and `residual_form_condition_is_tight` shows that one
  step past them it does not, while the exact form gives the clamped value.
- stage/residual_step.jsonl gains 32 vectors at the i32 limits, at r = ±R and
  ±(R + 1), with q = 1 and q = 65535, as §14.1 item 7 asks.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 19:31:39 -04:00
Transaction Science
wai-ops: mans_decode reports a refusal at the position whose step refuses
Only the `in` step set the reported position, so a refusal in a position's
`out` step (in sgm, the flush after an escape) named the last `in` of its
group. mans_decode/sgm/40 said at=11; symbol 10's escape flush refuses, and it
now says at=10. A flush that belongs to no single position reports the last
position whose `in` step ran, as integer-operators §14.1 now states.

The checker sets the position at each `in` and `out` step and names the
group, remainder and row-end flushes as such, following §14.1's wording.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 19:31:39 -04:00
Transaction Science
wai-ops: the strict run-out case alone, not paired with a non-minimal count
Its stream's groups were 2, 6, 0: a zero last group, so under final_only it showed
the non-minimal refusal, which has its own paired case. Now 1, 6: under canonical it
is refused at the symbol (stream_exhausted), under final_only the symbol decodes and
the end refuses (stream_exhausted at 1).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 19:31:39 -04:00
Transaction Science
wai-ops: CI on every leg the corpus runs on, and the corpus README
.github/workflows/wai-ops.yml, with a concurrency group per ref:

- linux, linux-arm64, macos: the unit tests in the default build (load step 8
  refuses every graph) and with the `uncertified` switch, the goldens in debug and
  release, and `wai-ops vectors verify`;
- wasm32-wasip2 under wasmtime 38.0.3: `wai-ops vectors verify`;
- wasm32-unknown-unknown under Node: every vector file recomputed;
- tools/wai_ops_check.py, the independent checker, and the concurrency gate.

ops-conformance/README.md names the layout, the conventions both recomputations
follow where §14.1 leaves a choice (data inputs only in `inputs`, a refused decode
leaves the state, each stage operator's `in`, `modes` and `expect`, and what `at`
reads for each), the lowered sets' digests, and how to regenerate and verify.

The three goldens that need data this repository does not commit (a jpegai bundle,
a legacy decoder's intermediates on one codestream, the reference encoder's mANS
streams) are now `#[ignore]` with the reason, so CI reports them ignored rather than
passed; locally, with the data, all three pass. The tagger now applies §8.5's fit
rule as written; the corpus is unchanged by it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 19:31:39 -04:00
Transaction Science
wai-ops: an independent checker, wai_ops_check.py, for the vectors and the lowerings
wai/tools/wai_ops_check.py, Python standard library only, sharing no code with
wai-ops. From integer-operators (and integer-payloads for the source forms), it
recomputes every vector file of ops-conformance: each graph vector's `load` (WHG1
and load steps 1–7) and every decode's `expect` (§4, every operator of §5, the
transposed convolution in its gather form), and each stage vector's `expect` (§5E);
writes each file canonically and requires the committed bytes. It re-lowers every
set the index lists by §13 and requires each lowered graph's bytes and each set's
digest. On the committed corpus it rewrites all 53 vector files and all 28 lowered
graphs byte for byte; a changed output, a changed symbol and a changed byte of a
lowered graph each fail it.

Independence: written in the same session as wai-ops, after it, from the text, with
the text open and the Rust closed, and structured differently where the text allows.
It is not the separate text-only session the plan asks for; that session is still
owed before D2a merges.

graph.rs gains tests that a graph round-trips, that the default build refuses every
graph at load step 8, and that the `uncertified` switch skips it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 19:31:39 -04:00
Transaction Science
wai-ops: the conformance corpus, its generator, and the WASI and browser-engine legs
wai/ops-conformance/, in integer-operators §14.1's format, written by
`wai-ops vectors gen`:

- vectors/<operator>.jsonl: one-operator graph vectors for every graph operator:
  random cases over several magnitudes, and the coverage classes of §14.1:
  bound-attaining inputs, rounding ties at every mode and the shifts the class
  names, geometry, the i32 limits and one past them, check and scalar ranges at
  their ends and one past, every run-time shape refusal, and the distinguishing
  cases (per-term igdn floors, leaky floors, softmax rows, elu(0), a half mean in
  layernorm_c, ε = 2^64 − 1, exp at n = 62 and 63).
- stage/<operator>.jsonl: E1–E13. E1 under every mode, with each strict refusal
  alone and in each pair one symbol can give, under both end rules; E8 with zero
  tails, short streams, and escapes at bounds of 128 and 255.
- graphs/: the phase form against conv_transpose (the generator checks the two
  outputs agree), a state carried across three decodes, a refusal at each load
  check (steps 1–7) and at each run step, and every lowering on a small set.
- certificates/<capability>/<set digest>/<role>.whg1: the lowered graphs of every
  committed set and of the small sets, with certificates/index.json.

Every vector's `profiles` is the profiles its graph meets under §7 and §8.3, from
the generator's own tagger; a case that meets neither is not written (its load
refusal is a D2b vector). The certifier must agree with every tag.

`wai-ops vectors verify` recomputes every vector file, re-lowers every set and
regenerates the corpus, and requires every byte to match. It passes natively, as
the same binary built for wasm32-wasip2 under wasmtime, and through wai-ops/node,
the recomputation as a wasm32-unknown-unknown module run by Node.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 19:31:38 -04:00
Transaction Science
wai-ops: the reference crate for wai-ops/1 (WHG1, plans, interpreter, stage operators, lowerings)
A new crate, wai/wai-ops: no_std with alloc, no dependencies.

- xint: a 512-bit signed integer with the saturation of integer-operators §8.1.
- json: a reader that keeps numbers as written, and the canonical writer of §8.5.
- graph: WHG1 parse and write, load steps 1–6 of §10.5.
- plan: the load-time plan (step 7) and the run-time plan (§4).
- interp: every graph operator of §5, exact in i128, with the policies and the
  sequence state of §10.3.
- stage: E1–E13; E1 with both escapes, both end rules and both table rules, E8
  total with every refusal stream_exhausted.
- lower: int_synth/1, whm1/1, wam1/1, wmb1/1, world/1 and jpegai-int/1 (§13.6.1),
  each writing §13.0's canonical bytes.

Load step 8 (the bounds pass and the verdict) is not built: without the
`uncertified` feature every graph is refused at step 8; with it, step 8 is skipped.

tests/goldens.rs lowers every committed set and decodes its committed payload
through the interpreter and the stage operators, and every output digest
reproduces: the four int_synth sets, both world clips frame by frame, the
int_hyper tiny set, splat, audio and int_mlicpp. Opt-in, against data that is not
committed: the jpegai scale path and both mANS decodes equal the legacy decoder's
every intermediate on a real codestream, and E8 equals the reference encoder's
streams and tables.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 19:31:38 -04:00