open-standards/wai/wai-int-module/sink.mjs
Transaction Science 98d646dc92 wai-int-module: the first WA²ISM module of record, the operator-set module held at the integer level on every engine
wai/wai-int-module is one WebAssembly module with the interface of waism §5 and nothing else:
no import, one memory with a declared maximum, and every allocation trapping where memory
cannot grow (R13). It decodes the integer payloads (WIV1, WIH1, WIA1, WIS1), int_synth,
int_mlicpp, opus.dred.int and avatar.face through wai-rs's integer decoders, whose networks
run on wai-ops/1; networks and weights arrive as each capability's set.

- record/: the scalar and SIMD128 builds (7,099 vector instructions), named by SHA-256 in
  manifest.json, each held at the integer level by the Rust checker and check-module.mjs.
  build.sh builds both with the machine's paths remapped and checks both with both checkers.
  A build on another host has other bytes (the compiler's crate hashes take in each path
  dependency's absolute path and the host) and gives every case the same outcome.
- corpus.json (corpus.py): every committed vector and refusal fixture of those
  capabilities, 120 cases, from the committed corpora.
- host/ (wasmtime 50.0.1 Cranelift and Winch, Wasmi 2.0.0 with floats off), run-node.mjs and
  browser/run-browser.mjs run every case as a sink does and print one run digest; every run,
  on Linux x86_64, Linux arm64 and macOS arm64, gives the same.
- plant.py plants a float or a relaxed vector instruction in a module, for the checkers.
- waism §5, The set: one file as its bytes, several as their file sequence. avatars §6 names
  generator.wfg and identity.wfi; avatars §7.8, opus-dred §4.8 and determinism-tiers §5 state
  the module as a fabric.

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

74 lines
3.2 KiB
JavaScript

// sink.mjs: one object decoded through a WAISM module, as waism §5 and §6 checks 11 to 13
// state, in any JavaScript engine: Node, or a browser's page or worker. No dependency.
//
// decode(module, cap, payload, set) → { output } | { refused } | { sink, detail }
//
// `module` is a compiled WebAssembly.Module; `cap` the capability's term (a string),
// `payload` and `set` Uint8Arrays. The module is instantiated with an empty import object
// for this one object and discarded after it. `output` is the module's output (a
// Uint8Array) where wai_run returned 0; `refused` its refusal code where it returned 1;
// `sink` the sink's own refusal of the run (waism §8): module_resources, module_trap or
// module_result_invalid. The wall-clock bound of waism §7 is the caller's: a worker that
// runs this, ended from outside when a run passes its limit (module_timeout).
const ENCODER = new TextEncoder();
const DECODER = new TextDecoder();
function sinkRefusal(sink, detail) {
return { sink, detail: String(detail) };
}
/** A refusal code a module returns: ASCII lowercase letters, digits and `_`. */
function isCode(b) {
if (b.length === 0) return false;
for (const c of b) {
if (!((c >= 0x61 && c <= 0x7a) || (c >= 0x30 && c <= 0x39) || c === 0x5f)) return false;
}
return true;
}
export async function decode(module, cap, payload, set) {
let inst;
try {
inst = await WebAssembly.instantiate(module, {});
} catch (e) {
return sinkRefusal('module_resources', e);
}
const x = inst.exports;
const call = (name, ...args) => x[name](...args);
const view = () => new Uint8Array(x.memory.buffer);
try {
// 1. The interface's version.
if (call('wai_abi') !== 1) return sinkRefusal('module_result_invalid', 'wai_abi is not 1');
// 2. The capability, the payload and the set, each at an offset from wai_alloc. An empty
// input passes 0, 0, with no call.
const args = [0, 0, 0, 0, 0, 0];
const inputs = [ENCODER.encode(cap), payload, set];
for (let i = 0; i < 3; i++) {
const b = inputs[i];
if (b.length === 0) continue;
const at = call('wai_alloc', b.length) >>> 0;
if (at === 0) return sinkRefusal('module_resources', 'wai_alloc gave 0');
const mem = view();
if (at + b.length > mem.length) return sinkRefusal('module_result_invalid', 'wai_alloc gave a region outside the memory');
mem.set(b, at);
args[2 * i] = at;
args[2 * i + 1] = b.length;
}
// 3. The run.
const status = call('wai_run', ...args);
// 4. The output.
const ptr = call('wai_out_ptr') >>> 0;
const len = call('wai_out_len') >>> 0;
const mem = view();
if (ptr + len > mem.length) return sinkRefusal('module_result_invalid', 'the output lies outside the memory');
const out = mem.slice(ptr, ptr + len);
// 5. What it is.
if (status === 0) return { output: out };
if (status === 1) return isCode(out) ? { refused: DECODER.decode(out) } : sinkRefusal('module_result_invalid', 'a refusal that is not a code');
return sinkRefusal('module_result_invalid', `wai_run gave ${status}`);
} catch (e) {
if (e instanceof WebAssembly.RuntimeError) return sinkRefusal('module_trap', e.message);
return sinkRefusal('module_trap', e);
}
}