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

nordisk/holger

xtask/src/suite_check.rs

//! **`cargo xtask suite-check`: the Holger MVP suite, compiled and tested on every push**
//! (lane G2, 2026-10-23; A18 §4 #1, #2, #3 and #9).
//!
//! Before this verb, the MVP rows were compiled only by the manual gate, the 42
//! `paired.rs` unit tests ran nowhere, holger-estate-front's tests ran nowhere (it is
//! its own workspace, so `--workspace` does not reach it), and the `sign`-gated
//! evidence tests were never turned on. This verb runs them all, one step after the
//! other, and is red if any step is red.
//!
//! The plan is READ OFF THE DECLARATION, never restated:
//!
//! * `row-check:<row>`: every cargo row of the MVP delivery
//!   (`holger_build_space::build_variant_set`) is compiled with `cargo check` and its
//!   OWN argv (package, features, `--no-default-features`, target); a row with its own
//!   `manifest_dir` is checked by its manifest path;
//! * `row-test:<row>`: every MVP row of the `holger` server binary on the host target
//!   runs its unit tests under its own features (`--bins`; the MVP rows carry `paired`,
//!   so this is where `paired.rs`'s tests run);
//! * `build:<feature>`: the `holger` binary with `paired`, `appliance` and
//!   `secure_update` each on its own, the three builds A18 named;
//! * `front:mount`: server-lib's public-page mount under `--features front` (A28 M14: no default build has it);
//! * `front:default`, `front:metered`: holger-estate-front's whole suite, both ways;
//! * `front:wg-hub`: the front's `open_hub` on a REAL TUN (lane HOLGER-WG, A18 §4 #6) —
//!   `wg_only::tests::open_hub_opens_the_overlay_interface_on_a_real_tun`, which skips by
//!   name where `/dev/net/tun` cannot be opened, and is REQUIRED (`HOLGER_WG_TUN_REQUIRED=1`
//!   in its environment) where this runner can open the node: a privileged container, the
//!   KVM host. The step is the whole suite's test run again by its name, so it can be run
//!   alone on such a runner (`--only front:wg-hub`);
//! * `trust:<name>`: the trust-depth tests of lane HOLGER-G3 ([`TRUST_STEPS`]): the
//!   secrets scanner and its gate;
//! * `downstream:<name>`: the H3 downstream ([`DOWNSTREAM_STEPS`]): its shape guard, its
//!   rules and its one line out, the real `holger-downstream` binary, the WireGuard
//!   downstream (`downstream-wg`: its binary and its tunnel tests), and that binary
//!   importing, pulling and serving an upstream's signed export;
//! * `estate:<name>`: H2's estate cut ([`estate_steps`]): server-lib's estate modules
//!   and integration tests with `estate`, and the off halves without it;
//! * `sign:holger-server-lib`: every server-lib test target whose `required-features`
//!   name `sign`, found in `cargo metadata` and run with exactly the features those
//!   targets require;
//! * `board:admission`: the estate board's integration test, which counts consumers
//!   only where the door admission's book is kept, run with `admission` DECLARED
//!   (A18 §4 #10: before, that branch was reached by feature unification or not at all).
//!
//! It runs HOST cargo, like `cargo xtask test`: run it inside the toolchain container
//! (`nordisk-cargo-toolchain:live`), or in CI's job container. `--list` prints the plan
//! and runs nothing; `--only <prefix>` runs the steps whose label starts with it.

use std::path::Path;
use std::process::Command;

use anyhow::{bail, Context, Result};

/// One cargo invocation of the plan.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Step {
    pub label: String,
    pub args: Vec<String>,
    /// Its environment beyond the runner's (`front:wg-hub` requires the TUN where it can).
    pub env: Vec<(String, String)>,
}

impl Step {
    fn new(label: impl Into<String>, args: Vec<String>) -> Step {
        Step {
            label: label.into(),
            args,
            env: Vec::new(),
        }
    }
}

/// The front's real-TUN test (holger-estate-front `wg_only::tests`).
pub const WG_HUB_TEST: &str = "wg_only::tests::open_hub_opens_the_overlay_interface_on_a_real_tun";
/// Its switch (holger-estate-front `wg_only::TUN_REQUIRED_ENV`): set, the test may not skip.
pub const WG_TUN_REQUIRED_ENV: &str = "HOLGER_WG_TUN_REQUIRED";

/// Pure: **the `front:wg-hub` step** — the real-TUN test by name, with `--nocapture` so a
/// skip is said. It is REQUIRED (the test may not skip) only when `required` — which the caller
/// takes from the runner's own [`WG_TUN_REQUIRED_ENV`]: a privileged runner that can create a
/// TUN (the KVM gate host, a privileged CI container) exports `HOLGER_WG_TUN_REQUIRED=1` before
/// `cargo xtask suite-check`, and the step hands it to the test; a plain container leaves it
/// unset and the test skips by name where `/dev/net/tun` cannot be used. Opening the node is
/// NOT the gate (opening succeeds without `CAP_NET_ADMIN`, which `TUNSETIFF` then needs), so the
/// requirement is the runner's explicit word, never a guess.
pub fn wg_hub_step(required: bool) -> Step {
    let args = [
        "test",
        "--manifest-path",
        "holger-estate-front/Cargo.toml",
        "--lib",
        WG_HUB_TEST,
        "--",
        "--nocapture",
    ]
    .map(String::from)
    .to_vec();
    Step {
        label: "front:wg-hub".into(),
        args,
        env: if required {
            vec![(WG_TUN_REQUIRED_ENV.to_string(), "1".to_string())]
        } else {
            Vec::new()
        },
    }
}

/// Did the runner ask for the real TUN (exported `HOLGER_WG_TUN_REQUIRED=1`)?
pub fn tun_required() -> bool {
    std::env::var(WG_TUN_REQUIRED_ENV).is_ok_and(|v| v.trim() == "1")
}

/// The suite whose rows this verb compiles.
pub const SUITE: &str = "MVP";

