//! Native-sink E2E: decode every shipped `.wai` neural sample through //! the Rust `ort`-backed runtime. Asserts the decoder produces sane //! output (right sample count for audio, right pixel grid for image, //! right frame count for video, and a non-trivial signal in each). //! //! Models are expected at `wai-web/demo/models//decoder.onnx` — //! built via the corresponding `tools/wai__export_onnx.py` once //! per machine (see wai-web/demo/models/README.md). //! //! Skipped (printed, not failed) when a given .onnx isn't present yet, //! so a fresh clone with only some models built still runs the tests //! that can run. #![cfg(feature = "neural")] use std::path::{Path, PathBuf}; use wai::container::{Conditioning, Manifest, ModelRequirement, Prior, Wai}; use wai::neural::{ decode_envelope, decode_envelope_strict, model_sha256, DecodeError, Decoded, ModelRegistry, }; /// The reason a pinned decode was refused with, or a description of what happened. fn refusal(r: Result) -> String { match r { Err(DecodeError::PriorMismatch(why)) => why.code().to_string(), Err(e) => format!("other error: {e}"), Ok(_) => "decoded".into(), } } fn repo_root() -> PathBuf { Path::new(env!("CARGO_MANIFEST_DIR")).join("..").canonicalize().unwrap() } fn model_path(name: &str) -> PathBuf { repo_root().join(format!("wai-web/demo/models/{name}/decoder.onnx")) } fn sample_path(name: &str) -> PathBuf { repo_root().join(format!("wai-web/demo/samples/{name}")) } fn load_envelope(name: &str) -> Wai { let bytes = std::fs::read(sample_path(name)) .unwrap_or_else(|e| panic!("read {name}: {e}")); Wai::from_bytes(&bytes).unwrap_or_else(|e| panic!("parse {name}: {e}")) } fn registry() -> ModelRegistry { ModelRegistry::new() .register("wai.neural.encodec32", model_path("encodec_32khz")) .register("wai.neural.dac", model_path("dac_44khz")) .register("wai.neural.mimi", model_path("mimi")) .register("wai.neural.wavtokenizer", model_path("wavtokenizer")) .register("wai.neural.bmshj2018", model_path("bmshj2018")) .register("wai.neural.video_bmshj2018", model_path("bmshj2018")) // shares the image decoder } fn assert_audio_sane(cap: &str, sample_file: &str, expected_sr: u32, min_samples: usize) { let onnx = model_path(match cap { "wai.neural.encodec32" => "encodec_32khz", "wai.neural.dac" => "dac_44khz", "wai.neural.mimi" => "mimi", "wai.neural.wavtokenizer" => "wavtokenizer", _ => unreachable!(), }); if !onnx.exists() { eprintln!("skipping {cap}: {} not built (see tools/wai__export_onnx.py)", onnx.display()); return; } let env = load_envelope(sample_file); assert_eq!(env.manifest.model_requirement.capability, cap, "{sample_file} declares wrong capability"); let dec = decode_envelope(&env, ®istry()) .unwrap_or_else(|e| panic!("decode {sample_file}: {e}")); match dec { Decoded::Audio(audio) => { assert_eq!(audio.sample_rate, expected_sr, "{cap}: wrong sample rate"); assert!(audio.samples.len() >= min_samples, "{cap}: only {} samples, expected ≥ {}", audio.samples.len(), min_samples); // Non-trivial signal: peak amplitude well above 0. let peak = audio.samples.iter().fold(0f32, |a, &b| a.max(b.abs())); assert!(peak > 0.01, "{cap}: peak={peak:.4} (silent decode?)"); // No NaNs. assert!(audio.samples.iter().all(|s| s.is_finite()), "{cap}: NaN/Inf in output"); println!(" {cap}: {} samples @ {} Hz, peak {:.3}", audio.samples.len(), audio.sample_rate, peak); } _ => panic!("{cap}: expected Decoded::Audio"), } } #[test] fn encodec32_decodes_natively() { assert_audio_sane("wai.neural.encodec32", "glass.encodec.wai", 32_000, 16_000); } #[test] fn dac_decodes_natively() { assert_audio_sane("wai.neural.dac", "glass.dac.wai", 44_100, 22_000); } #[test] fn mimi_decodes_natively() { assert_audio_sane("wai.neural.mimi", "glass.mimi.wai", 24_000, 12_000); } #[test] fn wavtokenizer_decodes_natively() { assert_audio_sane("wai.neural.wavtokenizer", "glass.wavtokenizer.wai", 24_000, 12_000); } #[test] fn bmshj2018_decodes_natively() { let onnx = model_path("bmshj2018"); if !onnx.exists() { eprintln!("skipping bmshj2018: {} not built", onnx.display()); return; } let env = load_envelope("kodim23.bmshj2018.wai"); let dec = decode_envelope(&env, ®istry()).expect("bmshj2018 decode"); match dec { Decoded::Image(img) => { assert_eq!(img.width, 256); assert_eq!(img.height, 256); assert_eq!(img.rgb.len(), 256 * 256 * 3); // Variance: a real image has lots of pixel variation. A blank // decode would be near-constant. let mean = img.rgb.iter().map(|&v| v as f64).sum::() / img.rgb.len() as f64; let var = img.rgb.iter() .map(|&v| (v as f64 - mean).powi(2)).sum::() / img.rgb.len() as f64; assert!(var > 100.0, "bmshj2018: variance {var:.0} suspiciously low"); println!(" bmshj2018: 256x256 RGB, mean={mean:.1}, var={var:.0}"); } _ => panic!("bmshj2018: expected Decoded::Image"), } } /// Determinism is half the `Prior.determinism` contract: a "replicate" claim /// is only meaningful if the same envelope decodes to the same bytes every /// time. Decode twice through the pinned single-thread runtime and require /// bit-identical output. #[test] fn bmshj2018_decode_is_deterministic() { let onnx = model_path("bmshj2018"); if !onnx.exists() { eprintln!("skipping determinism: {} not built", onnx.display()); return; } let env = load_envelope("kodim23.bmshj2018.wai"); let reg = registry(); let rgb = |w: &Wai| match decode_envelope(w, ®).expect("decode") { Decoded::Image(i) => i.rgb, _ => panic!("expected image"), }; let first = rgb(&env); let second = rgb(&env); assert_eq!(first, second, "bmshj2018 decode is not bit-reproducible across runs"); println!(" bmshj2018: byte-identical across two decodes ({} bytes)", first.len()); } /// The pin is enforced over the whole parameter set. `wai.neural.bmshj2018` reads /// `decoder.onnx` and `cdfs_q.json`, so it is registered with several files: a /// form-less pin over the decoder alone is refused (`form_required`) before anything /// is read, and a pin over the listing of the set (`wai.prior.set`) decodes; a pin /// over another listing is refused (`prior_not_held`), never a silent wrong image. #[test] fn pinned_prior_is_enforced() { let onnx = model_path("bmshj2018"); if !onnx.exists() { eprintln!("skipping prior-pin: {} not built", onnx.display()); return; } let base = load_envelope("kodim23.bmshj2018.wai"); let pin = |p: Prior| -> Wai { let mut m = base.manifest.clone(); m.conditioning.prior = Some(p); Wai::new(m, base.payload.clone()) }; let det = "int-rans/p16+onnx-cpu-f32/1thread"; // Form-less over a several-file capability: refused before anything is read. let decoder_only = Prior::new("bmshj2018-factorized/q3", model_sha256(&onnx).unwrap(), det); assert_eq!(refusal(decode_envelope(&pin(decoder_only), ®istry())), "form_required"); // The listing of decoder.onnx and every cdfs_q*.json, in a scratch copy of the set. let dir = std::env::temp_dir().join(format!("wai-bmshj-set-{}", std::process::id())); std::fs::create_dir_all(&dir).unwrap(); let mut names = vec!["decoder.onnx".to_string()]; for e in std::fs::read_dir(onnx.parent().unwrap()).unwrap().flatten() { let n = e.file_name().to_string_lossy().into_owned(); if n.starts_with("cdfs_q") && n.ends_with(".json") { names.push(n); } } for n in &names { std::fs::copy(onnx.parent().unwrap().join(n), dir.join(n)).unwrap(); } let listing = wai::pin::write_listing(&dir, &names).unwrap(); std::fs::write(dir.join("set.sha256"), &listing).unwrap(); let reg = ModelRegistry::new().register("wai.neural.bmshj2018", dir.join("decoder.onnx")); let set_pin = Prior::new("bmshj2018-factorized/q3", wai::pin::sha256_hex(&listing), det) .with_form(wai::codecs::CAP_PRIOR_SET); assert!(matches!(decode_envelope(&pin(set_pin.clone()), ®), Ok(Decoded::Image(_))), "the set pin over decoder.onnx and its CDF tables decodes"); let mut other = set_pin; other.sha256 = "00".repeat(32); assert_eq!(refusal(decode_envelope(&pin(other), ®)), "prior_not_held"); std::fs::remove_dir_all(&dir).ok(); println!(" pin: form-less refused (form_required), set pin decodes, other set refused"); } /// The pin check is pure hashing and runs with no ONNX model present, so this /// exercises SPEC §3.1's verification on every machine. A stand-in file plays the /// one-file parameter set of `wai.neural.encodec32`; the registry must accept the /// true digest and an absent pin, and refuse every other pin with its reason. #[test] fn resolve_checked_verifies_prior_hash() { let path = std::env::temp_dir().join(format!("wai_prior_check_model_{}.bin", std::process::id())); std::fs::write(&path, b"pretend onnx decoder weights v1").unwrap(); let real = model_sha256(&path).expect("hash stand-in model"); const ENCODEC: &str = "wai.neural.encodec32"; let reg = ModelRegistry::new() .register(ENCODEC, path.clone()) .register("wai.neural.bmshj2018", path.clone()); let code = |cap: &str, p: Option<&Prior>| match reg.resolve_verified(cap, p) { Ok(_) => "ok".to_string(), Err(DecodeError::PriorMismatch(r)) => r.code().to_string(), Err(e) => format!("{e:?}"), }; // No pin → unverified pass (the honest meaning of an unpinned decode). assert_eq!(code(ENCODEC, None), "ok"); // The true digest → pass; the verified bytes are the file's. let good = Prior::new("m/q3", real.clone(), "x"); assert_eq!(code(ENCODEC, Some(&good)), "ok"); // Another digest → refused, loudly. assert_eq!(code(ENCODEC, Some(&Prior::new("m/q3", "00".repeat(32), "x"))), "prior_not_held"); // The true digest uppercased is not 64 lowercase hex: malformed, not compared. assert_eq!(code(ENCODEC, Some(&Prior::new("m/q3", real.to_ascii_uppercase(), "x"))), "pin_malformed"); // A form this sink cannot read → refused as unreadable, not as a mismatch. match reg.resolve_verified(ENCODEC, Some(&good.clone().with_form(wai::codecs::CAP_PRIOR_NNC))) { Err(DecodeError::PriorMismatch(why)) => { assert_eq!(why.code(), "form_unreadable"); assert!(why.to_string().contains("wai.prior.nnc") && why.to_string().contains("cannot be read by this sink"), "{why}"); } other => panic!("an unreadable declared form must be refused, got {other:?}"), } // A declared form that is not a registered prior form. match reg.resolve_verified(ENCODEC, Some(&good.clone().with_form("wai.image.png"))) { Err(DecodeError::PriorMismatch(why)) => { assert_eq!(why.code(), "form_not_registered"); assert!(why.to_string().contains("is not a registered prior form"), "{why}"); } other => panic!("a non-form declared as a form must be refused, got {other:?}"), } // The same stand-in under a several-file capability: form-less is refused. assert_eq!(code("wai.neural.bmshj2018", Some(&good)), "form_required"); // Unknown capability → unregistered, regardless of pin. assert!(matches!(reg.resolve_verified("wai.neural.nope", None), Err(DecodeError::ModelNotRegistered(_)))); let _ = std::fs::remove_file(&path); println!(" resolve_verified: none=ok, true=ok, wrong/upper/forms/several-files refused with their reasons"); } #[test] fn video_bmshj2018_decodes_natively() { let onnx = model_path("bmshj2018"); if !onnx.exists() { eprintln!("skipping video_bmshj2018: {} not built", onnx.display()); return; } let env = load_envelope("test.video.wai"); let dec = decode_envelope(&env, ®istry()).expect("video decode"); match dec { Decoded::Video(v) => { assert!(v.frames_rgb.len() > 0, "no frames decoded"); assert_eq!(v.width, 256); assert_eq!(v.height, 256); assert!((v.fps - 12.0).abs() < 0.01, "fps {} != 12", v.fps); // First frame should have non-trivial variance. let f0 = &v.frames_rgb[0]; let mean = f0.iter().map(|&v| v as f64).sum::() / f0.len() as f64; let var = f0.iter().map(|&v| (v as f64 - mean).powi(2)).sum::() / f0.len() as f64; assert!(var > 100.0, "video frame 0 variance {var:.0} suspiciously low"); println!(" video_bmshj2018: {} frames {}x{} @ {} fps", v.frames_rgb.len(), v.width, v.height, v.fps); } _ => panic!("video_bmshj2018: expected Decoded::Video"), } } /// The replicate-soundness gate runs BEFORE any model is touched, so this is /// model-independent. `replicate` promises decode-equivalence (SPEC §7), so the /// capability's registry class decides first: only an integer-exact capability /// can back it, and then only with a pinned integer-exact prior. A prior that /// *declares* an integer contract over a float codec or over JPEG AI (integer /// entropy decode, float later stages) is refused. Non-`replicate` intents are /// unconstrained. #[test] fn strict_decode_gates_unsound_replicate() { fn env(cap: &str, prior: Option, intent: &str) -> Wai { let mut conditioning = Conditioning::new("k"); conditioning.prior = prior; let manifest = Manifest::new("image", intent, ModelRequirement::new(cap), conditioning) .with_target(serde_json::json!({"w": 256, "h": 256})); Wai::new(manifest, vec![]) } let p = |det: &str| Prior::new("m", "ab".repeat(32), det); // An integer-exact network read out of a form not established exact: refused // before any model is touched, and the reason names the form. The envelope is // built here, over an integer-exact capability, so neither the capability nor // the contract can be what refuses it; the same prior without a form passes. { let over_int_synth = |prior: Prior| { Wai::new( Manifest::new("image", "replicate", ModelRequirement::new("wai.neural.int_synth"), Conditioning::new("int_synth").with_prior(prior)) .with_target(serde_json::json!({"w": 256, "h": 256})), vec![], ) }; let exact = p("int-rans/p16+onnx-int8-integerized"); let nnc = exact.clone().with_form(wai::codecs::CAP_PRIOR_NNC); let reg = ModelRegistry::new(); assert!(matches!( decode_envelope_strict(&over_int_synth(exact), ®), Err(DecodeError::ModelNotRegistered(_)) )); match decode_envelope_strict(&over_int_synth(nnc), ®) { Err(DecodeError::UnsoundReplicate(why)) => { assert!(why.contains("wai.prior.nnc"), "the refusal must name the form: {why}"); assert!(!why.contains("not integer-exact"), "the contract is integer-exact: {why}"); } Err(e) => panic!("expected UnsoundReplicate, got {e:?}"), Ok(_) => panic!("expected UnsoundReplicate, got a decode"), } } let integer = p("int-rans/p16+onnx-int8-integerized"); let floaty = p("int-rans/p16+onnx-cpu-f32/1thread"); const FLOAT_CODEC: &str = "wai.neural.bmshj2018"; const INT_CODEC: &str = "wai.neural.int_synth"; const JPEGAI: &str = "wai.image.jpegai"; let reg = ModelRegistry::new(); // empty: the gate fires before model resolution // replicate over a float codec → rejected, whatever the prior declares. for prior in [Some(floaty.clone()), Some(integer.clone()), None] { assert!(matches!( decode_envelope_strict(&env(FLOAT_CODEC, prior, "replicate"), ®), Err(DecodeError::UnsoundReplicate(_)) )); } // replicate over JPEG AI → rejected even with an integer-declared prior: its // registry class is entropy-consistency only. match decode_envelope_strict(&env(JPEGAI, Some(integer.clone()), "replicate"), ®) { Err(DecodeError::UnsoundReplicate(why)) => assert!(why.contains("entropy-consistency"), "{why}"), other => panic!("jpegai replicate must be refused, got {:?}", other.map(|_| ())), } // replicate over the integer-exact codec: float or absent prior → rejected … for prior in [Some(floaty.clone()), None] { assert!(matches!( decode_envelope_strict(&env(INT_CODEC, prior, "replicate"), ®), Err(DecodeError::UnsoundReplicate(_)) )); } // … integer-exact prior → gate PASSES, falls through to model resolution // (ModelNotRegistered proves the gate let it past). assert!(matches!( decode_envelope_strict(&env(INT_CODEC, Some(integer.clone()), "replicate"), ®), Err(DecodeError::ModelNotRegistered(_)) )); // Non-replicate intents aren't constrained by the gate. for cap in [FLOAT_CODEC, JPEGAI] { assert!(matches!( decode_envelope_strict(&env(cap, Some(floaty.clone()), "improve"), ®), Err(DecodeError::ModelNotRegistered(_)) )); } // An unregistered capability is reported as such. assert!(matches!( decode_envelope_strict(&env("wai.image.nope", Some(integer), "replicate"), ®), Err(DecodeError::UnknownCapability(_)) )); println!(" strict gate: class first (float, entropy-only refused), then prior; non-replicate passes"); } /// `wai.neural.int_mlicpp` through the neural dispatch and the strict `replicate` /// gate, on the committed conformance vector (`tests/vectors/int_mlicpp/`, no model /// to fetch, so this never skips). The registered model is the one-file bundle the /// envelope's prior pins: the decode must reproduce the pinned image, a bundle that /// differs by one byte must be refused before anything is decoded, and `replicate` /// with the prior removed must be refused by the gate. The vector's weights are /// synthetic, so this checks the dispatch and the pin, not compression quality. #[test] fn int_mlicpp_decodes_through_the_strict_dispatch() { let d = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/vectors/int_mlicpp"); let bundle = d.join("model.wmb"); let env = Wai::from_bytes(&std::fs::read(d.join("stream.wai")).unwrap()).unwrap(); let expected: serde_json::Value = serde_json::from_slice(&std::fs::read(d.join("expected.json")).unwrap()).unwrap(); let reg = ModelRegistry::new().register("wai.neural.int_mlicpp", &bundle); assert_eq!(model_sha256(&bundle).unwrap(), env.prior().expect("pinned prior").sha256); match decode_envelope_strict(&env, ®) { Ok(Decoded::Image(img)) => { assert_eq!((img.width, img.height), (64, 64)); assert_eq!(format!("{:016x}", wai::int_hyper_synth::fnv1a(&img.rgb)), expected["rgb_fnv1a"].as_str().unwrap(), "the pinned image"); } Ok(_) => panic!("int_mlicpp must decode to an image"), Err(e) => panic!("int_mlicpp strict decode failed: {e}"), } let tampered = std::env::temp_dir().join(format!("wai-int-mlicpp-{}.wmb", std::process::id())); let mut bytes = std::fs::read(&bundle).unwrap(); let at = bytes.len() - 2; bytes[at] ^= 1; std::fs::write(&tampered, &bytes).unwrap(); let refused = decode_envelope_strict(&env, &ModelRegistry::new().register("wai.neural.int_mlicpp", &tampered)); std::fs::remove_file(&tampered).ok(); assert!(matches!(refused, Err(DecodeError::PriorMismatch(_))), "a one-byte-different bundle must be refused"); let mut manifest = env.manifest.clone(); manifest.conditioning.prior = None; let unpinned = Wai::new(manifest, env.payload.clone()); assert!(matches!(decode_envelope_strict(&unpinned, ®), Err(DecodeError::UnsoundReplicate(_))), "replicate without a pinned prior must be refused"); println!(" int_mlicpp: strict dispatch decodes the pinned image; tampered bundle and unpinned replicate refused"); } fn int_mlicpp_dir() -> PathBuf { Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/vectors/int_mlicpp") } fn image_fnv(r: Result) -> String { match r { Ok(Decoded::Image(img)) => format!("{:016x}", wai::int_hyper_synth::fnv1a(&img.rgb)), Ok(_) => "not an image".into(), Err(e) => format!("error: {e}"), } } /// `stream_set.wai` pins the same bundle through its listing (`wai.prior.set`, /// `decode-equivalence`). With `model.wmb` registered, the registry finds the /// listing beside it, verifies it and the bundle, and the strict dispatch decodes the /// pinned image from the verified bytes. #[test] fn int_mlicpp_set_pin_through_the_strict_dispatch() { let d = int_mlicpp_dir(); let env = Wai::from_bytes(&std::fs::read(d.join("stream_set.wai")).unwrap()).unwrap(); let reg = ModelRegistry::new().register("wai.neural.int_mlicpp", d.join("model.wmb")); assert_eq!(image_fnv(decode_envelope_strict(&env, ®)), "7c0b9a4b3423d775"); } /// SPEC §3.1 check 5 at the neural sink: a registry given a key log that holds /// `wai.neural.int_mlicpp`'s pinned sets to jwp-receipts §7.9 refuses the committed set /// once a key log revocation names its digest (`prior_revoked`), refuses it offline /// (`prior_not_authorised`), and decodes it while a current grant holds it. A key log /// that does not hold the capability to §7.9 still refuses the revoked set. The same /// envelope with its pin removed decodes the registered set unpinned, and check 5 runs /// over that set too (SPEC §4, *Module authorisation*). #[cfg(feature = "key_discovery")] #[test] fn int_mlicpp_revoked_set_is_refused_through_the_key_log() { use ed25519_dalek::SigningKey; use wai::key_log::{commitment, Anchor, KeyEntry, KeyStatus, ModuleForm, ModuleGrant, Revision, SinkKeyLog}; const P: &str = "https://publisher.example"; const MLIC: &str = "wai.neural.int_mlicpp"; let key = |s: u8| SigningKey::from_bytes(&[s; 32]); let d = int_mlicpp_dir(); let env = Wai::from_bytes(&std::fs::read(d.join("stream_set.wai")).unwrap()).unwrap(); let digest = wai::pin::sha256(&std::fs::read(d.join("model.sha256")).unwrap()); let sink_held = |revoked: Vec<[u8; 32]>, statuses: bool, held_to: bool| { let unsigned = Revision { origin: P.into(), seq: 0, prev: None, issued_at: "2026-09-01T00:00:00Z".into(), root: [0; 32], next_root: commitment(&key(0x62).verifying_key().to_bytes()), keys: vec![KeyEntry::active("modd", key(0x6b).verifying_key().to_bytes(), &["module/decoder"])], revoked_modules: vec![], grant_max_s: 3_600, status_max_age_s: 600, sig: [0; 64], }; let r0 = Revision::seal(&key(0x61), unsigned.clone()).unwrap(); let r1 = Revision::seal( &key(0x61), Revision { seq: 1, prev: Some(r0.revision_hash()), issued_at: "2026-09-10T00:00:00Z".into(), revoked_modules: revoked, ..unsigned }, ) .unwrap(); let grant = ModuleGrant::seal(&key(0x6b), "did:web:publisher.example#modd", P, digest, ModuleForm::Decoder, &[MLIC], "2026-09-20T05:30:00Z", "2026-09-20T06:30:00Z").unwrap().to_json(); let st = if statuses { vec![KeyStatus::seal(&key(0x61), &r1, "2026-09-20T05:55:00Z").to_json()] } else { vec![] }; let k = SinkKeyLog::new(vec![r0.clone(), r1], vec![Anchor::pinned(P, r0.revision_hash())]) .with_statuses(st) .with_grants(vec![grant]) .at("2026-09-20T06:00:00Z"); if held_to { k.hold_pinned_sets(MLIC, &[P]) } else { k } }; let sink = |revoked: Vec<[u8; 32]>, statuses: bool| sink_held(revoked, statuses, true); let reg = |k: SinkKeyLog| ModelRegistry::new().register(MLIC, d.join("model.wmb")).with_key_log(k); assert_eq!(refusal(decode_envelope(&env, ®(sink(vec![digest], true)))), "prior_revoked"); assert_eq!(refusal(decode_envelope(&env, ®(sink(vec![], false)))), "prior_not_authorised"); assert_eq!(image_fnv(decode_envelope_strict(&env, ®(sink(vec![], true)))), "7c0b9a4b3423d775"); assert_eq!(refusal(decode_envelope(&env, ®(sink_held(vec![digest], true, false)))), "prior_revoked"); assert_eq!(image_fnv(decode_envelope(&env, ®(sink_held(vec![], false, false)))), "7c0b9a4b3423d775"); let mut manifest = env.manifest.clone(); manifest.conditioning.prior = None; let unpinned = Wai::new(manifest, env.payload.clone()); let plain = ModelRegistry::new().register(MLIC, d.join("model.wmb")); assert_eq!(image_fnv(decode_envelope(&unpinned, &plain)), "7c0b9a4b3423d775", "no key log: unpinned decodes"); assert_eq!(refusal(decode_envelope(&unpinned, ®(sink(vec![digest], true)))), "prior_revoked"); assert_eq!(refusal(decode_envelope(&unpinned, ®(sink_held(vec![digest], true, false)))), "prior_revoked"); assert_eq!(refusal(decode_envelope(&unpinned, ®(sink(vec![], false)))), "prior_not_authorised"); assert_eq!(image_fnv(decode_envelope(&unpinned, ®(sink(vec![], true)))), "7c0b9a4b3423d775"); assert_eq!(image_fnv(decode_envelope(&unpinned, ®(sink_held(vec![], false, false)))), "7c0b9a4b3423d775"); // The bundle's own digest, which a form-less pin names, is checked too. let bundle = wai::pin::sha256(&std::fs::read(d.join("model.wmb")).unwrap()); assert_eq!(refusal(decode_envelope(&unpinned, ®(sink_held(vec![bundle], true, false)))), "prior_revoked"); let refused = reg(sink(vec![digest], true)).resolve_verified(MLIC, None); assert!(matches!(refused, Err(DecodeError::PriorMismatch(ref r)) if r.code() == "prior_revoked"), "resolve_verified checks an unpinned set too"); } /// The int_synth decode reads `int_synth.json` beside the registered path, so that /// one file is its parameter set and what a form-less pin covers (SPEC §5). The /// gradient corpus vector, pinned by the digest of its spec, decodes to the corpus /// hash; a pin over another spec is refused. #[test] fn int_synth_pin_covers_the_spec_it_reads() { let src = Path::new(env!("CARGO_MANIFEST_DIR")).join("../neural-conformance/vectors/gradient"); let spec = std::fs::read(src.join("int_synth.json")).unwrap(); let digest = wai::pin::sha256_hex(&spec); assert_eq!(digest, "1c4705d17c01f865b20d785191c7f63b5c18dcc8fce77e15852cf8240b7368be"); let latent = std::fs::read(src.join("latent.bin")).unwrap(); let env = |sha: &str| Wai::new( Manifest::new("image", "replicate", ModelRequirement::new("wai.neural.int_synth"), Conditioning::new("int_synth").with_prior(Prior::new("gradient", sha, "int-synth/i64"))), latent.clone()); // The registered path is the `model` stub the corpus convention uses. let reg = ModelRegistry::new().register("wai.neural.int_synth", src.join("model")); match decode_envelope_strict(&env(&digest), ®) { Ok(Decoded::Image(img)) => { let mut h = blake3::Hasher::new(); h.update(b"wai:int-synth-rgb\x01"); h.update(&img.rgb); assert_eq!(h.finalize().to_hex().as_str(), "1282839b699ad3e79fc810a92ef4220fec7a57a573bb6c844709af4c1fb3f638"); } other => panic!("the spec pin must decode, got {}", image_fnv(other)), } assert_eq!(refusal(decode_envelope(&env(&"ab".repeat(32)), ®)), "prior_not_held"); } /// A key log stand-in that revokes the digests it holds. #[derive(Debug)] struct Revokes(Vec); impl wai::pin::PinAuthority for Revokes { fn check(&self, cap: &str, prior: &Prior) -> Result<(), wai::container::PinRefusal> { self.check_unpinned(cap, std::slice::from_ref(&prior.sha256)) } fn check_unpinned(&self, cap: &str, digests: &[String]) -> Result<(), wai::container::PinRefusal> { if digests.iter().any(|d| self.0.contains(d)) { return Err(wai::container::PinRefusal::Revoked { capability: cap.into(), revoked_by: None }); } Ok(()) } } /// `wai.neural.int_synth` registered as a model directory, or as the `int_synth.json` /// inside it: the decode reads that one file, a form-less pin covers it, and check 5 /// runs over it, so a key log that revokes the spec refuses the unpinned decode either /// way (`prior_revoked`). Without the key log both registrations decode to the corpus /// hash. The unpinned decode reads the bytes check 5 ran over: the spec replaced on /// disk after the registry read it does not change the image. #[test] fn int_synth_check_5_covers_the_spec_a_model_directory_holds() { let cap = "wai.neural.int_synth"; let src = Path::new(env!("CARGO_MANIFEST_DIR")).join("../neural-conformance/vectors/gradient"); let spec = std::fs::read(src.join("int_synth.json")).unwrap(); let latent = std::fs::read(src.join("latent.bin")).unwrap(); let digest = wai::pin::sha256_hex(&spec); let dir = std::env::temp_dir().join(format!("wai-int-synth-dir-{}", std::process::id())); std::fs::create_dir_all(&dir).unwrap(); std::fs::write(dir.join("int_synth.json"), &spec).unwrap(); let env = |prior: Option| { let mut cond = Conditioning::new("int_synth"); if let Some(p) = prior { cond = cond.with_prior(p); } Wai::new(Manifest::new("image", "improve", ModelRequirement::new(cap), cond), latent.clone()) }; let rgb_hash = |r: Result| match r { Ok(Decoded::Image(img)) => { let mut h = blake3::Hasher::new(); h.update(b"wai:int-synth-rgb\x01"); h.update(&img.rgb); h.finalize().to_hex().to_string() } other => refusal(other), }; let want = "1282839b699ad3e79fc810a92ef4220fec7a57a573bb6c844709af4c1fb3f638"; for path in [dir.clone(), dir.join("int_synth.json")] { let revoking = ModelRegistry::new().register(cap, path.clone()).with_key_log(Revokes(vec![digest.clone()])); assert_eq!(refusal(decode_envelope(&env(None), &revoking)), "prior_revoked", "{}", path.display()); let plain = ModelRegistry::new().register(cap, path.clone()); assert_eq!(rgb_hash(decode_envelope(&env(None), &plain)), want, "{}", path.display()); let pin = Prior::new("gradient", digest.clone(), "int-synth/i64"); assert_eq!(rgb_hash(decode_envelope(&env(Some(pin)), &plain)), want, "{}: a form-less pin", path.display()); } let reg = ModelRegistry::new().register(cap, dir.clone()).with_key_log(Revokes(vec![])); let params = reg.resolve_verified(cap, None).expect("the unrevoked spec resolves"); std::fs::copy(src.join("../bloom/int_synth.json"), dir.join("int_synth.json")).unwrap(); assert_eq!(rgb_hash(wai::neural::decode_payload(cap, &latent, ¶ms)), want, "the decode read what check 5 ran over"); std::fs::remove_dir_all(&dir).ok(); } /// For every several-file capability the reference sink dispatches, a form-less pin /// is refused with `form_required` before any file is read — even when its digest is /// the stand-in's own, and even for a capability registered as a directory. #[test] fn several_file_capabilities_need_the_set_form() { let stand_in = std::env::temp_dir().join(format!("wai-several-{}.bin", std::process::id())); std::fs::write(&stand_in, b"stand-in").unwrap(); let digest = model_sha256(&stand_in).unwrap(); let mut n = 0; for &cap in wai::codecs::known_capabilities() { if wai::codecs::parameter_set_shape(cap) != Some(wai::codecs::ParameterSetShape::SeveralFiles) { continue; } let path = if cap == "wai.image.jpegai" { std::env::temp_dir() } else { stand_in.clone() }; let reg = ModelRegistry::new().register(cap, path); let env = Wai::new( Manifest::new("image", "improve", ModelRequirement::new(cap), Conditioning::new("k").with_prior(Prior::new("m", digest.clone(), "x"))), vec![]); assert_eq!(refusal(decode_envelope(&env, ®)), "form_required", "{cap}"); n += 1; } assert!(n > 0); std::fs::remove_file(&stand_in).ok(); } /// A pinned decode reads its parameters only from the bytes it verified: the spec /// file is overwritten after verification, and the decode still gives the image of /// the verified spec. #[test] fn pinned_decode_reads_only_verified_bytes() { let src = Path::new(env!("CARGO_MANIFEST_DIR")).join("../neural-conformance/vectors/gradient"); let dir = std::env::temp_dir().join(format!("wai-verified-bytes-{}", std::process::id())); std::fs::create_dir_all(&dir).unwrap(); std::fs::copy(src.join("int_synth.json"), dir.join("int_synth.json")).unwrap(); let spec = std::fs::read(dir.join("int_synth.json")).unwrap(); let latent = std::fs::read(src.join("latent.bin")).unwrap(); let reg = ModelRegistry::new().register("wai.neural.int_synth", dir.join("model")); let pin = Prior::new("gradient", wai::pin::sha256_hex(&spec), "int-synth/i64"); let params = reg.resolve_verified("wai.neural.int_synth", Some(&pin)).expect("verified"); let before = wai::neural::decode_payload("wai.neural.int_synth", &latent, ¶ms); // Replace the spec on disk with another one (the bloom vector's). std::fs::copy(src.join("../bloom/int_synth.json"), dir.join("int_synth.json")).unwrap(); let after = wai::neural::decode_payload("wai.neural.int_synth", &latent, ¶ms); assert_eq!(image_fnv(before), image_fnv(after), "the decode read the bytes it verified"); // An unpinned decode reads the file as it is now, and so differs (or fails). let unpinned = wai::neural::decode_payload("wai.neural.int_synth", &latent, ®.resolve_verified("wai.neural.int_synth", None).unwrap()); assert_ne!(image_fnv(unpinned), image_fnv(wai::neural::decode_payload("wai.neural.int_synth", &latent, ¶ms))); std::fs::remove_dir_all(&dir).ok(); } /// SPEC §7: the replicate rule reads the capability the envelope decodes through. /// The primary, `wai.image.jpegai`, cannot back `replicate`; the fallback, /// `wai.neural.int_mlicpp`, can, and the pin is the committed bundle's. With only /// the fallback held, and with both held (the primary's form-less pin is then /// refused, `form_required`), the strict decode goes through the fallback and gives /// the pinned image. With only the primary held it is refused before any file is read. #[test] fn strict_gate_reads_the_capability_it_decodes_through() { let d = int_mlicpp_dir(); let committed = Wai::from_bytes(&std::fs::read(d.join("stream.wai")).unwrap()).unwrap(); let mut manifest = committed.manifest.clone(); manifest.model_requirement = ModelRequirement::new("wai.image.jpegai").with_fallback("wai.neural.int_mlicpp"); let env = Wai::new(manifest, committed.payload.clone()); assert_eq!(env.intent(), "replicate"); let only_fallback = ModelRegistry::new().register("wai.neural.int_mlicpp", d.join("model.wmb")); assert_eq!(image_fnv(decode_envelope_strict(&env, &only_fallback)), "7c0b9a4b3423d775"); let both = ModelRegistry::new() .register("wai.image.jpegai", std::env::temp_dir()) .register("wai.neural.int_mlicpp", d.join("model.wmb")); assert_eq!(image_fnv(decode_envelope_strict(&env, &both)), "7c0b9a4b3423d775"); let only_primary = ModelRegistry::new().register("wai.image.jpegai", std::env::temp_dir()); assert!(matches!(decode_envelope_strict(&env, &only_primary), Err(DecodeError::UnsoundReplicate(_)))); } /// SPEC §4 steps 3 and 5 take only a dispatchable capability, so a string the /// sink's registry happens to hold but no dispatch could take (a record, a /// candidate) is not one the strict decode could go through: the strict path's /// early refusal does not read it, and the envelope gets the reason it gets from a /// registry that holds nothing (step 6's missing model), the same reason the /// non-strict path gives. A record has no replicate class, so a gate that read it /// would refuse the envelope as naming an unknown capability. #[test] fn strict_gate_ignores_a_held_capability_it_cannot_dispatch() { use wai::codecs::{capability_kind, is_candidate, registry::CAP_VIDEO_MANIFEST, Kind, CAP_TENSOR_NNC}; let d = int_mlicpp_dir(); let committed = Wai::from_bytes(&std::fs::read(d.join("stream.wai")).unwrap()).unwrap(); assert_eq!(capability_kind(CAP_VIDEO_MANIFEST), Some(Kind::Record)); assert!(is_candidate(CAP_TENSOR_NNC)); for held in [CAP_VIDEO_MANIFEST, CAP_TENSOR_NNC] { let mut manifest = committed.manifest.clone(); manifest.model_requirement = ModelRequirement::new("wai.neural.int_mlicpp").with_fallback(held); let env = Wai::new(manifest, committed.payload.clone()); assert_eq!(env.intent(), "replicate"); let holds = ModelRegistry::new().register(held, std::env::temp_dir()); for (path, got) in [ ("strict, held", decode_envelope_strict(&env, &holds)), ("strict, empty registry", decode_envelope_strict(&env, &ModelRegistry::new())), ("non-strict, held", decode_envelope(&env, &holds)), ] { assert!(matches!(got, Err(DecodeError::ModelNotRegistered(_))), "{held}, {path}: expected ModelNotRegistered, got {:?}", got.map(|_| ())); } } } /// SPEC §4 step 6: when the capability's pinned decode is refused with /// `set_incomplete` (step 3) and the fallback's pin is then refused (step 5), the /// error is step 3's reason. The pin is a `wai.prior.set` listing whose one file is /// not the `int_synth.json` the int_synth decode reads; the fallback holds another set. #[test] fn set_incomplete_at_step_3_outranks_the_fallback_refusal() { let dir = std::env::temp_dir().join(format!("wai-step6-{}", std::process::id())); std::fs::create_dir_all(&dir).unwrap(); std::fs::write(dir.join("other.bin"), b"not the spec").unwrap(); let listing = format!("{} other.bin\n", wai::pin::sha256_hex(b"not the spec")); std::fs::write(dir.join("set.sha256"), &listing).unwrap(); let pin = Prior::new("set", wai::pin::sha256_hex(listing.as_bytes()), "int-synth/i64") .with_form(wai::codecs::CAP_PRIOR_SET); let latent = std::fs::read(Path::new(env!("CARGO_MANIFEST_DIR")) .join("../neural-conformance/vectors/gradient/latent.bin")).unwrap(); let env = Wai::new( Manifest::new("image", "improve", ModelRequirement::new("wai.neural.int_synth").with_fallback("wai.neural.int_mlicpp"), Conditioning::new("int_synth").with_prior(pin)), latent); let reg = ModelRegistry::new() .register("wai.neural.int_synth", dir.join("model")) .register("wai.neural.int_mlicpp", int_mlicpp_dir().join("model.wmb")); let got = refusal(decode_envelope(&env, ®)); std::fs::remove_dir_all(&dir).ok(); assert_eq!(got, "set_incomplete"); } /// SPEC §7.1 step 5 under the strict policy: an entry the replicate rule leaves out /// is reported with its `replicate_*` reason, not as a capability the sink lacks. #[test] fn decode_multi_strict_reports_replicate_reasons() { use wai::container::{Rendition, WaiMulti}; use wai::neural::decode_multi_strict; let d = int_mlicpp_dir(); let pl = Wai::from_bytes(&std::fs::read(d.join("stream.wai")).unwrap()).unwrap().payload; let m = WaiMulti::new("image", "replicate", serde_json::Value::Null, vec![ Rendition::media("wai.image.jpegai", "jpegai", vec![0; 4]), Rendition::media("wai.neural.int_mlicpp", "int_mlicpp", pl) .with_prior(Prior::new("next", "5c".repeat(32), "int-rans/p16+int-mlicpp/i64")), ]); let reg = ModelRegistry::new() .register("wai.image.jpegai", std::env::temp_dir()) .register("wai.neural.int_mlicpp", d.join("model.wmb")); match decode_multi_strict(&m, ®) { Err(DecodeError::NoRendition(r)) => { let codes: Vec<(usize, &str)> = r.iter().map(|(i, why)| (*i, why.split(':').next().unwrap())).collect(); assert_eq!(codes, [(0, "replicate_class"), (1, "prior_not_held")], "{r:?}"); } other => panic!("expected NoRendition, got {:?}", other.map(|(i, _)| i)), } } /// SPEC §7.1 through the neural sink: a `WAI2` envelope carrying the committed /// int_mlicpp payload twice, pinned to a successor set (which names the committed /// bundle in `supersedes`) and to the committed bundle. `decode_multi_strict` skips /// the first, picks the second and decodes the pinned image; without the bundle the /// envelope is inert, with a reason per entry. #[test] fn wai2_decode_multi_picks_the_verified_rendition() { use wai::codecs::DeclaredTier; use wai::container::{Rendition, Supersedes, WaiMulti}; use wai::neural::{decode_multi, decode_multi_strict}; let d = int_mlicpp_dir(); let pl = Wai::from_bytes(&std::fs::read(d.join("stream.wai")).unwrap()).unwrap().payload; let committed = model_sha256(&d.join("model.wmb")).unwrap(); let det = "int-rans/p16+int-mlicpp/i64"; let m = WaiMulti::new("image", "replicate", serde_json::Value::Null, vec![ Rendition::media("wai.neural.int_mlicpp", "int_mlicpp", pl.clone()) .with_prior(Prior::new("next", "5c".repeat(32), det).with_tier(DeclaredTier::DecodeEquivalence) .with_supersedes(Supersedes::new(committed.clone()))), Rendition::media("wai.neural.int_mlicpp", "int_mlicpp", pl) .with_prior(Prior::new("committed", committed, det).with_tier(DeclaredTier::DecodeEquivalence)), ]); let reg = ModelRegistry::new().register("wai.neural.int_mlicpp", d.join("model.wmb")); match decode_multi_strict(&m, ®) { Ok((i, d)) => { assert_eq!(i, 1); assert_eq!(image_fnv(Ok(d)), "7c0b9a4b3423d775"); } Err(e) => panic!("decode_multi_strict: {e}"), } match decode_multi(&m, &ModelRegistry::new()) { Err(DecodeError::NoRendition(r)) => assert_eq!(r.len(), 2), other => panic!("expected NoRendition, got {:?}", other.map(|(i, _)| i)), } let tampered = std::env::temp_dir().join(format!("wai-multi-{}.wmb", std::process::id())); let mut b = std::fs::read(d.join("model.wmb")).unwrap(); b[10] ^= 1; std::fs::write(&tampered, &b).unwrap(); match decode_multi(&m, &ModelRegistry::new().register("wai.neural.int_mlicpp", &tampered)) { Err(DecodeError::NoRendition(r)) => { assert!(r[0].1.starts_with("prior_not_held") && r[1].1.starts_with("prior_not_held"), "{r:?}"); } other => panic!("expected NoRendition, got {:?}", other.map(|(i, _)| i)), } std::fs::remove_file(&tampered).ok(); } /// END-TO-END validation against the real CompressAI mbt2018-mean model: /// decode the SAME envelope in Rust and compare to CompressAI's own decode. /// The Gaussian-conditional entropy decode must be EXACT (same rANS bytes → /// same latents); only `g_s` (ONNX vs torch float) may differ by a hair. A /// large divergence means the entropy decode is wrong. Artifacts produced by /// the export/encode tools + a CompressAI reference decode; skipped if absent. #[test] fn mbt2018_mean_matches_compressai_reference() { let wai = Path::new("/tmp/test.mbt.wai"); let ref_rgb = Path::new("/tmp/ref.rgb"); let model_dir = Path::new("/tmp/wai_mbt"); if !wai.exists() || !ref_rgb.exists() || !model_dir.join("hyper_synthesis.onnx").exists() { eprintln!("skipping mbt reference match: /tmp artifacts not present"); return; } let env = Wai::read(wai).unwrap(); let reg = ModelRegistry::new().register("wai.neural.mbt2018_mean", model_dir.join("model")); let img = match decode_envelope(&env, ®).expect("rust decode") { Decoded::Image(i) => i, _ => panic!("expected image"), }; assert_eq!((img.width, img.height), (256, 256)); let reference = std::fs::read(ref_rgb).unwrap(); assert_eq!(img.rgb.len(), reference.len()); let diffs = || img.rgb.iter().zip(&reference).map(|(a, b)| (*a as i32 - *b as i32).abs()); let maxd = diffs().max().unwrap(); let meand = diffs().map(|d| d as f64).sum::() / reference.len() as f64; println!(" mbt2018_mean vs CompressAI: max|Δ|={maxd} mean|Δ|={meand:.3}"); assert!(maxd <= 4, "Rust decode diverges from CompressAI (max {maxd}) — entropy decode wrong"); } /// END-TO-END validation of the EXISTING factorized `image.rs` decoder against /// the real CompressAI bmshj2018-factorized. Factorized = static CDFs (no /// scale-from-network), so it shouldn't have the hyperprior's bucket-flip /// hazard. Skipped without /tmp artifacts. #[test] fn bmshj2018_matches_compressai_reference() { let wai = Path::new("/tmp/test.bmshj.wai"); let ref_rgb = Path::new("/tmp/ref_bmshj.rgb"); let model = Path::new("/tmp/wai_bmshj/decoder.onnx"); if !wai.exists() || !ref_rgb.exists() || !model.exists() { eprintln!("skipping bmshj reference match: /tmp artifacts not present"); return; } let env = Wai::read(wai).unwrap(); let reg = ModelRegistry::new().register("wai.neural.bmshj2018", model); let img = match decode_envelope(&env, ®).expect("rust decode") { Decoded::Image(i) => i, _ => panic!("expected image"), }; let reference = std::fs::read(ref_rgb).unwrap(); assert_eq!(img.rgb.len(), reference.len()); let diffs = || img.rgb.iter().zip(&reference).map(|(a, b)| (*a as i32 - *b as i32).abs()); let maxd = diffs().max().unwrap(); let meand = diffs().map(|d| d as f64).sum::() / reference.len() as f64; println!(" bmshj2018 vs CompressAI: max|Δ|={maxd} mean|Δ|={meand:.3}"); assert!(maxd <= 4, "bmshj2018 Rust decode diverges from CompressAI (max {maxd})"); } /// END-TO-END validation of the checkerboard CONTEXT decoder (`context.rs`) /// against a minimal CompressAI-compatible elic model run through the actual /// export/encode logic. Validates the 2-pass anchor→context→non-anchor /// orchestration + single-stream symbol order. Skipped without /tmp artifacts. #[test] fn elic_matches_reference() { let wai = Path::new("/tmp/test.elic.wai"); let ref_rgb = Path::new("/tmp/ref_elic.rgb"); let model = Path::new("/tmp/wai_elic/decoder.onnx"); let dir = Path::new("/tmp/wai_elic"); if !wai.exists() || !ref_rgb.exists() || !dir.join("context.onnx").exists() { eprintln!("skipping elic reference match: /tmp artifacts not present"); return; } let env = Wai::read(wai).unwrap(); let reg = ModelRegistry::new().register("wai.neural.elic", model); let img = match decode_envelope(&env, ®).expect("rust elic decode") { Decoded::Image(i) => i, _ => panic!("expected image"), }; let reference = std::fs::read(ref_rgb).unwrap(); assert_eq!(img.rgb.len(), reference.len()); let diffs = || img.rgb.iter().zip(&reference).map(|(a, b)| (*a as i32 - *b as i32).abs()); let maxd = diffs().max().unwrap(); let meand = diffs().map(|d| d as f64).sum::() / reference.len() as f64; println!(" elic vs reference: max|Δ|={maxd} mean|Δ|={meand:.3}"); assert!(maxd <= 4, "elic Rust decode diverges (max {maxd}) — checkerboard orchestration wrong"); } /// END-TO-END validation of the MLIC++ channel-autoregressive decoder /// (`mlicpp.rs`) against a minimal CompressAI-compatible model: K channel /// slices × checkerboard, the entropy net re-run on concat[y_so_far, hyper] as /// context grows. Validates the slice-loop ordering. Skipped without artifacts. #[test] fn mlicpp_matches_reference() { let wai = Path::new("/tmp/test.mlic.wai"); let ref_rgb = Path::new("/tmp/ref_mlic.rgb"); let model = Path::new("/tmp/wai_mlic/decoder.onnx"); let dir = Path::new("/tmp/wai_mlic"); if !wai.exists() || !ref_rgb.exists() || !dir.join("entropy.onnx").exists() { eprintln!("skipping mlicpp reference match: /tmp artifacts not present"); return; } let env = Wai::read(wai).unwrap(); let reg = ModelRegistry::new().register("wai.neural.mlicpp", model); let img = match decode_envelope(&env, ®).expect("rust mlicpp decode") { Decoded::Image(i) => i, _ => panic!("expected image"), }; let reference = std::fs::read(ref_rgb).unwrap(); assert_eq!(img.rgb.len(), reference.len()); let diffs = || img.rgb.iter().zip(&reference).map(|(a, b)| (*a as i32 - *b as i32).abs()); let maxd = diffs().max().unwrap(); let meand = diffs().map(|d| d as f64).sum::() / reference.len() as f64; println!(" mlicpp vs reference: max|Δ|={maxd} mean|Δ|={meand:.3}"); assert!(maxd <= 4, "mlicpp Rust decode diverges (max {maxd}) — slice orchestration wrong"); } /// MLICv2 shares MLIC++'s multi-reference /// channel-autoregressive decode — its gains live in the sink nets. Prove the /// route is LIVE (not just registered): an mlicpp-format envelope relabeled /// `wai.neural.mlicv2` decodes identically through `mlicpp::decode`. #[test] fn mlicv2_routes_through_mlicpp_decoder() { let wai = Path::new("/tmp/test.mlic.wai"); let ref_rgb = Path::new("/tmp/ref_mlic.rgb"); let model = Path::new("/tmp/wai_mlic/decoder.onnx"); let dir = Path::new("/tmp/wai_mlic"); if !wai.exists() || !ref_rgb.exists() || !dir.join("entropy.onnx").exists() { eprintln!("skipping mlicv2 route: /tmp artifacts not present"); return; } let base = Wai::read(wai).unwrap(); let mut m = base.manifest.clone(); m.model_requirement.capability = "wai.neural.mlicv2".into(); let env = Wai::new(m, base.payload.clone()); let reg = ModelRegistry::new().register("wai.neural.mlicv2", model); let img = match decode_envelope(&env, ®).expect("mlicv2 decode") { Decoded::Image(i) => i, _ => panic!("expected image"), }; let reference = std::fs::read(ref_rgb).unwrap(); let maxd = img.rgb.iter().zip(&reference) .map(|(a, b)| (*a as i32 - *b as i32).abs()).max().unwrap(); println!(" mlicv2 (via mlicpp route) vs reference: max|Δ|={maxd}"); assert!(maxd <= 4, "mlicv2 route diverges (max {maxd}) — dispatch not wired"); } /// END-TO-END validation of the SNAC multi-resolution decoder (`snac.rs`): /// N variable-length code levels → dynamic-input ONNX (codes_0..codes_{N-1}) → /// waveform. Validates the multi-level wire parse + dynamic dispatch against a /// clean synthetic decoder of SNAC's interface (the real SNAC model has known /// ONNX-export issues — noise/attention reshapes — which is a sink-side concern, /// not this decoder's). Skipped without /tmp artifacts. #[test] fn snac_matches_reference() { let wai = Path::new("/tmp/test.snac.wai"); let ref_f = Path::new("/tmp/ref_snac.f32"); let model = Path::new("/tmp/wai_snac/decoder.onnx"); if !wai.exists() || !ref_f.exists() || !model.exists() { eprintln!("skipping snac reference match: /tmp artifacts not present"); return; } let env = Wai::read(wai).unwrap(); let reg = ModelRegistry::new().register("wai.neural.snac", model); let audio = match decode_envelope(&env, ®).expect("snac decode") { Decoded::Audio(a) => a, _ => panic!("expected audio"), }; assert_eq!(audio.sample_rate, 24_000); let ref_bytes = std::fs::read(ref_f).unwrap(); let reference: Vec = ref_bytes.chunks_exact(4) .map(|c| f32::from_le_bytes(c.try_into().unwrap())).collect(); assert_eq!(audio.samples.len(), reference.len(), "sample count mismatch"); let maxd = audio.samples.iter().zip(&reference) .map(|(a, b)| (a - b).abs()).fold(0f32, f32::max); println!(" snac vs reference: max|Δ|={maxd:.2e} ({} samples, 3 levels)", audio.samples.len()); assert!(maxd < 1e-4, "snac decode diverges (max {maxd}) — multi-level dispatch wrong"); } /// CMIC (ICLR 2026, −15.91% vs VTM) uses the SCCTX entropy model (space-channel /// context = channel slices + checkerboard) — the mlicpp orchestration; its /// Mamba is in the sink transform. Prove the route is live: an mlicpp-format /// envelope relabeled `wai.neural.cmic` decodes identically. #[test] fn cmic_routes_through_mlicpp_decoder() { let wai = Path::new("/tmp/test.mlic.wai"); let ref_rgb = Path::new("/tmp/ref_mlic.rgb"); let model = Path::new("/tmp/wai_mlic/decoder.onnx"); let dir = Path::new("/tmp/wai_mlic"); if !wai.exists() || !ref_rgb.exists() || !dir.join("entropy.onnx").exists() { eprintln!("skipping cmic route: /tmp artifacts not present"); return; } let base = Wai::read(wai).unwrap(); let mut m = base.manifest.clone(); m.model_requirement.capability = "wai.neural.cmic".into(); let env = Wai::new(m, base.payload.clone()); let reg = ModelRegistry::new().register("wai.neural.cmic", model); let img = match decode_envelope(&env, ®).expect("cmic decode") { Decoded::Image(i) => i, _ => panic!("expected image"), }; let reference = std::fs::read(ref_rgb).unwrap(); let maxd = img.rgb.iter().zip(&reference) .map(|(a, b)| (*a as i32 - *b as i32).abs()).max().unwrap(); println!(" cmic (via mlicpp route) vs reference: max|Δ|={maxd}"); assert!(maxd <= 4, "cmic route diverges (max {maxd}) — dispatch not wired"); } /// END-TO-END validation of the DCVC INTER-frame video decoder /// (`video_dcvc.rs`): a frame loop that propagates a reference feature, decoded /// on CPU via ort (no GPU required). 3 moving frames through a /// minimal hyperprior + temporal-decoder model; the reference feature threads /// frame→frame so frames differ even from similar latents. Skipped w/o artifacts. #[test] fn dcvc_matches_reference() { let wai = Path::new("/tmp/test.dcvc.wai"); let ref_rgb = Path::new("/tmp/ref_dcvc.rgb"); let dir = Path::new("/tmp/wai_dcvc"); if !wai.exists() || !ref_rgb.exists() || !dir.join("temporal_decoder.onnx").exists() { eprintln!("skipping dcvc reference match: /tmp artifacts not present"); return; } let env = Wai::read(wai).unwrap(); let reg = ModelRegistry::new().register("wai.neural.dcvc_rt", dir.join("decoder.onnx")); let video = match decode_envelope(&env, ®).expect("dcvc decode") { Decoded::Video(v) => v, _ => panic!("expected video"), }; assert_eq!(video.frames_rgb.len(), 3, "frame count"); let reference = std::fs::read(ref_rgb).unwrap(); let flat: Vec = video.frames_rgb.concat(); assert_eq!(flat.len(), reference.len(), "total byte count"); let maxd = flat.iter().zip(&reference) .map(|(a, b)| (*a as i32 - *b as i32).abs()).max().unwrap(); // also confirm frames actually differ (temporal propagation did something) let f0_eq_f1 = video.frames_rgb[0] == video.frames_rgb[1]; println!(" dcvc (3 frames, temporal propagation) vs reference: max|Δ|={maxd} frames-differ={}", !f0_eq_f1); assert!(maxd <= 4, "dcvc decode diverges (max {maxd}) — temporal propagation wrong"); } /// END-TO-END validation of the GLC CATEGORICAL decoder (`glc.rs`): codebook /// indices via per-position softmax → CompressAI-exact pmf_to_quantized_cdf → /// bypass-free categorical rANS, over a checkerboard. A minimal VQ model + a /// matching categorical rANS encoder; reference = synthesis(true indices). /// Skipped without /tmp artifacts. #[test] fn glc_matches_reference() { let wai = Path::new("/tmp/test.glc.wai"); let ref_rgb = Path::new("/tmp/ref_glc.rgb"); let dir = Path::new("/tmp/wai_glc"); if !wai.exists() || !ref_rgb.exists() || !dir.join("hyper_entropy.onnx").exists() { eprintln!("skipping glc reference match: /tmp artifacts not present"); return; } let env = Wai::read(wai).unwrap(); let reg = ModelRegistry::new().register("wai.neural.glc", dir.join("decoder.onnx")); let img = match decode_envelope(&env, ®).expect("glc decode") { Decoded::Image(i) => i, _ => panic!("expected image"), }; let reference = std::fs::read(ref_rgb).unwrap(); assert_eq!(img.rgb.len(), reference.len()); let maxd = img.rgb.iter().zip(&reference) .map(|(a, b)| (*a as i32 - *b as i32).abs()).max().unwrap(); println!(" glc (categorical/VQ, 256 indices) vs reference: max|Δ|={maxd}"); assert!(maxd <= 4, "glc decode diverges (max {maxd}) — categorical entropy wrong"); } /// SNAC against the REAL pretrained snac_24khz model (not synthetic): exported /// after model surgery — zero-noise (NoiseBlock's torch.randn made decode /// stochastic; WAI needs determinism) + an export-clean snake. Validates the /// multi-level decoder on the genuine 3-codebook hierarchy. Skipped w/o files. #[test] fn snac_real_model_matches_reference() { let wai = Path::new("/tmp/test.snac_real.wai"); let ref_f = Path::new("/tmp/ref_snac_real.f32"); let model = Path::new("/tmp/wai_snac_real/decoder.onnx"); if !wai.exists() || !ref_f.exists() || !model.exists() { eprintln!("skipping real-snac match: /tmp artifacts not present"); return; } let env = Wai::read(wai).unwrap(); let reg = ModelRegistry::new().register("wai.neural.snac", model); let audio = match decode_envelope(&env, ®).expect("snac decode") { Decoded::Audio(a) => a, _ => panic!("expected audio"), }; assert_eq!(audio.sample_rate, 24_000); let reference: Vec = std::fs::read(ref_f).unwrap() .chunks_exact(4).map(|c| f32::from_le_bytes(c.try_into().unwrap())).collect(); assert_eq!(audio.samples.len(), reference.len()); let maxd = audio.samples.iter().zip(&reference) .map(|(a, b)| (a - b).abs()).fold(0f32, f32::max); println!(" REAL snac_24khz vs torch(deterministic): max|Δ|={maxd:.2e} ({} samples)", audio.samples.len()); assert!(maxd < 1e-3, "real snac decode diverges (max {maxd})"); } /// int_synth against a REAL trained model (not the constructed unit test): a float /// autoencoder trained on synthetic images, then quantised to the integer spec with /// per-layer activation-calibrated shifts. Confirms the Rust integer decode is /// BIT-IDENTICAL to the numpy integer-forward reference on a trained model (the /// determinism guarantee, on real weights). Skipped without /tmp artifacts. #[test] fn int_synth_trained_model_matches_integer_forward() { let wai = Path::new("/tmp/test.intsynth.wai"); let ref_rgb = Path::new("/tmp/ref_intsynth.rgb"); let dir = Path::new("/tmp/wai_intsynth"); if !wai.exists() || !ref_rgb.exists() || !dir.join("int_synth.json").exists() { eprintln!("skipping trained int_synth: /tmp artifacts not present"); return; } let env = Wai::read(wai).unwrap(); let reg = ModelRegistry::new().register("wai.neural.int_synth", dir.join("model")); let img = match decode_envelope(&env, ®).expect("int_synth decode") { Decoded::Image(i) => i, _ => panic!("expected image"), }; let reference = std::fs::read(ref_rgb).unwrap(); assert_eq!(img.rgb.len(), reference.len()); let maxd = img.rgb.iter().zip(&reference) .map(|(a, b)| (*a as i32 - *b as i32).abs()).max().unwrap(); println!(" trained int_synth: Rust vs numpy integer-forward max|Δ|={maxd} (must be 0 — integer-exact)"); assert_eq!(maxd, 0, "Rust integer decode must be bit-identical to the reference"); } /// A temporary directory holding the tiny conditional codec's set under its member /// names (`g_s.whm`, `h_s.whm`, `entropy.json`) and a listing, `set.sha256`, of the /// members `listed`. Returns the directory and the listing's SHA-256. fn int_hyper_set_dir(tag: &str, listed: &[&str]) -> (PathBuf, String) { let v = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/vectors/int_hyper"); let dir = std::env::temp_dir().join(format!("wai-int-hyper-{tag}-{}", std::process::id())); std::fs::create_dir_all(&dir).unwrap(); let mut files = std::collections::BTreeMap::new(); for (member, src) in [("entropy.json", "tiny_entropy.json"), ("g_s.whm", "tiny_g_s.bin"), ("h_s.whm", "tiny_h_s.bin")] { let b = std::fs::read(v.join(src)).unwrap(); std::fs::write(dir.join(member), &b).unwrap(); if listed.contains(&member) { files.insert(member.to_string(), b); } } let view: std::collections::BTreeMap = files.iter().map(|(k, v)| (k.clone(), v.as_slice())).collect(); let listing = wai::pin::listing_from(&view).unwrap(); std::fs::write(dir.join("set.sha256"), &listing).unwrap(); (dir, wai::pin::sha256_hex(&listing)) } /// `wai.neural.int_hyper` through the neural dispatch, which delegates it to /// `int_payload::decode_int`: its `WIH1` payload decodes from the three-file set, pinned /// through the set's listing (under the strict `replicate` gate) and unpinned, to the /// committed image. A pinned set whose listing leaves out `h_s.whm` is refused with /// `set_incomplete` naming it. The tool's JSON output carried as the payload is refused /// (`bad_magic`), and the refusal is final: the fallback the envelope names is not tried. /// An unpinned set without `h_s.whm` refuses a JSON form as `bad_magic` too, the payload /// being checked before any member is read, and a `WIH1` as `set_incomplete`. #[test] fn int_hyper_decodes_through_the_neural_dispatch() { use wai::codecs::{DeclaredTier, CAP_NEURAL_INT_HYPER as HYP, CAP_NEURAL_INT_SYNTH, CAP_PRIOR_SET}; let v = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/vectors/int_hyper"); let payload = std::fs::read(v.join("tiny_bitstream.wih1")).unwrap(); let rgb_sha = "dce7282d46f88f03d5dc0fd42f325756d310fe1fc982b6e1792a1fbfbeb482cf"; let env = |intent: &str, prior: Option, fallback: Option<&str>, payload: Vec| { let mut req = ModelRequirement::new(HYP); if let Some(f) = fallback { req = req.with_fallback(f); } let mut cond = Conditioning::new("int_hyper"); if let Some(p) = prior { cond = cond.with_prior(p); } Wai::new(Manifest::new("image", intent, req, cond), payload) }; let sha = |r: Result| match r { Ok(Decoded::Image(img)) => wai::pin::sha256_hex(&img.rgb), other => refusal(other), }; let (dir, digest) = int_hyper_set_dir("all", &["entropy.json", "g_s.whm", "h_s.whm"]); let reg = ModelRegistry::new().register(HYP, dir.join("g_s.whm")); let pin = Prior::new("tiny", digest, "decode-equivalence").with_form(CAP_PRIOR_SET).with_tier(DeclaredTier::DecodeEquivalence); assert_eq!(sha(decode_envelope_strict(&env("replicate", Some(pin), None, payload.clone()), ®)), rgb_sha); assert_eq!(sha(decode_envelope(&env("improve", None, None, payload.clone()), ®)), rgb_sha); let (part, digest) = int_hyper_set_dir("part", &["entropy.json", "g_s.whm"]); let pin = Prior::new("tiny", digest, "decode-equivalence").with_form(CAP_PRIOR_SET); let r = decode_envelope(&env("improve", Some(pin), None, payload.clone()), &ModelRegistry::new().register(HYP, part.join("g_s.whm"))); assert!(matches!(r, Err(DecodeError::PriorMismatch(wai::container::PinRefusal::SetIncomplete { ref path })) if path == "h_s.whm"), "{}", refusal(r)); let json = std::fs::read(v.join("tiny_bitstream.json")).unwrap(); let spec = Path::new(env!("CARGO_MANIFEST_DIR")).join("../neural-conformance/vectors/gradient/model"); let both = ModelRegistry::new().register(HYP, dir.join("g_s.whm")).register(CAP_NEURAL_INT_SYNTH, spec); for fallback in [None, Some(CAP_NEURAL_INT_SYNTH)] { match decode_envelope(&env("improve", None, fallback, json.clone()), &both) { Err(DecodeError::InvalidPayload(why)) => assert!(why.contains("bad_magic") && why.contains(HYP), "{why}"), other => panic!("a JSON form must be refused as bad_magic, got {}", refusal(other)), } } // An unpinned set that lacks a member: the payload is checked first, so a JSON form // is still bad_magic, and a WIH1 is set_incomplete, naming the member, so dispatch // moves on as it does for any decoder. let (lack, _) = int_hyper_set_dir("lack", &["entropy.json", "g_s.whm", "h_s.whm"]); std::fs::remove_file(lack.join("h_s.whm")).unwrap(); let reg = ModelRegistry::new().register(HYP, lack.join("g_s.whm")); match decode_envelope(&env("improve", None, None, json.clone()), ®) { Err(DecodeError::InvalidPayload(why)) => assert!(why.contains("bad_magic"), "{why}"), other => panic!("a JSON form must be refused as bad_magic, got {}", refusal(other)), } let r = decode_envelope(&env("improve", None, None, payload.clone()), ®); assert!(matches!(r, Err(DecodeError::PriorMismatch(wai::container::PinRefusal::SetIncomplete { ref path })) if path == "h_s.whm"), "{}", refusal(r)); std::fs::remove_dir_all(&dir).ok(); std::fs::remove_dir_all(&part).ok(); std::fs::remove_dir_all(&lack).ok(); } /// The integer video, audio and splat capabilities through the neural dispatch: /// `wai.video.int_motion`, which reads no parameter set, advertised with /// `ModelRegistry::builtin`; `wai.audio.int_codec` and `wai.splat.int_codec`, each /// registered as its one file, unpinned and under a form-less pin over that file. Each /// decodes to `Decoded::Int` in the integer form its digest is taken over, with the /// committed SHA-256. `builtin` does not advertise a capability that reads a set. #[cfg(all(feature = "video_int", feature = "audio_int", feature = "splat_int"))] #[test] fn integer_media_decode_through_the_neural_dispatch() { use wai::codecs::{CAP_AUDIO_INT_CODEC as AUD, CAP_NEURAL_INT_HYPER, CAP_SPLAT_INT_CODEC as SPL, CAP_VIDEO_INT_MOTION as MOT}; use wai::int_payload::IntDecoded; let v = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/vectors"); let rd = |rel: &str| std::fs::read(v.join(rel)).unwrap(); let side = |rel: &str, key: &str, field: &str| -> String { let j: serde_json::Value = serde_json::from_slice(&rd(rel)).unwrap(); j[key][field].as_str().unwrap().to_string() }; let env = |cap: &str, prior: Option, payload: Vec| { let mut cond = Conditioning::new("bytes"); if let Some(p) = prior { cond = cond.with_prior(p); } Wai::new(Manifest::new("binary", "improve", ModelRequirement::new(cap), cond), payload) }; let reg = ModelRegistry::new() .builtin(MOT) .register(AUD, v.join("int_audio/audio_model.bin")) .register(SPL, v.join("int_splat/splat_gs.bin")); assert!(reg.advertises(MOT)); assert!(!ModelRegistry::new().builtin(CAP_NEURAL_INT_HYPER).advertises(CAP_NEURAL_INT_HYPER)); match decode_envelope(&env(MOT, None, rd("int_video/int_video_bitstream.wiv1")), ®) { Ok(Decoded::Int(IntDecoded::Video { frames, width: 48, height: 48 })) => { let per: Vec = frames.iter().flat_map(|f| wai::pin::sha256(f)).collect(); assert_eq!(wai::pin::sha256_hex(&per), side("int_video/sha256.json", "int_video", "clip_sha256")); } other => panic!("int_motion: {}", refusal(other)), } let model = rd("int_audio/audio_model.bin"); for prior in [None, Some(Prior::new("audio", wai::pin::sha256_hex(&model), "decode-equivalence"))] { match decode_envelope(&env(AUD, prior, rd("int_audio/audio_bitstream.wia1")), ®) { Ok(Decoded::Int(IntDecoded::Pcm { samples, sample_rate: 16_000, channels: 1 })) => { let le: Vec = samples.iter().flat_map(|s| s.to_le_bytes()).collect(); assert_eq!(wai::pin::sha256_hex(&le), side("int_audio/sha256.json", "audio", "sha256")); } other => panic!("int_codec: {}", refusal(other)), } } let gs = rd("int_splat/splat_gs.bin"); for prior in [None, Some(Prior::new("splat", wai::pin::sha256_hex(&gs), "decode-equivalence"))] { match decode_envelope(&env(SPL, prior, rd("int_splat/splat.wis1")), ®) { Ok(Decoded::Int(IntDecoded::Attr { bytes, n_attr: 14, s: 32, .. })) => { assert_eq!(wai::pin::sha256_hex(&bytes), side("int_splat/sha256.json", "splat", "sha256")); } other => panic!("splat: {}", refusal(other)), } } } /// An integer capability this build has no decoder for (here `wai.video.int_motion`, /// without `video_int`) is refused with `unsupported_capability`, which is not final: /// SPEC §4 does not take step 3 with a capability the sink cannot decode, so dispatch /// moves on to the fallback, which decodes the payload. Without a fallback the /// capability is reported as unknown. #[cfg(not(feature = "video_int"))] #[test] fn an_integer_capability_without_a_decoder_moves_on_to_the_fallback() { let src = Path::new(env!("CARGO_MANIFEST_DIR")).join("../neural-conformance/vectors/gradient"); let latent = std::fs::read(src.join("latent.bin")).unwrap(); let (mot, synth) = ("wai.video.int_motion", "wai.neural.int_synth"); let reg = ModelRegistry::new().builtin(mot).register(synth, src.join("model")); let env = |fallback: Option<&str>| { let mut req = ModelRequirement::new(mot); if let Some(f) = fallback { req = req.with_fallback(f); } Wai::new(Manifest::new("image", "improve", req, Conditioning::new("int_synth")), latent.clone()) }; match decode_envelope(&env(Some(synth)), ®) { Ok(Decoded::Image(img)) => assert_eq!((img.width, img.height), (38, 38)), other => panic!("the fallback must decode, got {}", refusal(other)), } assert!(matches!(decode_envelope(&env(None), ®), Err(DecodeError::UnknownCapability(ref c)) if c == mot)); } /// A key log stand-in that holds the capability's sets to §7.9 and grants only the /// digests it holds: an unpinned set is authorised only under one of them. #[derive(Debug)] struct Grants(Vec); impl wai::pin::PinAuthority for Grants { fn check(&self, cap: &str, prior: &Prior) -> Result<(), wai::container::PinRefusal> { self.check_unpinned(cap, std::slice::from_ref(&prior.sha256)) } fn check_unpinned(&self, cap: &str, digests: &[String]) -> Result<(), wai::container::PinRefusal> { if digests.iter().any(|d| self.0.contains(d)) { return Ok(()); } Err(wai::container::PinRefusal::NotAuthorised { capability: cap.into(), check: None, reason: None }) } } /// A listing beside the registered path identifies a set only when it matches the /// files the decode reads. A key log that grants only the publisher's listing refuses /// an unpinned decode of other files (`prior_not_authorised`), with a copy of that /// listing beside them or not; the publisher's own files beside the same listing /// decode. The same holds for a one-file capability registered as its file, and for a /// capability outside the integer path (resolved, not decoded: no model is needed). #[test] fn a_listing_that_does_not_match_the_files_read_authorises_nothing() { use wai::codecs::{CAP_AUDIO_INT_CODEC as AUD, CAP_NEURAL_INT_HYPER as HYP}; let code = |r: Result| match r { Ok(_) => "decoded".to_string(), Err(e) => refusal(Err(e)), }; let v = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/vectors"); let root = std::env::temp_dir().join(format!("wai-stale-listing-{}", std::process::id())); let set: std::collections::BTreeMap> = [("entropy.json", "int_hyper/tiny_entropy.json"), ("g_s.whm", "int_hyper/tiny_g_s.bin"), ("h_s.whm", "int_hyper/tiny_h_s.bin")] .into_iter().map(|(k, f)| (k.to_string(), std::fs::read(v.join(f)).unwrap())).collect(); let view: std::collections::BTreeMap = set.iter().map(|(k, b)| (k.clone(), b.as_slice())).collect(); let granted = wai::pin::listing_from(&view).unwrap(); let write = |dir: &Path, files: &std::collections::BTreeMap>, listing: bool| { std::fs::create_dir_all(dir).unwrap(); for (k, b) in files { std::fs::write(dir.join(k), b).unwrap(); } if listing { std::fs::write(dir.join("publisher.sha256"), &granted).unwrap(); } }; let mut other = set.clone(); other.get_mut("entropy.json").unwrap().push(b' '); let env = Wai::new(Manifest::new("image", "improve", ModelRequirement::new(HYP), Conditioning::new("bytes")), std::fs::read(v.join("int_hyper/tiny_bitstream.wih1")).unwrap()); let reg = |dir: &Path| ModelRegistry::new().register(HYP, dir.to_path_buf()).with_key_log(Grants(vec![wai::pin::sha256_hex(&granted)])); for (name, files, listing, want) in [ ("other files", &other, false, "prior_not_authorised"), ("other files beside the granted listing", &other, true, "prior_not_authorised"), ("the granted files beside their listing", &set, true, "decoded"), ] { let dir = root.join(name.replace(' ', "-")); write(&dir, files, listing); assert_eq!(code(decode_envelope(&env, ®(&dir))), want, "{name}"); } // One file: the publisher's model.wam is granted under its listing; the sink's file // differs in its last byte. let model = std::fs::read(v.join("int_audio/audio_model.bin")).unwrap(); let one: std::collections::BTreeMap = [("model.wam".to_string(), model.as_slice())].into_iter().collect(); let pub_listing = wai::pin::listing_from(&one).unwrap(); let mut tampered = model.clone(); *tampered.last_mut().unwrap() ^= 1; let dir = root.join("audio"); std::fs::create_dir_all(&dir).unwrap(); std::fs::write(dir.join("model.wam"), &tampered).unwrap(); std::fs::write(dir.join("publisher.sha256"), &pub_listing).unwrap(); let envw = Wai::new(Manifest::new("audio", "improve", ModelRequirement::new(AUD), Conditioning::new("bytes")), std::fs::read(v.join("int_audio/audio_bitstream.wia1")).unwrap()); let reg = ModelRegistry::new().register(AUD, dir.join("model.wam")).with_key_log(Grants(vec![wai::pin::sha256_hex(&pub_listing)])); assert_eq!(code(decode_envelope(&envw, ®)), "prior_not_authorised", "a one-file set beside a stale listing"); // A capability outside the integer path: the listing must match the files beside it // and name the registered file. let cap = "wai.neural.bmshj2018"; let dir = root.join("onnx"); std::fs::create_dir_all(&dir).unwrap(); std::fs::write(dir.join("decoder.onnx"), b"publisher").unwrap(); let onnx: std::collections::BTreeMap = [("decoder.onnx".to_string(), &b"publisher"[..])].into_iter().collect(); let l = wai::pin::listing_from(&onnx).unwrap(); std::fs::write(dir.join("publisher.sha256"), &l).unwrap(); let reg = || ModelRegistry::new().register(cap, dir.join("decoder.onnx")).with_key_log(Grants(vec![wai::pin::sha256_hex(&l)])); assert!(reg().resolve_verified(cap, None).is_ok(), "the granted file beside its listing resolves"); std::fs::write(dir.join("decoder.onnx"), b"other").unwrap(); assert!(matches!(reg().resolve_verified(cap, None), Err(DecodeError::PriorMismatch(ref r)) if r.code() == "prior_not_authorised"), "another file beside the granted listing is not authorised"); std::fs::remove_dir_all(&root).ok(); } /// Outside the integer path, a granted listing authorises the files it names and /// nothing else: at a sink whose key log holds the capability's sets to §7.9, the /// unpinned decode reads only the part §7.9 authorised of what it read once /// (`ParamSource::Checked`), and a file the decode needs that the part does not name /// is `set_incomplete`, never read from disk. A `wai.neural.bmshj2018` payload reads /// its CDF tables (`cdfs_q3.json`) before it loads the decoder, so a decode that read /// the unauthorised tables beside the decoder would fail parsing them instead. /// /// - the decoder registered as its file, beside a granted listing that names only /// `decoder.onnx` and an unauthorised `cdfs_q3.json`: `set_incomplete`; /// - the directory registered, beside a granted listing that names only `notes.txt`: /// `set_incomplete`; /// - a granted listing of both files: the decode reads the tables from the set; /// - a one-file capability granted under its file's digest: that file alone; /// - a key log that only revokes: every file of the decoder's directory, read once. #[test] fn a_granted_listing_authorises_only_the_files_it_names() { use wai::neural::ParamSource; use wai::pin::Verified; let bm = "wai.neural.bmshj2018"; let dir = std::env::temp_dir().join(format!("wai-granted-listing-{}", std::process::id())); std::fs::create_dir_all(&dir).unwrap(); let files: [(&str, &[u8]); 3] = [("decoder.onnx", b"the publisher's decoder"), ("cdfs_q3.json", b"{\"unauthorised\": true}"), ("notes.txt", b"an unrelated file")]; for (n, b) in files { std::fs::write(dir.join(n), b).unwrap(); } let listing = |names: &[&str]| { let set: std::collections::BTreeMap = files.iter().filter(|(n, _)| names.contains(n)).map(|(n, b)| (n.to_string(), *b)).collect(); let l = wai::pin::listing_from(&set).unwrap(); std::fs::write(dir.join("granted.sha256"), &l).unwrap(); wai::pin::sha256_hex(&l) }; // h 1, w 1, an empty stream, quality 3, one channel, a 1 × 1 latent. let mut payload = Vec::new(); for v in [1u32, 1, 0, 3] { payload.extend_from_slice(&v.to_le_bytes()); } payload.extend_from_slice(&[1, 0]); let env = Wai::new(Manifest::new("image", "improve", ModelRequirement::new(bm), Conditioning::new("bytes")), payload); let names = |p: &ParamSource| match p { ParamSource::Checked { set: Verified::Set { files, .. }, .. } => files.keys().cloned().collect::>().join(","), ParamSource::Checked { set: Verified::File(_), .. } => "one file".into(), ParamSource::Unpinned(_) => "the path".into(), other => format!("{other:?}"), }; let case = |path: PathBuf, granted: &[&str]| { let reg = ModelRegistry::new().register(bm, path).with_key_log(Grants(vec![listing(granted)])); (names(®.resolve_verified(bm, None).unwrap()), refusal(decode_envelope(&env, ®))) }; let incomplete = |r: &str| r == "set_incomplete"; let (set, r) = case(dir.join("decoder.onnx"), &["decoder.onnx"]); assert_eq!(set, "decoder.onnx"); assert!(incomplete(&r), "a listing of the decoder alone does not authorise the tables beside it: {r}"); let (set, r) = case(dir.clone(), &["notes.txt"]); assert_eq!(set, "notes.txt"); assert!(incomplete(&r), "a listing of another file does not authorise the directory: {r}"); let (set, r) = case(dir.join("decoder.onnx"), &["cdfs_q3.json", "decoder.onnx"]); assert_eq!(set, "cdfs_q3.json,decoder.onnx"); assert!(r.contains("cdf parse cdfs_q3.json"), "the listed tables are read from the set: {r}"); // A one-file capability granted under its file's digest decodes from that file alone. std::fs::remove_file(dir.join("granted.sha256")).unwrap(); let enc = "wai.neural.encodec32"; let digest = wai::pin::sha256_hex(files[0].1); let reg = ModelRegistry::new().register(enc, dir.join("decoder.onnx")).with_key_log(Grants(vec![digest.clone()])); match reg.resolve_verified(enc, None).unwrap() { ParamSource::Checked { set: Verified::File(b), .. } => assert_eq!(b, files[0].1), other => panic!("expected the authorised file, got {other:?}"), } // A key log that only revokes holds nothing to §7.9: the decode reads every file of // the decoder's directory, read once. let reg = ModelRegistry::new().register(bm, dir.join("decoder.onnx")).with_key_log(Revokes(vec!["00".repeat(32)])); assert_eq!(names(®.resolve_verified(bm, None).unwrap()), "cdfs_q3.json,decoder.onnx,notes.txt"); std::fs::remove_dir_all(&dir).ok(); } /// At a sink whose key log only revokes, an unpinned decode outside the integer path /// is checked over every digest a pin over what it reads could name, and reads those /// bytes alone (SPEC §4, *Module authorisation*). With no listing beside the files, a /// key log that revokes the listing of `{decoder.onnx, cdfs_q3.json}` still refuses /// them (`prior_revoked`) through the listing derived from the directory, whether the /// decoder or the directory is registered; one that revokes a member's own digest /// refuses them too. The bytes were read once: tables swapped on disk after the check /// are not the tables the decode reads. With no key log, the decode reads the path. #[test] fn a_revoke_only_key_log_checks_and_reads_the_set_once() { use wai::neural::{decode_payload, ParamSource}; use wai::pin::Verified; let bm = "wai.neural.bmshj2018"; let root = std::env::temp_dir().join(format!("wai-revoke-only-{}", std::process::id())); let (decoder, cdfs_a, cdfs_b): (&[u8], &[u8], &[u8]) = (b"the publisher's decoder bytes", b"cdfs A: not JSON", b"{\"channels\": 1}"); let mk = |name: &str| { let d = root.join(name); std::fs::create_dir_all(&d).unwrap(); std::fs::write(d.join("decoder.onnx"), decoder).unwrap(); std::fs::write(d.join("cdfs_q3.json"), cdfs_a).unwrap(); d }; let set: std::collections::BTreeMap = [("decoder.onnx".to_string(), decoder), ("cdfs_q3.json".to_string(), cdfs_a)].into_iter().collect(); let listing = wai::pin::listing_from(&set).unwrap(); let revoked = wai::pin::sha256_hex(&listing); let mut payload = Vec::new(); for v in [1u32, 1, 0, 3] { payload.extend_from_slice(&v.to_le_bytes()); } payload.extend_from_slice(&[1, 0]); let env = Wai::new(Manifest::new("image", "improve", ModelRequirement::new(bm), Conditioning::new("bytes")), payload.clone()); let r = mk("revoked"); std::fs::write(r.join("set.sha256"), &listing).unwrap(); let file_reg = || ModelRegistry::new().register(bm, r.join("decoder.onnx")); assert_eq!(refusal(decode_envelope(&env, &file_reg().with_key_log(Revokes(vec![revoked.clone()])))), "prior_revoked", "the revoked set beside its listing"); std::fs::remove_file(r.join("set.sha256")).unwrap(); assert_eq!(refusal(decode_envelope(&env, &file_reg().with_key_log(Revokes(vec![revoked.clone()])))), "prior_revoked", "the decoder registered, no listing beside it"); let dir_reg = ModelRegistry::new().register(bm, r.clone()).with_key_log(Revokes(vec![revoked.clone()])); assert_eq!(refusal(decode_envelope(&env, &dir_reg)), "prior_revoked", "the directory registered, no listing beside it"); let member = Revokes(vec![wai::pin::sha256_hex(cdfs_a)]); assert_eq!(refusal(decode_envelope(&env, &file_reg().with_key_log(member))), "prior_revoked", "a member's own digest revoked"); // Read once: the tables swapped after the check are not read. The decode reads A // (not JSON: "expected value"); B would parse and lack a field. let t = mk("toctou"); let reg = ModelRegistry::new().register(bm, t.join("decoder.onnx")).with_key_log(Revokes(vec![])); let params = reg.resolve_verified(bm, None).unwrap(); std::fs::write(t.join("cdfs_q3.json"), cdfs_b).unwrap(); std::fs::write(t.join("cdfs_q4.json"), cdfs_b).unwrap(); let got = refusal(decode_payload(bm, &payload, ¶ms)); assert!(got.contains("cdf parse cdfs_q3.json: expected value"), "the decode read the tables checked: {got}"); match ¶ms { ParamSource::Checked { set: Verified::Set { files, .. }, model } => { assert_eq!(files.keys().collect::>(), ["cdfs_q3.json", "decoder.onnx"]); assert_eq!(model.as_deref(), Some("decoder.onnx")); } other => panic!("expected the files read once, got {other:?}"), } // No key log: no check 5, and the decode reads the path, as it always has. assert!(matches!(ModelRegistry::new().register(bm, t.join("decoder.onnx")).resolve_verified(bm, None), Ok(ParamSource::Unpinned(_)))); std::fs::remove_dir_all(&root).ok(); } /// The reference sink opens no encryption scheme, so an envelope whose manifest /// declares one is inert at it (SPEC §6.4 step 2, `unsupported_encryption`): a /// payload sent in the clear under a claim of encryption is not decoded as plaintext, /// and a tool's JSON form under that claim is not read as a payload either. The same /// payload without the claim decodes; a `WAI2` gives every entry the reason, also when /// its `security` member is not a security object. #[test] fn an_encrypted_envelope_is_inert_at_the_reference_sink() { use wai::codecs::CAP_NEURAL_INT_HYPER as HYP; use wai::container::{Rendition, Security, WaiMulti}; use wai::neural::decode_multi; let v = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/vectors"); let dir = std::env::temp_dir().join(format!("wai-encrypted-{}", std::process::id())); std::fs::create_dir_all(&dir).unwrap(); for (k, f) in [("entropy.json", "int_hyper/tiny_entropy.json"), ("g_s.whm", "int_hyper/tiny_g_s.bin"), ("h_s.whm", "int_hyper/tiny_h_s.bin")] { std::fs::copy(v.join(f), dir.join(k)).unwrap(); } let reg = ModelRegistry::new().register(HYP, dir.clone()); let (wih1, json) = (std::fs::read(v.join("int_hyper/tiny_bitstream.wih1")).unwrap(), std::fs::read(v.join("int_hyper/tiny_bitstream.json")).unwrap()); let env = |payload: &[u8], security: Option| { let mut m = Manifest::new("image", "improve", ModelRequirement::new(HYP), Conditioning::new("bytes")); m.security = security; Wai::from_bytes(&Wai::new(m, payload.to_vec()).to_emit_bytes().unwrap()).unwrap() }; assert!(matches!(decode_envelope(&env(&wih1, None), ®), Ok(Decoded::Image(_))), "in the clear, it decodes"); for payload in [&wih1, &json] { match decode_envelope(&env(payload, Some(Security::new("aes-256-gcm", 7))), ®) { Err(DecodeError::Encrypted(why)) => assert!(why.starts_with("unsupported_encryption: "), "{why}"), other => panic!("an encrypted envelope must be inert, got {}", refusal(other)), } } let multi = |security: Option| { let mut m = WaiMulti::new("image", "improve", serde_json::Value::Null, vec![Rendition::media(HYP, "bytes", wih1.clone())]); if let Some(s) = security { m.manifest.extra.insert("security".into(), s); } WaiMulti::from_bytes(&m.to_bytes().unwrap()).unwrap() }; assert!(matches!(decode_multi(&multi(None), ®), Ok((0, Decoded::Image(_))))); for s in [serde_json::json!({"encryption": "mls-sframe", "kid": 0}), serde_json::json!(true)] { match decode_multi(&multi(Some(s.clone())), ®) { Err(DecodeError::NoRendition(skips)) => assert_eq!(skips, vec![(0, "unsupported_encryption".to_string())], "{s}"), other => panic!("{s}: expected every entry inert, got {:?}", other.map(|(i, _)| i)), } } std::fs::remove_dir_all(&dir).ok(); } /// The neural registry's pinned path runs check 5 over every identity of the bytes it /// verified: a one-file set whose file digest a key log revokes is refused through a /// set-form pin over a listing of that file. #[test] fn a_pinned_set_revoked_under_its_file_digest_is_refused_through_a_listing_pin() { use wai::codecs::{CAP_AUDIO_INT_CODEC as AUD, CAP_PRIOR_SET}; let v = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/vectors"); let model = std::fs::read(v.join("int_audio/audio_model.bin")).unwrap(); let dir = std::env::temp_dir().join(format!("wai-listing-pin-{}", std::process::id())); std::fs::create_dir_all(&dir).unwrap(); std::fs::write(dir.join("model.wam"), &model).unwrap(); let one: std::collections::BTreeMap = [("model.wam".to_string(), model.as_slice())].into_iter().collect(); let listing = wai::pin::listing_from(&one).unwrap(); std::fs::write(dir.join("model.sha256"), &listing).unwrap(); let pin = Prior::new("m", wai::pin::sha256_hex(&listing), "decode-equivalence").with_form(CAP_PRIOR_SET); let plain = ModelRegistry::new().register(AUD, dir.join("model.wam")); assert!(plain.verify(AUD, &pin).is_ok(), "the pin verifies"); let revoking = ModelRegistry::new().register(AUD, dir.join("model.wam")).with_key_log(Revokes(vec![wai::pin::sha256_hex(&model)])); assert_eq!(revoking.verify(AUD, &pin).map(|_| ()).map_err(|r| r.code()), Err("prior_revoked")); std::fs::remove_dir_all(&dir).ok(); }