open-standards/wai/wai-web/demo/verify_int_synth_wasm.mjs
Transaction Science fb103ac5ae wai: one registry table, candidate capabilities, public-text checks
Every registered string now lives in one table (codecs/registry.rs) with
its kind, status, media class, registering SPEC section, edition and
registration date. `wai registry export` writes registry/capabilities.json,
its JSON Schema, the generated table in REGISTRY.md and vocab v2; --check
fails on drift. vocab v1 stays stable.

A candidate capability (a registered string whose payload format no
revision has pinned) must not be emitted. The C packers, the browser
writers and `wai wrap` refuse one, and `codecs::is_dispatchable` is the
single dispatch and selection predicate (SPEC §4): candidates,
companion-only capabilities, records and derivations are not
dispatchable, and an unregistered string is decoded only where the sink
advertises it.

The codec glossary is linked to the registry through a reviewed table and
held to its schema by a library test; `org` becomes `body`, from a closed
allowlist. The SPEC gains §5 sections on kinds and candidates, a §8
edition rule, corrected citations and rewritten appendices. The
quantum-ops vectors are regenerated with neutral device ids.

CI declares the feature-gated test targets with required-features, checks
the registry export, builds wai-web for wasm32, and runs two public-text
checks (comparative prose, and private name patterns) with a self-test.
The specification, extensions, research notes, READMEs, glossary and
source comments are rewritten to name no company or product and to make
no comparisons.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 22:38:09 -04:00

44 lines
2.4 KiB
JavaScript

// Reproducible proof: the wasm32 int_synth decode is byte-identical to the
// frozen NATIVE conformance corpus — i.e. the same learned-codec image, decoded
// in the browser's engine with no ML runtime, verifies against the native hash.
//
// Run via demo/verify_int_synth.sh (builds the nodejs-target pkg first), or:
// node verify_int_synth_wasm.mjs [path/to/wai_web.js] # default: ./pkg-node/wai_web.js
//
// Reads the staged vectors under demo/int_synth/ (copies of the conformance corpus
// ../../neural-conformance/), or, given a second argument, a corpus directory
// laid out like neural-conformance/ (expected_hashes.json + vectors/<name>/).
// Exit 0 iff all four match.
import { readFileSync } from 'node:fs';
import { dirname, resolve } from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url';
const here = dirname(fileURLToPath(import.meta.url));
const pkg = resolve(here, process.argv[2] ?? './pkg-node/wai_web.js');
const wai = await import(pathToFileURL(pkg).href);
const corpus = process.argv[3] ? resolve(process.argv[3]) : null;
const base = corpus ? `${corpus}/vectors` : resolve(here, 'int_synth');
const expected = JSON.parse(readFileSync(`${corpus ?? base}/expected_hashes.json`, 'utf8'));
// The conformance hash is domain-separated: blake3("wai:int-synth-rgb"||0x01||rgb).
const DOMAIN = new Uint8Array([...Buffer.from('wai:int-synth-rgb'), 0x01]);
let pass = true;
for (const name of ['gradient', 'bloom', 'facade', 'photo']) {
const payload = new Uint8Array(readFileSync(`${base}/${name}/latent.bin`));
const spec = new Uint8Array(readFileSync(`${base}/${name}/int_synth.json`));
const img = wai.decodeIntSynth(payload, spec);
const buf = new Uint8Array(DOMAIN.length + img.rgb.length);
buf.set(DOMAIN, 0); buf.set(img.rgb, DOMAIN.length);
const got = wai.blake3Hex(buf);
const exp = expected[name];
const ok = got === exp.rgb_hash && img.width === exp.width && img.height === exp.height
&& img.rgb.length === exp.width * exp.height * 3;
pass = pass && ok;
console.log(`${ok ? 'PASS' : 'FAIL'} ${name.padEnd(9)} ${img.width}x${img.height} ${img.rgb.length}B ${got.slice(0, 16)}… ${got === exp.rgb_hash ? '== frozen native hash' : 'MISMATCH'}`);
}
console.log(pass
? '\n✓ wasm32 int_synth decode is byte-identical to the native conformance corpus — in-browser, zero JS ML runtime.'
: '\n✗ mismatch');
process.exit(pass ? 0 : 1);