wai: the record made true #201
Loading…
Reference in a new issue
No description provided.
Delete branch "wai/d1-record-true"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Makes WAI's own record match its code, adds the protected-content lanes and the reader limits, and adds
wai/SECURITY.md.What changed
1. The QAT claim. SPEC §5 and determinism-tiers §5 said
wai.neural.int_synthdecodes "QAT weights". No committed model was trained that way. The trained corpus vector came fromtools/wai_int_synth_real.py: float training, then post-training quantisation with each layer's shift derived from its measured activation range. The synthetic vectors' weights are generated from a seed. Both texts, the capability comment, the module doc and a test comment now say this.tools/wai_int_synth_qat.pyis now marked experimental: it trains against one fixed shift and no committed model came from it.tools/wai_int_synth_export.pynames the working path. I also searched for "QAT", "quantization-aware" and "trained in integer" across the tree and checked each hit against its training tool. The otherint_*codecs and JPEG AI were already described as post-training quantised.ternary-ttcompared itself to QAT, and now compares itself toint_hyperinstead.2. Stale paths.
neural/int_synth.rs; the file isint_synth.rsat the crate root.wai-rs/src/quantum_ops.rs; it lives inwai-quantum.quantum_receipta feature list it no longer has..cargo/config.tomlthat does not exist;build.rsfinds libFLAC.The section-refs check was already green. A scan of every relative link and backticked path in the WAI texts found these and nothing else stale.
3. SPEC §6.5, "Protected content: two lanes" (normative).
Lane A, hardware-protected content. The media is decrypted and decoded inside the platform's protected media path. This revision registers no
security.encryptionvalue for it. WAI attests only its records about such a title: the served manifest, the segment map, the key-release decisions and the content hashes of WAI objects. None of them covers a decoded frame. Parametric synthesis is allowed only inside a decoder the protection system certifies, and it gets no tier and no output digest.Lane B,
mls-sframe. The application decrypts, so every record and tier applies as it does to plaintext. The section states that Lane B is not a protected-path robustness level and must not be offered for a licence term that requires one.Tier scope. determinism-tiers §5 gains a subsection on where
decode-equivalenceholds:412a08c5, and the release build validates with SIMD and relaxed-SIMD disabled;A WebAssembly decoder at the tier uses no relaxed-SIMD instruction and depends on no NaN's bits. The tier never covers output a sink cannot read.
Pointers. The
wai.video.keysrow and the confidentiality extension now say which lane they belong to.4. Reader limits and
wai/SECURITY.md.The gap. Nothing bounded
man_len. For eight bytes declaring u32::MAX,parse_headasked for 4 GiB (and so didhttp_verify.py).SPEC §2 Reader limits. No reader refuses a manifest for its size or nesting within 2²⁷ bytes (128 MiB) and 127 levels. Any reader may refuse one past those limits. A refusal for length comes from
man_lenalone (manifest_too_large). The layout does not change, and the §8 freeze stands.Why 2²⁷. The limit holds the largest manifest a conforming staged layer has. A
WIR1layer covers up to 2²⁰ units, and aprevwith one run per unit is about 94 MB. The first gate run falsified a 1 MiB limit:staged_resources.rswrites a 1.47 MB layer manifest, which that extension permits.wai-rs.
MANIFEST_MAX_LENis enforced by:manifest_bytes;parse_head(head_malformed);wai-web'spackandpackMulti.The writers also refuse a payload whose length does not fit its u32 field; before, they wrote it modulo 2^32.
include/wai.hgains the constant.Python verifiers.
staged_verify.py,claim_verify.py,pack_verify.pyandhttp_verify.pyapply the same length limit.SECURITY.mdcovers:wai.text.zstdandwai.text.xzdecompress with no output bound, and the fuzz smoke test is in no CI workflow;held_sets, pointing at the privacy rules still to come.Tests, falsified once
container::tests::a_manifest_past_the_reader_limit_is_refused_and_never_written, for both readers andmanifest_bytes, from eight bytes:A 2 MiB manifest round-trips byte for byte. The writers' capped serialiser accepts a manifest at a limit equal to its length and refuses it one byte below. Serialising 128 MiB takes a debug build about 17 s, so the real-size writer check is in
verify_pack.mjs.http_binding::tests::head_parse_refuses_a_manifest_past_the_reader_limit.container::tests::a_manifest_nested_past_127_is_refused: pins the existing nesting limit (127 read, 128 refused).container::tests::a_length_past_a_u32_field_is_refused.verify_pack.mjs(the wasm job):packandpackMultiwrite a 3 MiB manifest and refuse one byte past 2²⁷ (3.6 s, 340 MB locally).Each falsification was run after a commit:
check_manifest_lenfailed both limit tests.u32_fieldtruncate failed its test.packfailedverify_pack.mjs.read_wai1read the over-limit manifest.Each was restored through git and passes. Every changed Python verifier passes its corpus as CI runs it.
Checks
gate.sh d1is GREEN on the head: build, lib tests, carriage, the corpus loop, fast kernels, byte-exact, wasm32 check and the neural gates. The first run was RED onstaged_resourcesand falsified the 1 MiB limit (see above).check-public-names.shandcheck-comparative-prose.sh, file by file, on every changed file. The only prose hits are in CHANGELOG history that main already has, and the check's default scope excludes that file.check-wai-section-refs.py,check-workflow-concurrency.shandcheck-no-vanity-metrics.sh: green.For the owner
SECURITY.mdor the direction notes:held_setsprivacy rules, a follow-up to the HTTP receipts work;🤖 Generated with Claude Code
wai generateandwai score build|render, with native pins a sink checks against a220d16a48Form v0 names the model inside the payload by the SHA-256 of one file, and SPEC §5 never said how that relates to §3.1's parameter-set pin, which governs every GenerativeDeterministic capability: whether a generate envelope carries a pin, or which wins when a pin and `model` disagree. The library registers the set as several files, so a form-less pin over the very file `model` names would be refused form_required. SPEC §5 now states the relation: the model file is the parameter set and `model` its identity; an envelope that names the generator carries no `prior` and a sink refuses one that does, whatever it names. §3.1 says so beside the pin rules, the non-conforming list names it, and prior-carriage §7's row says the set is never pinned and names the file. No library source changes. `wai inspect` and `wai unwrap` reported a generate envelope with a corrupt payload as conforming ("component roles ✓", no payload line). They now report the payload (form v0, with the reader's reason), the intent and any pin of every envelope or WAI2 component that names the generator, ✓ or ✗; inspect's verdict says the envelope does not conform. inspect_and_unwrap_report_the_generators_envelope covers a prompt byte changed in place, the intent improve, a pin over the model file itself, and a WAI2 component with and without a pin. Co-Authored-By: Claude Opus 5.5 <[email protected]>