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

mikronova/modgunn

tests/dark_test_ratchet.rs

//! **Spärrhake (ratchet) over the dark-test census — the count can only fall.**
//!
//! A `tests/*.rs` file whose crate-level inner attribute `#![cfg(feature = "X")]`
//! is NOT satisfied by modgunn's `default` feature closure compiles to an EMPTY
//! test binary: `cargo test` prints `running 0 tests ... ok` and the file is
//! green-by-vacuum, forever. On a SECURITY platform that is the worst possible
//! place for a silent hole — untested verdict / ingest / provenance code that
//! reads exactly like a passing file.
//!
//! Measured on `oden` 2026-08-27 with `cargo test -p modgunn` (default closure
//! `scan` + `provenance-verify`): **9 of 12 `tests/*.rs` run ZERO tests** — 75 %,
//! the worst dark ratio in the constellation. The nine are pinned in
//! [`PINNED_DARK`] below. This guard RE-DERIVES the dark set from the real files
//! on every run and fails RED if a TENTH dark file appears (the ratchet), or if a
//! pinned file starts running (so the pin is tightened, never left to rot).
//!
//! ## Why the nine stay dark rather than being forced into `default`
//!
//! modgunn's `default` is deliberately LEAN — `scan` + `provenance-verify` only —
//! because holger's policy gate and static-holger LINK modgunn and must stay free
//! of the arrow / iceberg / redb tree. That leanness is correct and is NOT changed
//! here. "DARK" in this census means cfg-dark under a plain `cargo test` — it does
//! NOT mean "never run". Every one of the nine IS exercised in the forge; the
//! census stays at nine because the leanness that gates them is deliberate, not
//! because any is silenced. Silencing (a gated file no arm covers) is a separate
//! measure held at ZERO by `tests/no_silenced_tests.rs` — this file is the
//! orthogonal cfg-darkness ratchet, and the two are intentionally not merged (a
//! ratchet that only counted uncovered files would read zero whenever that guard
//! is green, and so guard nothing). The nine are exercised as follows:
//!   * FIVE run in `.nornir/brokkr.toml`'s `gatekeeper-tests` step — the ⭐
//!     variant's exact feature set (`scan,scip,warehouse,rustsec,provenance-verify`):
//!     `cli_behavior`, `cli_provenance`, `cli_scorecard`, `cli_warehouse`, `cli_zone`.
//!   * FOUR need `framework` / `manifests` / `testmatrix`, which NO ship-variant
//!     enables. Running them once meant smuggling their features into a fake
//!     ship-variant — a claim about what modgunn SHIPS, on the wrong axis. They now
//!     run via the forge's TEST-MATRIX path: named arms in
//!     `.nornir/testmatrix-arms.json` that `dwarves testmatrix modgunn` /
//!     `nornir_testmatrix::run_arm` execute and record PASS/FAIL for — a test
//!     target, never a delivered product. `cli_framework` (framework arm),
//!     `cli_ingest` + `manifests_ingest` (manifests arm), `testmatrix_wiring`
//!     (testmatrix arm) — proven RUN 2026-08-27, 4/4/1/1 tests, up from 0.
//!
//! Whichever the reason, this file makes the darkness **loud instead of silent**:
//! the nine `#[ignore]`d stubs below carry each dark file's name, show up as
//! `ignored` in a plain `cargo test` (never a fake `0 passed ... ok`), and PANIC
//! under `cargo test -- --ignored` with the exact command that runs the real file.
//!
//! Deliberately NOT feature-gated: a ratchet that compiled out under the lean
//! default would be the tenth silenced test, policing nothing.

use std::collections::BTreeSet;
use std::path::{Path, PathBuf};

/// The feature NAMES enabled by modgunn's `default` closure. `default =
/// ["scan","provenance-verify"]`, and `provenance-verify` pulls `scan`; no other
/// feature name is switched on. A `tests/*.rs` file is DARK iff its crate-level
/// `#![cfg(...)]` requires a feature outside this set.
const DEFAULT_ON: &[&str] = &["scan", "provenance-verify"];

/// Today's dark census (measured 2026-08-27, `cargo test -p modgunn`). The ratchet
/// pins this EXACT set. Adding a file here is only ever allowed to REMOVE names
/// (a dark file made to run) — a name appearing that is not here means a new dark
/// file slipped in, and the guard goes red.
const PINNED_DARK: &[&str] = &[
    "cli_behavior.rs",
    "cli_framework.rs",
    "cli_ingest.rs",
    "cli_provenance.rs",
    "cli_scorecard.rs",
    "cli_warehouse.rs",
    "cli_zone.rs",
    "manifests_ingest.rs",
    "testmatrix_wiring.rs",
];