/// **The trust-depth arms** (lane G3, A18 P0 #2): the tests of the scanners and
/// verifiers G3 added, each its own step `trust:<name>`, `(name, cargo args)`. One line per arm.
pub const TRUST_STEPS: &[(&str, &[&str])] = &[
    // Wolfi APK provenance: real Wolfi indexes (RSA256 and RSA/SHA-1) and packages, offline.
    (
        "apk-provenance",
        &[
            "test",
            "-p",
            "holger-provenance",
            "--test",
            "apk_wolfi",
            "--test",
            "minted",
        ],
    ),
    // The same through the server: the apk source, the worker's keys, the intake chain.
    (
        "apk-intake",
        &[
            "test",
            "-p",
            "holger-server-lib",
            "--no-default-features",
            "--features",
            "supply-chain,jobs,pull-apk",
            "--lib",
            "--",
            "apk",
        ],
    ),
    // Lane T8: the APK pull-through (real Wolfi bytes behind a fake upstream): the pinned
    // upstream index, the not-yet answers, Holger's own signed index of AVAILABLE packages.
    (
        "apk-pull",
        &[
            "test",
            "-p",
            "holger-server-lib",
            "--features",
            "jobs,online,supply-chain,pull-apk",
            "--test",
            "pull_through_apk",
        ],
    ),
    // The secrets scanner in the scan worker, its rules and the gates.secrets policy.
    (
        "secrets",
        &[
            "test",
            "-p",
            "holger-server-lib",
            "--features",
            "supply-chain,jobs",
            "--no-fail-fast",
            "--lib",
            "--test",
            "tier1_sources_steps_rules",
            "--",
            "secret",
        ],
    ),
    // T9b: OpenPGP (Maven Central's `.asc`) is opt-in. With holger-provenance's `pgp`:
    // T9's real Central signatures, and the build-feature tests on their built side.
    (
        "maven-pgp",
        &[
            "test",
            "-p",
            "holger-provenance",
            "--features",
            "pgp",
            "--test",
            "maven_pgp",
            "--test",
            "pgp_build_feature",
            "--test",
            "minted",
        ],
    ),
    // Without it, as the default `holger` is built: every pgp pin refused by name.
    (
        "pgp-not-built",
        &[
            "test",
            "-p",
            "holger-provenance",
            "--lib",
            "--test",
            "pgp_build_feature",
        ],
    ),
    // The same through the server without `maven-pgp`: the pull-through source, the
    // scanner's floor and the worker's keys refuse the pin by name.
    (
        "pgp-intake-not-built",
        &[
            "test",
            "-p",
            "holger-server-lib",
            "--no-default-features",
            "--features",
            "supply-chain,jobs",
            "--lib",
            "--",
            "pgp",
        ],
    ),
    // And with `maven-pgp`: the worker, the scanner and T9's Maven Central pull-through
    // held to its `.asc` (server-lib's `online` does not carry the verifier; the CLI's does).
    (
        "maven-pgp-intake",
        &[
            "test",
            "-p",
            "holger-server-lib",
            "--features",
            "jobs,online,supply-chain,maven-pgp",
            "--lib",
            "--test",
            "pull_through_npm_maven_crates",
            "--",
            "pgp",
        ],
    ),
    // H4, the sync protocol: the signed documents, the ledger and the alarm.
    ("sync-protocol", &["test", "-p", "holger-sync"]),
    // Two Holgers in one process: USB mode, pull mode over the door, the alarm, the tick job.
    (
        "sync-two-holgers",
        &[
            "test",
            "-p",
            "holger-server-lib",
            "--features",
            "jobs,online,sync,supply-chain",
            "--test",
            "sync_between_two_holgers",
        ],
    ),
    // The airgap bundle that carries the manifest, and the CLI's stick verbs.
    (
        "sync-bundle",
        &[
            "test",
            "-p",
            "holger",
            "--features",
            "supply-chain,secure_update,sign,sync",
            "--test",
            "airgap_export_import",
            "--",
            "sync",
        ],
    ),
    // The whole airgap export and import (the AVAILABLE set with its evidence and signed
    // attestations, verified and imported on the other side; lane OX-WIRED2).
    (
        "airgap-export",
        &[
            "test",
            "-p",
            "holger",
            "--features",
            "supply-chain,secure_update,sign",
            "--test",
            "airgap_export_import",
        ],
    ),
    // An invalidated package drops out of every index (Maven, cargo, npm, PEP 503/691, OCI tags).
    (
        "sync-indexes",
        &[
            "test",
            "-p",
            "holger-server-lib",
            "--features",
            "jobs,online,supply-chain",
            "--test",
            "pull_through_npm_maven_crates",
            "--test",
            "pull_through_runs_the_intake_chain",
            "--",
            "invalidated",
        ],
    ),
    // H6: Go modules pulled from a GOPROXY through the intake chain (held to the module zip
    // rules, scanned as the module at its version), and served from the sealed store.
    (
        "go-pull",
        &[
            "test",
            "-p",
            "holger-server-lib",
            "--features",
            "jobs,online,supply-chain",
            "--lib",
            "--test",
            "pull_through_npm_maven_crates",
            "--",
            "go_",
            "pull_intake::go",
        ],
    ),
    // The image catalog: the rpm sqlite database, Go build info and cargo-auditable.
    (
        "image-catalog",
        &["test", "-p", "holger-inspect", "--lib", "--no-fail-fast"],
    ),
    // Those packages reaching the advisory match, and the `wolfi` apk grammar (modgunn 0.0.8).
    (
        "image-match",
        &[
            "test",
            "-p",
            "holger-server-lib",
            "--no-default-features",
            "--features",
            "supply-chain,jobs",
            "--lib",
            "--no-fail-fast",
            "--",
            "sandbox::tests::an_image",
            "intel::tests::a_wolfi_rebuild",
        ],
    ),
];

/// **The public page's mount, tested where it is built** (A28 M14): `front` left server-lib's
/// `default`, so its mount tests (`exposed::http`) and the page half of
/// `the_default_server_serves_no_page` run here, under `--features front`, and nowhere else.
pub const FRONT_MOUNT_STEP: &[&str] = &[
    "test",
    "-p",
    "holger-server-lib",
    "--features",
    "front",
    "--no-fail-fast",
    "--lib",
    "--test",
    "the_default_server_serves_no_page",
    "--",
    "the_front_door_is_reached_by_head_and_by_a_write",
    "the_mount_names_every_path_the_door_owns",
    "the_http_door_serves_the_page_only_where_front_is_built",
    "the_default_features_name_no_front",
];

/// The three server builds A18 §4 #3 names besides the rows.
pub const FEATURE_BUILDS: [&str; 3] = ["paired", "appliance", "secure_update"];

/// A row's own argv with the verb swapped and the profile dropped: `check` and
/// `test` share one debug cache, and a profile changes no feature. A row with its own
/// `manifest_dir` (holger-estate-front) is reached by its manifest path, not `-p`.
pub(crate) fn row_args(v: &nornir_build_thing::BuildVariant, verb: &str) -> Vec<String> {
    let mut out = vec![verb.to_string()];
    let args = v.cargo_args();
    if let Some(dir) = &v.manifest_dir {
        if !args.iter().any(|a| a == "--manifest-path") {
            out.push("--manifest-path".into());
            out.push(format!("{dir}/Cargo.toml"));
        }
    }
    let mut it = args.into_iter().skip(1);
    while let Some(a) = it.next() {
        match a.as_str() {
            "--profile" => {
                it.next();
            }
            "-p" if v.manifest_dir.is_some() => {
                it.next();
            }
            _ => out.push(a),
        }
    }
    out
}

fn is_mvp_cargo(v: &nornir_build_thing::BuildVariant) -> bool {
    v.suites.iter().any(|s| s == SUITE) && v.kind.is_cargo()
}

