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

nordisk/gunnar

xtask/tests/the_shared_pieces_are_not_copied.rs

//! **Gunnar carries no copy of a piece the estate shares** (A28 M11/M12, A29-14/24, A32-30;
//! 2026-10-26, the day monetize 0.3.0 and nordisk-pairing 0.5.27 reached crates.io).
//!
//! Holger moved onto the shared crates first (P4a; holger's own
//! `xtask/tests/the_shared_pieces_are_not_copied.rs`). Until the publish, Gunnar could not
//! follow: its pump sits in the root workspace, which builds as a lone clone from crates.io.
//! This guard is Gunnar's half, so a fix made in the shared crate is never re-learned here.
//!
//! | piece | shared home | Gunnar's copy, gone |
//! |---|---|---|
//! | the box pump (key, Report/Orders/Ask, the puller, the wire) | monetize `monetize-estate-side::pump` | gunnar-repair `fleet.rs`'s copy, its vendored `proto/monetize/v1/fleet.proto` and `build.rs` |
//! | the supervised background duty (named, visible, a panic said as ALERT, stopped at the box's stop) | Skidbladnir `nordisk-pairing::duty` (0.5.27) | `gunnar_common::duty` |
//! | the front's web half (the certificate fed, kept or from ACME, the DNS check, the status, :80/:443, the callback-only names, the hand-over) | edda `estate-front::web` | gunnar-front `web/{acme,certs,dns,status}.rs` and the copied halves of `web/{mod,serve}.rs` |
//! | the sign-in-again link (the order's checks, the lifetime, the link, the mail's words) | monetize `monetize-estate-side::sign_in` | gunnar-repair `sign_in.rs` |
//! | the order check (`nordisk-order-v1`: canonical form, strict Ed25519, addressee, sequence, window) | monetize `monetize-estate-side::pump::check` | gunnar-repair `order.rs`'s `order_message`, `verify_order`, `accept_order` and `check_order`'s envelope |
//!
//! These read the tree only: no sibling, no network.

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

fn root() -> PathBuf {
    Path::new(env!("CARGO_MANIFEST_DIR"))
        .parent()
        .expect("xtask has a parent")
        .to_path_buf()
}

fn text(rel: &str) -> String {
    std::fs::read_to_string(root().join(rel)).unwrap_or_else(|e| panic!("{rel}: {e}"))
}

/// ★ M12: the pump is monetize-estate-side's; gunnar-repair writes only its executor.
#[test]
fn the_box_pump_is_the_shared_crates() {
    for gone in [
        "crates/gunnar-repair/proto",
        "crates/gunnar-repair/build.rs",
    ] {
        assert!(
            !root().join(gone).exists(),
            "{gone}: the wire is monetize-proto's, not a vendored (drifted) copy"
        );
    }
    let fleet = text("crates/gunnar-repair/src/fleet.rs");
    for gone in [
        "include_proto!",
        "fn fleet_call_message",
        "pub struct BoxKey",
        "pub struct Puller",
        "pub trait Link",
        "fn write_atomic",
        "CALL_DOMAIN",
    ] {
        assert!(
            !fleet.contains(gone),
            "gunnar-repair's fleet.rs still carries `{gone}`: it is monetize-estate-side::pump's"
        );
    }
    assert!(
        fleet.contains("pub use monetize_estate_side::pump::"),
        "gunnar-repair's fleet re-exports the shared pump"
    );
    assert!(
        fleet.contains("impl<E: Estate> PumpBox for GunnarBox<E>"),
        "gunnar's executor is the shared pump's PumpBox"
    );
    let manifest = text("crates/gunnar-repair/Cargo.toml");
    for gone in ["protoc-bin-vendored", "tonic-prost-build"] {
        assert!(
            !manifest.contains(gone),
            "gunnar-repair compiles no proto of its own: {gone}"
        );
    }
    assert!(
        text("crates/gunnar-server/src/repair.rs").contains("fleet::GunnarBox::new("),
        "gunnar-server's pull loop runs the shared puller over GunnarBox"
    );
}

