open-standards/wai/wai-rs/tests/ai_usage.rs
Transaction Science 9d8e806438 wai.ai.usage: AI usage statements bound to the bytes, the consumption claim class, and its corpus
The usage statement carries draft-ietf-aipref-vocab-08's Structured Field
value, the TDM Reservation Protocol's properties and the Training and Data
Mining Assertion 1.1's entries verbatim. It rides in an envelope's manifest
(signed by the object's receipt), a room's WAU1 record and a grant's terms;
HTTP fields and a MoQ catalog field are checked against it. One precedence
rule: a grant's terms, then the signed statements, most restrictive first.
The jwp-receipts claim class consumption carries an agent's statement of
what it consumed, under which term, having seen which statements; a gate
can require claims before serving an agent.

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

61 lines
2.9 KiB
Rust

//! `wai.ai.usage` (extensions/ai-usage.md): the committed corpus `live-conformance/usage/`
//! regenerates byte for byte from its fixed seeds, holds no other file, every case in it gets
//! the outcome it states, and the extension's §9 lists exactly the reasons the reference
//! reports. The generator itself asserts that the corpus gives every one of them.
#![cfg(feature = "ai_usage")]
use std::collections::BTreeMap;
use std::path::PathBuf;
use wai::ai_usage::{corpus, CODES};
fn wai_dir() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("..")
}
fn committed() -> BTreeMap<String, String> {
let dir = wai_dir().join("live-conformance/usage");
std::fs::read_dir(&dir)
.expect("the committed corpus")
.flatten()
.map(|e| (e.file_name().to_string_lossy().into_owned(), e.path()))
.filter(|(n, _)| n != "README.md")
.map(|(n, p)| (n, std::fs::read_to_string(p).expect("a text file")))
.collect()
}
#[test]
fn the_committed_corpus_regenerates_from_its_seeds() {
let files = committed();
let generated: BTreeMap<String, String> = corpus::generate().into_iter().collect();
let extra: Vec<&String> = files.keys().filter(|k| !generated.contains_key(*k)).collect();
let missing: Vec<&String> = generated.keys().filter(|k| !files.contains_key(*k)).collect();
let differ: Vec<&String> = generated.iter().filter(|(k, v)| files.get(*k).is_some_and(|f| f != *v)).map(|(k, _)| k).collect();
assert!(extra.is_empty() && missing.is_empty() && differ.is_empty(), "extra {extra:?}, missing {missing:?}, differ {differ:?}: run `wai_ai_usage_vectors gen`");
}
#[test]
fn every_case_gets_its_stated_outcome() {
let fails = corpus::verify(&committed());
assert!(fails.is_empty(), "{}", fails.join("\n"));
}
/// §9 of the extension lists exactly the codes `CODES` has, each once, in order.
#[test]
fn the_extension_lists_the_reasons() {
let text = std::fs::read_to_string(wai_dir().join("extensions/ai-usage.md")).expect("the extension");
let at = text.find("\n## 9. Reasons").expect("a §9");
let end = text[at + 1..].find("\n## ").map_or(text.len(), |e| at + 1 + e);
let listed: Vec<String> =
text[at..end].lines().filter(|l| l.starts_with("| `")).filter_map(|l| l.split('`').nth(1).map(String::from)).collect();
let want: Vec<String> = CODES.iter().map(|c| c.to_string()).collect();
assert_eq!(listed, want, "§9's table and CODES differ");
}
/// jwp-receipts §3.1's table lists the six class-rule codes of a `consumption` claim, at step 4.
#[test]
fn jwp_receipts_lists_the_class_rules() {
let text = std::fs::read_to_string(wai_dir().join("extensions/jwp-receipts.md")).expect("jwp-receipts");
for code in CODES.iter().filter(|c| c.starts_with("consumption_") && **c != "consumption_object_unknown") {
assert!(text.contains(&format!("| 4 | `{code}` |")), "jwp-receipts §3.1 does not list {code} at step 4");
}
}