Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/facett

facett-core/src/law.rs

//! **ROOT LAW #0 — the rayon-free law**, and the machinery that can actually
//! report RED on it. Shared so korp and facett hold the *same* line from *one*
//! writer (LAW 5) instead of two drifting copies of a grep.
//!
//! # Why this module exists
//!
//! `znippy-zoomies/tests/rayon_free_law.rs` has guarded the law for the codec
//! tree for months. korp and facett had **no gate at all**: a `rayon = "1"` in
//! `facett-map/Cargo.toml` would have passed every test in both repos.
//!
//! # The hard part: which rayon?
//!
//! A naive lockfile grep is worse than no gate, because it is red on day one and
//! stays red forever. Measured on 2026-08-03, `Cargo.lock` in **both** repos
//! contains `rayon 1.12.0` — pulled in like this:
//!
//! ```text
//! rayon ← av-scenechange ← rav1e ← ravif ← image ← dify ← egui_kittest
//!       ← nornir-robotui "snapshot"  [dev-dependencies]  ← korp / facett-*
//! ```
//!
//! Nobody chose that. It is the AVIF encoder inside the image crate that the
//! screenshot-diff crate inside the robot-UI harness happens to enable. LAW 3
//! forbids **us** using rayon; it does not forbid a third-party image decoder in
//! the fourth ring from using it in a test harness. A gate that goes red on that
//! edge gets switched off within a week, and a gate that ignores the whole axis
//! cannot see the day it stops being test-only.
//!
//! So this module separates **three** things and says which one it tripped on:
//!
//! 1. [`scan_source`] — **our own code** calling rayon. Always red.
//! 2. [`scan_manifests`] — **our own manifests** declaring rayon, in any
//!    dependency table. Always red.
//! 3. [`shipped_rayon_tree`] — a **normal (non-dev, non-build) dependency
//!    edge** that reaches rayon, i.e. rayon linked into something we ship.
//!    Red. [`unshipped_rayon_chain`] finds the dev/build edge and is reported as
//!    *context*, never as a failure.
//!
//! Measured 2026-08-03 with `cargo tree -e normal -i rayon --target all`:
//! "nothing to print" in korp and in facett. Check 3 is therefore **green
//! today** and still able to go red — which is the only kind of green worth
//! having (LAW 2).
//!
//! It is one feature flag away from red, and that is the point of keeping it:
//! `image` **is** already a normal dependency of korp (via `eframe`→`arboard`,
//! and via `facett-about`), just without its `avif` feature. Turning `avif` on
//! anywhere in the graph puts `rayon` in the shipped korp binary. Under
//! `--all-features` that is exactly what happens, measured on the same day —
//! which is why [`rayon_tree_all_features_chain`] exists: check 3 demonstrates its own
//! red on **every run** instead of asserting that it still could.
//!
//! # Which instrument decides which axis
//!
//! Check 3 reads `cargo tree`, **not** `cargo metadata`. The first cut of this
//! module decided it from the metadata resolve, and pointed at korp that resolve
//! reported a violation — `korp -> image -> rayon` — that does not exist:
//! `cargo metadata` unifies dev-dependency features into one graph, so `image`
//! appears with `avif` on and its `ravif → rayon` edge looks normal. The
//! dependency-KIND walk was right; the FEATURE resolution under it was not, and
//! it errs towards inventing violations. `cargo metadata` is kept for kind
//! attribution and for the dev-route context chain, where over-approximating
//! costs nothing. See [`overapproximated_normal_chain`].
//!
//! # Self-honesty
//!
//! The forbidden tokens below are built with [`concat!`] so this file does not
//! contain them literally. The scanner therefore covers itself — there is no
//! path carve-out for the guard, which is how a guard quietly stops guarding.

use std::collections::VecDeque;
use std::path::{Path, PathBuf};
use std::process::Command;

/// One offending line, located.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Hit {
    /// Absolute path of the file the hit is in.
    pub file: PathBuf,
    /// 1-based line number.
    pub line: usize,
    /// The offending token that matched.
    pub token: String,
    /// The source line, trimmed (comments already stripped).
    pub text: String,
}

impl std::fmt::Display for Hit {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}:{}: `{}` — {}", self.file.display(), self.line, self.token, self.text)
    }
}

/// Tokens that can only appear when rayon is actually being **used**. Method
/// calls are matched with their leading `.` and trailing `(` so an unrelated
/// identifier such as `par_sorted` is not a false positive.
///
/// Written through [`concat!`] so the constant does not match itself — this file
/// is scanned like every other (see the module docs).
fn rayon_call_tokens() -> Vec<String> {
    [
        concat!("use ", "rayon"),
        concat!("extern crate ", "rayon"),
        concat!("rayon", "::"),
        concat!(".", "par_iter("),
        concat!(".", "into_par_iter("),
        concat!(".", "par_iter_mut("),
        concat!(".", "par_bridge("),
        concat!(".", "par_chunks("),
        concat!(".", "par_chunks_mut("),
        concat!(".", "par_sort("),
        concat!(".", "par_sort_by("),
        concat!(".", "par_sort_unstable("),
        concat!(".", "par_extend("),
        concat!("Parallel", "Iterator"),
        concat!("IntoParallel", "Iterator"),
        concat!("ThreadPool", "Builder"),
    ]
    .iter()
    .map(|s| (*s).to_string())
    .collect()
}

/// The crate name the manifest scan looks for as a dependency key.
fn rayon_dep_key() -> String {
    concat!("ray", "on").to_string()
}

/// Strip a `//`-to-end-of-line comment so only live code is scanned. The repos
/// are full of prose *about* the law (`// never rayon here`); commentary is not
/// a violation of it.
fn strip_line_comment(line: &str) -> &str {
    match line.find("//") {
        Some(i) => &line[..i],
        None => line,
    }
}

/// Walk up from `start` to the outermost directory whose `Cargo.toml` declares a
/// `[workspace]`. Handles both shapes in this tree: facett's virtual root and
/// korp's `[workspace]`-plus-`[package]` root.
pub fn workspace_root(start: &Path) -> PathBuf {
    let mut found = start.to_path_buf();
    let mut cursor = Some(start);
    while let Some(dir) = cursor {
        let manifest = dir.join("Cargo.toml");
        if std::fs::read_to_string(&manifest)
            .map(|text| text.lines().any(|l| l.trim() == "[workspace]"))
            .unwrap_or(false)
        {
            found = dir.to_path_buf();
        }
        cursor = dir.parent();
    }
    found
}

/// Every `Cargo.toml` this workspace owns: the root, plus one per member listed
/// in the root `members = [...]` array, plus one per `exclude = [...]` leaf.
///
/// The excluded leaves are ours too. korp's root manifest excludes
/// `crates/korp-ontology`, `crates/korp-embed` and `crates/korp-demo` because
/// they carry their own empty `[workspace]` tables — and korp *depends* on
/// `korp-demo` by path, so a `rayon = "1"` in that leaf ships. Reading only the
/// members would have left first-party manifests and first-party `src/`
/// unscanned while the count still looked healthy.
pub fn workspace_manifests(root: &Path) -> Vec<PathBuf> {
    let mut out = vec![root.join("Cargo.toml")];
    for member in first_party_dirs(root) {
        let m = root.join(&member).join("Cargo.toml");
        if m.exists() {
            out.push(m);
        }
    }
    out
}

/// The `members = [...]` entries of the root manifest. Tolerates the array being
/// written on one line or spread over many.
pub fn workspace_members(root: &Path) -> Vec<String> {
    manifest_string_array(root, "members")
}

/// The `exclude = [...]` entries of the root manifest — self-rooting leaves that
/// live in this repo and are therefore first-party even though cargo does not
/// call them members.
pub fn workspace_excludes(root: &Path) -> Vec<String> {
    manifest_string_array(root, "exclude")
}

/// Members and excluded leaves together: every directory in this repo that holds
/// a package of ours.
pub fn first_party_dirs(root: &Path) -> Vec<String> {
    let mut out = workspace_members(root);
    for e in workspace_excludes(root) {
        if !out.contains(&e) {
            out.push(e);
        }
    }
    out
}

/// Read a `key = [ "a", "b" ]` array out of the root manifest's `[workspace]`
/// table.
///
/// Two things this does that the first version did not, both of them defects
/// that were found by pointing the guard at korp:
///
/// 1. **It anchors on a LINE, not on the first occurrence of the word.** korp's
///    root manifest says "are NOT pulled in as members" in its header comment
///    three lines above `[workspace]`. A bare `text.find("members")` landed
///    there, then took `[workspace]`'s own brackets as the array and returned
///    `["workspace"]` — one member that does not exist and none of the real
///    ones. The manifest scan read 1 file where it should read 2.
/// 2. **It stays inside `[workspace]`.** `exclude` is also a `[package]` key
///    (packaging excludes), and korp's root manifest carries both tables.
///
/// Comments are `#` here, not `//` — this is TOML, and an entry may be followed
/// by a trailing `# why`.
fn manifest_string_array(root: &Path, key: &str) -> Vec<String> {
    let Ok(text) = std::fs::read_to_string(root.join("Cargo.toml")) else {
        return Vec::new();
    };
    let mut cursor = 0usize;
    let mut start = None;
    let mut in_workspace = false;
    for line in text.split_inclusive('\n') {
        let trimmed = line.trim_start();
        if trimmed.starts_with('[') {
            in_workspace = trimmed.starts_with("[workspace]");
        } else if in_workspace
            && let Some(rest) = trimmed.strip_prefix(key)
            && rest.trim_start().starts_with('=')
        {
            start = Some(cursor + (line.len() - trimmed.len()));
            break;
        }
        cursor += line.len();
    }
    let Some(start) = start else { return Vec::new() };
    // Strip `#`-to-end-of-line on every line BEFORE locating the brackets, so a
    // trailing `"a", # the first one` cannot swallow the rest of the array. The
    // first cut of this function stripped per comma-separated piece instead, and
    // its own new test caught it eating `"b"`.
    let rest: String = text[start..]
        .lines()
        .map(|l| l.split('#').next().unwrap_or(""))
        .collect::<Vec<_>>()
        .join("\n");
    let Some(open) = rest.find('[') else { return Vec::new() };
    let Some(close) = rest[open..].find(']') else { return Vec::new() };
    rest[open + 1..open + close]
        .split(',')
        .map(|s| s.trim().trim_matches('"').to_string())
        .filter(|s| !s.is_empty())
        .collect()
}

/// Every directory of ours that holds first-party Rust: each member's `src`,
/// `tests`, `benches` and `examples`, plus the root package's own if the root
/// manifest carries a `[package]`. `target/` is never walked.
pub fn source_roots(root: &Path) -> Vec<PathBuf> {
    const SUBDIRS: &[&str] = &["src", "tests", "benches", "examples"];
    let mut dirs: Vec<PathBuf> = Vec::new();
    let push_for = |base: PathBuf, dirs: &mut Vec<PathBuf>| {
        for sub in SUBDIRS {
            let p = base.join(sub);
            if p.is_dir() {
                dirs.push(p);
            }
        }
    };
    push_for(root.to_path_buf(), &mut dirs);
    for member in first_party_dirs(root) {
        push_for(root.join(member), &mut dirs);
    }
    dirs
}

fn rs_files(dir: &Path, out: &mut Vec<PathBuf>) {
    let Ok(rd) = std::fs::read_dir(dir) else { return };
    for entry in rd.flatten() {
        let path = entry.path();
        if path.is_dir() {
            if path.file_name().map(|n| n == "target").unwrap_or(false) {
                continue;
            }
            rs_files(&path, out);
        } else if path.extension().and_then(|e| e.to_str()) == Some("rs") {
            out.push(path);
        }
    }
}