/// **The downstream's steps** (Holger v2.0 H3), each `downstream:<name>`, `(name, cargo args)`,
/// in order: the shape (no scanner, no wasm, no estate, no renderer, no internet client, and
/// clearly smaller than the default), its rules, its one line out, its views, the real
/// `holger-downstream` binary, the WireGuard downstream's binary and tunnel tests
/// (`downstream-wg`), and that binary importing, pulling and serving an upstream's
/// signed export, and the H6 end-to-end gate compiled (`cargo xtask e2e` runs it with its
/// real clients: pip, uv, cargo, mvn, skopeo and go).
pub const DOWNSTREAM_STEPS: &[(&str, &[&str])] = &[
    (
        "shape",
        &[
            "test",
            "--manifest-path",
            "estate/Cargo.toml",
            "-p",
            "holger-recipe",
            "--test",
            "downstream_shape",
        ],
    ),
    ("rules", &["test", "-p", "holger-downstream-rules"]),
    (
        "egress",
        &[
            "test",
            "-p",
            "holger-server-lib",
            "--no-default-features",
            "--features",
            "downstream,gateway",
            "--test",
            "a_downstream_dials_only_its_upstream",
        ],
    ),
    // The fetching downstream's one line out (lane HOL-CDS: `fetch` built, `boundary: Fetch`);
    // the step above is the one-way downstream's (a mirror refused by line, nothing dialled).
    (
        "egress-fetch",
        &[
            "test",
            "-p",
            "holger-server-lib",
            "--no-default-features",
            "--features",
            "downstream,gateway,fetch",
            "--test",
            "a_downstream_dials_only_its_upstream",
        ],
    ),
    (
        "views",
        &[
            "test",
            "-p",
            "holger-server-lib",
            "--no-default-features",
            "--features",
            "downstream,gateway",
            "--lib",
            "--",
            "pull_intake::crates",
            "pull_intake::go",
        ],
    ),
    // `sandbox-off`: the toolchain image has no container engine, so the binary's
    // verify-bundle jobs run in-process (lane HOL-SANDBOX-TRAIT); a shipped one never does.
    (
        "build",
        &[
            "build",
            "--manifest-path",
            "holger-downstream/Cargo.toml",
            "-p",
            "holger-downstream",
            "--features",
            "sandbox-off",
            "--bin",
            "holger-downstream",
        ],
    ),
    // Lane HOL-CDS: that binary is ONE-WAY. The upstream pushes into the diode folder, the
    // binary imports through its inbox after the admin's first-import authorization and
    // refuses a way out by line; its tree links no client and no server-lib `fetch`. Run
    // here, while the binary beside the tests is still the one-way build (wg-build below
    // overwrites it with the fetching one, which `serve` drives).
    (
        "one-way",
        &[
            "test",
            "-p",
            "holger",
            "--features",
            "supply-chain,secure_update,sign,jobs,sync",
            "--test",
            "one_way_downstream",
            "--test",
            "one_way_ships_no_client",
        ],
    ),
    // F9 (the field test of 2026-11-01): a downstream written as the guide writes it
    // (`steps:` and `sources:`, each source with no `url`) serves the image it imported, with
    // its referrers, from the ONE-WAY binary as well; `serve` below drives the fetching one.
    (
        "one-way-sources",
        &[
            "test",
            "-p",
            "holger",
            "--features",
            "supply-chain,secure_update,sign,jobs,sync",
            "--test",
            "downstream_serves_the_build_systems",
            "--",
            "a_downstream_written_with_sources",
        ],
    ),
    // The WireGuard downstream (lane HOL-WGDS, `downstream-wg`, default-off): the binary built
    // with its tunnel, and the tunnel's own tests (the signed invite kept once, the one route).
    (
        "wg-build",
        &[
            "build",
            "--manifest-path",
            "holger-downstream/Cargo.toml",
            "-p",
            "holger-downstream",
            "--features",
            "downstream-wg,sandbox-off",
            "--bin",
            "holger-downstream",
        ],
    ),
    (
        "wg-tunnel",
        &[
            "test",
            "-p",
            "holger-server-lib",
            "--no-default-features",
            "--features",
            "downstream,downstream-wg",
            "--lib",
            "--",
            "sync::tunnel",
        ],
    ),
    // The WireGuard downstream takes the upstream's signed invite through its own door
    // (OX-WGDS3; lane OX-WIRED2 put it in a step).
    (
        "wg-invite",
        &[
            "test",
            "-p",
            "holger-server-lib",
            "--features",
            "downstream-wg",
            "--test",
            "a_downstream_takes_its_invite_through_its_door",
        ],
    ),
    (
        "serve",
        &[
            "test",
            "-p",
            "holger",
            "--features",
            "supply-chain,secure_update,sign,jobs,sync",
            "--test",
            "downstream_serves_the_build_systems",
            // The two `boundary: Fetch` tests (pull, invalidation ack) need the FETCHING
            // binary, which downstream:wg-build left beside holger; a run after the one-way
            // build leaves them ignored by name. Not the real-client one (podman, CI full set).
            "--",
            "--include-ignored",
            "a_downstream_",
            "an_invalidated_package",
        ],
    ),
    // H6: the end-to-end gate, compiled on every push. Here it skips by name (no mvn, go,
    // uv or skopeo in the toolchain image); `cargo xtask e2e` runs it in its clients image.
    (
        "e2e",
        &[
            "test",
            "-p",
            "holger",
            "--features",
            "supply-chain,secure_update,sign,jobs,sync,online,fmt-all",
            "--test",
            "e2e_internet_to_build_systems",
        ],
    ),
];

/// **The thin client's steps** (lane B3, .nornir/SUITES.md `cli`), each `cli:<name>`: its
/// units; every console call is a command (the sibling holger-ui read when it is beside us);
/// thin and airgapped (its dependencies, the one connection to `--at`); every command group
/// against a REAL holger in the test process, the bundle export and the first-key doors among
/// them; and the binary `cargo install --path holger-cli` gives.
pub const CLI_STEPS: &[(&str, &[&str])] = &[
    ("unit", &["test", "-p", "holger-cli", "--lib", "--bins"]),
    (
        "parity",
        &[
            "test",
            "-p",
            "holger-cli",
            "--test",
            "every_ui_call_is_a_command",
        ],
    ),
    (
        "thin",
        &["test", "-p", "holger-cli", "--test", "thin_and_airgapped"],
    ),
    (
        "server",
        &["test", "-p", "holger-cli", "--test", "against_a_holger"],
    ),
    (
        "build",
        &["build", "-p", "holger-cli", "--bin", "holger-cli"],
    ),
    // `holger-cli --at https://<repo host>` through vm1's front to a real primary (B3 train 3).
    (
        "front",
        &[
            "test",
            "--manifest-path",
            "holger-estate-front/Cargo.toml",
            "--test",
            "holger_cli_reaches_the_estate_through_the_front",
        ],
    ),
];

/// **The estate's integration tests** (H2's estate cut, HCUT 2026-10-26): server-lib test
/// targets whose `required-features` are `["estate"]` — the twin over mutual TLS, certify,
/// the recharge lane and the pairing renewal. No default or downstream build reaches them.
pub const ESTATE_TESTS: &[&str] = &[
    "a_dead_main_is_recharged_from_its_remote_twin",
    "pairing_renewal",
    "the_twin_follows_over_mutual_tls_across_addresses",
    "the_twin_follows_at_once_when_certified",
];

/// **The shipped estate declaration's tests**: they boot `holger_recipe::estate_ron`, which
/// names a `replication_door`, so they need `estate` (and `supply-chain`, the declaration's
/// intake chain).
pub const ESTATE_DECLARATION_TESTS: &[&str] = &[
    "the_estate_declaration_runs_the_intake_chain",
    "the_estate_declaration_serves_npm_through_the_intake_chain",
    "the_shipped_declaration_keeps_the_fronts_installer_material",
    "an_airgap_estate_box_imports_signed_intel",
    "the_shipped_declaration_lets_the_front_certify_the_twin",
    "the_fed_public_repositories_are_read_with_no_sign_in",
    // HOL-MVP-FORMATS: the shipped declaration installs the provenance scanner.
    "the_estate_declaration_runs_the_provenance_scanner",
];

