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

nordisk/holger

holger-estate-front/tests/no_gunnar_in_the_graph.rs

//! **GUARD: holger has ZERO dependency on the gunnar repository** (owner
//! 2026-09-27: "why has HOLGER a dependency to gunnar now???"). holger follows
//! gunnar's PATTERN; it never links gunnar's code, never reads a gunnar
//! checkout.
//!
//! Read, not run (pure Rust, no `cargo metadata` subprocess): every lock holger
//! resolves — the root workspace's and this front's own — must name no package
//! `gunnar*`, and no manifest anywhere in the holger tree may point a `path`
//! dependency into a `gunnar` checkout (`../gunnar`, `…/gunnar-ui`, …). A
//! failure names the lock or manifest and the offending entry.

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

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

/// Does `path` step into a checkout of the gunnar repository (a component that
/// IS `gunnar` or starts `gunnar-`)?
fn into_gunnar(path: &str) -> bool {
    Path::new(path).components().any(|c| {
        c.as_os_str()
            .to_str()
            .is_some_and(|s| s == "gunnar" || s.starts_with("gunnar-") || s.starts_with("gunnar_"))
    })
}

fn manifests(dir: &Path, out: &mut Vec<PathBuf>) {
    let Ok(rd) = std::fs::read_dir(dir) else {
        return;
    };
    for e in rd.flatten() {
        let p = e.path();
        let name = e.file_name().to_string_lossy().to_string();
        if p.is_dir() {
            if name != "target" && !name.starts_with('.') {
                manifests(&p, out);
            }
        } else if name == "Cargo.toml" {
            out.push(p);
        }
    }
}

/// Every `path = "…"` of every dependency table of a manifest.
fn dep_paths(doc: &toml::Value) -> Vec<String> {
    let mut tables: Vec<&toml::Value> = Vec::new();
    for key in ["dependencies", "dev-dependencies", "build-dependencies"] {
        if let Some(t) = doc.get(key) {
            tables.push(t);
        }
    }
    if let Some(t) = doc.get("workspace").and_then(|w| w.get("dependencies")) {
        tables.push(t);
    }
    if let Some(t) = doc.get("patch").and_then(toml::Value::as_table) {
        tables.extend(t.values());
    }
    if let Some(t) = doc.get("target").and_then(toml::Value::as_table) {
        for v in t.values() {
            for key in ["dependencies", "dev-dependencies", "build-dependencies"] {
                if let Some(d) = v.get(key) {
                    tables.push(d);
                }
            }
        }
    }
    tables
        .iter()
        .filter_map(|t| t.as_table())
        .flat_map(|t| t.values())
        .filter_map(|d| d.get("path").and_then(toml::Value::as_str))
        .map(str::to_string)
        .collect()
}

#[test]
fn no_lock_holger_resolves_names_a_gunnar_package() {
    let root = holger_root();
    let mut offending = Vec::new();
    for lock in [
        root.join("Cargo.lock"),
        root.join("holger-estate-front/Cargo.lock"),
    ] {
        let text =
            std::fs::read_to_string(&lock).unwrap_or_else(|e| panic!("{}: {e}", lock.display()));
        let doc: toml::Table =
            toml::from_str(&text).unwrap_or_else(|e| panic!("{}: {e}", lock.display()));
        for p in doc
            .get("package")
            .and_then(toml::Value::as_array)
            .into_iter()
            .flatten()
        {
            let name = p
                .get("name")
                .and_then(toml::Value::as_str)
                .unwrap_or_default();
            if name.starts_with("gunnar") {
                offending.push(format!("{}: package `{name}`", lock.display()));
            }
        }
    }
    assert!(
        offending.is_empty(),
        "holger resolves gunnar's crates: {offending:#?}"
    );
}

#[test]
fn no_manifest_in_holger_points_into_a_gunnar_checkout() {
    let root = holger_root();
    let mut all = Vec::new();
    manifests(&root, &mut all);
    assert!(all.len() > 20, "the walk found the tree: {}", all.len());
    let mut offending = Vec::new();
    for m in &all {
        let text = std::fs::read_to_string(m).unwrap();
        let Ok(doc) = toml::from_str::<toml::Table>(&text).map(toml::Value::Table) else {
            continue;
        };
        for p in dep_paths(&doc) {
            if into_gunnar(&p) {
                offending.push(format!("{}: path = {p:?}", m.display()));
            }
        }
    }
    assert!(
        offending.is_empty(),
        "a holger manifest points into a gunnar checkout: {offending:#?}"
    );
}

