wai: reader limits that bound memory (manifest values, text decode), and the codec wrappers in CI #231

Merged
dcharlot merged 13 commits from wai/security-gaps into main 2026-10-13 06:36:49 -04:00

2026-10-13

Transaction Science
wai changelog: record the integer-operator crate, the bounds pass and its certificates
All checks were successful
WAI energy receipts / energy receipts · linux (pull_request) Successful in 2m10s
WAI HTTP delivery / WAI HTTP · does this change touch it (pull_request) Successful in 4s
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Successful in 1m21s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 1m18s
wai-pack / wai-pack · does this change touch it (pull_request) Successful in 4s
wai-quantum WebGPU member / shader checks · browser build · wasip2 inertness · MSRV (pull_request) Successful in 3m8s
wai-quantum WebGPU member / member · software Vulkan (linux) (pull_request) Successful in 1m53s
WAI section references / cited sections exist (pull_request) Successful in 11s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 18m19s
wai-web reach builds / wai-web reach · does this change touch it (pull_request) Successful in 12s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 5m21s
workflow hygiene / every workflow supersedes its own queue (pull_request) Successful in 5s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 2m58s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 1m16s
wai-pack / wai-pack · macos (pull_request) Successful in 1m10s
WAI HTTP delivery / HTTP corpus · falsify mutations 0/3 (pull_request) Successful in 40m1s
WAI HTTP delivery / HTTP corpus · falsify mutations 1/3 (pull_request) Successful in 38m46s
WAI HTTP delivery / HTTP corpus · falsify patches 0/3 (pull_request) Successful in 5m0s
WAI HTTP delivery / HTTP corpus · falsify patches 1/3 (pull_request) Successful in 5m58s
WAI HTTP delivery / HTTP corpus · falsify patches 2/3 (pull_request) Successful in 5m43s
WAI HTTP delivery / HTTP corpus · every patch and mutation in exactly one shard (pull_request) Successful in 4s
WAI HTTP delivery / HTTP corpus · verified both ways, and the differential (pull_request) Successful in 2m23s
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Successful in 1m5s
WAI HTTP delivery / HTTP corpus · falsify mutations 2/3 (pull_request) Successful in 40m37s
wai-pack / wai-pack · linux (pull_request) Successful in 1m19s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 20s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m23s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 4m9s
wai-web reach builds / wai-web reach builds · the package of record, every output as recorded (pull_request) Successful in 2m26s
wai-web reach builds / wai-web reach builds · this tree's wai-web, every rung on its engine line (pull_request) Successful in 4m25s
The two pull requests that added wai-ops, wai-verify, the operator corpus, the
independent certifier and load step 8 wrote no changelog entry. This is it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 01:01:58 -04:00
Transaction Science
wai-conformance: run the manifest memory and reader-equivalence tests
Neither test file was named by any step, so no job ran them. They join the
release step of the cargo-class job on every platform leg.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 00:58:45 -04:00
Transaction Science
Merge main into wai/security-gaps
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 00:55:40 -04:00
Transaction Science
Merge main into wai/security-gaps
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 00:55:39 -04:00
Transaction Science
wai: the refused-layer memory check measures against the envelope's read
The check bounded a refused layer's peak by twice the envelope's length. The
manifest reader now builds its tree at the size counted, within the bound SPEC
§2 states, and that read is the larger part of what a refusal takes, so the old
bound failed and a peak could no longer show a unit decoded after the read. The
check now measures reading the same envelope and bounds what the refusal
allocates beyond it. Falsified: one unit's output allocated before the refusal
fails it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 00:55:29 -04:00

2026-10-12

Transaction Science
wai: the codec wrappers run in CI; SECURITY.md and the changelog say what is bounded
wai-conformance.yml gains codec-wrappers on the macOS runner: fuzz smoke, the
text decode limits and the C entry points, built with the codecs feature, which
no job built before. The step fails when a test binary ran no test.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 20:43:11 -04:00
Transaction Science
wai: the text decode limits in SPEC §2, SECURITY.md and the C header
SPEC §2 gains the reader limits for wai.text.zstd and wai.text.xz: 2^27 decoded
bytes and 2^27 bytes of window or dictionary, with their refusal reasons.
SECURITY.md now states what the manifest readers and the text decoders bound
and which tests measure it, in place of the two gaps it listed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 20:40:30 -04:00
Transaction Science
wai: zstd and xz decode within a bound of their output and window
wai.text.zstd and wai.text.xz decoded the whole stream into memory, so a few
kilobytes could ask for any amount. Both decoders now write at most 2^27 bytes
(text_decoded_too_long) into a buffer that is never sized past that, and give
the decoder at most 2^27 bytes of window or dictionary (text_window_too_large),
refused from the stream's declaration. A zstd frame that declares a longer
content size is refused before anything is decoded. The writers refuse what a
reader may refuse.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 20:34:58 -04:00
Transaction Science
Merge main into wai/security-gaps
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 20:28:02 -04:00

2026-10-11

Transaction Science
wai: the value limit in SPEC §2, the Python verifiers and the HTTP corpus
SPEC §2 states the value limit (2^22, manifest_too_many_values) beside the
length and nesting limits, and what the two bound together. staged_verify,
claim_verify, http_verify and pack_verify refuse past it and check both edges
in memory; the HTTP corpus gains parse_head cases at the limit and one past it
(pad_values), verified by wai_http_vectors and http_verify.py alike.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-11 23:32:44 -04:00
Transaction Science
wai: read a manifest within a bound of its values and length (SPEC §2)
read_manifest and read_manifest_v2 count the manifest's values in the first
pass (refusing past 2^22, manifest_too_many_values), then build one JSON
tree at the sizes counted and move its members into the manifest types, so
no member is held twice as serde's flatten holds it. Every reference reader
(Wai, WaiMulti, the HTTP head) reads through them; the writers refuse what
they refuse.

tests/manifest_parse_memory.rs measures the peak with a counting allocator
against 128 bytes a value plus one a byte; tests/manifest_reader_equivalence.rs
holds the reader to serde's derived reader over every committed envelope and
1488 mutations.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-11 22:57:23 -04:00
Transaction Science
wai: WIP, count a manifest's values before parsing it (SPEC §2 reader limit)
check_manifest_text: one pass refusing a member named twice and more than
2^22 values (manifest_too_many_values); the readers and writers use it.
The memory probe is scratch and will become the measured test.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-11 22:20:30 -04:00