/// ★ M11: the order check is the shared pump's (`pump::check`); gunnar reads only the body.
#[test]
fn the_order_check_is_the_shared_pumps() {
    let order = text("crates/gunnar-repair/src/order.rs");
    for gone in [
        "fn order_message",
        "ORDER_DOMAIN",
        "fn verify_order",
        "fn accept_order",
        "verify_strict",
        "pub struct SignedOrder",
        "fn check_order",
    ] {
        assert!(!order.contains(gone), "gunnar-repair's order.rs still carries `{gone}`: the check is monetize-estate-side::pump::check");
    }
    assert!(
        order.contains("pub fn decode(seq: u64, kind: &str, body: &[u8])"),
        "gunnar reads the checked order's body"
    );
    assert!(
        !text("crates/gunnar-repair/Cargo.toml").contains("verify = ["),
        "no `verify` feature: gunnar verifies no order itself"
    );
    assert!(
        !root()
            .join("crates/gunnar-front/tests/one_order_check.rs")
            .exists(),
        "one check, so no test that holds two together"
    );
    assert!(
        text("crates/gunnar-repair/src/fleet.rs")
            .contains("crate::decode(o.seq, &o.kind, o.body.as_bytes())"),
        "GunnarBox reads the body of the order the pump checked"
    );
}

/// ★ The sign-in-again link a sold main mints and mails is monetize-estate-side::sign_in.
#[test]
fn the_sign_in_link_is_the_shared_crates() {
    assert!(
        !root().join("crates/gunnar-repair/src/sign_in.rs").exists(),
        "gunnar-repair/src/sign_in.rs: the link is monetize-estate-side::sign_in"
    );
    assert!(
        text("crates/gunnar-repair/src/lib.rs").contains("pub use monetize_estate_side::sign_in;"),
        "gunnar-repair re-exports the shared link"
    );
    assert!(
        !root()
            .join("crates/gunnar-front/tests/one_sign_in_link.rs")
            .exists(),
        "one link, so no test that holds two together"
    );
    let server = text("crates/gunnar-server/Cargo.toml");
    assert!(server.contains("fleet-pull = [\"replication\", \"gunnar-repair/fleet\", \"dep:lettre\"]"), "the main mails a resend link only in a build that pulls the order (fleet-pull), so SMTP leaves the community build");
}

/// ★ A32-30: a box's background duty is nordisk-pairing's (0.5.27), ONE registry of duties, so
/// the box's stop stops every one of them.
#[test]
fn the_background_duty_is_nordisk_pairings() {
    assert!(
        !root().join("crates/gunnar-common/src/duty.rs").exists(),
        "gunnar-common/src/duty.rs: the duty is nordisk_pairing::duty"
    );
    for dir in [
        "crates/gunnar-server/src",
        "crates/gunnar-front/src",
        "crates/gunnar-common/src",
    ] {
        for f in rust_files(&root().join(dir)) {
            let t = std::fs::read_to_string(&f).unwrap();
            assert!(
                !t.contains("gunnar_common::duty") && !t.contains("pub mod duty"),
                "{} still names gunnar's own duty",
                f.display()
            );
        }
    }
}

/// The Rust files under `dir`, recursively.
fn rust_files(dir: &Path) -> Vec<PathBuf> {
    let mut out = Vec::new();
    for e in std::fs::read_dir(dir)
        .unwrap_or_else(|e| panic!("{}: {e}", dir.display()))
        .flatten()
    {
        let p = e.path();
        if p.is_dir() {
            out.extend(rust_files(&p));
        } else if p.extension().is_some_and(|x| x == "rs") {
            out.push(p);
        }
    }
    out
}

/// ★ A32-11: gunnar-front's web half is edda's estate-front; Gunnar keeps only its own layers
/// (the ACME switch, the login names, git's paths, the CLI hole, the access log, its TLS groups).
#[test]
fn the_fronts_web_half_is_estate_front() {
    for gone in ["acme.rs", "certs.rs", "dns.rs", "status.rs"] {
        assert!(
            !root()
                .join("crates/gunnar-front/src/web")
                .join(gone)
                .exists(),
            "gunnar-front/src/web/{gone}: it is estate_front::web's"
        );
    }
    let m = text("crates/gunnar-front/src/web/mod.rs");
    assert!(
        m.split_whitespace()
            .collect::<String>()
            .contains("pubuseestate_front::web::{acme,certs,dns,"),
        "gunnar-front re-exports the shared web half"
    );
    for gone in [
        "fn renew_at",
        "fn look_needs",
        "struct SaidOnce",
        "tokio::spawn(serve::serve_https",
    ] {
        assert!(
            !m.contains(gone),
            "gunnar-front's web/mod.rs still carries `{gone}`: it is estate-front's"
        );
    }
    let serve = text("crates/gunnar-front/src/web/serve.rs");
    for gone in [
        "pub async fn serve_https",
        "pub fn tls_config",
        "pub struct App",
        "async fn serve_conn",
    ] {
        assert!(
            !serve.contains(gone),
            "gunnar-front's web/serve.rs still carries `{gone}`: it is estate-front's"
        );
    }
    assert!(
        text("crates/gunnar-front/Cargo.toml").contains("acme = [\"estate-front/acme\"]"),
        "gunnar-front's `acme` is estate-front's"
    );
}