/// What a source scan found, plus how much it looked at — a scan that found
/// nothing because it read nothing is the hollow green this whole module is
/// about, so the count travels with the verdict.
#[derive(Debug, Clone, Default)]
pub struct Scan {
    /// Offending lines.
    pub hits: Vec<Hit>,
    /// How many files were actually read.
    pub scanned: usize,
}

/// Scan every first-party `.rs` file under `root` for live rayon usage.
pub fn scan_source(root: &Path) -> Scan {
    let tokens = rayon_call_tokens();
    let mut files = Vec::new();
    for dir in source_roots(root) {
        rs_files(&dir, &mut files);
    }
    let mut hits = Vec::new();
    for file in &files {
        let Ok(text) = std::fs::read_to_string(file) else { continue };
        for (i, raw) in text.lines().enumerate() {
            let code = strip_line_comment(raw);
            for tok in &tokens {
                if code.contains(tok.as_str()) {
                    hits.push(Hit {
                        file: file.clone(),
                        line: i + 1,
                        token: tok.clone(),
                        text: code.trim().to_string(),
                    });
                }
            }
        }
    }
    Scan { hits, scanned: files.len() }
}

/// Scan every first-party `Cargo.toml` for a `rayon` dependency key, in any
/// dependency table (`[dependencies]`, `[dev-dependencies]`,
/// `[build-dependencies]`, `[target.'…'.dependencies]`,
/// `[workspace.dependencies]`). Comments are stripped: a manifest may freely
/// explain *why* rayon is banned.
pub fn scan_manifests(root: &Path) -> Scan {
    let key = rayon_dep_key();
    let manifests = workspace_manifests(root);
    let mut hits = Vec::new();
    for manifest in &manifests {
        let Ok(text) = std::fs::read_to_string(manifest) else { continue };
        let mut in_deps = false;
        for (i, raw) in text.lines().enumerate() {
            let line = raw.trim();
            if line.starts_with('[') {
                in_deps = line.contains("dependencies]");
                continue;
            }
            if !in_deps {
                continue;
            }
            let code = strip_line_comment(line);
            let name = code.split('=').next().unwrap_or("").trim().trim_matches('"');
            if name == key {
                hits.push(Hit {
                    file: manifest.clone(),
                    line: i + 1,
                    token: key.clone(),
                    text: code.trim().to_string(),
                });
            }
        }
    }
    Scan { hits, scanned: manifests.len() }
}

/// Run `cargo metadata` for `root` and return the parsed document.
///
/// `--offline --locked` on purpose: the guard must never mutate `Cargo.lock`
/// (LAW 6) and must never reach the network from a test. A stale lock is a hard
/// error, not a skip — a guard that skips itself is the disease.
pub fn cargo_metadata(root: &Path) -> Result<serde_json::Value, String> {
    let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".into());
    let out = Command::new(cargo)
        .args(["metadata", "--format-version", "1", "--offline", "--locked"])
        .current_dir(root)
        .output()
        .map_err(|e| format!("could not run `cargo metadata` in {}: {e}", root.display()))?;
    if !out.status.success() {
        let stderr = String::from_utf8_lossy(&out.stderr);
        return Err(format!(
            "`cargo metadata --offline --locked` failed in {} ({}):\n{}",
            root.display(),
            out.status,
            stderr.lines().take(8).collect::<Vec<_>>().join("\n"),
        ));
    }
    serde_json::from_slice(&out.stdout).map_err(|e| format!("cargo metadata is not JSON: {e}"))
}

/// Package-id → package-name index from a `cargo metadata` document.
fn id_to_name(md: &serde_json::Value) -> std::collections::HashMap<String, String> {
    md["packages"]
        .as_array()
        .map(|ps| {
            ps.iter()
                .filter_map(|p| {
                    Some((p["id"].as_str()?.to_string(), p["name"].as_str()?.to_string()))
                })
                .collect()
        })
        .unwrap_or_default()
}

/// Which dependency kinds an edge carries. `cargo metadata` spells a normal
/// dependency as `kind: null`.
fn edge_kinds(dep: &serde_json::Value) -> Vec<String> {
    dep["dep_kinds"]
        .as_array()
        .map(|ks| {
            ks.iter()
                .map(|k| k["kind"].as_str().unwrap_or("normal").to_string())
                .collect()
        })
        .unwrap_or_default()
}

/// Breadth-first walk from the workspace members to `target_name`.
///
/// `require_non_normal` is what keeps the two answers from collapsing into one:
/// with it set, a chain only counts if it crosses at least one `dev` or `build`
/// edge, so "the dev-only route" cannot be silently answered with the shipped
/// route. The BFS state therefore carries that flag, and a package is re-visited
/// once per flag value.
///
/// Returns the shortest qualifying chain of package names, workspace member
/// first.
fn chain_to(
    md: &serde_json::Value,
    target_name: &str,
    require_non_normal: bool,
) -> Option<Vec<String>> {
    let names = id_to_name(md);
    let nodes: std::collections::HashMap<&str, &serde_json::Value> = md["resolve"]["nodes"]
        .as_array()?
        .iter()
        .filter_map(|n| Some((n["id"].as_str()?, n)))
        .collect();

    let members: Vec<&str> =
        md["workspace_members"].as_array()?.iter().filter_map(|m| m.as_str()).collect();

    let mut seen: std::collections::HashSet<(&str, bool)> = std::collections::HashSet::new();
    let mut queue: VecDeque<(&str, bool, Vec<String>)> = VecDeque::new();
    for m in members {
        if seen.insert((m, false)) {
            let label = names.get(m).cloned().unwrap_or_else(|| m.to_string());
            queue.push_back((m, false, vec![label]));
        }
    }

    while let Some((id, crossed, path)) = queue.pop_front() {
        if names.get(id).map(|n| n == target_name).unwrap_or(false)
            && path.len() > 1
            && (crossed || !require_non_normal)
        {
            return Some(path);
        }
        let Some(node) = nodes.get(id) else { continue };
        let Some(deps) = node["deps"].as_array() else { continue };
        for dep in deps {
            let kinds = edge_kinds(dep);
            // A single dependency can carry several kinds at once (normal AND
            // dev). Take the cheapest interpretation: if it is normal at all,
            // the shipped walk may use it without crossing.
            let has_normal = kinds.iter().any(|k| k == "normal");
            let has_other = kinds.iter().any(|k| k == "dev" || k == "build");
            let Some(pkg) = dep["pkg"].as_str() else { continue };

            // Which flag values this edge can hand on. The shipped walk only
            // ever follows a normal edge and never sets the flag, so it can
            // never answer with a dev route.
            let mut onward: Vec<bool> = Vec::new();
            if has_normal {
                onward.push(crossed);
            }
            if require_non_normal && has_other {
                onward.push(true);
            }

            for next_crossed in onward {
                if !seen.insert((pkg, next_crossed)) {
                    continue;
                }
                let mut next = path.clone();
                next.push(names.get(pkg).cloned().unwrap_or_else(|| pkg.to_string()));
                queue.push_back((pkg, next_crossed, next));
            }
        }
    }
    None
}

/// A **normal** dependency path from this workspace to rayon, as `cargo
/// metadata` sees it.
///
/// **Do not decide the shipped axis with this.** It over-approximates and it was
/// measured doing so: pointed at korp on 2026-08-03 it reported
/// `korp -> image -> rayon` while `cargo tree -e normal -i rayon --target all`
/// said "nothing to print". `cargo metadata`'s resolve unifies
/// dev-dependency features into one graph, so `image` shows up with `avif` on
/// and its `ravif -> rayon` edge looks normal. The dependency-KIND walk under
/// this function is right; the FEATURE resolution beneath it is not, and it errs
/// in the direction that invents violations. Kept for kind attribution and for
/// [`unshipped_rayon_chain`] (where over-approximating a *context* chain is
/// harmless); the verdict belongs to [`shipped_rayon_tree`].
pub fn overapproximated_normal_chain(md: &serde_json::Value) -> Option<Vec<String>> {
    chain_to(md, &rayon_dep_key(), false)
}

/// A path to rayon that crosses at least one **dev** or **build** edge: real,
/// known, and **not** a violation — third-party test-harness weight, nothing we
/// chose and nothing that ships. Reported as context so the gate can say which
/// of the two axes it tripped on, and used as the walker's own liveness check.
pub fn unshipped_rayon_chain(md: &serde_json::Value) -> Option<Vec<String>> {
    chain_to(md, &rayon_dep_key(), true)
}

// ───────────────────────── the shipped verdict, from cargo tree ──────────────
//
// `cargo tree -e normal -i rayon --target all` is the command that was actually
// measured on 2026-08-03, and it is the one that resolves features the way a
// build does. Everything below reads ITS output. `cargo metadata` stays where it
// belongs: dependency-kind attribution and the dev-route context chain.

/// Run `cargo tree -i <crate> --target all -e <edges>` in `root` and hand back
/// stdout.
///
/// `--offline --locked` for the same reason [`cargo_metadata`] uses them: a
/// guard must never mutate `Cargo.lock` (LAW 6) and never reach the network. A
/// stale lock is a hard error, not a skip.
///
/// `extra` carries the feature selection — `["--all-features"]`,
/// `["--no-default-features", "--features", "robot-watch"]`, or nothing for the
/// default shape. It is a parameter and not a bool because **the default shape
/// is not the only shape that ships**: measured on oden 2026-08-03, korp is
/// clean at default features and at five of its six single-feature builds, and
/// `--no-default-features --features robot-watch` puts rayon on a NORMAL edge —
/// and that is the build `.nornir/ingest-tab-app-robot.md:27` tells people to
/// make. A gate that only ever asks about the default answer is blind to
/// exactly the binary the documentation recommends.
pub fn rayon_tree(root: &Path, edges: &str, extra: &[&str]) -> Result<String, String> {
    dep_tree(root, &rayon_dep_key(), edges, extra)
}

/// [`rayon_tree`], generalized to ANY banned crate — the ONE `cargo tree -i`
/// runner every law shares (LAW 5). LAW 3's guard asks it about rayon; LAW 4's
/// (`webgl_free_law.rs`, here and in korp) asks it about `glow` / `khronos-egl`,
/// with the identical `--offline --locked --target all` discipline and the same
/// "stderr is part of the answer" contract.
pub fn dep_tree(root: &Path, krate: &str, edges: &str, extra: &[&str]) -> Result<String, String> {
    let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".into());
    let mut cmd = Command::new(cargo);
    cmd.args(["tree", "-i", krate, "--target", "all", "-e", edges])
        .args(["--offline", "--locked"])
        .args(extra)
        .current_dir(root);
    let out = cmd
        .output()
        .map_err(|e| format!("could not run `cargo tree` in {}: {e}", root.display()))?;
    let stdout = String::from_utf8_lossy(&out.stdout).to_string();
    let stderr = String::from_utf8_lossy(&out.stderr).to_string();
    if !out.status.success() {
        return Err(format!(
            "`cargo tree -e {edges} -i {krate} --target all {}` failed in {} ({}):\n{}",
            extra.join(" "),
            root.display(),
            out.status,
            stderr.lines().take(8).collect::<Vec<_>>().join("\n"),
        ));
    }
    // Exit code is not the answer here. `cargo tree` says "nothing to print" on
    // stderr and exits 0, and a command that failed to name a crate at all would
    // also exit 0 with empty stdout. The caller gets stderr folded in so
    // "nothing to print" is a fact it can read, not an absence it must guess at.
    Ok(if stdout.trim().is_empty() { stderr } else { stdout })
}

/// Did `cargo tree -i` find no path at all? True for the "nothing to print"
/// notice and for genuinely empty output.
pub fn tree_found_nothing(out: &str) -> bool {
    out.trim().is_empty() || out.contains("nothing to print")
}

