mod anchors;
use std::collections::{HashMap, HashSet};
fn repo() -> std::path::PathBuf {
std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"))
}
fn norm(s: &str) -> String {
s.split_whitespace().collect::<Vec<_>>().join(" ")
}
fn version_triple(s: &str) -> bool {
let parts: Vec<&str> = s.split('.').collect();
parts.len() == 3
&& parts
.iter()
.all(|p| !p.is_empty() && p.bytes().all(|b| b.is_ascii_digit()))
}
#[test]
fn ledger_gate_ledger_is_consistent_and_backs_the_readme_badges() {
let raw = std::fs::read_to_string(repo().join("INTROSPECTION.json"))
.expect("INTROSPECTION.json must exist at the repo root");
let doc: serde_json::Value = serde_json::from_str(&raw).expect("INTROSPECTION.json parses");
assert_eq!(doc["schema"], 1, "ledger schema version");
let verified = doc["verified_claude_code"]
.as_str()
.expect("verified_claude_code is a string");
assert!(
version_triple(verified),
"verified_claude_code `{verified}` is a version triple"
);
let claims = doc["claims"].as_array().expect("claims is an array");
assert!(!claims.is_empty(), "the ledger is never empty");
let allowed = ["holds", "refined", "drifted", "unverifiable-here"];
let mut ids: HashSet<&str> = HashSet::new();
let mut evidence: HashMap<String, &str> = HashMap::new();
let mut file_cache: HashMap<String, Option<FileText>> = HashMap::new();
let mut failures: Vec<String> = Vec::new();
for c in claims {
let id = c["id"].as_str().unwrap_or("");
if id.is_empty() || !ids.insert(id) {
failures.push(format!("claim id missing or duplicated: `{id}`"));
continue;
}
for key in ["area", "behavior", "depends", "instrument"] {
if c[key].as_str().is_none_or(|s| s.trim().is_empty()) {
failures.push(format!("{id}: `{key}` is empty"));
}
}
let checks = c["checks"].as_array().cloned().unwrap_or_default();
let at_version: Vec<&serde_json::Value> = checks
.iter()
.filter(|k| k["claude_code"].as_str() == Some(verified))
.collect();
if at_version.is_empty() {
failures.push(format!("{id}: no check at Claude Code {verified}"));
}
for k in &at_version {
let verdict = k["verdict"].as_str().unwrap_or("");
if !allowed.contains(&verdict) {
failures.push(format!("{id}: verdict `{verdict}` is not in {allowed:?}"));
}
let instrument = k["instrument"].as_str().unwrap_or("").trim();
let observed = k["observed"].as_str().unwrap_or("").trim();
if observed.is_empty() {
failures.push(format!(
"{id}: a check at {verified} has an empty `observed`"
));
}
if instrument.is_empty() {
failures.push(format!("{id}: `{verdict}` without an instrument"));
}
if verdict != "unverifiable-here" {
let key = format!("{}|{}", norm(instrument), norm(observed));
if let Some(other) = evidence.insert(key, id) {
failures.push(format!(
"{id}: evidence (instrument, observed) identical to {other}'s - \
a check is written per claim, never replaced mechanically"
));
}
}
}
if c["code"].as_array().is_none_or(|a| a.is_empty()) {
failures.push(format!(
"{id}: no code site (every claim cites at least one)"
));
}
check_attribution(id, c, &mut failures);
check_latest_verdict_and_leg_hygiene(id, c, &checks, &mut failures);
check_code_sites(id, c, &mut file_cache, &mut failures);
}
let anchors = anchors::tally(claims, verified, &mut failures);
let readme = std::fs::read_to_string(repo().join("README.md")).expect("README.md");
let badge_re = regex::Regex::new(r"Claude%20Code-(\d+\.\d+\.\d+)-").unwrap();
match badge_re.captures(&readme) {
Some(cap) => {
if &cap[1] != verified {
failures.push(format!(
"README badge says Claude Code {} but the ledger is verified at {verified}",
&cap[1]
));
}
}
None => failures.push("README has no `verified against Claude Code` badge".to_string()),
}
let mutation_re = regex::Regex::new(r"mutation%20score-\d+(\.\d+)?%25").unwrap();
if !mutation_re.is_match(&readme) {
failures.push("README has no mutation-score badge".to_string());
}
check_readme_tally(claims, &anchors, verified, &readme, &mut failures);
assert!(
failures.is_empty(),
"INTROSPECTION.json gate failed ({} problem(s)):\n {}",
failures.len(),
failures.join("\n ")
);
}
struct FileText {
whole: String,
lines: Vec<String>,
}
fn file_text<'a>(
cache: &'a mut HashMap<String, Option<FileText>>,
path: &str,
) -> Option<&'a FileText> {
cache
.entry(path.to_string())
.or_insert_with(|| {
std::fs::read_to_string(repo().join(path))
.ok()
.map(|s| FileText {
whole: norm(&s),
lines: s.lines().map(str::to_string).collect(),
})
})
.as_ref()
}
fn line_range(spec: &str) -> Option<(usize, usize)> {
let (a, b) = spec.split_once('-').unwrap_or((spec, spec));
let a: usize = a.trim().parse().ok()?;
let b: usize = b.trim().parse().ok()?;
(a > 0 && b >= a).then_some((a, b))
}
fn range_too_wide(first: usize, last: usize, snippet: &str) -> Option<(usize, usize)> {
let width = last - first + 1;
let lines = snippet.split('\n').count();
(width > lines + 2).then_some((width, lines))
}
fn check_code_sites(
id: &str,
c: &serde_json::Value,
cache: &mut HashMap<String, Option<FileText>>,
failures: &mut Vec<String>,
) {
for site in c["code"].as_array().cloned().unwrap_or_default() {
let path = site["path"].as_str().unwrap_or("");
let snippet = site["snippet"].as_str().unwrap_or("");
if path.is_empty() || snippet.trim().is_empty() {
failures.push(format!("{id}: a code site lacks a path or a snippet"));
continue;
}
let Some(text) = file_text(cache, path) else {
failures.push(format!("{id}: code site `{path}` does not exist"));
continue;
};
let want = norm(snippet);
if !text.whole.contains(&want) {
failures.push(format!(
"{id}: snippet not found verbatim in `{path}` (the code moved - fix the site)"
));
continue;
}
let spec = site["lines"].as_str().unwrap_or("");
let Some((first, last)) = line_range(spec) else {
failures.push(format!(
"{id}: code site `{path}` has `lines` `{spec}`, which is neither `N` nor `A-B`"
));
continue;
};
let start = (first - 1).min(text.lines.len());
let end = last.min(text.lines.len()).max(start);
if !norm(&text.lines[start..end].join("\n")).contains(&want) {
failures.push(format!(
"{id}: snippet is not inside `{path}` lines {spec} \
(the range drifted - recompute it from the snippet)"
));
}
if let Some((width, lines)) = range_too_wide(first, last, snippet) {
failures.push(format!(
"{id}: `{path}` lines {spec} spans {width} line(s) for a {lines}-line snippet \
(a range is the snippet's own span, not a window around it)"
));
}
}
}
#[test]
fn ledger_gate_a_declared_range_may_not_be_padded() {
let three = "one\ntwo\nthree";
assert_eq!(range_too_wide(10, 12, three), None);
assert_eq!(range_too_wide(10, 14, three), None);
assert_eq!(range_too_wide(10, 15, three), Some((6, 3)));
assert_eq!(range_too_wide(1, 99999, three), Some((99999, 3)));
assert_eq!(range_too_wide(7, 7, "fn f() {}"), None);
assert_eq!(range_too_wide(7, 10, "fn f() {}"), Some((4, 1)));
}
fn check_anchor_line(
a: &anchors::Anchors,
verified: &str,
block: &str,
failures: &mut Vec<String>,
) {
let re = regex::Regex::new(
r"anchors byte-exact at Claude Code (\d+\.\d+\.\d+): ([\d,]+) of ([\d,]+) \(elided ([\d,]+), absent ([\d,]+), prefix-only ([\d,]+)\)",
)
.unwrap();
let Some(cap) = re.captures(block) else {
failures.push(
"README ledger tally carries no `anchors byte-exact at Claude Code ...` line"
.to_string(),
);
return;
};
if &cap[1] != verified {
failures.push(format!(
"README anchor line names Claude Code {} but the ledger is verified at {verified}",
&cap[1]
));
}
let num = |i: usize| {
cap[i]
.replace(',', "")
.parse::<usize>()
.unwrap_or(usize::MAX)
};
let mut expected = vec![
("total anchors", num(3), a.total),
("absent", num(5), a.absent),
("prefix-only", num(6), a.prefix_only),
];
if let Some((exact, elided)) = a.measured {
expected.push(("byte-exact", num(2), exact));
expected.push(("elided", num(4), elided));
}
for (label, said, is) in expected {
if said != is {
failures.push(format!(
"README anchor line says {label} {said} but the ledger has {is}"
));
}
}
}
fn check_readme_tally(
claims: &[serde_json::Value],
anchors: &anchors::Anchors,
verified: &str,
readme: &str,
failures: &mut Vec<String>,
) {
let Some(start) = readme.find("<!-- ledger-tally:begin -->") else {
failures.push("README has no ledger-tally table".to_string());
return;
};
let block = &readme[start..];
let block = &block[..block
.find("<!-- ledger-tally:end -->")
.unwrap_or(block.len())];
let row_re = regex::Regex::new(r"(?m)^\| ([a-z-]+) \| (\d+) \|").unwrap();
let mut rows: HashMap<String, usize> = HashMap::new();
for cap in row_re.captures_iter(block) {
rows.insert(cap[1].to_string(), cap[2].parse().unwrap_or(usize::MAX));
}
for key in [
"end-to-end",
"producer-only",
"specimen-only",
"partial-producer",
"by-elimination",
"upstream",
] {
let expected = claims
.iter()
.filter(|c| c["attribution"].as_str() == Some(key))
.count();
match rows.get(key) {
Some(n) if *n == expected => {}
Some(n) => failures.push(format!(
"README tally row `{key}` says {n} but the ledger has {expected}"
)),
None => failures.push(format!("README tally has no `{key}` row")),
}
}
match rows.get("total") {
Some(n) if *n == claims.len() => {}
_ => failures.push(format!(
"README tally total does not equal the ledger's {} claims",
claims.len()
)),
}
check_anchor_line(anchors, verified, block, failures);
}
fn check_latest_verdict_and_leg_hygiene(
id: &str,
c: &serde_json::Value,
checks: &[serde_json::Value],
failures: &mut Vec<String>,
) {
if let Some(last) = checks.last() {
if last["verdict"].as_str() == Some("drifted") {
failures.push(format!(
"{id}: the latest check is `drifted` with no fix or retirement check after it (a drift is a same-release correctness task)"
));
}
}
for leg in c["open_legs"].as_array().cloned().unwrap_or_default() {
let s = leg.as_str().unwrap_or("").trim_start();
if s.starts_with("TEXT") {
failures.push(format!(
"{id}: an open leg is an unconsumed text correction (`TEXT ...`): rewrite the claim text"
));
} else if s.starts_with("Text rewrite rejected")
|| s.contains("was rejected on adversarial re-read")
{
failures.push(format!(
"{id}: an open leg records a rejected rewrite, so the refuted text is still shipping: rewrite it to acceptance, split, or retire"
));
}
}
}
fn check_attribution(id: &str, c: &serde_json::Value, failures: &mut Vec<String>) {
const ATTRIBUTIONS: [&str; 6] = [
"end-to-end",
"producer-only",
"specimen-only",
"partial-producer",
"by-elimination",
"upstream",
];
let attribution = c["attribution"].as_str().unwrap_or("");
if !ATTRIBUTIONS.contains(&attribution) {
failures.push(format!(
"{id}: `attribution` `{attribution}` is not in {ATTRIBUTIONS:?}"
));
}
if let (Some(producer), Some(specimen)) = (c["producer_trace"].as_str(), c["specimen"].as_str())
{
let derived = match (producer, specimen) {
("complete", "observed") => "end-to-end",
("complete", "none") => "producer-only",
("partial" | "none", "observed") => "specimen-only",
("partial", "none") => "partial-producer",
("none", "none") => "by-elimination",
("upstream", "observed") => "upstream",
_ => "",
};
if derived.is_empty() {
failures.push(format!(
"{id}: legs producer_trace `{producer}` / specimen `{specimen}` are not from the closed sets"
));
} else if derived != attribution {
failures.push(format!(
"{id}: attribution `{attribution}` does not follow from the legs (`{producer}` + `{specimen}` = `{derived}`)"
));
}
} else if attribution != "end-to-end" {
failures.push(format!(
"{id}: attribution `{attribution}` with no `producer_trace`/`specimen` legs recorded"
));
}
let open_legs = c["open_legs"].as_array().cloned().unwrap_or_default();
let legs_named = open_legs
.iter()
.any(|l| l.as_str().is_some_and(|s| !s.trim().is_empty()));
if !matches!(attribution, "end-to-end" | "upstream") && !legs_named {
failures.push(format!(
"{id}: attribution `{attribution}` without a non-empty `open_legs` entry"
));
}
if attribution == "end-to-end" && legs_named {
failures.push(format!(
"{id}: end-to-end with a non-empty `open_legs` (close the leg, or move a non-gap note to `residue`)"
));
}
if attribution == "upstream"
&& c["upstream_reason"]
.as_str()
.is_none_or(|s| s.trim().is_empty())
{
failures.push(format!(
"{id}: attribution `upstream` without an `upstream_reason` naming the producer domain"
));
}
if attribution == "by-elimination"
&& c["checks"]
.as_array()
.is_some_and(|ks| ks.iter().any(|k| k["verdict"].as_str() == Some("holds")))
{
failures.push(format!(
"{id}: a by-elimination claim carries a `holds` verdict (trace the producer or the specimen first)"
));
}
}