/// ★ A32-30 (recharge): the front's kept bundle and its re-admission are nordisk-pairing's
/// (`kept`, the same Holger's front uses): gunnar-front keeps only WHEN to recharge and its
/// shop's calls, never a second Kept, plan move, path list or readmit.
#[test]
fn the_fronts_kept_bundle_is_nordisk_pairings() {
    let r = text("crates/gunnar-front/src/recharge.rs");
    for gone in [
        "pub struct Kept",
        "pub fn moved(",
        "pub fn paths_for(",
        "pub fn readmit(",
        "impl Kept",
    ] {
        assert!(
            !r.contains(gone),
            "gunnar-front's recharge.rs still carries `{gone}`: it is nordisk_pairing::kept's"
        );
    }
    assert!(
        r.contains("pub use nordisk_pairing::kept::{"),
        "gunnar-front re-exports the shared kept bundle"
    );
}

/// ★ RA3-8: **the exclusive gate's fix is jera's** (jera 0.2.1: a look at the gate never takes
/// it). Gunnar worked around jera 0.2.0's `try_acquire` probe with its own 20 ms re-ask
/// (`DEFER_POLL`), so each deferring lane woke 50 times a second while monetize's kept jera's
/// 2 s. Gunnar requires 0.2.1 and takes jera's own re-ask; `jobs_started_at_the_same_instant_all_look_at_once`
/// (gunnar-common) holds that the lanes still start together on it.
#[test]
fn the_gate_fix_is_jeras_and_gunnar_keeps_no_re_ask_of_its_own() {
    let jera = text("Cargo.toml")
        .lines()
        .find(|l| l.trim_start().starts_with("jera ="))
        .expect("the root names jera")
        .to_string();
    assert!(
        jera.contains("version = \"0.2.2\""),
        "the root must require jera 0.2.2: the release with the gate fix (0.2.1) and `jobs::duty`, the one duty wrapper: {jera}"
    );
    assert!(
        text("crates/gunnar-common/src/jobs.rs").contains("jera::jobs::duty::start("),
        "gunnar-common's jobs run on jera::jobs::duty, not on a copy of its loop (lane hol-312fix)"
    );
    let short_poll = concat!("new_with", "_poll(");
    let own_poll = concat!("DEFER", "_POLL");
    for rel in [
        "crates/gunnar-common/src/jobs.rs",
        "crates/gunnar-server/src/job_queue.rs",
    ] {
        let src = text(rel);
        assert!(
            !src.contains(short_poll),
            "{rel} still builds its ChainQueue with its own re-ask: jera's default is the one"
        );
        assert!(
            !src.contains(own_poll),
            "{rel} still carries Gunnar's 20 ms copy of jera's gate fix"
        );
    }
}

/// ★ RA4-7: the spawn guard (A32-14) is nornir-xtask-support's `spawn_guard`, the one call-shape
/// matcher gunnar, monetize, holger and edda run. xtask has no dependency that could unify into
/// the appliance, so the guard runs in its own detached workspace, `xtask/guards`, which
/// `cargo xtask ci` tests by manifest path.
#[test]
fn the_spawn_guard_is_nornir_xtask_supports() {
    assert!(
        !root().join("xtask/tests/spawn_reasons.rs").exists(),
        "xtask/tests/spawn_reasons.rs: the hand copy of the matcher is gone"
    );
    let guard = text("xtask/guards/tests/spawn_reasons.rs");
    assert!(
        guard.contains("nornir_xtask_support::spawn_guard"),
        "the guard calls the shared matcher"
    );
    for gone in [
        "fn unreasoned(",
        "fn production(",
        "fn awaited_at(",
        "const SPAWNS",
    ] {
        assert!(
            !guard.contains(gone),
            "the guard still carries its own `{gone}`"
        );
    }
    assert!(
        text("xtask/guards/Cargo.toml").contains("[workspace]"),
        "xtask/guards is detached: nornir-xtask-support never unifies into the root"
    );
    assert!(
        text("xtask/src/main.rs").contains("\"xtask/guards/Cargo.toml\""),
        "`cargo xtask ci` runs the detached guard by manifest path (DETACHED)"
    );
}