/// The chain `cargo tree -i` drew, from the first package of OURS back up to
/// rayon.
///
/// `cargo tree -i` prints the inverted tree: rayon at depth 0, its dependents
/// below it. A package is ours when the path cargo printed in parentheses is
/// under `root`. Returns e.g.
/// `["korp", "eframe", "egui-winit", "arboard", "image", "ravif", "rav1e",
///   "av-scenechange", "rayon"]`.
///
/// `None` means the tree named nothing of ours — either it is empty (clean) or
/// the format changed, and the caller must not read those two as the same thing.
pub fn tree_chain_to_first_party(out: &str, root: &Path) -> Option<Vec<String>> {
    let here = format!("({}", root.display());
    let mut stack: Vec<String> = Vec::new();
    for line in out.lines() {
        // The tree prefix is drawn from these five characters, four per level.
        let prefix: String =
            line.chars().take_while(|c| matches!(c, '│' | ' ' | '├' | '└' | '─')).collect();
        let body = &line[prefix.len()..];
        if body.is_empty() || body.starts_with('[') {
            // `[dev-dependencies]` / `[build-dependencies]` markers carry no
            // package of their own.
            continue;
        }
        let depth = prefix.chars().count() / 4;
        let Some(name) = body.split_whitespace().next().map(str::to_string) else { continue };
        stack.truncate(depth);
        stack.push(name);
        if body.contains(&here) {
            let mut chain = stack.clone();
            chain.reverse();
            return Some(chain);
        }
    }
    None
}

/// The verdict: is rayon reachable from this workspace over **normal** edges?
///
/// `Ok(None)` is clean. `Ok(Some(chain))` is a LAW 3 violation on a shipped
/// edge.
pub fn shipped_rayon_tree(root: &Path) -> Result<Option<Vec<String>>, String> {
    shipped_rayon_tree_with(root, &[])
}

/// [`shipped_rayon_tree`] for ONE feature selection — the build shape is a
/// parameter, because rayon can sit behind a feature and in korp it does.
///
/// Pass `&[]` for the default shape, or e.g.
/// `&["--no-default-features", "--features", "server"]`.
pub fn shipped_rayon_tree_with(
    root: &Path,
    features: &[&str],
) -> Result<Option<Vec<String>>, String> {
    let out = rayon_tree(root, "normal", features)?;
    if tree_found_nothing(&out) {
        return Ok(None);
    }
    Ok(Some(tree_chain_to_first_party(&out, root).unwrap_or_else(|| {
        out.lines().map(str::trim).filter(|l| !l.is_empty()).map(str::to_string).collect()
    })))
}

/// The `--no-default-features --features <name>` argv for one feature.
pub fn only_feature(name: &str) -> Vec<String> {
    vec!["--no-default-features".into(), "--features".into(), name.into()]
}

/// The same instrument and the same parser, asked a question this tree is
/// **known** to answer yes to: reach rayon over edges of *any* kind.
///
/// Both repos really do carry rayon in `Cargo.lock`, through
/// `nornir-robotui`'s snapshot harness (`egui_kittest → dify → image → ravif →
/// rav1e → av-scenechange`), and every edge of that is a `[dev-dependencies]`
/// edge. So this call must always come back with a chain that ends at one of
/// OUR packages — and [`shipped_rayon_tree`] is the identical command with the
/// single `-e` flag narrowed to `normal`.
///
/// What it proves: cargo ran, rayon is in the graph, the parser read real
/// cargo output, and the walk reaches this workspace. What it does **not**
/// prove: that a *normal* edge would be detected — that is what
/// `the_tree_parser_reads_a_real_violation_chain_all_the_way_to_us` is for,
/// which is proven red against a captured violation. Stated plainly because a
/// liveness check dressed up as a red proof is the disease this module is about.
///
/// A guard whose clean answer is `None` cannot tell "clean" from "the command
/// stopped working". This makes it say which, on every run.
pub fn rayon_tree_liveness_chain(root: &Path) -> Result<Option<Vec<String>>, String> {
    let out = rayon_tree(root, "normal,dev,build", &[])?;
    if tree_found_nothing(&out) {
        return Ok(None);
    }
    Ok(tree_chain_to_first_party(&out, root))
}

/// The `-e normal` query under `--all-features`, which in **korp** really does
/// produce a shipped violation: `--all-features` turns on `image`'s `avif` and
/// `ravif → rav1e → av-scenechange → rayon` becomes a normal edge reaching korp
/// itself. Measured on oden 2026-08-03 — the same command that says "nothing to
/// print" at default features prints that chain.
///
/// This is the strongest available proof for check 3, because the failing query
/// is byte-for-byte the query the verdict uses. It is **not** universal:
/// measured the same day, facett answers "nothing to print" even under
/// `--all-features`, because `--all-features` applies to workspace members only
/// and no facett member turns `avif` on. Callers that cannot get a chain here
/// must fall back to [`rayon_tree_liveness_chain`], not skip the axis.
pub fn rayon_tree_all_features_chain(root: &Path) -> Result<Option<Vec<String>>, String> {
    let out = rayon_tree(root, "normal", &["--all-features"])?;
    if tree_found_nothing(&out) {
        return Ok(None);
    }
    Ok(tree_chain_to_first_party(&out, root))
}

/// The feature set cargo resolves for `pkg` when the **whole workspace** is
/// selected — exactly what `cargo test --workspace` compiles with.
///
/// This asks cargo rather than re-implementing feature unification, because a
/// hand-rolled resolver that quietly disagrees with cargo is a guard that
/// reports on a build nobody runs.
pub fn workspace_features(md: &serde_json::Value, pkg: &str) -> Option<Vec<String>> {
    let names = id_to_name(md);
    let mut out: Vec<String> = Vec::new();
    let mut found = false;
    for node in md["resolve"]["nodes"].as_array()? {
        let id = node["id"].as_str()?;
        if names.get(id).map(|n| n != pkg).unwrap_or(true) {
            continue;
        }
        found = true;
        if let Some(fs) = node["features"].as_array() {
            out.extend(fs.iter().filter_map(|f| f.as_str().map(str::to_string)));
        }
    }
    if !found {
        return None;
    }
    out.sort();
    out.dedup();
    Some(out)
}

/// A test the default build never runs, because a `cfg` switches it off.
///
/// Two shapes, both silent, told apart by [`whole_file`](Self::whole_file):
///
/// * a crate-level `#![cfg(feature = "…")]` — the WHOLE target compiles to an
///   empty binary that prints `0 tests, 0 benchmarks`;
/// * a per-`fn` `#[cfg(feature = "…")]` on `#[test]` inside a file that otherwise
///   runs — libtest never lists the fn at all, so it does not even reach the
///   `filtered out` count.
///
/// The second shape is the more dangerous one: the target's OTHER tests report a
/// cheerful `ok`, so the file looks alive while the arm that needed the feature is
/// gone. MEASURED in this workspace 2026-08-22 — facett-map alone carries 3 files
/// of that shape (`cull_envelope`, `fill_extent_gate`, `paint_order_pixels`).
#[derive(Debug, Clone)]
pub struct GatedTestFile {
    /// The file.
    pub file: PathBuf,
    /// The feature the `cfg` demands.
    pub feature: String,
    /// How many `#[test]`/`#[tokio::test]` functions this entry silences — the
    /// number that disappears when the feature is off.
    pub tests: usize,
    /// `true` when a crate-level `#![cfg(…)]` takes the whole target down;
    /// `false` when only the individual `#[test]` fns counted here are gated.
    pub whole_file: bool,
}

/// Find every `tests/*.rs` under `crate_dir` that a feature `cfg` can silence —
/// crate-level and per-`fn` alike.
///
/// A gated file whose feature is off compiles to an empty binary that prints
/// `0 tests, 0 benchmarks` and exits 0 — indistinguishable from a passing file.
/// That is the exact shape of a green nobody has seen red. A per-`fn` gate is
/// quieter still: the target runs, reports `ok`, and the gated fns are not even
/// counted as `filtered out`.
///
/// One entry per (file, feature). A crate-level `#![cfg(all(feature = "a",
/// not(target_arch = "wasm32")))]` yields one entry for `a` — every feature the
/// `cfg` REQUIRES is a separate entry, because each one alone can silence the file.
/// `any(feature = …)` is deliberately NOT modelled (a file behind `any` is reachable
/// through either arm, which this shape cannot express); [`any_feature_cfgs`] finds
/// them so the day one is written it is a visible decision and not a silent miss.
pub fn gated_test_files(crate_dir: &Path) -> Vec<GatedTestFile> {
    let mut out = Vec::new();
    let Ok(rd) = std::fs::read_dir(crate_dir.join("tests")) else { return out };
    for entry in rd.flatten() {
        let path = entry.path();
        if path.extension().and_then(|e| e.to_str()) != Some("rs") {
            continue;
        }
        let Ok(text) = std::fs::read_to_string(&path) else { continue };
        let lines: Vec<&str> = text.lines().collect();

        let is_test_attr =
            |l: &str| l.trim().starts_with("#[test]") || l.trim().starts_with("#[tokio::test");

        // ── crate-level: the whole target goes silent ────────────────────────
        let crate_feats: Vec<String> = lines
            .iter()
            .filter(|l| l.trim_start().starts_with("#![cfg("))
            .flat_map(|l| required_features_of_cfg(l))
            .collect();
        if !crate_feats.is_empty() {
            let tests = lines.iter().filter(|l| is_test_attr(l)).count();
            let mut seen: Vec<String> = Vec::new();
            for f in crate_feats {
                if seen.contains(&f) {
                    continue;
                }
                seen.push(f.clone());
                out.push(GatedTestFile { file: path.clone(), feature: f, tests, whole_file: true });
            }
            // A file already dead at the top cannot ALSO be counted per fn.
            continue;
        }

        // ── per-fn: the target runs and the gated fns are simply not there ───
        // Attributes may sit on either side of `#[test]`, so the contiguous run of
        // `#[…]` lines around it is the attribute block to read.
        let mut per_feature: Vec<(String, usize)> = Vec::new();
        for (i, l) in lines.iter().enumerate() {
            if !is_test_attr(l) {
                continue;
            }
            let mut feats: Vec<String> = Vec::new();
            let mut j = i;
            while j > 0 && lines[j - 1].trim_start().starts_with("#[") {
                j -= 1;
                feats.extend(required_features_of_cfg(lines[j]));
            }
            let mut k = i + 1;
            while k < lines.len() && lines[k].trim_start().starts_with("#[") {
                feats.extend(required_features_of_cfg(lines[k]));
                k += 1;
            }
            feats.sort();
            feats.dedup();
            for f in feats {
                match per_feature.iter_mut().find(|(g, _)| *g == f) {
                    Some((_, n)) => *n += 1,
                    None => per_feature.push((f, 1)),
                }
            }
        }
        for (feature, tests) in per_feature {
            out.push(GatedTestFile { file: path.clone(), feature, tests, whole_file: false });
        }
    }
    out.sort_by(|a, b| (&a.file, &a.feature).cmp(&(&b.file, &b.feature)));
    out
}

/// Every `cfg` line under `crate_dir/tests` that uses `any(feature = …)`.
///
/// [`gated_test_files`] models a `cfg` as a set of features that are ALL required.
/// `any(...)` breaks that: the file is reachable through either arm, and reporting
/// it as "needs feature A" would be a lie that could send someone declaring an arm
/// nobody needs. There are none in this workspace today; this is what says so, and
/// what will say otherwise the day one is written.
pub fn any_feature_cfgs(crate_dir: &Path) -> Vec<(PathBuf, String)> {
    let mut out = Vec::new();
    let Ok(rd) = std::fs::read_dir(crate_dir.join("tests")) else { return out };
    for entry in rd.flatten() {
        let path = entry.path();
        if path.extension().and_then(|e| e.to_str()) != Some("rs") {
            continue;
        }
        let Ok(text) = std::fs::read_to_string(&path) else { continue };
        for l in text.lines() {
            let t = l.trim_start();
            if (t.starts_with("#[cfg(") || t.starts_with("#![cfg(")) && t.contains("any(") && t.contains("feature") {
                out.push((path.clone(), t.to_string()));
            }
        }
    }
    out
}

