open-standards/wai/wai-pack/Cargo.toml
Transaction Science 07a34c7e36 wai-pack: a still's reader inflates as zlib does; png_diff runs both readers
The reader used miniz_oxide, which accepts a dynamic block whose lone distance
code is longer than one bit. zlib's inflate, and so pack_verify.py, refuses
that block. A golden resealed with such a still verified in wai-pack and was
refused by pack_verify. Both readers now refuse incomplete code sets exactly as
zlib does: the only incomplete literal/length or distance code allowed is one
whose longest code is one bit.

The reader now uses its own inflater (png::inflate_zlib), written from RFC
1950/1951 to zlib's inflate rules:

- the header's check bits, method, window and preset-dictionary flag;
- the stored-block complement;
- the symbol counts;
- a complete code-length code;
- repeats with a length before them and within the code lengths;
- a code for the end of the block;
- over-subscribed and incomplete codes;
- a code with no symbol, or a distance past the bytes written, refused where it
  is read;
- the Adler-32, with nothing after it.

miniz_oxide is kept only as a dev-dependency: the writer's round-trip test reads
its stills back with an inflater independent of the reader's.

packaging §5.7 now states these rules instead of "any PNG reader", and says
that a still the verifier does not read is prefix-digest.

stills/ gains the same dynamic block twice: a lone one-bit distance code
(read) and a lone two-bit one (refused, still-incomplete-dist).

png_diff.py drives wai-pack's reader (a new stage-json op, read-png) against
pack_verify.py's. The inputs are:

- zlib's own streams at every level, strategy and window;
- the packager's own stills;
- dynamic blocks built on each code-set rule (22 kinds, each checked against
  the verdict the rules give it);
- mutations of all of these.

wai-pack.yml runs it in debug and release.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 13:42:54 -04:00

49 lines
2.1 KiB
TOML

[package]
name = "wai-pack"
version = "0.1.0"
edition = "2024"
rust-version = "1.97"
license = "Apache-2.0"
description = "The reference packager of WAI's packaging extension: a declared policy and its digest, scene-cut segmentation with a bounded lookahead, staged packages of refinement layers and stills, live windows, simulated delivery, and the conformance corpus that pins them."
repository = "https://git.transaction.science/Transaction-Science/open-standards"
publish = false
# Its own workspace and Cargo.lock, like the other crates beside wai-rs.
[workspace]
[lib]
name = "wai_pack"
[[bin]]
name = "wai-pack"
path = "src/bin/wai_pack.rs"
[dependencies]
# The standard's crate: canonical JSON and the capability registry (ungated); the
# integer video encoder and decoder (video_int); the stage index and the package receipt
# (video_package); HTTP delivery's codecs union and floor (http); staged measurement's
# counted bytes and output digest (stage_measure); the measurement claim and its figure
# view (receipt_claims); and the model meter (energy_meter). No codec library is linked.
wai = { path = "../wai-rs", default-features = false, features = ["video_int", "video_package", "http", "stage_measure", "receipt_claims", "energy_meter"] }
ed25519-dalek = "2"
# TOML 1.0 (the 0.8 line; later lines read TOML 1.1, which a policy must not use).
toml = { version = "0.8", default-features = false, features = ["parse"] }
serde_json = "1"
blake3 = "1"
sha2 = "0.10"
# Inflate, for the verifier's reader of a still (src/png.rs): an implementation apart from
# the packer's own deflate, so a still is decoded by code that did not write it.
# Release builds check integer overflow as debug builds do, so the release tests in CI
# catch a wrapped product (a field read as u16 and doubled) rather than run past it.
[dev-dependencies]
# An inflater independent of the reader's own, to read the writer's stills back in a test.
miniz_oxide = "0.8"
[profile.release]
overflow-checks = true
# R3 of the design: no float decides anything. The library and the CLI deny float
# arithmetic outright.
[lints.clippy]
float_arithmetic = "deny"