Round 3 of the package review. A. §3.2: an override only forces royalty_free_only on. Overrides.royalty_free_only is a bool (force on); Policy::effective ORs it in. Both verifiers read policy.json's royalty_free_only as that override, so a policy.json of false over a policy.toml of true is policy-json-mismatch. pack_verify.py parses policy.toml, applies the override, then checks §3.6 under the effective policy (§11.3 step 4), no longer refusing at the parse. Corpus case policy-json-relaxes-royalty-free (the review's pk-pol-rfo-false: a patent-pool floor relabelled through the objects and index, sealed with policy.json false). golden::reseal_as seals a policy.json given as bytes. The policy corpus's override case is now eq-defaults-a.toml forced on (example.toml forced off was a relaxation); packs.rs takes the line out of the policy instead. B. pack_verify.py's strict walk raises on a directory it cannot read (os.walk onerror) and refuses it, as read_strict does. C. Both verifiers refuse a directory below the package that holds nothing (unexpected-file); §11.1 says "no other file or directory". Corpus cases empty-directory, empty-dot-directory (.git/refs) and unreadable-directory (mode 0, or empty where the platform has no modes). Package cases are now written out and verified as directories by both verifiers (golden::package_case_verdict). D. wai-pack pack refuses an --out that exists and is not empty (pack-out-not-empty, pack::out_dir_ready), before any work; §11.4 and §12. refusals.rs runs the command line: a stale claim left alone, a file in the way, an empty and a new directory packed and verified. E. A class named classic in any case is pack-id (eq_ignore_ascii_case); corpus case class-named-classic-in-capitals. F. review.rs deep_alterations_never_panic: 300 seeded rounds of floor-unit, framing, base-payload and index-field alterations through golden::replace_object and a re-seal; never a panic; anything accepted is in a stated equivalence class (AV1 frame data, producer statements, equivalent WIV1 encodings) or the golden itself. Floors: review 9, refusals 5. Co-Authored-By: Claude Opus 5.5 <[email protected]>
226 lines
11 KiB
Rust
226 lines
11 KiB
Rust
//! Every refusal of the packer this revision names (packaging §7.3, §11.4, §12), each from
|
|
//! the golden's inputs with one thing changed: the supplied floor's reasons, what this
|
|
//! revision does not pack yet, a meter that gives no figure, the encoder's caps, and an
|
|
//! output directory that is not empty.
|
|
|
|
use std::collections::BTreeMap;
|
|
use std::path::{Path, PathBuf};
|
|
|
|
type Files = BTreeMap<String, Vec<u8>>;
|
|
|
|
fn corpus() -> PathBuf {
|
|
Path::new(env!("CARGO_MANIFEST_DIR")).join("../pack-conformance")
|
|
}
|
|
|
|
fn golden_policy() -> String {
|
|
String::from_utf8(std::fs::read(corpus().join("packs/video-base-01/policy.toml")).unwrap()).unwrap()
|
|
}
|
|
|
|
fn golden_floor() -> Vec<u8> {
|
|
std::fs::read(corpus().join("packs/video-base-01/floor/v.obu")).unwrap()
|
|
}
|
|
|
|
/// The golden policy with its floor pinned to the listing of `floor`, and `edit` applied.
|
|
fn policy_for(floor: &Files, edit: &dyn Fn(String) -> String) -> Vec<u8> {
|
|
let listing = wai_pack::floor::listing_sha256(floor).unwrap();
|
|
let p = golden_policy();
|
|
let at = p.find("supplied_listing = \"").unwrap() + "supplied_listing = \"".len();
|
|
let p = format!("{}{listing}{}", &p[..at], &p[at + 64..]);
|
|
edit(p).into_bytes()
|
|
}
|
|
|
|
fn pack(policy: &[u8], floor: Files, meter: Option<Box<dyn wai::energy_meter::Meter>>) -> String {
|
|
let mut o = wai_pack::pack::PackOpts::new(ed25519_dalek::SigningKey::from_bytes(&[0x5a; 32]), "did:key:test", floor);
|
|
o.meter = meter;
|
|
o.power_reader = "model".into();
|
|
o.issued_at = "2026-10-06T00:00:00Z".into();
|
|
let mut src = BTreeMap::new();
|
|
src.insert("v".to_string(), wai_pack::fixture::generate("video-base-01").unwrap());
|
|
match wai_pack::pack::pack(policy, &src, &mut o) {
|
|
Ok(_) => "ok".into(),
|
|
Err(e) => e.code,
|
|
}
|
|
}
|
|
|
|
fn units() -> Vec<Vec<u8>> {
|
|
wai_pack::av1::temporal_units(&golden_floor()).unwrap().iter().map(|t| t.bytes()).collect()
|
|
}
|
|
|
|
fn floor_of(stream: Vec<u8>) -> Files {
|
|
let mut f = BTreeMap::new();
|
|
f.insert("v.obu".to_string(), stream);
|
|
f
|
|
}
|
|
|
|
fn case(stream: Vec<u8>, edit: &dyn Fn(String) -> String) -> String {
|
|
let fl = floor_of(stream);
|
|
pack(&policy_for(&fl, edit), fl, None)
|
|
}
|
|
|
|
/// §7.3: each reason a supplied floor is refused with, before anything is written.
|
|
#[test]
|
|
fn every_floor_reason() {
|
|
let u = units();
|
|
let id = |p: String| p;
|
|
assert_eq!(case(golden_floor(), &id), "ok");
|
|
// No floor rung.
|
|
assert_eq!(
|
|
case(golden_floor(), &|p: String| p.replace("[[ladder]]\nid = \"f0\"\ncomponent = \"v\"\ncapability = \"wai.video.av1\"\nrole = \"floor\"\nparams = { source = \"supplied\" }\n", "")),
|
|
"floor-missing"
|
|
);
|
|
// A listing the policy does not pin.
|
|
let fl = floor_of(golden_floor());
|
|
let mut pol = String::from_utf8(policy_for(&fl, &id)).unwrap();
|
|
let at = pol.find("supplied_listing = \"").unwrap() + "supplied_listing = \"".len();
|
|
pol.replace_range(at..at + 64, &"0".repeat(64));
|
|
assert_eq!(pack(pol.as_bytes(), fl, None), "floor-listing-mismatch");
|
|
// No stream for the component.
|
|
let mut other = BTreeMap::new();
|
|
other.insert("w.obu".to_string(), golden_floor());
|
|
assert_eq!(pack(&policy_for(&other, &id), other, None), "floor-stream-missing");
|
|
// A stream cut inside its last unit; an empty stream.
|
|
let g = golden_floor();
|
|
assert_eq!(case(g[..g.len() - 3].to_vec(), &id), "floor-av1-malformed");
|
|
assert_eq!(case(Vec::new(), &id), "floor-av1-malformed");
|
|
// One unit short.
|
|
assert_eq!(case(u[..u.len() - 1].concat(), &id), "floor-frame-count");
|
|
// The piece of frames 85 to 134 opening on an inter frame, with no key frame
|
|
// anywhere in it.
|
|
let mut inter = u.clone();
|
|
inter[85] = u[86].clone();
|
|
assert_eq!(case(inter.concat(), &id), "floor-keyframe-mismatch");
|
|
// A key frame inside piece 2: refused, unless extra key frames are allowed.
|
|
let mut extra = u.clone();
|
|
extra[86] = u[85].clone();
|
|
assert_eq!(case(extra.concat(), &id), "floor-keyframe-mismatch");
|
|
assert_eq!(case(extra.concat(), &|p: String| p.replace("[floor]\n", "[floor]\nextra_keyframes = true\n")), "ok");
|
|
}
|
|
|
|
/// §11.4: what this revision does not pack yet is refused by name, every
|
|
/// `pack-capability-unsupported` naming its capability.
|
|
#[test]
|
|
fn what_this_revision_does_not_pack() {
|
|
let fl = floor_of(golden_floor());
|
|
let run = |edit: &dyn Fn(String) -> String| pack(&policy_for(&fl, edit), fl.clone(), None);
|
|
// Another medium, and two components.
|
|
assert_eq!(run(&|p: String| p.replace("media = \"video\"", "media = \"image\"")), "pack-media-unsupported");
|
|
assert_eq!(
|
|
run(&|p: String| p.replace("[segmentation]", "[[component]]\nid = \"a\"\nmedia = \"audio\"\n\n[component.timebase]\nnum = 48000\nden = 1\n\n[[ladder]]\nid = \"ab\"\ncomponent = \"a\"\ncapability = \"wai.audio.flac\"\nrole = \"base\"\n\n[segmentation]")),
|
|
"pack-media-unsupported"
|
|
);
|
|
// A refinement rung.
|
|
assert_eq!(
|
|
run(&|p: String| p.replace("[floor]", "[[ladder]]\nid = \"r1\"\ncomponent = \"v\"\ncapability = \"wai.video.int_refine\"\nrole = \"refinement\"\nrefines = \"b0\"\nparams = { q = 6 }\n\n[live]\nlayer_lag_ms = [0, 200]\n\n[floor]")),
|
|
"pack-refinement-unsupported"
|
|
);
|
|
// A rule's ladder subset.
|
|
assert_eq!(
|
|
run(&|p: String| format!("{p}\n[[rule]]\nid = \"s\"\nwhen = {{ piece_kind = [\"static\"] }}\nthen = {{ ladder = [\"b0\", \"f0\"] }}\n")),
|
|
"pack-rule-ladder-unsupported"
|
|
);
|
|
// A floor to encode.
|
|
assert_eq!(run(&|p: String| p.replace("params = { source = \"supplied\" }", "params = { source = \"encode\" }")), "pack-floor-encode-unsupported");
|
|
// A base of another capability; two bases; a floor of another capability.
|
|
assert_eq!(
|
|
run(&|p: String| p.replace("capability = \"wai.video.int_motion\"\nrole = \"base\"\nparams = { block = 16, search = 4, mv_precision = 1, q_candidates = [16, 12, 8], max_sse_px_milli = 30000 }", "capability = \"wai.image.png\"\nrole = \"base\"")),
|
|
"pack-capability-unsupported:wai.image.png"
|
|
);
|
|
assert_eq!(
|
|
run(&|p: String| p.replace("[floor]", "[[ladder]]\nid = \"b1\"\ncomponent = \"v\"\ncapability = \"wai.image.png\"\nrole = \"base\"\n\n[floor]")),
|
|
"pack-capability-unsupported:wai.image.png"
|
|
);
|
|
assert_eq!(
|
|
run(&|p: String| p.replace("capability = \"wai.video.av1\"\nrole = \"floor\"\nparams = { source = \"supplied\" }", "capability = \"wai.image.png\"\nrole = \"floor\"")),
|
|
"pack-capability-unsupported:wai.image.png"
|
|
);
|
|
}
|
|
|
|
/// A meter that was asked for and gives no figure refuses the pack: a model past its
|
|
/// range, and one whose figure rounds to nothing.
|
|
#[test]
|
|
fn a_meter_with_no_figure_refuses_the_pack() {
|
|
let fl = floor_of(golden_floor());
|
|
let pol = policy_for(&fl, &|p: String| p);
|
|
let clock = |step: u64| {
|
|
let mut t = 0u64;
|
|
move || {
|
|
let v = t;
|
|
t += step;
|
|
v
|
|
}
|
|
};
|
|
let huge = wai::energy_meter::ModelMeter::new(clock(1_000_000), u64::MAX / 2);
|
|
assert_eq!(pack(&pol, fl.clone(), Some(Box::new(huge))), "pack-meter");
|
|
let tiny = wai::energy_meter::ModelMeter::new(clock(1), 1);
|
|
assert_eq!(pack(&pol, fl.clone(), Some(Box::new(tiny))), "pack-meter");
|
|
let fine = wai::energy_meter::ModelMeter::new(clock(1_000_000), 500);
|
|
assert_eq!(pack(&pol, fl, Some(Box::new(fine))), "ok");
|
|
}
|
|
|
|
/// The encoder's caps (the review's clipcap): a 4K piece of 50 frames is past the clip
|
|
/// cap (more than 2^30 samples), refused for that before anything is allocated or any
|
|
/// frame is read; the packer reports it `pack-encode`.
|
|
#[test]
|
|
fn the_encoder_refuses_a_piece_past_its_caps() {
|
|
let (h, w) = (2160u32, 3840u32);
|
|
let frames: Vec<Vec<u8>> = (0..50).map(|_| Vec::new()).collect();
|
|
let p = wai_pack::encode::MotionParams { block: 16, search: 7, mv_precision: 2, q_candidates: vec![8], max_sse_px_milli: 0 };
|
|
let e = wai_pack::encode::choose_q(&frames, h, w, &p).map(|q| q.q).unwrap_err();
|
|
assert_eq!((e.code(), e.detail()), ("too_large", "the clip exceeds the clip cap"));
|
|
// One frame fewer than the cap allows passes the caps (and is then refused for its
|
|
// frames, which hold nothing).
|
|
let n = ((1u64 << 30) / (3 * h as u64 * w as u64)) as usize;
|
|
let e = wai_pack::encode::choose_q(&frames[..n], h, w, &p).map(|q| q.q).unwrap_err();
|
|
assert_ne!(e.code(), "too_large", "{e}");
|
|
}
|
|
|
|
/// §11.4: `wai-pack pack` writes a package only into a new or empty directory. Into one
|
|
/// that holds a file (a measurement claim of an earlier pack, here) it refuses with
|
|
/// `pack-out-not-empty` before any work, and leaves the directory as it was; into an
|
|
/// empty one it packs a package that verifies.
|
|
#[test]
|
|
fn the_packer_refuses_an_out_directory_that_is_not_empty() {
|
|
let bin = env!("CARGO_BIN_EXE_wai-pack");
|
|
let dir = std::env::temp_dir().join(format!("wai-pack-out-{}", std::process::id()));
|
|
let _ = std::fs::remove_dir_all(&dir);
|
|
std::fs::create_dir_all(&dir).unwrap();
|
|
let src = dir.join("v.y4m");
|
|
std::fs::write(&src, wai_pack::fixture::generate("video-base-01").unwrap()).unwrap();
|
|
let golden = corpus().join("packs/video-base-01");
|
|
let run = |out: &Path| {
|
|
std::process::Command::new(bin)
|
|
.arg("pack")
|
|
.arg("--policy")
|
|
.arg(golden.join("policy.toml"))
|
|
.arg("--out")
|
|
.arg(out)
|
|
.arg("--key")
|
|
.arg(golden.join("key.hex"))
|
|
.arg("--source")
|
|
.arg(format!("v={}", src.display()))
|
|
.output()
|
|
.unwrap()
|
|
};
|
|
// A directory holding an earlier pack's measurement claim.
|
|
let stale = dir.join("stale");
|
|
std::fs::create_dir_all(stale.join("claims")).unwrap();
|
|
std::fs::write(stale.join("claims/old.measurement.json"), b"{}").unwrap();
|
|
let o = run(&stale);
|
|
assert!(!o.status.success());
|
|
let err = String::from_utf8_lossy(&o.stderr);
|
|
assert!(err.contains("pack-out-not-empty"), "{err}");
|
|
let left = wai_pack::verify::read_strict(&stale).unwrap();
|
|
assert_eq!(left.keys().collect::<Vec<_>>(), ["claims/old.measurement.json"], "nothing written");
|
|
// A file where the directory would be.
|
|
let file = dir.join("a-file");
|
|
std::fs::write(&file, b"x").unwrap();
|
|
assert!(String::from_utf8_lossy(&run(&file).stderr).contains("pack-out-not-empty"));
|
|
// An empty directory, and one that does not exist yet.
|
|
std::fs::create_dir_all(dir.join("empty")).unwrap();
|
|
for out in [dir.join("empty"), dir.join("new")] {
|
|
let o = run(&out);
|
|
assert!(o.status.success(), "{}", String::from_utf8_lossy(&o.stderr));
|
|
assert!(wai_pack::verify::verify_dir(&out).is_ok(), "the package verifies");
|
|
}
|
|
let _ = std::fs::remove_dir_all(&dir);
|
|
}
|