/// **The estate's steps**, each `estate:<name>`: server-lib's estate modules' unit tests
/// with `estate` (`lib`), the estate integration tests ([`ESTATE_TESTS`], `twin`), and the
/// off halves a build without the estate answers with (`off`, the default features).
pub fn estate_steps() -> Vec<Step> {
    let s = |v: &[&str]| v.iter().map(|a| a.to_string()).collect::<Vec<_>>();
    let lib = s(&[
        "test",
        "-p",
        "holger-server-lib",
        "--features",
        "estate",
        "--lib",
        "--",
        "grow::",
        "twin_tls::",
        "admin_view::",
        "cert_health::",
        "recharge_lane::",
        "twin::",
        "admin_view_tests::the_admins_snapshot",
    ]);
    let mut twin = s(&[
        "test",
        "-p",
        "holger-server-lib",
        "--features",
        "estate",
        "--no-fail-fast",
    ]);
    for t in ESTATE_TESTS {
        twin.extend(["--test".to_string(), t.to_string()]);
    }
    let off = s(&[
        "test",
        "-p",
        "holger-server-lib",
        "--lib",
        "--",
        "plane_off",
        "mtls_off",
        "disks_off",
        "admin_view_tests::the_admins_snapshot",
    ]);
    let mut decl = s(&[
        "test",
        "-p",
        "holger-server-lib",
        "--features",
        "estate,supply-chain,auth-passkey",
        "--no-fail-fast",
    ]);
    for t in ESTATE_DECLARATION_TESTS {
        decl.extend(["--test".to_string(), t.to_string()]);
    }
    vec![
        Step::new("estate:lib", lib),
        Step::new("estate:twin", twin),
        Step::new("estate:declaration", decl),
        Step::new("estate:off", off),
    ]
}

/// The plan from the declared rows (not yet the `sign` steps, which need cargo metadata).
pub fn plan_from_rows(rows: &[nornir_build_thing::BuildVariant]) -> Vec<Step> {
    let mut steps = Vec::new();
    let mut checked = std::collections::BTreeSet::new();
    for v in rows.iter().filter(|v| is_mvp_cargo(v)) {
        if checked.insert(v.name.clone()) {
            steps.push(Step::new(
                format!("row-check:{}", v.name),
                row_args(v, "check"),
            ));
        }
    }
    // The server rows' unit tests, on the host: `--bins` and no `--bin` (every bin the
    // features enable runs its tests) and no `--target` (a musl row's tests run on the host
    // triple). A row whose feature set an earlier row already tested is not tested again.
    // The DEV `…-narrate` rows are their payloads plus the sender: checked above, not tested.
    let mut tested: std::collections::BTreeSet<Vec<String>> = std::collections::BTreeSet::new();
    for v in rows.iter().filter(|v| {
        is_mvp_cargo(v)
            && v.package.as_deref() == Some(holger_recipe::variants::SERVER_CLI)
            && v.manifest_dir.is_none()
            && !v.features.iter().any(|f| f == "dev-narrate")
    }) {
        let mut key = v.features.clone();
        key.sort();
        if !tested.insert(key) {
            continue;
        }
        let mut args: Vec<String> = row_args(v, "test");
        for flag in ["--bin", "--target"] {
            if let Some(i) = args.iter().position(|a| a == flag) {
                args.drain(i..i + 2);
            }
        }
        args.insert(3, "--bins".into());
        args.push("--no-fail-fast".into());
        steps.push(Step::new(format!("row-test:{}", v.name), args));
    }
    for f in FEATURE_BUILDS {
        steps.push(Step::new(
            format!("build:{f}"),
            [
                "check",
                "-p",
                holger_recipe::variants::SERVER_CLI,
                "--features",
                f,
            ]
            .map(String::from)
            .to_vec(),
        ));
    }
    for (name, args) in TRUST_STEPS {
        steps.push(Step::new(
            format!("trust:{name}"),
            args.iter().map(|a| a.to_string()).collect(),
        ));
    }
    for (name, args) in DOWNSTREAM_STEPS {
        steps.push(Step::new(
            format!("downstream:{name}"),
            args.iter().map(|a| a.to_string()).collect(),
        ));
    }
    for (name, args) in CLI_STEPS {
        steps.push(Step::new(
            format!("cli:{name}"),
            args.iter().map(|a| a.to_string()).collect(),
        ));
    }
    steps.extend(estate_steps());
    steps.push(Step::new(
        "front:mount",
        FRONT_MOUNT_STEP.iter().map(|a| a.to_string()).collect(),
    ));
    let front = [
        "test",
        "--manifest-path",
        "holger-estate-front/Cargo.toml",
        "--no-fail-fast",
    ]
    .map(String::from)
    .to_vec();
    steps.push(Step::new("front:default", front.clone()));
    let mut metered = front;
    metered.extend(["--features".to_string(), "metered".to_string()]);
    steps.push(Step::new("front:metered", metered));
    steps.push(wg_hub_step(tun_required()));
    steps
}

/// The `sign` steps from `cargo metadata --no-deps --format-version 1`: per package
/// that has them, its test targets whose `required-features` name `sign`, run together
/// with the union of what they require.
pub fn sign_steps(metadata: &serde_json::Value) -> Vec<Step> {
    let mut steps = Vec::new();
    for pkg in metadata["packages"].as_array().into_iter().flatten() {
        let name = pkg["name"].as_str().unwrap_or_default();
        if name != SIGN_PACKAGE {
            continue;
        }
        let mut tests = std::collections::BTreeSet::new();
        let mut features = std::collections::BTreeSet::new();
        for t in pkg["targets"].as_array().into_iter().flatten() {
            let is_test = t["kind"]
                .as_array()
                .is_some_and(|k| k.iter().any(|k| k == "test"));
            let req: Vec<&str> = t["required-features"]
                .as_array()
                .into_iter()
                .flatten()
                .filter_map(|f| f.as_str())
                .collect();
            if is_test && req.contains(&"sign") {
                tests.insert(t["name"].as_str().unwrap_or_default().to_string());
                features.extend(req.iter().map(|f| f.to_string()));
            }
        }
        if tests.is_empty() {
            continue;
        }
        let mut args = vec![
            "test".to_string(),
            "-p".into(),
            name.to_string(),
            "--features".into(),
            features.into_iter().collect::<Vec<_>>().join(","),
            "--no-fail-fast".into(),
        ];
        for t in tests {
            args.push("--test".into());
            args.push(t);
        }
        steps.push(Step::new(format!("sign:{name}"), args));
    }
    steps
}

/// The package whose `sign`-gated tests are dark without this verb (A18 §3).
pub const SIGN_PACKAGE: &str = "holger-server-lib";

/// The estate board's integration test (A13), and the feature it declares (A18 §4 #10).
pub const BOARD_TEST: &str = "the_estate_board_counts_upstreams_downstreams_and_consumers";
pub const BOARD_FEATURE: &str = "admission";

/// The board step: the one test, with its declared feature.
pub fn board_step() -> Step {
    Step {
        label: format!("board:{BOARD_FEATURE}"),
        args: [
            "test",
            "-p",
            SIGN_PACKAGE,
            "--features",
            BOARD_FEATURE,
            "--no-fail-fast",
            "--test",
            BOARD_TEST,
        ]
        .map(String::from)
        .to_vec(),
        env: Vec::new(),
    }
}

fn cargo() -> std::ffi::OsString {
    std::env::var_os("CARGO").unwrap_or_else(|| "cargo".into())
}

/// The whole plan: the rows', then the `sign` steps from this checkout's metadata.
pub fn plan(root: &Path) -> Result<Vec<Step>> {
    let set = holger_build_space::build_variant_set()?;
    let mut steps = plan_from_rows(&set.variants);
    let out = Command::new(cargo())
        .args(["metadata", "--no-deps", "--format-version", "1"])
        .current_dir(root)
        .output()
        .context("running cargo metadata")?;
    if !out.status.success() {
        bail!(
            "cargo metadata failed: {}",
            String::from_utf8_lossy(&out.stderr)
        );
    }
    let meta: serde_json::Value =
        serde_json::from_slice(&out.stdout).context("reading cargo metadata")?;
    let sign = sign_steps(&meta);
    if sign.is_empty() {
        bail!("no {SIGN_PACKAGE} test target requires `sign`: the sign step would run nothing");
    }
    steps.extend(sign);
    steps.push(board_step());
    Ok(steps)
}