/// Every feature a `cfg` attribute line REQUIRES: each `feature = "x"` that is not
/// inside a `not(…)` and not inside an `any(…)`.
///
/// `#![cfg(feature = "wgpu")]`                                   → `["wgpu"]`
/// `#![cfg(all(feature = "gfx-v2-gpu", not(target_arch = "…")))]` → `["gfx-v2-gpu"]`
/// `#![cfg(not(target_arch = "wasm32"))]`                        → `[]` (no feature)
/// `#[cfg(any(feature = "a", feature = "b"))]`                   → `[]` (see
/// [`any_feature_cfgs`])
fn required_features_of_cfg(line: &str) -> Vec<String> {
    let t = line.trim();
    if !(t.starts_with("#[cfg(") || t.starts_with("#![cfg(")) {
        return Vec::new();
    }
    let mut out = Vec::new();
    // Walk the line tracking whether we are inside a `not(` or `any(` group. Both
    // make a `feature = "x"` inside them NOT a requirement.
    let bytes = t.as_bytes();
    let mut depth_stack: Vec<bool> = Vec::new(); // true = this group negates/relaxes
    let mut i = 0usize;
    while i < bytes.len() {
        if bytes[i] == b'(' {
            let before = &t[..i];
            let neg = before.ends_with("not") || before.ends_with("any");
            depth_stack.push(neg);
            i += 1;
            continue;
        }
        if bytes[i] == b')' {
            depth_stack.pop();
            i += 1;
            continue;
        }
        if t[i..].starts_with("feature") {
            let rest = t[i + "feature".len()..].trim_start();
            if let Some(rest) = rest.strip_prefix('=') {
                let rest = rest.trim_start();
                if let Some(rest) = rest.strip_prefix('"') && let Some(end) = rest.find('"') {
                    // Skip the outermost `cfg(` group itself: it is never a
                    // negation, and `depth_stack` already carries it.
                    let relaxed = depth_stack.iter().skip(1).any(|n| *n);
                    if !relaxed {
                        out.push(rest[..end].to_string());
                    }
                }
            }
            i += "feature".len();
            continue;
        }
        i += 1;
    }
    out
}
// ── The attribute-owner law ───────────────────────────────────────────────────
//
// **An attribute binds to the NEXT item.** Anything inserted between the two —
// a doc comment, a doc comment plus a whole new item — silently re-parents it.
// The code compiles, the tests stay green, and something stops existing.
//
// Three independent instances were measured on 2026-08-22, all found by
// accident:
//
// 1. `nornir/src/lib.rs` — a doc comment landed between `#[cfg(feature = "mcp")]`
//    and `pub mod mcp_stdio;`. `mcp_stdio` became UNCONDITIONAL (281 rmcp/schemars
//    errors in every default build) and the new `lens_chain` module inherited the
//    gate, so it compiled ONLY with `mcp` — which is what hid the fact that it did
//    not compile at all.
// 2. `edda/crates/nornir-service` — the same wedge moved `#[cfg(feature =
//    "auth-provider")]` onto a `pub use`, and every default build of the crate
//    failed on an unresolved `provider`.
// 3. `korp/src/main.rs` — a new test was pasted between an existing `#[test]` and
//    its function. One function then carried two `#[test]`s and
//    `korp_state_exposes_all_views` carried none: it had not run for months, with
//    the whole suite green. The only signal was one `duplicate_macro_attributes`
//    warning.
//
// Instance 3 is why this is a source scan and not only a lint switch. `rustc`
// does warn on the duplicate, but a warning in a 20 000-line build log is not a
// gate, and neither `duplicate_macro_attributes` nor `unused_attributes` says
// anything about instances 1 and 2 — there the attribute is *used*, just by the
// wrong item.
//
// Measured cost of the three rules over the whole constellation on 2026-08-22
// (26 repos, ~1.1 M lines of first-party Rust): 3 duplicate blocks, 9
// gate-before-doc blocks, 1 orphaned test function. Small enough to be a hard
// gate rather than a report.

/// Attributes that decide whether an item **exists**, or whether a function is a
/// test. These are the ones whose owner is worth a build failure: a re-parented
/// `#[derive]` fails to compile, a re-parented `#[cfg]` or `#[test]` does not.
fn attr_changes_existence(name: &str) -> bool {
    matches!(name, "cfg" | "cfg_attr") || attr_is_test(name)
}

/// A test-declaring attribute, in any of the spellings this constellation uses.
/// Matched on the last `::` segment so `tokio::test` and a bare `test` are one
/// answer.
fn attr_is_test(name: &str) -> bool {
    let last = name.rsplit("::").next().unwrap_or(name);
    // `wasm_bindgen_test` is how garmr-webui declares all seventeen of its browser
    // tests; a set of exact names missed every one of them and called the file
    // seventeen dead tests.
    last == "test"
        || last.ends_with("_test")
        || matches!(last, "bench" | "rstest" | "proptest" | "test_case" | "quickcheck")
        || matches!(name, "ignore" | "should_panic")
}

/// Attributes that may not legally appear twice on one item. `cfg`, `allow`,
/// `derive`, `serde` and friends repeat all the time and are not on this list —
/// a duplicate of those is caught by the byte-identical rule instead, which
/// cannot produce a false positive.
fn attr_is_non_repeatable(name: &str) -> bool {
    let last = name.rsplit("::").next().unwrap_or(name);
    matches!(
        last,
        "test"
            | "bench"
            | "rstest"
            | "ignore"
            | "should_panic"
            | "no_mangle"
            | "global_allocator"
            | "panic_handler"
            | "proc_macro"
            | "proc_macro_derive"
            | "proc_macro_attribute"
    )
}

/// The attribute path at the head of `#[…]` / `#![…]`, e.g. `cfg`, `tokio::test`.
fn attr_path(line: &str) -> Option<String> {
    let t = line.trim_start();
    let rest = t.strip_prefix("#[").or_else(|| t.strip_prefix("#!["))?;
    let mut out = String::new();
    for c in rest.chars() {
        if c.is_alphanumeric() || c == '_' || c == ':' {
            out.push(c);
        } else if c.is_whitespace() && out.is_empty() {
            continue;
        } else {
            break;
        }
    }
    if out.is_empty() { None } else { Some(out) }
}

/// One entry of an attribute block, in source order.
#[derive(Debug, Clone, PartialEq, Eq)]
enum Piece {
    /// An outer `#[…]` attribute: (line, path, full text).
    Attr(usize, String, String),
    /// A `///` doc comment line.
    Doc(usize),
}

/// Parse the attribute/doc block that starts at `lines[i]`, returning its pieces
/// and the index of the ITEM line it binds to.
///
/// Multi-line attributes are followed by bracket balance, which is what the first
/// cut of this scanner got wrong: `#[ignore = "…"]` spread over four lines made
/// the walk stop early and report two perfectly attributed heavy tests in
/// `nornir-build-thing` as orphans. Blank lines are also legal between an
/// attribute and its item (`znippy-zoomies/src/stree.rs` writes them), and
/// stopping there produced three more phantom orphans.
fn parse_block(lines: &[&str], start: usize) -> (Vec<Piece>, usize) {
    let mut pieces = Vec::new();
    let mut i = start;
    while i < lines.len() {
        let t = lines[i].trim_start();
        if t.starts_with("#[") {
            // Anything after the closing bracket on the same line means this is an
            // item line carrying an inline attribute (`#[serde(default)] pub a: u8,`),
            // not a block entry — otherwise struct fields read as one long block.
            let mut depth: i32 = 0;
            let mut end = i;
            let mut tail_is_clean = false;
            'outer: for (k, l) in lines.iter().enumerate().skip(i) {
                for (ci, c) in l.char_indices() {
                    if c == '[' {
                        depth += 1;
                    } else if c == ']' {
                        depth -= 1;
                        if depth == 0 {
                            end = k;
                            let tail = l[ci + 1..].trim();
                            tail_is_clean = tail.is_empty() || tail.starts_with("//");
                            break 'outer;
                        }
                    }
                }
            }
            if !tail_is_clean {
                break;
            }
            let text: String = lines[i..=end].join(" ").split_whitespace().collect::<Vec<_>>().join(" ");
            let path = attr_path(t).unwrap_or_default();
            pieces.push(Piece::Attr(i + 1, path, text));
            i = end + 1;
            continue;
        }
        if t.starts_with("///") {
            pieces.push(Piece::Doc(i + 1));
            i += 1;
            continue;
        }
        if t.starts_with("//") || t.is_empty() {
            i += 1;
            continue;
        }
        break;
    }
    (pieces, i)
}

/// Line ranges of every `#[cfg(test)] mod … { … }` in a file, by brace balance.
fn cfg_test_mod_ranges(lines: &[&str]) -> Vec<(usize, usize)> {
    let mut out = Vec::new();
    for (i, l) in lines.iter().enumerate() {
        if !l.trim_start().starts_with("#[cfg(test)]") {
            continue;
        }
        let (_, item) = parse_block(lines, i);
        let Some(head) = lines.get(item) else { continue };
        let h = head.trim_start();
        if !(h.starts_with("mod ") || h.starts_with("pub mod ")) {
            continue;
        }
        let mut depth: i32 = 0;
        let mut opened = false;
        for (k, l) in lines.iter().enumerate().skip(item) {
            depth += l.matches('{').count() as i32 - l.matches('}').count() as i32;
            if l.contains('{') {
                opened = true;
            }
            if opened && depth <= 0 {
                out.push((item, k));
                break;
            }
        }
    }
    out
}

/// `fn some_name()` — a zero-argument free function, the shape every test has.
fn zero_arg_fn_name(line: &str) -> Option<&str> {
    let t = line.trim_start();
    let t = t.strip_prefix("pub ").unwrap_or(t).trim_start();
    let t = t.strip_prefix("async ").unwrap_or(t).trim_start();
    let t = t.strip_prefix("unsafe ").unwrap_or(t).trim_start();
    let rest = t.strip_prefix("fn ")?;
    let name_end = rest.find(|c: char| !(c.is_alphanumeric() || c == '_'))?;
    let (name, tail) = rest.split_at(name_end);
    let tail = tail.trim_start();
    if !tail.starts_with("()") {
        return None;
    }
    if name.is_empty() { None } else { Some(name) }
}