/// Every `tests/*.rs` known to exist on the pinned checkout — the anchor the
/// non-vacuity check asserts the directory walk actually found (LAW 2: a walk that
/// silently reads nothing reports "0 dark" and proves nothing). Includes the three
/// LIVE files so the classifier is exercised in BOTH directions.
const KNOWN_FILES: &[&str] = &[
    // the 9 dark
    "cli_behavior.rs",
    "cli_framework.rs",
    "cli_ingest.rs",
    "cli_provenance.rs",
    "cli_scorecard.rs",
    "cli_warehouse.rs",
    "cli_zone.rs",
    "manifests_ingest.rs",
    "testmatrix_wiring.rs",
    // the 3 live
    "build_variants.rs",
    "engine_ab_equivalence.rs",
    "no_silenced_tests.rs",
];

fn tests_dir() -> PathBuf {
    Path::new(env!("CARGO_MANIFEST_DIR")).join("tests")
}

/// Read every `.rs` directly under `tests/`, excluding this ratchet file itself.
fn integration_test_files() -> BTreeSet<String> {
    let mut out = BTreeSet::new();
    let dir = tests_dir();
    for entry in std::fs::read_dir(&dir)
        .unwrap_or_else(|e| panic!("cannot read {} — RED, not a skip: {e}", dir.display()))
    {
        let entry = entry.expect("dir entry");
        if !entry.file_type().map(|t| t.is_file()).unwrap_or(false) {
            continue;
        }
        let name = entry.file_name().to_string_lossy().into_owned();
        if name.ends_with(".rs") && name != "dark_test_ratchet.rs" {
            out.insert(name);
        }
    }
    out
}

/// The feature names required by a file's crate-level `#![cfg(...)]`, or `None`
/// when the file carries no crate-level gate (i.e. it always compiles = LIVE).
///
/// Only the shapes this repo uses are understood: `#![cfg(feature = "x")]` and
/// `#![cfg(all(feature = "a", feature = "b"))]` (AND semantics). Any `not(` / `any(`
/// operator PANICS rather than being silently misread — the guard must never
/// classify by guessing.
fn crate_cfg_features(file: &str) -> Option<Vec<String>> {
    let path = tests_dir().join(file);
    let text = std::fs::read_to_string(&path)
        .unwrap_or_else(|e| panic!("cannot read {} — RED: {e}", path.display()));

    // Find the crate-level inner attribute. It is `#![cfg(...)]` on its own line in
    // every file here; scan line-wise so a `#[cfg(...)]` on an item is not mistaken
    // for it.
    let line = text
        .lines()
        .map(str::trim)
        .find(|l| l.starts_with("#![cfg("))?;

    if line.contains("not(") || line.contains("any(") {
        panic!(
            "{file}: crate-level cfg `{line}` uses not()/any(), which this ratchet does \
             not resolve. Teach `crate_cfg_features` the shape rather than letting the \
             dark census guess."
        );
    }

    // Extract every `feature = "NAME"`.
    let mut feats = Vec::new();
    let mut rest = line;
    while let Some(i) = rest.find("feature") {
        rest = &rest[i + "feature".len()..];
        // skip to the opening quote of the value
        if let Some(q0) = rest.find('"') {
            let after = &rest[q0 + 1..];
            if let Some(q1) = after.find('"') {
                feats.push(after[..q1].to_string());
                rest = &after[q1 + 1..];
                continue;
            }
        }
        break;
    }
    if feats.is_empty() {
        panic!("{file}: crate-level cfg `{line}` names no `feature = \"...\"` — unrecognized shape");
    }
    Some(feats)
}

/// A file is DARK when it has a crate-level gate requiring a feature outside the
/// default closure.
fn is_dark(file: &str) -> bool {
    match crate_cfg_features(file) {
        None => false,
        Some(feats) => feats.iter().any(|f| !DEFAULT_ON.contains(&f.as_str())),
    }
}