#[test]
fn the_guard_sees_what_it_guards() {
    assert!(into_gunnar("../../gunnar/crates/gunnar-front"));
    assert!(into_gunnar("../gunnar-ui/crates/gunnar-ui-server"));
    assert!(!into_gunnar(
        "../../Skidbladnir/crates/installer/nordisk-pairing"
    ));
    assert!(!into_gunnar("../../holger-ui/crates/holger-ui-server"));
    let doc = toml::Value::Table(toml::from_str("[dependencies]\na = { path = \"../gunnar/x\" }\n[target.'cfg(unix)'.dev-dependencies]\nb = { path = \"../y\" }\n").unwrap());
    assert_eq!(
        dep_paths(&doc),
        vec!["../gunnar/x".to_string(), "../y".to_string()]
    );
}

// ── The PAYLOAD: what `holger-mvp-metered` actually links ─────────────────────
//
// Measured 2026-09-28 on the shipped payload (holger-mvp-metered, 63.4 MB,
// sha256 15aac30e…c449c): 9 byte runs spell "gunnar", and NONE of them is
// gunnar's code. Two classes are legitimate and are allowed BY NAME below:
//
//  (a) data that enumerates products — `nordisk_pairing::seed::Kind
//      { Front, Gunnar, Holger }` (Skidbladnir, seed.rs:66-72): its Debug
//      names ("FrontGunnar…") and serde names ("front","gunnar","holger");
//  (b) the git package format's frozen wire names in znippy-common
//      (index.rs:328-357): `__gunnar_graph__`, `__gunnar_reach__`,
//      `__gunnar_secrets__` as rodata, and `__gunnar_oid__` / `__gunnar_refs__`
//      as 8-byte immediates of the inlined `is_reserved_module` compare
//      (`48 b8 "__gunnar"` then `H3 …`/`H1 …` — hence "__gunnarH3"/"H1").
//
// Category (c) — gunnar's CODE linked in — is what these guards refuse: a
// package in the payload's closure that is gunnar's (by name, or one of
// gunnar's storage crates that carry a neutral name), and any "gunnar" byte run
// in a built payload that is not one of the classified ones above.

/// The root of the shipped payload (`--bin holger-mvp-metered`).
const PAYLOAD_ROOT: &str = "holger";

/// gunnar's own code published under names that do not start with `gunnar`.
/// Linking either is linking gunnar's git server storage.
const GUNNAR_CODE_UNDER_NEUTRAL_NAMES: &[&str] = &["storage-git-gix", "znippy-plugin-git"];

fn is_gunnar_code(package: &str) -> bool {
    package.starts_with("gunnar") || GUNNAR_CODE_UNDER_NEUTRAL_NAMES.contains(&package)
}

/// Transitive closure of `root` over a Cargo.lock's `dependencies` edges (by
/// name — two versions of one name fold together, which can only widen it).
fn lock_closure(lock: &toml::Table, root: &str) -> std::collections::BTreeSet<String> {
    let mut edges: std::collections::BTreeMap<String, Vec<String>> = Default::default();
    for p in lock
        .get("package")
        .and_then(toml::Value::as_array)
        .into_iter()
        .flatten()
    {
        let name = p
            .get("name")
            .and_then(toml::Value::as_str)
            .unwrap_or_default()
            .to_string();
        let deps = p
            .get("dependencies")
            .and_then(toml::Value::as_array)
            .into_iter()
            .flatten();
        let deps = deps
            .filter_map(toml::Value::as_str)
            .filter_map(|d| d.split_whitespace().next())
            .map(str::to_string);
        edges.entry(name).or_default().extend(deps);
    }
    let mut seen = std::collections::BTreeSet::new();
    let mut todo = vec![root.to_string()];
    while let Some(n) = todo.pop() {
        if seen.insert(n.clone()) {
            todo.extend(edges.get(&n).into_iter().flatten().cloned());
        }
    }
    seen
}

#[test]
fn the_payload_closure_links_no_gunnar_code() {
    let lock_path = holger_root().join("Cargo.lock");
    let lock: toml::Table = toml::from_str(&std::fs::read_to_string(&lock_path).unwrap()).unwrap();
    let closure = lock_closure(&lock, PAYLOAD_ROOT);
    // The walk reached the real graph (measured: 666 crates for the metered
    // feature set via `cargo tree`; the lock closure is a superset of that).
    assert!(
        closure.len() > 300,
        "the closure of {PAYLOAD_ROOT} is only {} crates — wrong root?",
        closure.len()
    );
    for must in ["znippy-common", "nordisk-pairing"] {
        assert!(
            closure.contains(must),
            "{must} is expected in the payload closure"
        );
    }
    let offending: Vec<_> = closure.iter().filter(|p| is_gunnar_code(p)).collect();
    assert!(
        offending.is_empty(),
        "{PAYLOAD_ROOT} links gunnar's code: {offending:?}"
    );
}