/// The three shapes, found in one `.rs` file. `path` is only used to label the
/// hits and to decide whether the file is a test surface.
///
/// Public so a guard can plant a shape in a string and watch this name it — a
/// scanner that has never been seen red is exactly the hollow green the module
/// docs are about.
pub fn attribute_hits(path: &Path, text: &str) -> Vec<Hit> {
    let lines: Vec<&str> = text.lines().collect();
    let mut hits = Vec::new();
    let p = path.to_string_lossy().replace('\\', "/");
    // cargo compiles `tests/*.rs` as test binaries and everything DEEPER as a shared
    // helper module that sibling binaries pull in with `mod support;`. In a helper,
    // "nothing in this file calls it" says nothing at all — `nornir`'s
    // `tests/support/mcp_harness.rs` is called only from the binaries that include it.
    let is_support = ["/tests/", "/benches/"].iter().any(|d| {
        p.rsplit_once(d).is_some_and(|(_, rest)| rest.contains('/'))
    });
    let is_test_surface = p.contains("/tests/") || p.contains("/benches/");
    let test_mods = cfg_test_mod_ranges(&lines);

    let mut i = 0usize;
    while i < lines.len() {
        let t = lines[i].trim_start();
        let starts_block = t.starts_with("#[") || t.starts_with("///");
        if !starts_block {
            // R3 — a test-shaped function that carries no attribute block at all.
            if let Some(name) = zero_arg_fn_name(lines[i]) {
                maybe_orphan_test(
                    path, &lines, text, i, name, &[], is_support, is_test_surface, &test_mods,
                    &mut hits,
                );
            }
            i += 1;
            continue;
        }
        let (pieces, item) = parse_block(&lines, i);
        if pieces.is_empty() {
            i += 1;
            continue;
        }
        let item_line = lines.get(item).copied().unwrap_or("<end of file>");

        // R1 — the same attribute twice on one item: either a non-repeatable
        // attribute by name, or a byte-identical repeat of any attribute.
        let mut by_name: Vec<(usize, &str)> = Vec::new();
        let mut by_text: Vec<(usize, &str)> = Vec::new();
        for piece in &pieces {
            let Piece::Attr(ln, name, txt) = piece else { continue };
            if attr_is_non_repeatable(name) {
                if let Some((first, _)) = by_name.iter().find(|(_, n)| *n == name) {
                    hits.push(Hit {
                        file: path.to_path_buf(),
                        line: *ln,
                        token: format!("duplicate #[{name}]"),
                        text: format!(
                            "`{item_line}` carries #[{name}] twice (also line {first}) — the first \
                             one lost its item: whatever it was written for is now unattributed"
                        ),
                    });
                }
                by_name.push((*ln, name));
            }
            if let Some((first, _)) = by_text.iter().find(|(_, x)| *x == txt) {
                hits.push(Hit {
                    file: path.to_path_buf(),
                    line: *ln,
                    token: format!("duplicate {txt}"),
                    text: format!(
                        "`{item_line}` carries the identical attribute twice (also line {first}) — \
                         the first one was written for a different item"
                    ),
                });
            }
            by_text.push((*ln, txt));
        }

        // R2 — an existence-gating attribute above a doc comment. Docs come
        // first, gates come last, so that pasting `/// doc` + a new item under an
        // existing gate is impossible to do silently.
        let mut gate: Option<(usize, &str)> = None;
        for piece in &pieces {
            match piece {
                Piece::Attr(ln, name, txt) if attr_changes_existence(name) => {
                    gate = Some((*ln, txt));
                }
                Piece::Doc(ln) => {
                    if let Some((gl, gtxt)) = gate {
                        hits.push(Hit {
                            file: path.to_path_buf(),
                            line: gl,
                            token: format!("gate above a doc comment {gtxt}"),
                            text: format!(
                                "{gtxt} at line {gl} sits ABOVE the doc comment at line {ln}, and \
                                 therefore gates `{item_line}` — check that is the item it was \
                                 written for, then put the gate directly on it, below its doc"
                            ),
                        });
                        break;
                    }
                }
                _ => {}
            }
        }

        // R3 — the function this block binds to, with no test attribute on it.
        if let Some(name) = zero_arg_fn_name(item_line) {
            maybe_orphan_test(
                path, &lines, text, item, name, &pieces, is_support, is_test_surface, &test_mods,
                &mut hits,
            );
        }
        // Continue AFTER the item, or the item line is re-read as a bare line with no
        // attribute block — which reported every properly attributed test in
        // `facet-wrapped` as an orphan the first time this ran.
        i = item + 1;
    }
    hits
}

/// R3: a zero-argument function in a test scope, with a sentence-shaped name, no
/// test attribute, no `allow(dead_code)`, and no other mention of its own name in
/// the file — i.e. a test that stopped being a test and that nothing calls.
///
/// `korp_state_exposes_all_views` had been in exactly this state for months.
#[allow(clippy::too_many_arguments)]
fn maybe_orphan_test(
    path: &Path,
    lines: &[&str],
    text: &str,
    item: usize,
    name: &str,
    pieces: &[Piece],
    is_support: bool,
    is_test_surface: bool,
    test_mods: &[(usize, usize)],
    hits: &mut Vec<Hit>,
) {
    if is_support {
        return;
    }
    if !is_test_surface && !test_mods.iter().any(|(a, b)| item >= *a && item <= *b) {
        return;
    }
    // Test names in this constellation are sentences; a two-word `fn setup()` is a
    // helper, and guessing at helpers is how a guard earns its way to being off.
    if name.matches('_').count() < 2 {
        return;
    }
    for piece in pieces {
        let Piece::Attr(_, attr_name, txt) = piece else { continue };
        if attr_is_test(attr_name) || txt.contains("dead_code") {
            return;
        }
    }
    // Called from somewhere in this file ⇒ a helper, not a stranded test.
    let mentions = text.match_indices(name).filter(|(i, _)| {
        let before = text[..*i].chars().next_back();
        let after = text[i + name.len()..].chars().next();
        !before.is_some_and(|c| c.is_alphanumeric() || c == '_')
            && !after.is_some_and(|c| c.is_alphanumeric() || c == '_')
    });
    if mentions.count() > 1 {
        return;
    }
    let _ = lines;
    hits.push(Hit {
        file: path.to_path_buf(),
        line: item + 1,
        token: "test function with no #[test]".to_string(),
        text: format!(
            "`fn {name}()` sits in a test scope, is named like a test, carries no test \
             attribute and is called by nothing — it does not run, and the suite is green"
        ),
    });
}

/// Scan every first-party `.rs` file under `root` for the attribute-owner law.
///
/// Reuses [`source_roots`], so it reads exactly the files the rayon law reads —
/// one walker, one definition of "ours" (LAW 5). `scanned` travels with the
/// verdict for the same reason it does there: a scan that read nothing finds
/// nothing, and that is the false green this constellation keeps producing.
pub fn scan_attributes(root: &Path) -> Scan {
    let mut files = Vec::new();
    for dir in source_roots(root) {
        rs_files(&dir, &mut files);
    }
    let mut hits = Vec::new();
    for file in &files {
        let Ok(text) = std::fs::read_to_string(file) else { continue };
        hits.extend(attribute_hits(file, &text));
    }
    Scan { hits, scanned: files.len() }
}


// ── The checkout-surface law ──────────────────────────────────────────────────
//
// Measured on oden 2026-08-22/23: **737 repo-escaping `path =` dependencies
// across 17 repos** (nornir 174, korp 127, dwarves 125). Every one of them is a
// build reaching *out of its own checkout* into a sibling directory, and cargo
// resolves it by PATH — it has no opinion at all about which commit that sibling
// is parked on.
//
// The consequence is not theoretical. Three separate "findings" filed the same
// night were phantoms of stale primary checkouts: a dwarves red that was a
// 10-commit-behind edda, a "`facett_core::law::dep_tree` does not exist" that
// was a 4-commit-behind facett (the fn is right here in this file), and a third.
// While thirteen lanes built against them the primaries stood at facett −4,
// korp −27, edda −10, dwarves −7, znippy-zoomies −7, knut −3 — and
// `~/git/facett`, the checkout every facett path dep in the
// constellation lands in, was sitting on *another lane's branch*, 400 lines of
// this file behind `origin/main`.
//
// A compile error is what that looks like from the inside, so the reflex is to
// go fix the code. The check below is the cheap thing that would have said the
// true sentence instead: **your sibling is not at the ref you think.**
//
// It deliberately answers about the CHECKOUT, not about the code. [`sibling_survey`]
// walks the repo-escaping path deps of a workspace, resolves each to the git
// checkout that actually contains it, and reports how that checkout's `HEAD`
// stands against its own `origin/HEAD`. [`sibling_offenders`] is the assertable
// form: empty means every sibling this build links against is at its remote's
// default ref, and anything else is the phantom, named, before it becomes a
// mystery compile failure.
//
// Why `origin/HEAD` and not `origin/main`: znippy's canonical branch is
// `master` and znippy-zoomies' is `main`, so the branch name is not knowable
// from outside the repo. `git symbolic-ref refs/remotes/origin/HEAD` asks the
// repo instead of a table — which is the same correction LAW 6 already makes in
// prose.
//
// This shells out to `git`, the way [`cargo_metadata`] shells out to cargo: the
// question is "what does the tool that owns this state say", and re-implementing
// ref resolution would be a second writer of it (LAW 5).

/// A `path = "…"` dependency whose target lies outside the repo that declared it.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EscapingDep {
    /// The dependency name as the manifest spells it.
    pub name: String,
    /// The manifest that declared it.
    pub manifest: PathBuf,
    /// The literal `path = "…"` value.
    pub declared: String,
    /// `declared`, resolved against the manifest's directory and normalised.
    /// Lexical only — the target may not exist, and that is a finding, not an error.
    pub resolved: PathBuf,
}

/// What a sibling checkout is actually doing, as opposed to what the builder assumed.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SiblingState {
    /// The path does not exist. This is the "the build dies outright" case: it is
    /// why one `cargo check` from a worktree needed twelve sibling worktrees,
    /// discovered one cargo error at a time.
    Missing,
    /// The path exists but is in no git checkout — nothing pins it at all.
    Untracked,
    /// A detached HEAD. Not necessarily wrong, but nothing says which ref it means.
    Detached { head: String },
    /// The checkout has no `origin/HEAD`, so it cannot say what its own canonical
    /// branch is. Ask the repo, not a table — and this repo declines to answer.
    NoOriginHead,
    /// HEAD and `origin/HEAD` name different commits. **This is the phantom.**
    Drifted { head: String, expected: String, behind: usize, ahead: usize },
    /// HEAD is exactly `origin/HEAD`. `dirty` still travels, because an aligned
    /// ref with uncommitted source in it is a different build from the one the ref names.
    Aligned { head: String, dirty: usize },
}

impl SiblingState {
    /// Is this a state a build may rely on? Only [`SiblingState::Aligned`] with a
    /// clean tree is. Everything else means the linked code is not the code the
    /// ref names.
    pub fn is_trustworthy(&self) -> bool {
        matches!(self, SiblingState::Aligned { dirty: 0, .. })
    }
}

/// One repo-escaping dependency, and the state of the checkout it landed in.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Sibling {
    pub dep: EscapingDep,
    /// The checkout root that contains [`EscapingDep::resolved`], if any.
    pub checkout: Option<PathBuf>,
    pub state: SiblingState,
}

impl Sibling {
    /// One line, in the shape the report asks for: subject, status, detail.
    pub fn describe(&self) -> String {
        let where_ = self.checkout.clone().unwrap_or_else(|| self.dep.resolved.clone());
        match &self.state {
            SiblingState::Missing => {
                format!("{} — MISSING — {} declares path {:?}, nothing is there", self.dep.name, self.dep.manifest.display(), self.dep.declared)
            }
            SiblingState::Untracked => {
                format!("{} — UNTRACKED — {} is in no git checkout, so no ref pins it", self.dep.name, where_.display())
            }
            SiblingState::Detached { head } => {
                format!("{} — DETACHED — {} is at {head} with no branch; nothing says which ref that is", self.dep.name, where_.display())
            }
            SiblingState::NoOriginHead => {
                format!("{} — NO-ORIGIN-HEAD — {} cannot name its own canonical branch", self.dep.name, where_.display())
            }
            SiblingState::Drifted { head, expected, behind, ahead } => {
                format!(
                    "{} — DRIFTED — {} is at {head}, origin/HEAD is {expected} (behind {behind}, ahead {ahead}); this build links THAT, not the ref you think",
                    self.dep.name,
                    where_.display()
                )
            }
            SiblingState::Aligned { head, dirty } => {
                format!("{} — DIRTY — {} is at origin/HEAD {head} but carries {dirty} uncommitted change(s)", self.dep.name, where_.display())
            }
        }
    }
}

