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

42 lines
2.3 KiB
JavaScript

// Checks the browser sink's advertised capability menu against the registry:
// every string `known_capabilities()` returns is a registered payload or
// companion capability whose status is `registered` (no candidate, SPEC §5), as
// both the wasm build's own registry (`isCandidate`, `isRegistered`) and the
// committed export wai/registry/capabilities.json say.
//
// node verify_menu.mjs [path/to/wai_web.js] [path/to/capabilities.json]
// The package path is relative to this directory (as in the other verify scripts);
// the export path is relative to the working directory (default: this tree's).
// Exit 0 iff every check holds.
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 exportPath = process.argv[3] ? resolve(process.argv[3]) : resolve(here, '../../registry/capabilities.json');
const wai = await import(pathToFileURL(pkg).href);
const registry = new Map(JSON.parse(readFileSync(exportPath, 'utf8')).capabilities.map((c) => [c.capability, c]));
let pass = true;
const fail = (msg) => { pass = false; console.log(`FAIL ${msg}`); };
const menu = Array.from(wai.known_capabilities());
if (menu.length === 0) fail('the menu is empty');
for (const cap of menu) {
const r = registry.get(cap);
if (!r) { fail(`${cap}: not in ${exportPath}`); continue; }
if (!['payload', 'companion'].includes(r.kind)) fail(`${cap}: kind ${r.kind}, not a payload or companion capability`);
if (r.status !== 'registered') fail(`${cap}: status ${r.status} — a candidate must not be advertised`);
if (wai.isCandidate(cap)) fail(`${cap}: the wasm registry calls it a candidate`);
if (!wai.isRegistered(cap)) fail(`${cap}: the wasm registry does not register it`);
}
// The wasm build's registry agrees with the export on every candidate.
for (const [cap, r] of registry) {
if (['payload', 'companion'].includes(r.kind) && wai.isCandidate(cap) !== (r.status === 'candidate')) {
fail(`${cap}: isCandidate disagrees with the export (${r.status})`);
}
}
console.log(pass ? `PASS the browser menu is registered and names no candidate`
: '\n✗ the browser menu disagrees with the registry');
process.exit(pass ? 0 : 1);