open-standards/wai/wai-int-module/README.md
Transaction Science f5bb6842af
Some checks failed
wai-int-module WAISM module of record / does this change touch it (push) Successful in 22s
WAI breaking changes and the conformance runner / WAI breaking · does this change touch WAI (push) Successful in 14s
wai-int-module WAISM module of record / linux · both checkers, wasmtime (Cranelift, Winch), Wasmi and Node (push) Successful in 7m49s
WAI breaking changes and the conformance runner / WAI breaking · wire, record and API against main · linux (push) Successful in 2m16s
WAI breaking changes and the conformance runner / WAI breaking and conform · their tests, and the independent verifiers through wai conform · linux (push) Successful in 5m38s
wai-int-module WAISM module of record / the module of record in Chromium (push) Failing after 30m1s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (push) Failing after 4m34s
wai-int-module WAISM module of record / linux-arm64 · both checkers, wasmtime (Cranelift, Winch), Wasmi and Node (push) Successful in 6m18s
wai-int-module: the README names the build macOS arm64 ran
Node and Chromium on macOS arm64 ran the build of this source made over wai 0.4.0, before main
moved wai to 0.5.0, with the same run digest; the README says so beside the table.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-08 16:45:56 -05:00

6.2 KiB

wai-int-module — the operator-set module

The first module of record of WA²ISM™'s integer level (extensions/waism.md, waism/1-int): one WebAssembly module, with the interface of waism §5 and nothing else, that decodes WAI's integer capabilities. Its decoders are wai-rs's, whose networks run on the integer operator set (wai-ops/1, integer-operators). The networks and their weights are not in the module: each arrives as its capability's parameter set, data a sink holds to its digest, so one checked module serves every capability below.

capability payload set output
wai.neural.int_hyper WIH1 the file sequence of entropy.json, g_s.whm, h_s.whm RGB8
wai.video.int_hyper WIV1, keyframe 1 the same each frame's SHA-256, in order
wai.video.int_motion WIV1, keyframe 0 none each frame's SHA-256, in order
wai.audio.int_codec WIA1 model.wam int16 PCM, little-endian
wai.splat.int_codec WIS1 g_s.whm the attribute tensor
wai.neural.int_synth the latent int_synth.json RGB8
wai.neural.int_mlicpp the coded image model.wmb RGB8
wai.audio.opus.dred.int an Opus packet the draft's weights file the feature rows, i32 little-endian; none for a packet with no DRED
wai.avatar.face WFK1 the file sequence of generator.wfg, identity.wfi the frames' RGB8, one after another

Each output is the capability's canonical buffer (waism §5 step 5): for video, a per-frame hash, whose SHA-256 is the clip digest the integer-payload corpus states. A refusal is the capability's own code, with wai_run returning 1. A set of one file is that file's bytes; a set of several is their file sequence (waism §5, The set).

What holds it

  • No floating point, no import, a fixed interface. Both of the profile's checkers (../wai-module-check), the Rust checker and check-module.mjs, hold each build at the integer level. Every allocation traps where memory cannot grow, so a failed memory.grow inside wai_run ends in a trap and never in an output (R13); wai_alloc alone returns 0.
  • The module corpus. corpus.json, written by corpus.py from the committed corpora: every vector and refusal fixture of the capabilities above, 120 cases, each with its capability, payload, set and the SHA-256 of the output or the refusal code. Its sources are int-payload-conformance/, neural-conformance/, wai-rs/tests/vectors/int_mlicpp/, live-conformance/dred/ (whose weights file live-conformance/dred/fetch.sh fetches and checks) and live-conformance/avatar-face/ (each frame vector as a segment of one frame).
  • The engines. Each runner decodes every case on an instance of its own, as waism §5 and §6 checks 11 to 13 state, holds every output to the corpus, and prints a run digest: the SHA-256 of one line a case, its name and its outcome. Every run gives the same run digest.
runner engine
host/ wasmtime 50.0.1 with Cranelift, and with Winch; Wasmi 2.0.0 with its floating point turned off
run-node.mjs Node, each module in a worker under a wall-clock limit
browser/run-browser.mjs Chromium, headless: each case in a page's worker, each output sent back as bytes and held to the corpus outside the page

The modules of record

record/ holds two builds of this crate for wasm32-unknown-unknown, named by their SHA-256 in record/manifest.json:

file build instructions of them 128-bit vector instructions
wai_int.wasm scalar 314,437 0
wai_int.simd128.wasm SIMD128 313,155 7,099

The SIMD128 build is the same source, which the compiler lowers to WebAssembly's integer vector instructions where it can. Its output is the scalar build's: every case gives the same outcome in both, on every engine.

Each module of record gave every case of the corpus its stated outcome, with run digest 0098ef57a0c75c4563b842e8969778b7744a258872ae7ae48917fb1a93b3aaf5, on these (macOS arm64: the build of this source made over wai 0.4.0, before its version moved to 0.5.0, with SHA-256 80e64e02…1441 and f0f9e1df…1fc1):

host wasmtime 50.0.1, Cranelift wasmtime 50.0.1, Winch Wasmi 2.0.0 Node Chromium, headless
Linux x86_64 yes yes yes 22.23.4 148.0.7778.96
Linux arm64 yes yes yes 24.22.2
macOS arm64 26.13.0 156.0.8078.4

The module is the same source on every host, and its bytes are not: the compiler's crate hashes take in the absolute path of each path dependency and the host it runs on, and they order what it emits. Linux arm64's build of this source has other bytes (765,514 and 773,603), and on wasmtime with both compilers, Wasmi and Node there it gave every case the same outcome, the same run digest. So record/ is named by its SHA-256, and a build is held to the corpus, not to record/'s bytes.

Building and running

bash build.sh [--out DIR]                        # both builds, each held by both checkers
bash ../live-conformance/dred/fetch.sh DRED      # the weights file the corpus names
(cd host && cargo run --release -- --external DRED ../corpus.json ../record/wai_int.wasm ../record/wai_int.simd128.wasm)
node run-node.mjs --external DRED corpus.json record/wai_int.wasm record/wai_int.simd128.wasm
node browser/run-browser.mjs --browser PATH --external DRED corpus.json record/wai_int.wasm
python3 -I corpus.py --check                     # corpus.json is the committed corpora's
python3 -I plant.py float|relaxed IN OUT         # a rule-breaking instruction, for the checkers

build.sh names no path of the machine that runs it in the module: the checkout, the Cargo home and the toolchain are remapped.

CI: .github/wai-conformance/verifiers/module-check.sh holds record/ to its manifest and both builds at the integer level by both checkers, and refuses the module of record with a float instruction planted, and with a relaxed vector instruction, at the rule and offset the plant gives; .github/workflows/wai-int-module.yml runs the engines.