/// Every `path = "…"` dependency declared anywhere in `root`'s manifests, in
/// declaration order, without deduplication.
///
/// Text-based on purpose. `cargo metadata` would answer this too, but it needs a
/// resolvable graph — and the whole failure mode being guarded here is a graph
/// that does not resolve because a sibling is missing or stale. A check that can
/// only run once the build works is not a pre-build check.
pub fn declared_path_deps(root: &Path) -> Vec<EscapingDep> {
    let mut out = Vec::new();
    for manifest in workspace_manifests(root) {
        let Ok(text) = std::fs::read_to_string(&manifest) else { continue };
        let dir = manifest.parent().unwrap_or(root).to_path_buf();
        for (name, declared) in path_deps_in_manifest(&text) {
            let resolved = normalise(&dir.join(&declared));
            out.push(EscapingDep { name, manifest: manifest.clone(), declared, resolved });
        }
    }
    out
}

/// The subset of [`declared_path_deps`] that leaves `root` — the ones cargo
/// resolves into somebody else's checkout.
pub fn escaping_path_deps(root: &Path) -> Vec<EscapingDep> {
    let root = normalise(root);
    declared_path_deps(&root).into_iter().filter(|d| !d.resolved.starts_with(&root)).collect()
}

/// Parse `path = "…"` out of one manifest's text, pairing each with the
/// dependency name it belongs to.
///
/// Handles the three shapes this constellation actually writes: an inline table
/// (`edda = { path = "../edda" }`), a dotted section
/// (`[dependencies.edda]` … `path = "../edda"`), and a `[patch.crates-io]` entry —
/// which is the same escape wearing a different hat and is the one a
/// dependency-name-only parser silently drops.
pub fn path_deps_in_manifest(text: &str) -> Vec<(String, String)> {
    let mut out = Vec::new();
    let mut section_key: Option<String> = None;
    for line in text.lines() {
        let t = line.trim();
        if t.starts_with('#') {
            continue;
        }
        if t.starts_with('[') {
            // `[dependencies.edda]`, `[target.'cfg(x)'.dependencies.edda]`,
            // `[patch.crates-io.edda]` → the last segment is the dep name.
            // A bare `[dependencies]` / `[patch.crates-io]` has no name of its own.
            let head = t.trim_start_matches('[').trim_end_matches(']');
            let last = head.rsplit('.').next().unwrap_or("").trim().trim_matches('"');
            section_key = match last {
                "dependencies" | "dev-dependencies" | "build-dependencies" | "crates-io"
                | "workspace" | "package" | "features" | "lib" | "bin" | "patch" => None,
                "" => None,
                other => Some(other.to_string()),
            };
            continue;
        }
        let Some(value) = quoted_value_of(t, "path") else { continue };
        // Inline table: the key before the first `=` is the dep name.
        let name = match t.split_once('=') {
            Some((k, rest)) if rest.trim_start().starts_with('{') => {
                k.trim().trim_matches('"').to_string()
            }
            _ => section_key.clone().unwrap_or_else(|| "<unnamed>".to_string()),
        };
        out.push((name, value));
    }
    out
}

/// `key = "value"` anywhere in `line`, returning `value`. Refuses to match a
/// longer key that merely ends in `key` (`rustc-path = "…"` is not `path`).
fn quoted_value_of(line: &str, key: &str) -> Option<String> {
    let mut from = 0usize;
    while let Some(i) = line[from..].find(key) {
        let at = from + i;
        let before_ok = at == 0 || !matches!(line.as_bytes()[at - 1], b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9' | b'-' | b'_' | b'.');
        let rest = &line[at + key.len()..];
        let after = rest.trim_start();
        if before_ok && after.starts_with('=') {
            let v = after[1..].trim_start();
            if let Some(stripped) = v.strip_prefix('"') && let Some(end) = stripped.find('"') {
                return Some(stripped[..end].to_string());
            }
        }
        from = at + key.len();
    }
    None
}

/// Lexical path normalisation: fold away `.` and `..` without touching the disk,
/// so a dep pointing at a directory that does not exist still gets an answer.
fn normalise(p: &Path) -> PathBuf {
    let mut out = PathBuf::new();
    for c in p.components() {
        match c {
            std::path::Component::CurDir => {}
            // `..` above the root is still the root (POSIX): `/a/../../b` is `/b`,
            // not `/../b`. Only a RELATIVE path may keep a leading `..`.
            std::path::Component::ParentDir => {
                if !out.pop() && !out.has_root() {
                    out.push("..");
                }
            }
            other => out.push(other.as_os_str()),
        }
    }
    out
}

/// The git checkout that contains `p`: the nearest ancestor holding a `.git`
/// entry. A worktree's `.git` is a file, not a directory — both count, which is
/// the whole point on a box with 264 registered worktrees.
pub fn checkout_root(p: &Path) -> Option<PathBuf> {
    let mut cursor = Some(p);
    while let Some(dir) = cursor {
        if dir.join(".git").exists() {
            return Some(dir.to_path_buf());
        }
        cursor = dir.parent();
    }
    None
}

fn git(repo: &Path, args: &[&str]) -> Option<String> {
    let out = Command::new("git").arg("-C").arg(repo).args(args).output().ok()?;
    if !out.status.success() {
        return None;
    }
    Some(String::from_utf8_lossy(&out.stdout).trim().to_string())
}

/// Where one checkout stands against its own `origin/HEAD`.
///
/// The SHA decides, not the branch. A lane worktree created with
/// `git worktree add --detach <repo> origin/main` is detached *and* exactly right,
/// and that is the standard shape on this box — grading it red would train
/// everyone to ignore the check. [`SiblingState::Detached`] therefore means
/// "detached **and** not at `origin/HEAD`", which is a real unknown.
pub fn checkout_state(repo: &Path) -> SiblingState {
    let branch = git(repo, &["symbolic-ref", "--quiet", "--short", "HEAD"]);
    let head = git(repo, &["rev-parse", "HEAD"]).unwrap_or_default();
    let Some(origin_head) = git(repo, &["symbolic-ref", "--quiet", "--short", "refs/remotes/origin/HEAD"]) else {
        return SiblingState::NoOriginHead;
    };
    let expected = git(repo, &["rev-parse", &origin_head]).unwrap_or_default();
    let dirty = git(repo, &["status", "--porcelain"])
        .map(|s| s.lines().filter(|l| !l.trim().is_empty()).count())
        .unwrap_or(0);
    if head == expected && !head.is_empty() {
        return SiblingState::Aligned { head: short(&head), dirty };
    }
    if branch.is_none() {
        return SiblingState::Detached { head: short(&head) };
    }
    let (ahead, behind) = git(repo, &["rev-list", "--left-right", "--count", &format!("HEAD...{origin_head}")])
        .and_then(|s| {
            let mut it = s.split_whitespace();
            Some((it.next()?.parse().ok()?, it.next()?.parse().ok()?))
        })
        .unwrap_or((0usize, 0usize));
    SiblingState::Drifted { head: short(&head), expected: short(&expected), behind, ahead }
}

fn short(sha: &str) -> String {
    sha.chars().take(12).collect()
}

/// Every repo-escaping path dep of `root`, with the state of the checkout it
/// resolves into. Deduplicated by checkout, because 127 escapes into the same
/// eight siblings is one answer repeated 127 times.
pub fn sibling_survey(root: &Path) -> Vec<Sibling> {
    let mut seen: Vec<PathBuf> = Vec::new();
    let mut out = Vec::new();
    for dep in escaping_path_deps(root) {
        let checkout = checkout_root(&dep.resolved);
        let state = match &checkout {
            _ if !dep.resolved.exists() => SiblingState::Missing,
            None => SiblingState::Untracked,
            Some(repo) => {
                if seen.contains(repo) {
                    continue;
                }
                seen.push(repo.clone());
                checkout_state(repo)
            }
        };
        out.push(Sibling { dep, checkout, state });
    }
    out
}

/// The assertable form: every sibling this build links against that is **not**
/// at its remote's default ref with a clean tree.
///
/// ```no_run
/// # use std::path::Path;
/// # use facett_core::law;
/// let bad = law::sibling_offenders(Path::new("."));
/// assert!(bad.is_empty(), "{}", bad.iter().map(|s| s.describe()).collect::<Vec<_>>().join("\n"));
/// ```
pub fn sibling_offenders(root: &Path) -> Vec<Sibling> {
    sibling_survey(root).into_iter().filter(|s| !s.state.is_trustworthy()).collect()
}

// ─── does the repo RESOLVE at all ──────────────────────────────────────────

/// A repo whose dependency graph cannot be resolved, and the first line cargo
/// gave as the reason.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Unresolvable {
    /// The repo root that failed.
    pub root: PathBuf,
    /// Cargo's own first diagnostic line, kept verbatim.
    pub reason: String,
}

impl Unresolvable {
    /// One line for a failure message.
    #[must_use]
    pub fn describe(&self) -> String {
        format!("{} does not resolve: {}", self.root.display(), self.reason)
    }
}

/// **Does this repo's dependency graph resolve?** `cargo metadata --no-deps`,
/// which reads manifests and answers without compiling anything.
///
/// It exists because a repo that does not RESOLVE is invisible to everything
/// else. It is not red — a compile-coverage sweep cannot compile a target it
/// cannot enumerate, a dep-graph tool has no graph, and the warehouse indexer
/// skips it. MEASURED 2026-08-23: **modgunn and ordning could not resolve for
/// nine days** and nothing in the constellation said so. modgunn's cause was a
/// feature naming a feature that no longer existed (`skade/sql`, dropped
/// 2026-08-14) — which is a *resolution* error, not a build error, so no amount
/// of building would have found it.
///
/// Cheap on purpose: ~4 s per repo, no network (`--offline` is NOT passed —
/// a repo that needs the registry to resolve genuinely does not resolve
/// offline, and pretending otherwise would trade one blindness for another).
///
/// `Ok(())` means cargo answered. Anything else is the first line of why not.
pub fn resolves(root: &Path) -> Result<(), String> {
    let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".into());
    let out = Command::new(cargo)
        .args(["metadata", "--no-deps", "--format-version", "1"])
        .current_dir(root)
        .output()
        .map_err(|e| format!("could not run `cargo metadata` in {}: {e}", root.display()))?;
    if out.status.success() {
        return Ok(());
    }
    let stderr = String::from_utf8_lossy(&out.stderr);
    // Cargo's first `error:` line is the cause; the rest is the trace. Fall back
    // to the first non-empty line so an unfamiliar failure is still named rather
    // than reported as an empty string, which would read like success.
    let reason = stderr
        .lines()
        .find(|l| l.trim_start().starts_with("error"))
        .or_else(|| stderr.lines().find(|l| !l.trim().is_empty()))
        .unwrap_or("cargo metadata failed with no output")
        .trim()
        .to_string();
    Err(reason)
}

/// [`resolves`] over many repo roots — the constellation sweep.
///
/// Returns only the failures, so an empty vec is the assertion. A root that is
/// not a cargo repo at all (no `Cargo.toml`) is skipped, not reported: this
/// guard is about repos that USED to resolve, not about directories.
pub fn unresolvable(roots: &[PathBuf]) -> Vec<Unresolvable> {
    roots
        .iter()
        .filter(|r| r.join("Cargo.toml").is_file())
        .filter_map(|r| resolves(r).err().map(|reason| Unresolvable { root: r.clone(), reason }))
        .collect()
}

#[cfg(test)]
mod resolution_tests {
    use super::*;

    /// Write a minimal cargo repo and hand back its root.
    fn repo(dir: &Path, manifest: &str) -> PathBuf {
        std::fs::create_dir_all(dir.join("src")).unwrap();
        std::fs::write(dir.join("Cargo.toml"), manifest).unwrap();
        std::fs::write(dir.join("src/lib.rs"), "").unwrap();
        dir.to_path_buf()
    }

