wai-ops: int_synth decodes through the integer operator set, goldens unchanged (D2c, M1) #242
Merged
dcharlot
merged 14 commits from 2026-10-14 02:13:11 -04:00
wai/d2c-decoders-on-ops into main 2026-10-13
Merge origin/main (at
1ec8f447, with #233, #234, #236, #238, #239, #240) into wai/d2c-decoders-on-ops
All checks were successful
WAI HTTP delivery / HTTP corpus · falsify patches 1/3 (pull_request) Has been skipped
WAI HTTP delivery / HTTP corpus · falsify patches 2/3 (pull_request) Has been skipped
WAI HTTP delivery / HTTP corpus · every patch and mutation in exactly one shard (pull_request) Has been skipped
WAI HTTP delivery / HTTP corpus · verified both ways, and the differential (pull_request) Has been skipped
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Has been skipped
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Successful in 1m25s
wai formal verification (integer core) / kani (integer-core) (pull_request) Successful in 6m43s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 1m18s
wai-ops differential (nightly) / differential · debug (pull_request) Successful in 2m31s
wai-ops integer operators / linux-x86_64 (pull_request) Successful in 52s
wai-ops differential (nightly) / differential · release (pull_request) Successful in 2m55s
wai-ops integer operators / wasm32-wasip2 (wasmtime) (pull_request) Successful in 28s
wai-ops integer operators / wasm32 under Node (pull_request) Successful in 20s
wai-pack / wai-pack · does this change touch it (pull_request) Successful in 4s
wai-ops integer operators / independent checker (Python) (pull_request) Successful in 33s
wai-pack / wai-pack · macos (pull_request) Successful in 1m31s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 1m38s
wai-quantum WebGPU member / member · software Vulkan (linux) (pull_request) Successful in 2m19s
WAI section references / cited sections exist (pull_request) Successful in 11s
wai-quantum WebGPU member / shader checks · browser build · wasip2 inertness · MSRV (pull_request) Successful in 3m30s
wai-web reach builds / wai-web reach · does this change touch it (pull_request) Successful in 4s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 3m14s
workflow hygiene / every workflow supersedes its own queue (pull_request) Successful in 8s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 5m27s
wai-pack / wai-pack · linux (pull_request) Successful in 1m22s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 4m4s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 24s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m21s
wai-web reach builds / wai-web reach builds · the package of record, every output as recorded (pull_request) Successful in 2m48s
wai-web reach builds / wai-web reach builds · this tree's wai-web, every rung on its engine line (pull_request) Successful in 4m53s
Co-Authored-By: Claude Opus 5.5 <[email protected]> # Conflicts: # .github/workflows/wai-conformance.yml
D2c M1 gate 7: the direct path's guard code goes
What the certified graph now carries, deleted from int_synth: - the direct decode's fast dispatch (its own conv_transpose2d over int_kernels::conv_acc_i64) and its guard reference_output_side, which kept the fast kernel to output sizes the scalar kernel's i64 arithmetic could form: the decode runs through the operator set, whose plan forms every size in checked 64-bit arithmetic under the 2^26 caps, and whose lowering refuses a field past 32 bits; - the kernel_equivalence module that held that dispatch to the scalar kernel (retargeted at gate 5: the fast kernels are held to the interpreter); - the ops module, folded into decode_from_spec and header(). The direct decode stays, test-only (legacy_int), as the differential's oracle: legacy::decode_from_spec over the scalar kernel alone (reference:: conv_transpose2d, kept verbatim, with its hand-computed unit tests). Callers of int_synth::ops now call int_synth::decode_from_spec (both wai-rs test files and byte-exact's lowering golden). int_kernels' documentation no longer describes an int_synth dispatch or its i64 size guard. Co-Authored-By: Claude Opus 5.5 <[email protected]>
D2c M1 gate 6: int_synth decodes through wai-ops; the direct decode is test-only
The switch. int_synth::decode_from_spec (and so decode, decode_bytes, the int_payload dispatch, the neural sink and the browser crate) decodes through the integer operator set: the payload checked, the set lowered by int_synth/1, loaded under acc64 with its bounds certificate, run by the interpreter with the fast kernels behind it. The direct decode (int_synth::legacy, its serde specs, conv_transpose2d, reference_output_side and the scalar reference) is behind cfg(any(test, feature = "legacy_int")). byte-exact-conformance declares legacy_int; tests/int_synth_ops.rs, which compares the two, requires it. Every committed output is unchanged: the fast-kernel steps' tests in both profiles (int_kernels_vectors' corpus under every policy, int_payload, int_synth_ops, the differential), the int-synth corpus loop, byte-exact's goldens, and the browser crate's wasm32 decode of the corpus under Node. The planned breaks take effect. tests/int_kernels_geometry.rs: a stride past 32 bits, an uncropped output past 2^26 (pad 2^12; pad 2^9 still decodes to the bias) and the u32 and 2^62 fields of the size-overflow case are refused under every policy and in every build, where the direct decode returned or panicked. O12 (tests/int_synth_ops.rs): every committed int_synth set has layers, each with out_ch, k and stride at least 1, fields below 2^32 and a shift of at most 63, and lowers and loads under acc64 (overflow_acc64, the falsification set, alone fails); every committed payload has a reserved byte of 0, C >= 1, C*S*S <= 2^26, its exact length, and decodes. Text: integer-payloads §13 (a non-empty layers list, fields below 2^32, out_ch, k and stride at least 1; the reference decoder decodes through the lowering), integer-operators §13.1's load checks (at least one layer, the 32-bit fields, out_ch >= 1), §15.3 (no layers, out_ch 0, a field of 2^32 or more), its status note, SPEC §8 *Planned breaks*, and the CHANGELOG. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Merge origin/main (at
c20f8473, with #237) into wai/d2c-decoders-on-ops
Co-Authored-By: Claude Opus 5.5 <[email protected]> # Conflicts: # wai/CHANGELOG.md
D2c M1 gate 5: the fast kernels behind the interpreter, held to it
wai-ops: interp::Kernels, a host's kernels for some operators (integer- operators §6), and run_with, which asks the host first for each operator and computes it itself where the host declines; the plan, every check and range policy, the state and every refusal stay the interpreter's. interp::rq exposes the requantisation so a host's outputs are the interpreter's. run and run_observed are unchanged (interp::Reference, a host that has none). wai-rs int_ops: Host lends the interpreter this crate's fast convolution and transposed convolution (int_kernels::conv_acc_i128, each output finished with interp::rq) under a fast Policy, and declines under the reference policy, for geometry the kernel does not cover, operands past its bound, or a value that would leave i64. run1 runs through it. Retargeted equivalence, both halves against the interpreter: - per operator (int_ops::equivalence): 400 random convolutions and transposed convolutions, every rounding mode, bias kind and multiplier choice, under every fast policy against the interpreter alone; the fast kernel must actually run; a check range refuses before any kernel; - per decoder (tests/int_synth_ops.rs): every committed int_synth vector, and the fixtures' base, through the lowering under the reference and four fast policies, the same bytes. The inverse-GDN arm the draft had waits for M4. Co-Authored-By: Claude Opus 5.5 <[email protected]>
D2c M1 gate 4: int_synth through wai-ops against its direct decode, differentially
tests/int_ops_differential.rs (feature legacy_int, test-only; a [[test]] entry with required-features): - an oracle that names, from the payload and the set alone, the planned break of integer-operators §15.3 a case falls under: a reserved byte that is not 0, C of 0, latents past 2^26, no layers, a field past 32 bits, a shift of 128 or more, k or stride of 0, out_ch of 0, an uncropped output or a tensor past 2^26, a certificate that does not meet acc64 (lowered and loaded), and a shift from 64 to 127 (exact now, by build before); - random sets and payloads (1-3 layers, kernels 1-4, strides 1-3, paddings and output paddings mostly in range, shifts 0-24, weights to 2^4, 2^10, 2^14 and, one set in eight, 2^20; latents a quarter at their ends; outputs one in eight off the payload's H and W; reserved bytes one in thirty-two not 0): outside a planned break both decodes give the same bytes or both refuse, and the direct decode never panics; under one, the decode through the operator set refuses; - each planned break shown on a payload and set the direct decode decodes, the operator set refusing it (or, for a shift of 64, giving it its exact meaning). Among them two the extension's text does not yet list: a set with no layers, and a layer with out_ch 0. Fixed count (3000 cases) on every push in wai-conformance's fast-kernel steps, both profiles (legacy_int at the end of the feature list, where gate tooling that greps for the step still finds it). WAI_DIFF_SECS / WAI_DIFF_SEED run it by time and seed: wai-ops-differential.yml does, an hour per profile, nightly on linux, seeded by the date. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Merge origin/main (at
bd3983c6, with #229-#232, #235, #142, #209, #210) into wai/d2c-decoders-on-ops
Co-Authored-By: Claude Opus 5.5 <[email protected]> # Conflicts: # .github/workflows/wai-conformance.yml # wai/CHANGELOG.md
D2c M1 gate 3: refusal parity, int_synth's registry ops member and SPEC citations
Refusal parity (tests/int_synth_ops.rs): one fixture for each refusal the
direct decode makes (a payload short or long, a side of 2^64 or 2^255, C*S*S
past the word, an output that is not [3, H, W], an H of 0, a first in_ch that
is not C, a set that is not JSON or has no layers, a malformed layer, a
negative, fractional or non-boolean field, a weight or bias count off by one,
a value past i32, layers that do not chain, an output side of 0). Each is
refused by both decodes, and a sink's int_payload dispatch reports it as
payload_malformed, the one code integer-payloads §13 gives. The lowered graph's
input check [-128, 127] decodes at both ends and refuses one past each with
field_range at input 0.
The registry's ops member (integer-operators §11): codecs::OpsMember and
capability_ops, Registration::ops, the export's ops member and its schema
(built in its own function: the schema literal had reached json!'s recursion
limit). wai.neural.int_synth gets {set wai-ops/1, profile acc64, subset full,
lowering int_synth/1}; a unit test pins it as the only member, on a
NeuralIntegerExact capability. registry/ regenerated by `wai registry export`.
SPEC §5's row cites integer-payloads §13 and integer-operators §13.1; SPEC §7
says a NeuralIntegerExact capability that decodes through the operator set
names it in its ops member. REGISTRY.md lists the member; CHANGELOG entry.
int_ops::PROFILE is private: as a public constant, cbindgen wrote an opaque
Profile typedef into include/wai.h.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
D2c M1 gate 2: int_synth's decode through its lowering equals every golden
int_synth gains its decode through the integer operator set, int_synth::ops: the payload's header checked (integer-payloads §13, the reserved byte, C >= 1 and the 2^26 cap among them), the set lowered by int_synth/1, the graph loaded under acc64 with its bounds certificate and run by the operator set's interpreter (int_ops::run1), the [3, H, W] output laid out as RGB8. The direct decode moves, unchanged, into int_synth::legacy, and decode_from_spec still calls it: the switch is gate 6. Golden equality, on every committed golden: - tests/int_synth_ops.rs: each neural-conformance vector decodes through the lowering to the direct decode's bytes, its SHA-256 sidecar, its BLAKE3 rgb_hash and sizes, and photo's Python integer-forward reference; the browser demo's payloads and digests are byte copies of the corpus's. Both profiles, on every wai-conformance leg. - byte-exact-conformance: the cross-architecture int_synth golden (84e76529...) through the lowering as well, on every leg of the byte-equality matrix. The crate includes int_ops.rs and depends on wai-ops; the matrix fires on both. - wai-ops' own goldens already decode the corpus through the interpreter on every native leg and under WASI (wai-ops.yml). Co-Authored-By: Claude Opus 5.5 <[email protected]>
D2c M1 gate 1: the test asserts each set's verdict before its committed bytes
So that a set changed past its acc32 bound reads as the verdict that flipped, not as a digest that moved. Co-Authored-By: Claude Opus 5.5 <[email protected]>
D2c M1 gate 1: int_synth's lowering and certificate, as this crate loads them
wai-rs depends on wai-ops (behind neural_int) and gains src/int_ops.rs, the bridge every integer decoder will load its lowered graphs through: from their canonical bytes, under acc64, load steps 1-8 with the bounds certificate. tests/int_synth_ops.rs: every committed int_synth set (the neural-conformance corpus and the ops-conformance set) lowers through int_synth/1 to the committed graph, the committed certificate is that graph's, and loading it gives the certificate's verdict: acc64 for all, acc32 for facade, gradient, bloom and the small set, not for photo, as the design predicted. The browser demo's sets are byte copies of the corpus's. The two falsification sets fail the profile they claim: overflow_acc64 is refused at load step 8, claim_acc32 loads under acc64 and does not meet acc32. The independent checker re-lowers and re-certifies every set byte for byte (wai-ops.yml, unchanged). CI: the fast-kernels steps (both profiles) name the new test; wai-conformance, wai-web-wasm and wai-neural-gates fire on wai-ops changes. wai-pack, wai-rs and wai-web lockfiles gain wai-ops. Co-Authored-By: Claude Opus 5.5 <[email protected]>
D2c: set the WIP draft aside so the tree builds; M1's gates re-land it in order
The draft (140de363) switched wai.neural.int_synth onto wai-ops in one step, before its golden, refusal, differential and fast-kernel gates existed, and it did not compile: byte-exact-conformance declared `mod int_codec_golden;`, a file that was never written. Every file the draft touched is restored to main's text here, so wai/ equals main's at1fa13396and the tree builds. The gates of the design's migration plan (lowering and certificate, golden equality, refusal parity, differential, fast-kernel parity, switch, delete) then land one commit each, drawing on the draft. Not re-landed by M1, for the milestones they belong to: int_codec_golden (the cross-architecture goldens of wai.audio.int_codec and wai.splat.int_codec, with the int_audio and int_splat includes beside it: M2 and M3), the parsed-network lowering entry points in wai-ops' whm1/wam1/world lowerings (M2 to M6), and the inverse-GDN host kernel (M4). Co-Authored-By: Claude Opus 5.5 <[email protected]>
Merge origin/main (at
1fa13396, with D2b #221, #227 and #228) into wai/d2c-decoders-on-ops
One conflict, wai/CHANGELOG.md: both sides added sections at the top of v0.4.0; both are kept, this branch's first. wai-ops is main's D2b as it was (the branch already sat on d2b-bounds); Cargo.toml, lib.rs and the lockfiles merged cleanly. Co-Authored-By: Claude Opus 5.5 <[email protected]>
WIP (does not compile): D2c, decoders on wai-ops, as left when a write was refused
Saved so the work is not lost. byte-exact-conformance/src/lib.rs declares mod int_codec_golden, and that file does not exist yet, so the tree does not build. Contains the Kernels trait in wai-ops/interp.rs, wai-rs/src/int_ops.rs, int_synth decoding through int_synth/1, tests/int_ops_differential.rs and the SPEC text for the planned breaks. Co-Authored-By: Claude Opus 5.5 <[email protected]>