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]>
42 lines
2.3 KiB
JavaScript
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);
|