#[test]
fn dark_test_count_never_rises_over_the_pinned_census() {
    let files = integration_test_files();

    // ── Non-vacuity (LAW 2): the walk actually found the real files. ───────────
    assert!(
        !files.is_empty(),
        "the ratchet scanned ZERO test files under {} — it proved nothing",
        tests_dir().display()
    );
    for known in KNOWN_FILES {
        assert!(
            files.contains(*known),
            "known test file `{known}` is missing from {} — the census is reading the \
             wrong tree, or the file was renamed (re-pin KNOWN_FILES/PINNED_DARK).",
            tests_dir().display()
        );
    }

    // ── Classifier is exercised in BOTH directions, so it cannot be a constant. ─
    assert!(
        is_dark("cli_warehouse.rs"),
        "classifier says cli_warehouse.rs (`#![cfg(feature = \"warehouse\")]`, warehouse \
         off by default) is NOT dark — the cfg reader is broken"
    );
    assert!(
        !is_dark("engine_ab_equivalence.rs"),
        "classifier says engine_ab_equivalence.rs (`#![cfg(feature = \"scan\")]`, scan ON \
         by default) IS dark — the default-closure resolution is broken"
    );
    assert!(
        !is_dark("no_silenced_tests.rs"),
        "classifier says no_silenced_tests.rs (no crate-level cfg) IS dark — broken"
    );

    // ── The ratchet itself. ────────────────────────────────────────────────────
    let dark: BTreeSet<String> = files.iter().filter(|f| is_dark(f)).cloned().collect();
    let pinned: BTreeSet<String> = PINNED_DARK.iter().map(|s| s.to_string()).collect();

    let newly_dark: Vec<&String> = dark.difference(&pinned).collect();
    let now_live: Vec<&String> = pinned.difference(&dark).collect();

    assert!(
        newly_dark.is_empty(),
        "RATCHET RED — {} NEW dark test file(s) run ZERO tests under `cargo test` \
         (default = {DEFAULT_ON:?}):\n{}\nEach is green-by-vacuum. Either wire it into a \
         forge test arm that exercises its feature, or if it genuinely needs a feature \
         the lean default can't carry, give it a loud `#[ignore]` stub in \
         dark_test_ratchet.rs. Do NOT raise PINNED_DARK to hide it.",
        newly_dark.len(),
        newly_dark
            .iter()
            .map(|f| format!("  · {f}"))
            .collect::<Vec<_>>()
            .join("\n")
    );

    assert!(
        now_live.is_empty(),
        "RATCHET — {} pinned dark file(s) now RUN:\n{}\nGood — the count fell. Remove them \
         from PINNED_DARK (and the matching `#[ignore]` stub) so the pin tracks reality.",
        now_live.len(),
        now_live
            .iter()
            .map(|f| format!("  · {f}"))
            .collect::<Vec<_>>()
            .join("\n")
    );

    // Belt and suspenders: the exact pinned count.
    assert_eq!(
        dark.len(),
        PINNED_DARK.len(),
        "dark count {} != pinned {} — see the messages above",
        dark.len(),
        PINNED_DARK.len()
    );
}

// ─────────────────────────────────────────────────────────────────────────────
// LOUD stubs — one per dark file. In a plain `cargo test` these appear as
// `ignored` (never a silent `0 passed ... ok`); under `cargo test -- --ignored`
// each PANICS with the exact command that runs the real file. This is the
// "always-compiled `#[ignore]` stub bearing the real file's name" the darkness
// deserves. `run --ignored` here MUST fail — it is a marker, not a passing test.
// ─────────────────────────────────────────────────────────────────────────────

macro_rules! dark_marker {
    ($fn:ident, $file:literal, $needs:literal, $run:literal) => {
        #[test]
        #[ignore = concat!($file, " is DARK by default — needs features: ", $needs)]
        fn $fn() {
            panic!(
                "{} did NOT run under the default feature set (needs: {}). \
                 This stub makes the darkness loud. Run the real file with:\n    {}",
                $file, $needs, $run
            );
        }
    };
}

// The five the forge's gatekeeper-tests step already runs (⭐ variant features).
dark_marker!(
    dark_cli_behavior_rs,
    "tests/cli_behavior.rs",
    "warehouse",
    "cargo test -p modgunn --no-default-features --features scan,scip,warehouse,rustsec,provenance-verify --release"
);
dark_marker!(
    dark_cli_provenance_rs,
    "tests/cli_provenance.rs",
    "provenance-verify + warehouse",
    "cargo test -p modgunn --no-default-features --features scan,scip,warehouse,rustsec,provenance-verify --release"
);
dark_marker!(
    dark_cli_scorecard_rs,
    "tests/cli_scorecard.rs",
    "warehouse",
    "cargo test -p modgunn --no-default-features --features scan,scip,warehouse,rustsec,provenance-verify --release"
);
dark_marker!(
    dark_cli_warehouse_rs,
    "tests/cli_warehouse.rs",
    "warehouse (+ test-support for the seeding path)",
    "cargo test -p modgunn --no-default-features --features scan,scip,warehouse,rustsec,provenance-verify --release"
);
dark_marker!(
    dark_cli_zone_rs,
    "tests/cli_zone.rs",
    "warehouse",
    "cargo test -p modgunn --no-default-features --features scan,scip,warehouse,rustsec,provenance-verify --release"
);

// The four the forge's TEST-MATRIX path runs — the named framework / manifests /
// testmatrix arms in `.nornir/testmatrix-arms.json` (no ship-variant enables them).
dark_marker!(
    dark_cli_framework_rs,
    "tests/cli_framework.rs",
    "warehouse + framework",
    "cargo test -p modgunn --no-default-features --features scan,warehouse,framework --test cli_framework"
);
dark_marker!(
    dark_cli_ingest_rs,
    "tests/cli_ingest.rs",
    "manifests + warehouse",
    "cargo test -p modgunn --no-default-features --features scan,warehouse,manifests --test cli_ingest"
);
dark_marker!(
    dark_manifests_ingest_rs,
    "tests/manifests_ingest.rs",
    "manifests",
    "cargo test -p modgunn --no-default-features --features scan,manifests --test manifests_ingest"
);
dark_marker!(
    dark_testmatrix_wiring_rs,
    "tests/testmatrix_wiring.rs",
    "testmatrix",
    "cargo test -p modgunn --no-default-features --features scan,testmatrix --test testmatrix_wiring"
);