fn only() -> Option<String> {
    let args: Vec<String> = std::env::args().skip(2).collect();
    args.iter()
        .position(|a| a == "--only")
        .and_then(|i| args.get(i + 1).cloned())
}

pub fn list(root: &Path) -> Result<()> {
    for s in plan(root)? {
        let env: String = s.env.iter().map(|(k, v)| format!("{k}={v} ")).collect();
        println!("{:<34} {env}cargo {}", s.label, s.args.join(" "));
    }
    Ok(())
}

/// `holger-downstream` is a workspace of its own: a build of it goes into the ROOT's target
/// directory (`--target-dir`), beside the `holger` whose tests look for it there.
pub fn with_root_target(root: &Path, args: &[String]) -> Vec<String> {
    let mut out = args.to_vec();
    if let Some(i) = out.iter().position(|a| a == "holger-downstream/Cargo.toml") {
        let target = std::env::var_os("CARGO_TARGET_DIR")
            .map(std::path::PathBuf::from)
            .unwrap_or_else(|| root.join("target"));
        out.insert(i + 1, "--target-dir".into());
        out.insert(i + 2, target.display().to_string());
    }
    out
}

pub fn run(root: &Path) -> Result<()> {
    let only = only();
    let steps: Vec<Step> = plan(root)?
        .into_iter()
        .filter(|s| only.as_deref().is_none_or(|p| s.label.starts_with(p)))
        .collect();
    if steps.is_empty() {
        bail!(
            "suite-check: no step matches --only {}",
            only.unwrap_or_default()
        );
    }
    let mut red = Vec::new();
    for s in &steps {
        let env: String = s.env.iter().map(|(k, v)| format!("{k}={v} ")).collect();
        println!(
            "\n=== suite-check {} : {env}cargo {} ===",
            s.label,
            s.args.join(" ")
        );
        let t0 = std::time::Instant::now();
        let ok = Command::new(cargo())
            .args(with_root_target(root, &s.args))
            .envs(s.env.iter().cloned())
            .current_dir(root)
            .status()
            .with_context(|| format!("running {}", s.label))?
            .success();
        println!(
            "=== {} : {} in {:.0} s ===",
            s.label,
            if ok { "green" } else { "RED" },
            t0.elapsed().as_secs_f64()
        );
        if !ok {
            red.push(s.label.clone());
        }
    }
    println!(
        "\n=== suite-check: {} of {} step(s) green ===",
        steps.len() - red.len(),
        steps.len()
    );
    if red.is_empty() {
        return Ok(());
    }
    bail!("suite-check RED: {}", red.join(", "))
}

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

    fn rows() -> Vec<nornir_build_thing::BuildVariant> {
        holger_build_space::build_variant_set()
            .expect("the declaration loads")
            .variants
    }

    fn labels(steps: &[Step]) -> Vec<String> {
        steps.iter().map(|s| s.label.clone()).collect()
    }

    #[test]
    fn every_mvp_cargo_row_is_checked_with_its_own_features() {
        let rows = rows();
        let steps = plan_from_rows(&rows);
        let mvp: Vec<_> = rows
            .iter()
            .filter(|v| v.suites.iter().any(|s| s == SUITE) && v.kind.is_cargo())
            .collect();
        assert!(
            mvp.len() >= 5,
            "the MVP delivery has its cargo rows: {:?}",
            mvp.iter().map(|v| &v.name).collect::<Vec<_>>()
        );
        for v in mvp {
            let step = steps
                .iter()
                .find(|s| s.label == format!("row-check:{}", v.name))
                .unwrap_or_else(|| panic!("{} is not checked: {:?}", v.name, labels(&steps)));
            assert_eq!(step.args[0], "check");
            if !v.features.is_empty() {
                let i = step
                    .args
                    .iter()
                    .position(|a| a == "--features")
                    .expect("the row's features are passed");
                assert_eq!(step.args[i + 1], v.features.join(","), "{}", v.name);
            }
            if let Some(t) = &v.target {
                assert!(
                    step.args
                        .windows(2)
                        .any(|w| w[0] == "--target" && &w[1] == t),
                    "{} keeps its target",
                    v.name
                );
            }
            if let Some(dir) = &v.manifest_dir {
                assert!(
                    step.args
                        .windows(2)
                        .any(|w| w[0] == "--manifest-path" && w[1] == format!("{dir}/Cargo.toml")),
                    "{} is checked by its own manifest: {:?}",
                    v.name,
                    step.args
                );
                assert!(
                    !step.args.iter().any(|a| a == "-p"),
                    "{}: no -p beside a manifest path",
                    v.name
                );
                assert_eq!(
                    step.args.iter().filter(|a| *a == "--manifest-path").count(),
                    1,
                    "{}: one manifest path: {:?}",
                    v.name,
                    step.args
                );
            }
        }
    }

    #[test]
    fn the_paired_unit_tests_run_under_the_mvp_server_row() {
        let steps = plan_from_rows(&rows());
        let step = steps
            .iter()
            .find(|s| s.label == "row-test:mvp-server-musl")
            .unwrap_or_else(|| panic!("no row-test:mvp-server-musl: {:?}", labels(&steps)));
        assert_eq!(&step.args[..3], ["test", "-p", "holger"]);
        assert!(
            step.args.iter().any(|a| a == "--bins"),
            "the bins' unit tests: {:?}",
            step.args
        );
        let i = step.args.iter().position(|a| a == "--features").unwrap();
        assert!(
            step.args[i + 1].split(',').any(|f| f == "paired"),
            "the row carries paired: {:?}",
            step.args
        );
        assert!(
            !step.args.iter().any(|a| a == "--bin" || a == "--target"),
            "all bins, host target: {:?}",
            step.args
        );
    }

    #[test]
    fn paired_appliance_and_secure_update_each_build() {
        let steps = plan_from_rows(&rows());
        for f in FEATURE_BUILDS {
            let step = steps
                .iter()
                .find(|s| s.label == format!("build:{f}"))
                .unwrap_or_else(|| panic!("no build:{f}"));
            assert_eq!(step.args, ["check", "-p", "holger", "--features", f]);
        }
    }

    #[test]
    fn the_trust_depth_tests_are_steps() {
        let steps = plan_from_rows(&rows());
        for (name, args) in TRUST_STEPS {
            let step = steps
                .iter()
                .find(|s| s.label == format!("trust:{name}"))
                .unwrap_or_else(|| panic!("trust:{name}"));
            assert_eq!(
                step.args,
                args.iter().map(|a| a.to_string()).collect::<Vec<_>>()
            );
        }
        assert!(steps.iter().any(|s| s.label == "trust:image-catalog"));
    }

    /// H4: the sync protocol's documents, the two Holgers in one process (USB, pull,
    /// the alarm, the tick job), the bundle that carries a manifest, and every index
    /// dropping an invalidated package each run in the suite with their features.
    #[test]
    fn the_sync_protocol_runs_in_the_suite() {
        let steps = plan_from_rows(&rows());
        let step = |l: &str| {
            steps
                .iter()
                .find(|s| s.label == l)
                .unwrap_or_else(|| panic!("no {l}: {:?}", labels(&steps)))
                .args
                .clone()
        };
        assert_eq!(step("trust:sync-protocol"), ["test", "-p", "holger-sync"]);
        let two = step("trust:sync-two-holgers");
        assert!(
            two.windows(2)
                .any(|w| w == ["--features", "jobs,online,sync,supply-chain"]),
            "{two:?}"
        );
        assert!(
            two.windows(2)
                .any(|w| w == ["--test", "sync_between_two_holgers"]),
            "{two:?}"
        );
        let bundle = step("trust:sync-bundle");
        assert!(
            bundle.windows(2).any(|w| w == ["-p", "holger"])
                && bundle.iter().any(|a| a.contains("sync")),
            "{bundle:?}"
        );
        let idx = step("trust:sync-indexes");
        for t in [
            "pull_through_npm_maven_crates",
            "pull_through_runs_the_intake_chain",
        ] {
            assert!(idx.windows(2).any(|w| w == ["--test", t]), "{idx:?}");
        }
        assert_eq!(
            idx.last().map(String::as_str),
            Some("invalidated"),
            "{idx:?}"
        );
        // B1: the Go index is one of them (its `@v/list` and `@latest` drop the version).
        let go = std::fs::read_to_string(
            crate::workspace_root().join("server/lib/tests/pull_through_npm_maven_crates.rs"),
        )
        .expect("the test");
        assert!(
            go.contains(
                "fn an_invalidated_go_module_version_drops_from_list_and_latest_and_is_refused()"
            ),
            "the Go index's invalidation test is in pull_through_npm_maven_crates"
        );
    }

    /// ★ H3: the downstream's steps run in order, the real binary built before the test
    /// that drives it, and the shape guard first.
    #[test]
    fn the_downstream_is_built_and_tested_on_every_push() {
        let steps = plan_from_rows(&rows());
        let at = |n: &str| {
            steps
                .iter()
                .position(|s| s.label == format!("downstream:{n}"))
                .unwrap_or_else(|| panic!("no downstream:{n}: {:?}", labels(&steps)))
        };
        assert!(
            at("shape") < at("build") && at("build") < at("serve"),
            "{:?}",
            labels(&steps)
        );
        // The one-way tests drive the one-way binary: after `build`, before `wg-build` (fetch).
        for one_way in ["one-way", "one-way-sources"] {
            assert!(
                at("build") < at(one_way) && at(one_way) < at("wg-build"),
                "{one_way}: {:?}",
                labels(&steps)
            );
        }
        let build = &steps[at("build")];
        assert!(
            build
                .args
                .windows(2)
                .any(|w| w[0] == "-p" && w[1] == "holger-downstream"),
            "the product crate: {:?}",
            build.args
        );
        let t = std::fs::read_to_string(
            crate::workspace_root().join("server/cli/tests/downstream_serves_the_build_systems.rs"),
        )
        .expect("the test");
        assert!(
            t.contains("with_file_name(\"holger-downstream\")"),
            "the test drives the binary the build step made"
        );
    }

    /// ★ The WireGuard downstream (`downstream-wg`, lane HOL-WGDS) is compiled and its
    /// tunnel tested on every push: the product crate with `downstream-wg`, and server-lib's
    /// `sync::tunnel` tests with `downstream-wg`.
    #[test]
    fn the_wireguard_downstream_is_built_and_its_tunnel_tested_on_every_push() {
        let steps = plan_from_rows(&rows());
        let step = |l: &str| {
            steps
                .iter()
                .find(|s| s.label == l)
                .unwrap_or_else(|| panic!("no {l}: {:?}", labels(&steps)))
                .args
                .clone()
        };
        let build = step("downstream:wg-build");
        assert_eq!(build[0], "build", "{build:?}");
        assert!(
            build.windows(2).any(|w| w == ["-p", "holger-downstream"]),
            "{build:?}"
        );
        // …into the root's target directory, beside the `holger` its tests run.
        let at = with_root_target(
            Path::new("/r"),
            &build.iter().map(|a| a.to_string()).collect::<Vec<_>>(),
        );
        assert!(at.windows(2).any(|w| w[0] == "--target-dir"), "{at:?}");
        // `sandbox-off` beside it (lane HOL-SANDBOX-TRAIT): no container engine in the image.
        assert!(
            build
                .windows(2)
                .any(|w| w[0] == "--features" && w[1].split(',').any(|f| f == "downstream-wg")),
            "{build:?}"
        );
        assert!(
            build
                .windows(2)
                .any(|w| w == ["--bin", "holger-downstream"]),
            "{build:?}"
        );
        let tunnel = step("downstream:wg-tunnel");
        assert_eq!(tunnel[0], "test", "{tunnel:?}");
        assert!(
            tunnel.windows(2).any(|w| w == ["-p", "holger-server-lib"]),
            "{tunnel:?}"
        );
        assert!(
            tunnel
                .windows(2)
                .any(|w| w[0] == "--features" && w[1].split(',').any(|f| f == "downstream-wg")),
            "{tunnel:?}"
        );
        assert!(
            tunnel.iter().any(|a| a == "sync::tunnel"),
            "the tunnel's tests: {tunnel:?}"
        );
    }

    /// ★ Lane OX-WIRED2: the WireGuard downstream's invite door and the whole airgap export
    /// and import are run on every push (before, the invite door ran in no CI step, and of
    /// airgap_export_import only its `sync` tests ran).
    #[test]
    fn the_wireguard_invite_door_and_the_whole_airgap_export_run_on_every_push() {
        let steps = plan_from_rows(&rows());
        let step = |l: &str| {
            steps
                .iter()
                .find(|s| s.label == l)
                .unwrap_or_else(|| panic!("no {l}: {:?}", labels(&steps)))
                .args
                .clone()
        };
        let invite = step("downstream:wg-invite");
        assert_eq!(invite[0], "test", "{invite:?}");
        assert!(
            invite
                .windows(2)
                .any(|w| w[0] == "--features" && w[1].split(',').any(|f| f == "downstream-wg")),
            "{invite:?}"
        );
        assert!(
            invite
                .windows(2)
                .any(|w| w == ["--test", "a_downstream_takes_its_invite_through_its_door"]),
            "{invite:?}"
        );
        let airgap = step("trust:airgap-export");
        assert!(
            airgap
                .windows(2)
                .any(|w| w == ["--test", "airgap_export_import"]),
            "{airgap:?}"
        );
        assert!(
            !airgap.iter().any(|a| a == "--"),
            "every test of it, not a filter: {airgap:?}"
        );
        for f in ["supply-chain", "secure_update", "sign"] {
            assert!(
                airgap
                    .windows(2)
                    .any(|w| w[0] == "--features" && w[1].split(',').any(|x| x == f)),
                "{f}: {airgap:?}"
            );
        }
    }

    /// ★ H2's estate cut (HCUT): the estate's own tests run in the suite with `estate`,
    /// which no default or downstream build carries, and the off halves without it.
    #[test]
    fn the_estate_code_is_tested_with_and_without_its_feature() {
        let steps = plan_from_rows(&rows());
        let step = |l: &str| {
            steps
                .iter()
                .find(|s| s.label == l)
                .unwrap_or_else(|| panic!("no {l}: {:?}", labels(&steps)))
                .args
                .clone()
        };
        let lib = step("estate:lib");
        assert!(
            lib.windows(2).any(|w| w == ["--features", "estate"])
                && lib.iter().any(|a| a == "--lib"),
            "{lib:?}"
        );
        for m in [
            "grow::",
            "twin_tls::",
            "admin_view::",
            "cert_health::",
            "recharge_lane::",
        ] {
            assert!(lib.iter().any(|a| a == m), "estate:lib runs `{m}`: {lib:?}");
        }
        let twin = step("estate:twin");
        assert!(
            twin.windows(2).any(|w| w == ["--features", "estate"]),
            "{twin:?}"
        );
        let manifest =
            std::fs::read_to_string(crate::workspace_root().join("server/lib/Cargo.toml"))
                .expect("server-lib manifest");
        for t in ESTATE_TESTS {
            assert!(
                twin.windows(2).any(|w| w[0] == "--test" && w[1] == *t),
                "estate:twin runs `{t}`: {twin:?}"
            );
            assert!(
                manifest.contains(&format!("name = \"{t}\"\nrequired-features = [\"estate\"]")),
                "`{t}` requires `estate` in server/lib/Cargo.toml"
            );
        }
        let decl = step("estate:declaration");
        for t in ESTATE_DECLARATION_TESTS {
            assert!(
                decl.windows(2).any(|w| w[0] == "--test" && w[1] == *t),
                "estate:declaration runs `{t}`: {decl:?}"
            );
            let at = manifest
                .find(&format!("name = \"{t}\""))
                .unwrap_or_else(|| panic!("no [[test]] {t}"));
            let req = manifest[at..]
                .lines()
                .find(|l| l.starts_with("required-features"))
                .unwrap_or_default();
            assert!(req.contains("\"estate\""), "`{t}` requires `estate`: {req}");
        }
        let off = step("estate:off");
        assert!(
            !off.iter().any(|a| a == "estate" || a.contains("estate,")),
            "the off halves run without the estate: {off:?}"
        );
        for m in ["plane_off", "mtls_off", "disks_off"] {
            assert!(off.iter().any(|a| a == m), "estate:off runs `{m}`: {off:?}");
        }
    }

    /// ★ H6: the end-to-end gate is compiled on every push with the features `cargo xtask e2e`
    /// builds it with, and the Go pull's tests run.
    #[test]
    fn the_e2e_gate_is_compiled_on_every_push_and_the_go_pull_is_tested() {
        let steps = plan_from_rows(&rows());
        let step = |l: &str| {
            steps
                .iter()
                .find(|s| s.label == l)
                .unwrap_or_else(|| panic!("no {l}: {:?}", labels(&steps)))
                .args
                .clone()
        };
        let e2e = step("downstream:e2e");
        assert!(
            e2e.windows(2)
                .any(|w| w[0] == "--features" && w[1] == crate::e2e::GATE_FEATURES),
            "the verb's features: {e2e:?}"
        );
        assert!(
            e2e.windows(2)
                .any(|w| w == ["--test", crate::e2e::GATE_TEST]),
            "{e2e:?}"
        );
        let go = step("trust:go-pull");
        assert!(
            go.windows(2)
                .any(|w| w == ["--test", "pull_through_npm_maven_crates"])
                && go.iter().any(|a| a == "go_"),
            "{go:?}"
        );
        let t = std::fs::read_to_string(
            crate::workspace_root().join("server/lib/tests/pull_through_npm_maven_crates.rs"),
        )
        .expect("the test");
        assert!(t.contains("fn a_go_module_is_pulled_from_a_goproxy_held_for_a_person_and_served_from_the_sealed_store()"));
    }

    /// ★ A28 M14: the page's mount tests run with `front`, which no default build carries.
    #[test]
    fn the_thin_client_is_tested_against_a_real_holger_on_every_push() {
        let steps = plan_from_rows(&rows());
        let got: Vec<String> = labels(&steps)
            .into_iter()
            .filter(|l| l.starts_with("cli:"))
            .collect();
        assert_eq!(
            got,
            [
                "cli:unit",
                "cli:parity",
                "cli:thin",
                "cli:server",
                "cli:build",
                "cli:front"
            ]
        );
        let repo = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
            .parent()
            .unwrap();
        for (name, args) in CLI_STEPS {
            let dir = if args.contains(&"holger-estate-front/Cargo.toml") {
                "holger-estate-front/tests"
            } else {
                "holger-cli/tests"
            };
            if let Some(i) = args.iter().position(|a| *a == "--test") {
                assert!(
                    repo.join(dir).join(format!("{}.rs", args[i + 1])).is_file(),
                    "cli:{name} names a test that exists: {}",
                    args[i + 1]
                );
            }
        }
    }

    #[test]
    fn the_front_mount_is_tested_with_its_feature() {
        let steps = plan_from_rows(&rows());
        let step = steps
            .iter()
            .find(|s| s.label == "front:mount")
            .unwrap_or_else(|| panic!("no front:mount: {:?}", labels(&steps)));
        assert_eq!(
            &step.args[..5],
            ["test", "-p", "holger-server-lib", "--features", "front"]
        );
        let lib =
            std::fs::read_to_string(crate::workspace_root().join("server/lib/src/exposed/http.rs"))
                .expect("http.rs");
        for name in [
            "the_front_door_is_reached_by_head_and_by_a_write",
            "the_mount_names_every_path_the_door_owns",
        ] {
            assert!(
                step.args.iter().any(|a| a == name),
                "{name} is in the step: {:?}",
                step.args
            );
            assert!(
                lib.contains(&format!("fn {name}()")),
                "{name} is still a test in exposed/http.rs"
            );
        }
        let t = std::fs::read_to_string(
            crate::workspace_root().join("server/lib/tests/the_default_server_serves_no_page.rs"),
        )
        .expect("the test");
        assert!(t.contains("fn the_http_door_serves_the_page_only_where_front_is_built()"));
    }

    #[test]
    fn the_estate_fronts_suite_runs_both_ways() {
        let steps = plan_from_rows(&rows());
        let front = |l: &str| {
            steps
                .iter()
                .find(|s| s.label == l)
                .unwrap_or_else(|| panic!("no {l}: {:?}", labels(&steps)))
                .args
                .clone()
        };
        assert_eq!(
            front("front:default"),
            [
                "test",
                "--manifest-path",
                "holger-estate-front/Cargo.toml",
                "--no-fail-fast"
            ]
        );
        assert_eq!(
            front("front:metered"),
            [
                "test",
                "--manifest-path",
                "holger-estate-front/Cargo.toml",
                "--no-fail-fast",
                "--features",
                "metered"
            ]
        );
    }

    /// ★ The front's `open_hub` runs on a REAL TUN where the runner can open one (required
    /// there, by its environment), and may skip by name where it cannot (lane HOLGER-WG).
    #[test]
    fn the_fronts_real_tun_test_is_required_where_the_runner_can_open_the_node() {
        let steps = plan_from_rows(&rows());
        let step = steps
            .iter()
            .find(|s| s.label == "front:wg-hub")
            .unwrap_or_else(|| panic!("no front:wg-hub: {:?}", labels(&steps)));
        assert_eq!(
            step.args,
            [
                "test",
                "--manifest-path",
                "holger-estate-front/Cargo.toml",
                "--lib",
                WG_HUB_TEST,
                "--",
                "--nocapture"
            ]
        );
        assert_eq!(
            step.env.is_empty(),
            !tun_required(),
            "required exactly when the runner exported {WG_TUN_REQUIRED_ENV}: {:?}",
            step.env
        );
        assert_eq!(
            wg_hub_step(true).env,
            [(WG_TUN_REQUIRED_ENV.to_string(), "1".to_string())]
        );
        assert!(wg_hub_step(false).env.is_empty());
        assert_eq!(
            wg_hub_step(true).args,
            wg_hub_step(false).args,
            "the same test either way; only the requirement differs"
        );
        let src = std::fs::read_to_string(
            crate::workspace_root().join("holger-estate-front/src/wg_only.rs"),
        )
        .expect("wg_only.rs");
        assert!(
            src.contains(&format!("fn {}(", WG_HUB_TEST.rsplit("::").next().unwrap())),
            "the test exists by that name"
        );
        assert!(
            src.contains(&format!("\"{WG_TUN_REQUIRED_ENV}\"")),
            "the switch is the front's"
        );
    }

    #[test]
    fn the_sign_gated_tests_are_found_in_the_metadata_and_run_with_their_features() {
        let meta = serde_json::json!({ "packages": [
            { "name": "holger-server-lib", "targets": [
                { "name": "plain", "kind": ["test"] },
                { "name": "b_signed", "kind": ["test"], "required-features": ["supply-chain", "sign"] },
                { "name": "a_signed", "kind": ["test"], "required-features": ["sign"] },
                { "name": "metered_only", "kind": ["test"], "required-features": ["metered"] },
            ]},
            { "name": "other", "targets": [ { "name": "x", "kind": ["test"], "required-features": ["sign"] } ] },
        ]});
        let steps = sign_steps(&meta);
        assert_eq!(steps.len(), 1, "{steps:?}");
        assert_eq!(steps[0].label, "sign:holger-server-lib");
        assert_eq!(
            steps[0].args,
            [
                "test",
                "-p",
                "holger-server-lib",
                "--features",
                "sign,supply-chain",
                "--no-fail-fast",
                "--test",
                "a_signed",
                "--test",
                "b_signed"
            ]
        );
    }

    #[test]
    fn the_real_manifest_has_the_three_signed_evidence_tests() {
        let root = crate::workspace_root();
        let out = Command::new(std::env::var_os("CARGO").unwrap_or_else(|| "cargo".into()))
            .args([
                "metadata",
                "--no-deps",
                "--format-version",
                "1",
                "--offline",
            ])
            .current_dir(&root)
            .output()
            .expect("cargo metadata runs");
        assert!(
            out.status.success(),
            "{}",
            String::from_utf8_lossy(&out.stderr)
        );
        let meta: serde_json::Value = serde_json::from_slice(&out.stdout).unwrap();
        let steps = sign_steps(&meta);
        let all = steps
            .iter()
            .flat_map(|s| s.args.iter().cloned())
            .collect::<Vec<_>>()
            .join(" ");
        for t in [
            "the_evidence_rpc_returns_signed_records",
            "the_license_scanner_signs_its_evidence",
            "the_scanner_framework_records_signed_evidence",
        ] {
            assert!(all.contains(t), "{t} is not in the sign steps: {all}");
        }
    }

    #[test]
    fn the_trust_depth_arms_run() {
        let steps = plan_from_rows(&rows());
        let apk = steps
            .iter()
            .find(|s| s.label == "trust:apk-provenance")
            .unwrap_or_else(|| panic!("no apk arm: {:?}", labels(&steps)));
        assert_eq!(&apk.args[..3], ["test", "-p", "holger-provenance"]);
        assert!(
            steps.iter().any(|s| s.label == "trust:apk-intake"),
            "{:?}",
            labels(&steps)
        );
    }

    /// T9b: the OpenPGP verifier is tested both ways, built (`pgp`) and not built.
    #[test]
    fn the_pgp_feature_is_tested_built_and_not_built() {
        let steps = plan_from_rows(&rows());
        let step = |l: &str| {
            steps
                .iter()
                .find(|s| s.label == l)
                .unwrap_or_else(|| panic!("no {l}: {:?}", labels(&steps)))
                .args
                .clone()
        };
        let on = step("trust:maven-pgp");
        assert_eq!(
            &on[..5],
            ["test", "-p", "holger-provenance", "--features", "pgp"]
        );
        assert!(
            on.windows(2).any(|w| w == ["--test", "maven_pgp"]),
            "{on:?}"
        );
        let off = step("trust:pgp-not-built");
        assert!(
            !off.iter()
                .any(|a| a.contains("pgp") && a.starts_with("--features"))
                && !off.contains(&"--features".to_string()),
            "{off:?}"
        );
        assert!(
            off.windows(2).any(|w| w == ["--test", "pgp_build_feature"]),
            "{off:?}"
        );
        let intake = step("trust:pgp-intake-not-built");
        assert!(
            intake.contains(&"--no-default-features".to_string())
                && !intake
                    .iter()
                    .any(|a| a.contains("online") || a.contains("maven-pgp")),
            "{intake:?}"
        );
        let intake_on = step("trust:maven-pgp-intake");
        assert!(
            intake_on
                .iter()
                .any(|a| a.split(',').any(|f| f == "maven-pgp")),
            "{intake_on:?}"
        );
        assert!(
            intake_on
                .windows(2)
                .any(|w| w == ["--test", "pull_through_npm_maven_crates"]),
            "{intake_on:?}"
        );
    }

    #[test]
    fn the_apk_pull_through_runs_in_the_suite() {
        // Lane T8: the APK pull-through's tests (real Wolfi bytes behind a fake upstream)
        // need `jobs,online`; no other step turns them on. `pull-apk` carries Holger's own
        // APK re-signing key (H3 on H2: no longer `jobs`).
        let steps = plan_from_rows(&rows());
        let s = steps
            .iter()
            .find(|s| s.label == "trust:apk-pull")
            .unwrap_or_else(|| panic!("no trust:apk-pull: {:?}", labels(&steps)));
        assert_eq!(&s.args[..3], ["test", "-p", "holger-server-lib"]);
        assert!(
            s.args
                .windows(2)
                .any(|w| w == ["--features", "jobs,online,supply-chain,pull-apk"]),
            "{:?}",
            s.args
        );
        assert!(
            s.args
                .windows(2)
                .any(|w| w == ["--test", "pull_through_apk"]),
            "{:?}",
            s.args
        );
        // The real `apk add` needs podman and the network: it is the demo's row, not the suite's.
        assert!(
            !s.args.iter().any(|a| a.contains("ignored")),
            "{:?}",
            s.args
        );
    }

    #[test]
    fn the_trust_depth_tests_run_in_the_suite() {
        let steps = plan_from_rows(&rows());
        let s = steps
            .iter()
            .find(|s| s.label == "trust:secrets")
            .unwrap_or_else(|| panic!("no trust:secrets: {:?}", labels(&steps)));
        assert_eq!(&s.args[..3], ["test", "-p", "holger-server-lib"]);
        assert!(
            s.args
                .windows(2)
                .any(|w| w[0] == "--test" && w[1] == "tier1_sources_steps_rules"),
            "{:?}",
            s.args
        );
        assert_eq!(
            s.args.last().map(String::as_str),
            Some("secret"),
            "the secrets tests by name"
        );
    }

    #[test]
    fn the_board_test_runs_with_admission_declared_and_the_manifest_declares_it() {
        let step = board_step();
        assert_eq!(step.label, "board:admission");
        assert_eq!(
            step.args,
            [
                "test",
                "-p",
                "holger-server-lib",
                "--features",
                "admission",
                "--no-fail-fast",
                "--test",
                BOARD_TEST
            ]
        );
        let root = crate::workspace_root();
        assert!(root
            .join("server/lib/tests")
            .join(format!("{BOARD_TEST}.rs"))
            .is_file());
        let manifest = std::fs::read_to_string(root.join("server/lib/Cargo.toml")).unwrap();
        let at = manifest
            .find(&format!("name = \"{BOARD_TEST}\""))
            .expect("the board test is a declared [[test]]");
        let rest = &manifest[at..];
        let req = rest.lines().nth(1).unwrap_or_default();
        assert!(
            req.starts_with("required-features") && req.contains(&format!("\"{BOARD_FEATURE}\"")),
            "the board test declares admission: {req}"
        );
    }

    #[test]
    fn the_list_is_not_empty_and_labels_are_unique() {
        let steps = plan_from_rows(&rows());
        let mut l = labels(&steps);
        let n = l.len();
        l.sort();
        l.dedup();
        assert_eq!(l.len(), n, "labels are unique");
        assert!(n >= 11, "{n} steps");
    }
}