/// Every "gunnar" (any case) in `bytes`, with the reason it is allowed, or
/// `Err(context)` for one that is not classified.
fn classify_gunnar_runs(bytes: &[u8]) -> Vec<Result<&'static str, String>> {
    const WIRE: &[&[u8]] = &[b"_oid__", b"_graph__", b"_reach__", b"_refs__", b"_secrets"];
    let mut out = Vec::new();
    let mut i = 0;
    while i + 6 <= bytes.len() {
        if !bytes[i..i + 6].eq_ignore_ascii_case(b"gunnar") {
            i += 1;
            continue;
        }
        let before = &bytes[i.saturating_sub(5)..i];
        let after = &bytes[i + 6..(i + 6 + 8).min(bytes.len())];
        let verdict = if before.ends_with(b"__")
            && (WIRE.iter().any(|w| after.starts_with(w))
                || after.first().is_some_and(|b| *b != b'_'))
        {
            // `__gunnar_<section>__`, or the 8-byte immediate `__gunnar` of the
            // inlined compare (the next byte is an opcode, never `_`).
            Ok("(b) znippy-common git-format wire name")
        } else if before.eq_ignore_ascii_case(b"front")
            || after.len() >= 6 && after[..6].eq_ignore_ascii_case(b"holger")
        {
            Ok("(a) nordisk_pairing::seed::Kind variant name")
        } else {
            let lo = i.saturating_sub(40);
            let hi = (i + 46).min(bytes.len());
            Err(String::from_utf8_lossy(&bytes[lo..hi])
                .replace(|c: char| !c.is_ascii_graphic(), "."))
        };
        out.push(verdict);
        i += 6;
    }
    out
}

#[test]
fn the_classifier_knows_every_measured_shape_and_refuses_a_new_one() {
    let measured: &[&[u8]] = &[
        b"BodyWriteAborted__gunnar_secretslastModifiedTime",
        b"\0__gunnar_reach____\0",
        b"_nest_tail_param__gunnar_graph__\0",
        b"installer.FrontGunnarParseIntError",
        b"TunnelKindwireguardtailscalemullvadfrontgunnarholgerFront",
        b"\x48\xb8__gunnarH3\x07\x48\xb9ar_oid__",
        b"\x48\xba__gunnarH1\xd1\x48\x8b",
    ];
    for m in measured {
        let v = classify_gunnar_runs(m);
        assert_eq!(v.len(), 1, "{:?}", String::from_utf8_lossy(m));
        assert!(v[0].is_ok(), "{v:?}");
    }
    for bad in [
        &b"gunnar_server::serve"[..],
        b"crates/gunnar-pack/src/lib.rs",
        b"GunnarForge",
    ] {
        assert!(
            classify_gunnar_runs(bad).iter().any(Result::is_err),
            "{:?} must be refused",
            String::from_utf8_lossy(bad)
        );
    }
}

/// Scan a BUILT payload. The binary is not built by this test (a 5-minute
/// musl build is the Build Thing's job); point `HOLGER_PAYLOAD_BIN` at it, or
/// leave it where the Build Thing puts it. With neither present the test says
/// so on stderr and verifies nothing.
#[test]
fn a_built_payload_carries_no_unclassified_gunnar_bytes() {
    let default = holger_root().join("target/x86_64-unknown-linux-musl/release/holger-mvp-metered");
    let bin = std::env::var_os("HOLGER_PAYLOAD_BIN")
        .map(PathBuf::from)
        .unwrap_or(default);
    let Ok(bytes) = std::fs::read(&bin) else {
        eprintln!(
            "NOT VERIFIED: no payload at {} (set HOLGER_PAYLOAD_BIN)",
            bin.display()
        );
        return;
    };
    let verdicts = classify_gunnar_runs(&bytes);
    let unclassified: Vec<_> = verdicts.iter().filter_map(|v| v.as_ref().err()).collect();
    eprintln!(
        "{}: {} gunnar run(s), {} unclassified",
        bin.display(),
        verdicts.len(),
        unclassified.len()
    );
    assert!(
        unclassified.is_empty(),
        "{}: gunnar bytes that are neither (a) nor (b): {unclassified:#?}",
        bin.display()
    );
}