open-standards/wai/wai-web/demo/verify_int_hyper_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

79 lines
4.1 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Reproducible proof: the wasm32 FULL CONDITIONAL codec decode is byte-identical
// to the native reference — a pretrained learned image codec (PTQ of mbt2018_mean)
// whose whole bitstream→image decode (factorized z, integer h_s, integer-σ
// entropy, integer g_s) runs in the browser engine with NO ML runtime, and whose
// RGB verifies against the native FNV-1a hash. The integer-entropy contract,
// in-browser.
//
// Run via demo/verify_int_hyper.sh (builds the nodejs-target pkg first), or:
// node verify_int_hyper_wasm.mjs [path/to/wai_web.js] [model-dir]
// The model dir (default $WAI_SOTA_INT_DIR or /tmp/sota_int) holds the artifacts
// tools/wai_sota_int_synth_export.py emits (the g_s/h_s model JSONs are large, so
// they are NOT committed — regenerate them with the export tool).
import { readFileSync, existsSync } 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 named = process.argv[3] ?? process.env.WAI_SOTA_INT_DIR;
const dir = resolve(named || '/tmp/sota_int');
// The same rule as wai-rs/tests/support/require_vectors.rs: a missing artifact is a
// failure when WAI_REQUIRE_SOTA_VECTORS is on (any value but empty, 0, false, no), or
// when a directory was named (the argument or WAI_SOTA_INT_DIR); it skips only when
// neither holds and the default location lacks the artifacts.
const sw = (process.env.WAI_REQUIRE_SOTA_VECTORS ?? '').trim().toLowerCase();
const required = !['', '0', 'false', 'no'].includes(sw);
const ARTIFACTS = ['cond.json', 'cond_entropy.json', 'cond_bitstream.json', 'int_synth_sota_model.json',
'int_hs_model.json', 'int_synth_sota_model.bin', 'int_hs_model.bin'];
const missing = ARTIFACTS.filter((f) => !existsSync(`${dir}/${f}`));
if (missing.length) {
if (required || named) {
console.error(`FAIL: missing in ${dir}: ${missing.join(', ')}`
+ (required ? ' (WAI_REQUIRE_SOTA_VECTORS is set)' : ' (the directory was named explicitly)'));
process.exit(1);
}
console.log(`skip: artifacts not in ${dir} (run tools/wai_sota_int_synth_export.py) — NOT VERIFIED`);
process.exit(0);
}
const wai = await import(pathToFileURL(pkg).href);
const bytes = (name) => new Uint8Array(readFileSync(`${dir}/${name}`));
// FNV-1a 64-bit — the same dependency-free checksum the export tool and the
// native Rust decode share (no domain separation; raw RGB bytes).
function fnv1a(buf) {
const mask = (1n << 64n) - 1n;
let h = 14695981039346656037n;
for (let i = 0; i < buf.length; i++) h = ((h ^ BigInt(buf[i])) * 1099511628211n) & mask;
return h.toString(16).padStart(16, '0');
}
const conf = JSON.parse(readFileSync(`${dir}/cond.json`, 'utf8'));
const ent = bytes('cond_entropy.json'); // y Gaussian-conditional + z factorized tables
const bs = bytes('cond_bitstream.json'); // z_rans + y_rans
function check(label, img) {
const got = fnv1a(img.rgb);
const ok = got === conf.rgb_hash
&& img.width === conf.out_w && img.height === conf.out_h
&& img.rgb.length === conf.out_w * conf.out_h * conf.out_c;
console.log(`${ok ? 'PASS' : 'FAIL'} ${label.padEnd(12)} ${img.width}x${img.height} ${img.rgb.length}B `
+ `${got.slice(0, 16)}… ${got === conf.rgb_hash ? '== native hash' : `MISMATCH (want ${conf.rgb_hash})`} `
+ `(${conf.psnr_cond?.toFixed?.(2) ?? '?'} dB)`);
return ok;
}
// JSON model path and the COMPACT BINARY model path must both reproduce the
// native hash (the binary is what the browser demo downloads — ~½ the size).
const json = check('json model', wai.decodeIntHyper(
bytes('int_synth_sota_model.json'), bytes('int_hs_model.json'), ent, bs));
const bin = check('binary model', wai.decodeIntHyperBin(
bytes('int_synth_sota_model.bin'), bytes('int_hs_model.bin'), ent, bs));
const pass = json && bin;
console.log(pass
? '\n✓ wasm32 conditional-codec decode (JSON + compact-binary model) is byte-identical to the native reference — a pretrained learned codec decoded in-browser, zero JS ML runtime.'
: '\n✗ mismatch');
process.exit(pass ? 0 : 1);