//! Conservation conformance — the reference [`DeterministicVerifier`] //! must produce exactly the findings listed in //! `conformance/vectors.json` for every vector. Any independent //! implementation (other language, FFI binding, alternate verifier) is //! conformant iff it produces the same `Vec` for //! every input listed here, in the same order, byte-equal under //! serde_json's snake_case-tagged enum serialization. use jouleclaw_conservation::{ CanonicalJsonByteCount, ConservationClaim, DeterministicVerifier, Delta, Output, Spec, Substrate, VerificationFinding, Verifier, }; use serde_json::Value; const VECTORS: &str = include_str!("../conformance/vectors.json"); fn check_vector(v: &Value) { let n = v["n"].as_i64().expect("n"); let desc = v["description"].as_str().expect("description"); let input = &v["input"]; let expected = v["expected_findings"].as_array().expect("expected findings"); let measure = CanonicalJsonByteCount; let spec_bytes = input["spec_bytes_utf8"].as_str().expect("spec_bytes_utf8").as_bytes(); let output_bytes = input["output_bytes_utf8"].as_str().expect("output_bytes_utf8").as_bytes(); let spec = Spec::from_bytes(spec_bytes, &measure); let output = Output::from_bytes(output_bytes, &measure); let mut delta = Delta::empty(); if let Some(fields) = input["delta_fields"].as_object() { for (k, val) in fields { delta.set(k.clone(), val.as_str().expect("delta value is string").to_string()); } } delta.recount(&measure); let substrate = Substrate { id: input["substrate_id"].as_str().unwrap_or("").to_string(), arrangement_hash: input["substrate_arrangement_hash"] .as_str() .unwrap_or("") .to_string(), used_info: jouleclaw_conservation::InformationContent( input["substrate_used_info"].as_u64().unwrap_or(0), ), }; let residual_tolerance = input["residual_tolerance"].as_u64().unwrap_or(0); let required_slots: Vec = input["required_slots"] .as_array() .expect("required_slots array") .iter() .map(|s| s.as_str().expect("required slot is string").to_string()) .collect(); let claim = ConservationClaim::seal(&measure, spec, output, delta, substrate, residual_tolerance) .expect("seal"); let findings: Vec = DeterministicVerifier.verify(&claim, &required_slots); let got = serde_json::to_value(&findings).expect("findings serialise"); let expected_v = Value::Array(expected.clone()); assert_eq!( got, expected_v, "vector {n} ({desc}): findings mismatch.\n got = {got}\n expected = {expected_v}", ); } #[test] fn every_conservation_vector_matches_the_reference_verifier() { let suite: Value = serde_json::from_str(VECTORS).expect("vectors.json parses"); let count = suite["vector_count"].as_u64().expect("vector_count") as usize; let vectors = suite["vectors"].as_array().expect("vectors array"); assert_eq!(vectors.len(), count, "vector_count mismatch"); for v in vectors { check_vector(v); } }