    /// A repo that resolves answers `Ok`; one whose feature names a feature that
    /// does not exist does not — **and that is the exact shape that hid modgunn
    /// for nine days** (`warehouse-sql = [..., "skade/sql"]` after skade dropped
    /// `sql` on 2026-08-14). It is a RESOLUTION failure, so no amount of
    /// building finds it: cargo cannot even enumerate the targets.
    #[test]
    fn a_feature_naming_a_feature_that_does_not_exist_does_not_resolve() {
        let tmp = std::env::temp_dir().join(format!("law-resolves-{}", std::process::id()));
        let _ = std::fs::remove_dir_all(&tmp);

        let good = repo(
            &tmp.join("good"),
            "[package]\nname = \"good\"\nversion = \"0.0.0\"\nedition = \"2021\"\n",
        );
        assert!(resolves(&good).is_ok(), "a plain repo resolves");

        // The mutation: a feature that forwards to one its own dependency table
        // cannot supply. Nothing else about the manifest changes.
        let bad = repo(
            &tmp.join("bad"),
            "[package]\nname = \"bad\"\nversion = \"0.0.0\"\nedition = \"2021\"\n\
             [features]\nwarehouse-sql = [\"nope/sql\"]\n",
        );
        let err = resolves(&bad).expect_err("a feature naming a missing dependency cannot resolve");
        assert!(
            err.to_lowercase().contains("error"),
            "the reason is cargo's own first line, kept verbatim: {err}"
        );

        // The sweep reports only the failure, and reports it by name.
        let bad_list = unresolvable(&[good.clone(), bad.clone()]);
        assert_eq!(bad_list.len(), 1, "one of the two does not resolve: {bad_list:?}");
        assert_eq!(bad_list[0].root, bad);
        assert!(bad_list[0].describe().contains("does not resolve"));

        // A directory that is not a cargo repo is SKIPPED, not reported — this
        // guard is about repos that used to resolve, not about directories.
        let plain = tmp.join("not-a-repo");
        std::fs::create_dir_all(&plain).unwrap();
        assert!(unresolvable(&[plain]).is_empty(), "a non-repo directory is not a failure");

        let _ = std::fs::remove_dir_all(&tmp);
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    /// The `cfg` parser, on the four shapes this workspace actually contains plus
    /// the two it must refuse to guess about.
    ///
    /// This is the part that used to be a `strip_prefix("#![cfg(feature")`, which
    /// meant `#![cfg(all(feature = "gfx-v2-gpu", …))]` — facett-demo's
    /// `tests/gfx_v2_device.rs`, six test fns — was invisible to the whole
    /// gated-test guard.
    #[test]
    fn a_cfg_names_the_features_it_requires_and_no_others() {
        let f = |l: &str| required_features_of_cfg(l);
        assert_eq!(f(r#"#![cfg(feature = "wgpu")]"#), ["wgpu"]);
        assert_eq!(f(r#"#[cfg(feature = "wgpu")]"#), ["wgpu"]);
        assert_eq!(
            f(r#"#![cfg(all(feature = "gfx-v2-gpu", not(target_arch = "wasm32")))]"#),
            ["gfx-v2-gpu"]
        );
        assert_eq!(f(r#"#![cfg(all(feature = "a", feature = "b"))]"#), ["a", "b"]);
        // NOT requirements: a negated feature, and an `any` alternative.
        assert!(f(r#"#![cfg(not(feature = "wgpu"))]"#).is_empty());
        assert!(f(r#"#[cfg(any(feature = "a", feature = "b"))]"#).is_empty());
        // Not a cfg at all.
        assert!(f(r#"#![cfg(not(target_arch = "wasm32"))]"#).is_empty());
        assert!(f(r#"#[test]"#).is_empty());
        assert!(f(r#"// #![cfg(feature = "wgpu")]"#).is_empty());
    }

    /// The scanner sees BOTH shapes, and tells them apart.
    ///
    /// A per-`fn` gate is the quiet one: the target still reports `ok`, and the
    /// gated fn is not even counted as `filtered out`. Before this, only the
    /// crate-level shape was ever counted.
    #[test]
    fn the_scanner_finds_per_fn_gates_as_well_as_whole_file_ones() {
        let dir = std::env::temp_dir().join(format!("facett_law_gated_{}", std::process::id()));
        let tests = dir.join("tests");
        std::fs::create_dir_all(&tests).expect("scratch dir");

        std::fs::write(
            tests.join("whole.rs"),
            "#![cfg(all(feature = \"gfx\", not(target_arch = \"wasm32\")))]\n\
             #[test]\nfn a() {}\n#[test]\nfn b() {}\n",
        )
        .unwrap();
        std::fs::write(
            tests.join("partial.rs"),
            "#[test]\nfn cpu_one() {}\n\
             #[cfg(feature = \"wgpu\")]\n#[test]\nfn gpu_before() {}\n\
             #[test]\n#[cfg(feature = \"wgpu\")]\nfn gpu_after() {}\n\
             #[test]\nfn cpu_two() {}\n",
        )
        .unwrap();
        std::fs::write(tests.join("plain.rs"), "#[test]\nfn only() {}\n").unwrap();

        let found = gated_test_files(&dir);
        let _ = std::fs::remove_dir_all(&dir);

        assert_eq!(found.len(), 2, "one whole-file entry and one per-fn entry: {found:#?}");

        let whole = found.iter().find(|g| g.whole_file).expect("the crate-level cfg was seen");
        assert_eq!(whole.feature, "gfx", "an `all(feature = …, not(…))` still names its feature");
        assert_eq!(whole.tests, 2, "the whole target's fns go silent");

        let partial = found.iter().find(|g| !g.whole_file).expect("the per-fn cfgs were seen");
        assert_eq!(partial.feature, "wgpu");
        assert_eq!(
            partial.tests, 2,
            "both `#[cfg]`-before-`#[test]` and `#[test]`-before-`#[cfg]` are gated fns"
        );
        assert!(
            found.iter().all(|g| !g.file.ends_with("plain.rs")),
            "an ungated file must not be reported as gated — that would make the guard cry wolf"
        );
    }

    #[test]
    fn comment_stripping_keeps_code_and_drops_prose() {
        assert_eq!(strip_line_comment("let x = 1; // rayon::scope is banned").trim(), "let x = 1;");
        assert_eq!(strip_line_comment("//! never rayon").trim(), "");
        assert_eq!(strip_line_comment("let y = 2;").trim(), "let y = 2;");
    }

    #[test]
    fn the_forbidden_tokens_are_not_spelled_literally_in_this_file() {
        // The scanner covers its own source (no path carve-out), so the tokens
        // must be assembled rather than written out — otherwise this module
        // trips the law it enforces, and someone "fixes" it by adding an
        // exemption that then hides real hits.
        let me = include_str!("law.rs");
        for tok in rayon_call_tokens() {
            let literal_uses = me
                .lines()
                .filter(|l| !strip_line_comment(l).trim().is_empty())
                .filter(|l| strip_line_comment(l).contains(&tok))
                .count();
            assert_eq!(literal_uses, 0, "`{tok}` appears literally in live code in law.rs");
        }
    }

    /// **This test used to REQUIRE the blindness.** It asserted
    /// `crate_level_cfg_feature("#[cfg(feature = \"wgpu\")]") == None` — i.e. that a
    /// per-`fn` gate is not a gate — and so it was the reason nothing ever counted
    /// the quiet shape. Both are gates; only the blast radius differs, and
    /// [`GatedTestFile::whole_file`] carries that.
    #[test]
    fn both_gate_shapes_are_read_and_a_non_cfg_line_is_not() {
        assert_eq!(required_features_of_cfg("#![cfg(feature = \"wgpu\")]"), ["wgpu"]);
        assert_eq!(required_features_of_cfg("  #![cfg(feature=\"gpu\")]  "), ["gpu"]);
        assert_eq!(required_features_of_cfg("#[cfg(feature = \"wgpu\")]"), ["wgpu"]);
        assert!(required_features_of_cfg("fn main() {}").is_empty());
    }

    /// The `guard-7(a)` case, verbatim in shape: korp's root manifest names
    /// "members" in a header comment three lines above `[workspace]`. The old
    /// `text.find("members")` landed in that comment, took `[workspace]`'s own
    /// brackets as the array and returned `["workspace"]` — so korp's manifest
    /// scan read 1 file where it should read 2, and the liveness assert in the
    /// gate refused the green it could not stand behind.
    #[test]
    fn the_word_members_in_a_header_comment_is_not_the_members_key() {
        let dir = scratch("header-comment");
        std::fs::write(
            dir.join("Cargo.toml"),
            "# korp is the workspace ROOT. The `crates/*` leaves are NOT pulled in\n\
             # as members — they are self-rooting.\n\
             [workspace]\n\
             resolver = \"3\"\n\
             members = [\"xtask\"]\n\
             exclude = [\"crates/korp-ontology\", \"crates/korp-demo\"]\n\
             \n\
             [package]\n\
             name = \"korp\"\n\
             exclude = [\"docs/*\"]\n",
        )
        .unwrap();
        assert_eq!(workspace_members(&dir), vec!["xtask".to_string()]);
        // `exclude` must come from `[workspace]`, not from `[package]`.
        assert_eq!(
            workspace_excludes(&dir),
            vec!["crates/korp-ontology".to_string(), "crates/korp-demo".to_string()]
        );
        // Both, because korp *depends on* `crates/korp-demo` by path: a
        // `rayon = "1"` there ships.
        assert_eq!(
            first_party_dirs(&dir),
            vec![
                "xtask".to_string(),
                "crates/korp-ontology".to_string(),
                "crates/korp-demo".to_string()
            ]
        );
        std::fs::remove_dir_all(&dir).ok();
    }

    #[test]
    fn a_trailing_toml_comment_inside_the_array_is_not_a_member() {
        let dir = scratch("array-comment");
        std::fs::write(
            dir.join("Cargo.toml"),
            "[workspace]\nmembers = [\n  \"a\", # the first one\n  \"b\",\n]\n",
        )
        .unwrap();
        assert_eq!(workspace_members(&dir), vec!["a".to_string(), "b".to_string()]);
        std::fs::remove_dir_all(&dir).ok();
    }

    fn scratch(tag: &str) -> PathBuf {
        let dir = std::env::temp_dir()
            .join(format!("facett-law-{tag}-{}-{:?}", std::process::id(), std::thread::current().id()));
        std::fs::create_dir_all(&dir).unwrap();
        dir
    }

    /// The complete, verbatim stdout of
    /// `cargo tree -e normal -i rayon --target all --all-features --offline
    /// --locked`, run in korp on oden 2026-08-03. Not a hand-drawn tree: this is
    /// the shape the guard has to read, dedupe markers (`(*)`), branch points
    /// and all. A parser tested only against the clean case is a parser that has
    /// never been asked to find anything.
    const KORP_ALL_FEATURES_TREE: &str = "\
rayon v1.12.0
├── av-scenechange v0.14.1
│   └── rav1e v0.8.1
│       └── ravif v0.13.0
│           └── image v0.25.10
│               ├── arboard v3.6.1
│               │   └── egui-winit v0.35.0
│               │       └── eframe v0.35.0
│               │           ├── korp v0.1.0 (/home/alice/scratch/lawfix/korp)
│               │           └── nornir-robotui v0.3.0
│               │               └── korp v0.1.0 (/home/alice/scratch/lawfix/korp)
│               ├── dify v0.8.0
│               │   └── egui_kittest v0.35.0
│               │       └── nornir-robotui v0.3.0 (*)
│               ├── eframe v0.35.0 (*)
│               ├── egui_kittest v0.35.0 (*)
│               ├── facett-about v0.1.13 (/home/alice/scratch/lawfix/facett/facett-about)
│               │   └── korp v0.1.0 (/home/alice/scratch/lawfix/korp)
│               ├── korp v0.1.0 (/home/alice/scratch/lawfix/korp)
│               ├── nornir-robotui v0.3.0 (*)
│               └── webp v0.3.1
│                   └── nornir-robotui v0.3.0 (*)
├── dify v0.8.0 (*)
├── image v0.25.10 (*)
├── maybe-rayon v0.1.1
│   └── rav1e v0.8.1 (*)
└── ravif v0.13.0 (*)
";

    #[test]
    fn the_tree_parser_reads_a_real_violation_chain_all_the_way_to_us() {
        assert!(!tree_found_nothing(KORP_ALL_FEATURES_TREE));

        // (1) A straight descent: rayon down to korp, first hit in the file.
        let korp = Path::new("/home/alice/scratch/lawfix/korp");
        let chain = tree_chain_to_first_party(KORP_ALL_FEATURES_TREE, korp)
            .expect("the chain reaches korp and must be readable");
        assert_eq!(
            chain,
            vec![
                "korp",
                "eframe",
                "egui-winit",
                "arboard",
                "image",
                "ravif",
                "rav1e",
                "av-scenechange",
                "rayon"
            ]
        );

        // (2) The same capture read as FACETT's workspace. This is the case that
        // makes the test able to fail: `facett-about` sits at depth 5, but the
        // three lines before it descend to depth 7, so the walker must POP back
        // up. A depth arithmetic that never pops still answers (1) correctly —
        // every line in that path goes one level deeper — and answers this one
        // with the stale `dify/egui_kittest/nornir-robotui` branch still on the
        // stack. Measured: with the divisor wrong, (1) stayed green and this
        // assert went red.
        let facett = Path::new("/home/alice/scratch/lawfix/facett");
        let via_facett = tree_chain_to_first_party(KORP_ALL_FEATURES_TREE, facett)
            .expect("facett-about is first-party to the facett workspace");
        assert_eq!(
            via_facett,
            vec!["facett-about", "image", "ravif", "rav1e", "av-scenechange", "rayon"]
        );

        // (3) …and it must not claim a chain for a workspace it is not looking at.
        assert_eq!(tree_chain_to_first_party(KORP_ALL_FEATURES_TREE, Path::new("/nowhere")), None);
    }

    #[test]
    fn nothing_to_print_is_the_clean_answer_and_empty_is_not_silently_the_same() {
        // The literal notice cargo emits (on stderr) when `-i` finds no path.
        let clean = "warning: nothing to print.\n\nTo find dependencies that require \
                     specific target platforms, try to use option `--target all` first.\n";
        assert!(tree_found_nothing(clean));
        assert!(tree_found_nothing("   \n"));
        assert!(!tree_found_nothing(KORP_ALL_FEATURES_TREE));
        // A clean tree names nothing of ours — the two answers must not collapse.
        assert_eq!(tree_chain_to_first_party(clean, Path::new("/home/alice/scratch/lawfix/korp")), None);
    }

    #[test]
    fn members_parse_from_a_multi_line_array() {
        let dir = scratch("multiline");
        std::fs::write(
            dir.join("Cargo.toml"),
            "[workspace]\nmembers = [\n  \"a\",\n  \"b\",\n]\n",
        )
        .unwrap();
        assert_eq!(workspace_members(&dir), vec!["a".to_string(), "b".to_string()]);
        std::fs::remove_dir_all(&dir).ok();
    }

    // ── the checkout-surface law ──────────────────────────────────────────────

    /// The three manifest shapes this constellation actually writes, plus the two
    /// this parser must not guess about.
    ///
    /// The `[patch.crates-io]` case is the one that makes this test able to fail:
    /// a parser that only reads `[dependencies]` tables drops every patch entry,
    /// and a `[patch.crates-io]` path override is precisely the escape that
    /// silently rebinds a build to a sibling checkout. `rustc-path` is the other
    /// direction — a substring match on `path` claims it and invents an escape.
    #[test]
    fn a_manifest_names_the_paths_it_escapes_through_and_no_others() {
        let text = r#"
[package]
name = "consumer"
# edda = { path = "../commented-out" }

[dependencies]
edda = { path = "../edda" }
facett-core = { version = "0.1", path = "../facett/facett-core" }
in-repo = { path = "crates/in-repo" }
plain = "1.0"

[dependencies.knut]
version = "0.2"
path = "../knut"

[target.'cfg(unix)'.dependencies.tunnr]
path = "../tunnr"

[patch.crates-io]
znippy = { path = "../znippy" }

[build]
rustc-path = "/usr/bin/rustc"
"#;
        let got = path_deps_in_manifest(text);
        assert_eq!(
            got,
            vec![
                ("edda".to_string(), "../edda".to_string()),
                ("facett-core".to_string(), "../facett/facett-core".to_string()),
                ("in-repo".to_string(), "crates/in-repo".to_string()),
                ("knut".to_string(), "../knut".to_string()),
                ("tunnr".to_string(), "../tunnr".to_string()),
                ("znippy".to_string(), "../znippy".to_string()),
            ],
            "the commented line, the plain version dep and rustc-path must not appear"
        );
    }

    /// `..` is folded lexically, because the target of a broken path dep does not
    /// exist and `canonicalize` would only be able to say so by returning an error.
    #[test]
    fn a_path_that_does_not_exist_still_normalises() {
        assert_eq!(normalise(Path::new("/a/b/../c/./d")), PathBuf::from("/a/c/d"));
        assert_eq!(normalise(Path::new("/a/../../b")), PathBuf::from("/b"));
    }

    /// Run `git` with a fixed identity so the fixture does not depend on whatever
    /// the box's global config happens to be.
    fn gitx(repo: &Path, args: &[&str]) {
        let out = Command::new("git")
            .arg("-C")
            .arg(repo)
            .args(args)
            .env("GIT_AUTHOR_NAME", "law fixture")
            .env("GIT_AUTHOR_EMAIL", "law@example.invalid")
            .env("GIT_COMMITTER_NAME", "law fixture")
            .env("GIT_COMMITTER_EMAIL", "law@example.invalid")
            .output()
            .expect("git runs");
        assert!(
            out.status.success(),
            "git {args:?} in {} failed: {}",
            repo.display(),
            String::from_utf8_lossy(&out.stderr)
        );
    }

    fn write(p: &Path, text: &str) {
        std::fs::create_dir_all(p.parent().unwrap()).unwrap();
        std::fs::write(p, text).unwrap();
    }

    /// **The red proof.** A consumer workspace with one repo-escaping path dep,
    /// pointed at a sibling checkout that is deliberately one commit behind its
    /// own `origin/HEAD` — the exact shape of the three phantom findings of
    /// 2026-08-22, where a stale primary checkout was read as a code defect.
    ///
    /// The test asserts the guard reports **red first** and only then that the
    /// same guard goes green once the sibling is fast-forwarded. A check proven
    /// only in its green state cannot be told apart from a check that returns
    /// the empty vector unconditionally — which is what nine guards on this box
    /// were doing (LAW 2).
    #[test]
    fn a_sibling_parked_off_origin_head_is_named_before_the_build_can_lie_about_it() {
        let root = scratch("siblings");
        std::fs::remove_dir_all(&root).ok();
        std::fs::create_dir_all(&root).unwrap();

        // The sibling's remote: a normal repo we clone from, so `origin/HEAD` is
        // set the way every real checkout on this box has it set.
        let upstream = root.join("upstream-sib");
        std::fs::create_dir_all(&upstream).unwrap();
        gitx(&upstream, &["init", "-q", "-b", "main"]);
        write(&upstream.join("Cargo.toml"), "[package]\nname = \"sib\"\nversion = \"0.1.0\"\n");
        write(&upstream.join("src/lib.rs"), "pub fn v() -> u32 { 1 }\n");
        gitx(&upstream, &["add", "Cargo.toml", "src/lib.rs"]);
        gitx(&upstream, &["commit", "-qm", "sib v1"]);

        // The sibling checkout the consumer's path dep will land in.
        let sib = root.join("sib");
        std::fs::remove_dir_all(&sib).ok();
        gitx(&root, &["clone", "-q", upstream.to_str().unwrap(), "sib"]);

        // Upstream moves on. The sibling does not — this is the whole disease.
        write(&upstream.join("src/lib.rs"), "pub fn v() -> u32 { 2 }\npub fn added() {}\n");
        gitx(&upstream, &["commit", "-qam", "sib v2"]);
        gitx(&sib, &["fetch", "-q", "origin"]);

        // The consumer: one escaping dep (`../sib`) and one in-repo dep, so the
        // filter has something to be wrong about in both directions.
        let consumer = root.join("consumer");
        write(
            &consumer.join("Cargo.toml"),
            "[workspace]\nmembers = [\"crates/app\"]\n\n[package]\nname = \"consumer\"\n\n\
             [dependencies]\nsib = { path = \"../sib\" }\napp = { path = \"crates/app\" }\n",
        );
        write(&consumer.join("crates/app/Cargo.toml"), "[package]\nname = \"app\"\n");

        let escaping = escaping_path_deps(&consumer);
        assert_eq!(escaping.len(), 1, "only `../sib` leaves the consumer repo, got {escaping:?}");
        assert_eq!(escaping[0].name, "sib");
        assert_eq!(escaping[0].resolved, normalise(&root.join("sib")));

        // ── RED ──────────────────────────────────────────────────────────────
        let bad = sibling_offenders(&consumer);
        assert_eq!(bad.len(), 1, "the stale sibling must be reported, got {bad:?}");
        match &bad[0].state {
            SiblingState::Drifted { behind, ahead, .. } => {
                assert_eq!((*behind, *ahead), (1, 0), "one commit behind origin/HEAD, none ahead");
            }
            other => panic!("expected Drifted, got {other:?}"),
        }
        assert!(
            bad[0].describe().contains("DRIFTED"),
            "the one-liner must say which way it failed: {}",
            bad[0].describe()
        );
        assert_eq!(bad[0].checkout.as_deref(), Some(normalise(&root.join("sib")).as_path()));

        // ── GREEN, and only now ──────────────────────────────────────────────
        gitx(&sib, &["merge", "-q", "--ff-only", "origin/main"]);
        let good = sibling_offenders(&consumer);
        assert!(good.is_empty(), "a fast-forwarded sibling is clean, got {good:?}");
        assert!(matches!(
            checkout_state(&sib),
            SiblingState::Aligned { dirty: 0, .. }
        ));

        // ── the standard lane shape: DETACHED, and exactly right ─────────────
        // `git worktree add --detach <repo> origin/main` is how nearly every lane
        // on this box checks a sibling out. Grading that red would make the whole
        // guard noise, so the SHA decides and only a detached HEAD that is NOT at
        // origin/HEAD is unknown. Both directions asserted, or "detached is fine"
        // would silently mean "detached is never checked".
        gitx(&sib, &["checkout", "-q", "--detach", "origin/main"]);
        assert!(
            sibling_offenders(&consumer).is_empty(),
            "a worktree detached AT origin/HEAD is the sanctioned lane shape"
        );
        gitx(&sib, &["checkout", "-q", "--detach", "origin/main~1"]);
        let det = sibling_offenders(&consumer);
        assert_eq!(det.len(), 1);
        assert!(matches!(det[0].state, SiblingState::Detached { .. }), "{}", det[0].describe());
        gitx(&sib, &["checkout", "-q", "main"]);

        // ── and dirt on an aligned ref is still not the ref ───────────────────
        write(&sib.join("src/lib.rs"), "pub fn v() -> u32 { 99 }\n");
        let dirty = sibling_offenders(&consumer);
        assert_eq!(dirty.len(), 1, "uncommitted source under an aligned ref is a different build");
        assert!(dirty[0].describe().contains("DIRTY"), "{}", dirty[0].describe());

        // ── and a sibling that is not there at all is the other real failure ──
        std::fs::remove_dir_all(&sib).unwrap();
        let gone = sibling_offenders(&consumer);
        assert_eq!(gone.len(), 1);
        assert_eq!(gone[0].state, SiblingState::Missing, "{}", gone[0].describe());

        std::fs::remove_dir_all(&root).ok();
    }

}