xtask/src/main.rs
//! holger xtask — the repo's verbs (see [`VERBS`]; `cargo xtask` alone lists them).
//!
//! `cargo xtask test` is the everyday suite: the wasm guests, then
//! `cargo test --workspace` with default features and with `metered`.
//! `cargo xtask gate` is the full gate (rules, rows, tests, bench drivers, arms).
//! An unknown verb prints the list and exits 2; it never runs anything.
use std::process::Command;
mod appliance_iso;
mod appliance_pack;
/// `bench` — the THIN door onto `nornir bench run holger`: it owns no benchmark
/// knowledge, resolves the config, passes the selection through and then PROVES
/// the row reached the warehouse instead of trusting an exit code.
mod bench;
mod bench_readme;
/// `bench-landed` — the guard: the newest receipt has a warehouse row.
mod benchland;
/// `bench --local` — every arm in this checkout, a receipt, a table and the
/// regression check against `bench_baseline.json`; no nornir needed.
mod benchlocal;
mod ci;
/// `demo` — the Holger 1.0 demo as one command (`demo airgap`), and its declared test row (`demo tests`).
mod demo;
/// A downstream's medium and its VM (lane OX-WGDS3).
mod downstream;
/// `e2e` — Holger's end-to-end proof gate (Holger v2.0 H6): internet → upstream → USB →
/// downstream → real build systems, and an invalidation back; a receipt.
mod e2e;
/// `estate-media` — Holger's release media and live apps for the ONE box (lane L21).
mod estate_media;
mod fast;
mod fmt;
mod forge_door;
/// `gate` — **the gate the house did not have**: the rules, the shipped rows,
/// the suites and the published bench drivers, behind one verb.
mod gate;
mod gen_proto;
mod installer_iso;
mod installtest;
mod lone_clone;
mod paid_guard;
// The launcher's module, compiled here too: the real xtask refreshes the copy as well
// (`cargo run -p xtask` straight, or a Build Thing that calls it so).
/// `products` — the by-hand guide "Three products by hand" (.nornir/README.md), run as written.
mod products;
mod scan_worker;
#[path = "../boot/src/siblings.rs"]
mod siblings;
mod sigstore_trust;
/// `suite-check` — the MVP suite compiled and tested: rows, paired, the front, `sign`.
mod suite_check;
mod twin;
// HOL-NCSC: the release statement that names every shipped artifact (media, app archives, binaries).
mod k8s;
mod release_attest;
/// `build-wasm-plugins` — the build door for the wasm package handlers, and the
/// one place that decides where a built module lives.
mod wasm_plugins;
/// **Introspection / emit marker** — record one functional-status row for the
/// nornir test matrix. Wraps `nornir_testmatrix::functional_status` behind the
/// `testmatrix` feature (a compiled-out `#[inline]` no-op otherwise). Each xtask
/// verb that runs to completion emits one — reaching the call means the preceding
/// `run(..)` did NOT `exit(1)`, so `ok` is an honest success verdict.
#[inline]
fn functional_status(component: &str, check: &str, ok: bool, detail: &str) {
#[cfg(feature = "testmatrix")]
nornir_testmatrix::functional_status(component, check, ok, detail);
#[cfg(not(feature = "testmatrix"))]
{
let _ = (component, check, ok, detail);
}
}
/// The workspace root = the dir above `xtask/` (where `Cargo.toml` declares the
/// workspace). Build variants are pressed against this root.
fn workspace_root() -> std::path::PathBuf {
std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.parent()
.expect("xtask has a parent (workspace root)")
.to_path_buf()
}
// ── DELETED 2026-08-01: `const DEPLOYMENT_TIERS: [&str; 3]` ─────────────────────
//
// It was `["embedded", "mini", "full"]` — a hardcoded list of THREE tier names in a
// repo whose `.nornir/build-variants.toml` declares THIRTEEN variants. `build --all`
// walked exactly those three and was structurally blind to the other ten, so
// `mvp-server`, `server-local`, every UI tier and both agents could not be reached
// through the build verb at all. That is why holger needed a SECOND verb
// (`build-mvp`, reading holger-build's 3×3 matrix) to press its MVP row: the MVP was
// not expressible through the build space, so a parallel selector grew beside it.
//
// A constant that lists a subset of a declaration is a second declaration, and this one
// disagreed with the first by ten entries. It is replaced by
// `nornir_build_thing::suite_cli::resolve`, which asks the TOML which variants are in the
// requested delivery. `--all` is now simply "omit --variant", and adding a fourteenth variant
// needs no xtask change.
//
// The three names were not wrong, they were incomplete — `embedded`/`mini`/`full` are
// still the mutually-exclusive server modes guarded by the `compile_error!`s in
// `server/cli/src/main.rs`, and `.nornir/holger-tiers.md` still explains them. What is
// gone is this file's private opinion about which variants exist.
/// **The build environment, resolved ONCE per `build` invocation.**
///
/// It is not a bag of options: every field is either the recipe's
/// (`tc`) or cargo's own ladder (`target_dir`, `registry`, via
/// `HostPaths::from_env`). The xtask contributes none of it.
struct CargoRoad {
tc: nornir_build_thing::cargo_container::CargoToolchain,
runner: nornir_build_thing::cargo_container::DraupnirCargoRunner,
target_dir: std::path::PathBuf,
registry: Option<std::path::PathBuf>,
}
/// **Enter the image holger declares** — and refuse rather than fall back.
///
/// # The defect this closes
///
/// Until 2026-09-17 the line below `assemble_one_tier` was
/// `holger_build_space::build_tier`, which goes through
/// `nornir_build_thing::assemble()` → `build_variant` → `Command::new("cargo")`
/// **in the host's environment**. The rustc version, the installed target set,
/// the C compiler and `~/.cargo/config.toml`'s linker choice all came from
/// whichever box typed the command, so `mvp-server-musl` — which targets
/// `x86_64-unknown-linux-musl` — was one `musl-gcc`-less laptop away from a red
/// that says nothing about holger. MEASURED on loki 2026-09-17 in gunnar, which
/// has the identical shape: the host build resolved its row correctly, compiled
/// for minutes and died inside `aws-lc-sys` on a missing
/// `x86_64-linux-musl-gcc`.
///
/// The image is `[build.toolchain]` in `holger-recipe`, entered through the ONE
/// loop the kernel kind, the package kind and korp-installer's compose already
/// drive. There is deliberately NO host fallback: a road taken only when the box
/// happens to be equipped is the bug, not the fix.
///
/// # The proof, and the refusal that earned the `siblings` list
///
/// MEASURED on loki 2026-09-17. The first run never reached a container, and
/// that is the seam working — `check_escaping_path_deps` named the four sibling
/// repos the declaration had missed, with a manifest for each:
///
/// ```text
/// ✗ variant 'mvp-server-musl' failed to assemble: [build.toolchain]: path
/// dependencies escape this repo into sibling repo(s) the declaration does not
/// list … Add `siblings = ["Skidbladnir", "facett", "modgunn",
/// "znippy-zoomies"]`.
/// ```
///
/// With the declaration corrected from that list (0.6 s to refuse, not an hour
/// into a compile):
///
/// ```text
/// $ cargo run -q -p xtask -- build --suite MVP --variant mvp-server-musl
/// toolchain image nordisk-cargo-toolchain:live ready in 0.2 s (2026-09-17; the road names the pin now) → building in
/// nordisk-cargo-toolchain@sha256:3d5115ba… (rust 1.97.1, 8192 MiB, 8 cpus,
/// network none, siblings: Skidbladnir, draupnir, edda, facett, modgunn,
/// znippy, znippy-zoomies)
/// === building variant 'mvp-server-musl' in nordisk-cargo-toolchain@sha256:3d5115ba… ===
/// built in 88.9 s
/// digest : 9789f8eae6ab83a5724c42e00f9b944e5a532eb88609ec1afe00d9baf55f9fd1
/// artifact : target/x86_64-unknown-linux-musl/release/holger-mvp (32849680 bytes)
/// sha256:48e74a0dfec7dbad0a8df323c9fddc2500b2f6404a13ce6b0ea28d99a7f78586
/// === build --suite MVP: 1/1 variant(s) assembled (mvp-server-musl) ===
/// ```
///
/// Host `sha256sum` agrees with the attested digest and `file` calls it a
/// static-pie x86-64 ELF. loki has no `x86_64-linux-musl-gcc` at all, which is
/// the whole point: it was never asked for one.
fn cargo_road(root: &std::path::Path) -> anyhow::Result<CargoRoad> {
use nornir_build_thing::cargo_container as cc;
let set = holger_build_space::build_variant_set()?;
let Some(tc) = cc::toolchain_with_override(set.toolchain.clone())? else {
anyhow::bail!(
"holger declares no `[build.toolchain]`, so there is no image to build in, and \
`cargo xtask build` does NOT fall back to host cargo: a build whose verdict \
depends on which box typed it is not a build. Declare the table in \
`holger-recipe/src/lib.rs` (and re-emit `.nornir/build-variants.toml`), or set \
{} to a digest-pinned reference for a one-off run.",
cc::TOOLCHAIN_IMAGE_OVERRIDE_ENV
);
};
let paths = cc::HostPaths::from_env(root);
std::fs::create_dir_all(&paths.target_dir)?;
let runner = cc::DraupnirCargoRunner::new();
// **Step 1 is the image, minted and never assumed.** `image_sha256` is a
// manifest digest and nothing pulls it — there is no registry behind
// `nordisk-cargo-toolchain`. The kernel road mints in its step 1; so does
// this one, from the Containerfile embedded in `nornir-build-thing` (the
// repo never supplies its own build environment), reproducibly, so the
// digest a fresh box lands is the digest the declaration pins and a re-mint
// is answered from podman's layer cache.
let ctx = paths.target_dir.join("nordisk-cargo-toolchain-context");
let t0 = std::time::Instant::now();
// The pin, present or minted under the shared recipe's own `:recipe-…` tag; never `:live`
// (holger-ui 3e89bb5: a `:live` re-mint un-names whatever image the tag held, and a pin on
// it then goes to a registry that does not exist).
let built = runner
.ensure_declared_toolchain(&ctx, &tc)
.map(|m| match m {
cc::ToolchainMint::AlreadyPresent => tc.image_ref(),
cc::ToolchainMint::Minted { tag } => tag,
})
.map_err(|e| {
anyhow::anyhow!(
"mint the declared toolchain image: {e:#}\n This is step 1 and it needs a \
container engine socket — the ONE thing the host is asked for. The \
declaration pins {}; nothing pulls it, every box mints it.",
tc.image_ref()
)
})?;
println!(
"toolchain image {built} ready in {:.1} s → building in {} (rust {}, {} MiB, {} cpus, \
network {}, siblings: {})",
t0.elapsed().as_secs_f64(),
tc.image_ref(),
tc.rust_version,
tc.mem_limit_mb,
tc.cpus,
if tc.network { "on" } else { "none" },
if tc.siblings.is_empty() {
"none".to_string()
} else {
tc.siblings.join(", ")
}
);
Ok(CargoRoad {
tc,
runner,
target_dir: paths.target_dir.clone(),
registry: paths.registry_bind().map(std::path::Path::to_path_buf),
})
}
/// Build ONE variant **in the declared container** through
/// `cargo_container::build_variant_in_container` — the same loop, the same
/// `--message-format=json` parse and the same content-hashing the host road had,
/// with the toolchain recorded in the provenance read off the CONTAINER's own
/// `rustc --version` rather than the host's. Prints the receipt and emits its
/// `functional_status` row; returns the honest per-variant verdict.
fn assemble_one_tier(road: &CargoRoad, tier: &str, root: &std::path::Path) -> anyhow::Result<bool> {
assemble_one_tier_in(road, &holger_build_space::build_variant_set()?, tier, root)
}
/// [`assemble_one_tier`] over a given set (the products with the operator's `--features`).
fn assemble_one_tier_in(
road: &CargoRoad,
set: &nornir_build_thing::BuildVariantSet,
tier: &str,
root: &std::path::Path,
) -> anyhow::Result<bool> {
println!(
"\n=== building variant '{tier}' in {} ===",
road.tc.image_ref()
);
let t0 = std::time::Instant::now();
let out = nornir_build_thing::cargo_container::build_variant_in_container(
set,
tier,
root,
&road.target_dir,
road.registry.as_deref(),
&road.tc,
&road.runner,
)?;
println!(
" {} in {:.1} s",
if out.success { "built" } else { "FAILED" },
t0.elapsed().as_secs_f64()
);
println!(" digest : {}", out.attestation.digest_hex());
println!(" sealed : {}", out.attestation.is_sealed());
// The provenance record's OWN hashes — what is printed is what was attested,
// not a second hashing pass here.
for a in &out.attestation.record.artifacts {
println!(
" artifact : {} ({} bytes) sha256:{}",
a.path, a.bytes, a.sha256
);
}
functional_status(
"xtask/build",
"assemble_variant",
out.success,
&format!(
"built '{tier}' in {}: {} artifact(s)",
road.tc.image_ref(),
out.attestation.record.artifacts.len()
),
);
Ok(out.success)
}
/// **THE build verb** — `cargo xtask build --suite MVP [--variant <v>] [--list] [--features <f>]`.
///
/// # What is shared and what is holger's
///
/// The **selector** is shared with every other repo in the house:
/// [`nornir_build_thing::suite_cli`] parses the flags and
/// [`suite_cli::resolve`](nornir_build_thing::suite_cli::resolve) asks
/// `.nornir/build-variants.toml` which variants are in the requested delivery. This file
/// contributes no variant name, no feature string and no bin name, which is the whole
/// change: the previous version kept its own three-name list and could not see ten of
/// holger's thirteen variants.
///
/// The **action** is holger's, and is deliberately richer than the shared one.
/// `suite_cli::run` builds with a plain cargo spawn; [`assemble_one_tier`] goes through
/// `nornir_build_thing::assemble()`, which captures a build-provenance record + a
/// build-info lineage per variant and can seal it. Both live in `nornir-build-thing` — this
/// is one library with two entry points, not two build implementations — and holger
/// takes the attesting one because its artifacts are what an airgapped customer
/// receives and the provenance is the point.
///
/// `--list` delegates WHOLLY to `suite_cli::run`, so the describe output is byte-for-byte
/// the same shape korp, dwarves, nornir and modgunn print. Omitting `--variant` is what
/// `--all` used to mean.
///
/// # `--atom` is accepted as a deprecated spelling of `--variant`
///
/// Kept because scripts and `.nornir/*.md` recipes use it, and rejecting it outright
/// would turn a rename into an outage. It warns and maps through the SAME resolver, so
/// it cannot become a second selector.
fn run_build() -> anyhow::Result<()> {
let argv: Vec<String> = std::env::args().skip(2).collect();
run_build_with(&argv)
}
/// **The four products with the operator's cargo features** (`build --features <f>` and no
/// `--variant`): each product row with the features on top, listed (`--list`) or built in
/// the pinned toolchain container like any row.
fn run_products_with(
root: &std::path::Path,
args: &nornir_build_thing::suite_cli::BuildArgs,
) -> anyhow::Result<()> {
let set = holger_build_space::build_variant_set()?;
if let Some(s) = args.suite.as_deref() {
anyhow::ensure!(
set.suites().contains(&s),
"--suite {s}: no such delivery. Declared: {}",
set.suites().join(", ")
);
}
let mut featured = set.clone();
for p in holger_recipe::variants::PRODUCTS {
featured = featured.with_cargo_features(p, &args.cargo)?;
}
let flags = args.cargo.argv().join(" ");
println!(
"the products with `{flags}` — {} variant(s):",
holger_recipe::variants::PRODUCTS.len()
);
for p in holger_recipe::variants::PRODUCTS {
println!(" {p}: {}", featured.require(p)?.command_line());
}
if args.list {
functional_status(
"xtask/build",
"build_list",
true,
&format!("the products with `{flags}`"),
);
return Ok(());
}
let road = cargo_road(root)?;
let mut failed = Vec::new();
for p in holger_recipe::variants::PRODUCTS {
match assemble_one_tier_in(&road, &featured, p, root) {
Ok(true) => {}
Ok(false) => failed.push(p.to_string()),
Err(e) => {
eprintln!("✗ product '{p}' failed to assemble: {e:#}");
failed.push(p.to_string());
}
}
}
functional_status(
"xtask/build",
"assemble_all",
failed.is_empty(),
&format!("the products with `{flags}`; failed: {failed:?}"),
);
anyhow::ensure!(
failed.is_empty(),
"build --features {}: product(s) {} did not succeed",
args.cargo.features.join(","),
failed.join(", ")
);
println!("\n=== build: the four products with `{flags}` assembled ===");
Ok(())
}
/// The body of [`run_build`]; the gate's phase 2 calls it once per delivery.
fn run_build_with(argv: &[String]) -> anyhow::Result<()> {
use nornir_build_thing::suite_cli;
// `--atom <x>` / `--atom=<x>` → `--variant <x>`, with a warning. THE WORD IS
// VARIANT (workspace law: variant -> features -> settings/sub-settings -> typ);
// "atom" is the old spelling this repo printed until 2026-09-20 and is kept only
// so a script written against it still runs. Everything else is handed to the
// shared parser untouched, so an unknown flag produces the shared error text
// rather than a holger-specific one.
let mut rewritten: Vec<String> = Vec::with_capacity(argv.len() + 2);
let mut it = argv.iter();
while let Some(a) = it.next() {
if a == "--atom" {
eprintln!(
"holger xtask build: `--atom` is the old name for `--variant`; use --variant"
);
rewritten.push("--variant".to_string());
if let Some(v) = it.next() {
rewritten.push(v.clone());
}
} else if let Some(v) = a.strip_prefix("--atom=") {
eprintln!(
"holger xtask build: `--atom=` is the old name for `--variant=`; use --variant"
);
rewritten.push(format!("--variant={v}"));
} else if a == "--all" {
// `--all` used to mean "the three tiers". It now means "every variant of
// the delivery", which is what omitting --variant already does — so it is
// a no-op that says so rather than being silently ignored.
eprintln!(
"holger xtask build: `--all` is implied — omitting --variant builds every \
variant of the delivery (which is now all of them, not three)"
);
} else {
rewritten.push(a.clone());
}
}
let args = suite_cli::parse(&rewritten)?;
let root = workspace_root();
// THE PRODUCTS WITH EXTRAS (HOL-PRODUCTS): `--features <f>` with no `--variant` goes to
// the four products only (`--suite MVP --features full`: every product with everything).
// The estate's rows, the media and the wasm guests are declared builds, never re-featured.
if !args.cargo.is_empty() && args.atom.is_none() {
return run_products_with(&root, &args);
}
// DESCRIBE: the shared resolver prints it, so every repo's `--list` reads alike.
if args.list {
// The OPEN load (`holger_recipe::load`): the sold row's commercial edge
// (`plugin → monetize-impl/holger-guest`) is lazy, so the open tree lists
// without a monetize-impl checkout. `--build`/`--param` keep the shared
// door's own refusals.
let names = if args.builds.is_empty() && args.params.is_empty() {
let (lines, names) = holger_recipe::load::list(&root, &args)?;
for line in lines {
println!("{line}");
}
names
} else {
suite_cli::run(&root, &args)?
};
functional_status(
"xtask/build",
"build_list",
true,
&format!(
"{} variant(s) resolved ({})",
names.len(),
names.join(" · ")
),
);
return Ok(());
}
// PRESS: the SHARED resolver decides WHICH variants; holger's attesting seam does the
// building. `suite_cli::resolve` errors on an unknown suite/variant and on a delivery
// that resolves to zero variants, so an empty run cannot reach the loop below.
let set = holger_build_space::build_variant_set()?;
let (suite, chosen) = suite_cli::resolve(&set, &args)?;
let names: Vec<String> = chosen.iter().map(|v| v.name.clone()).collect();
// The build ENVIRONMENT, resolved and entered ONCE before the first variant is
// touched: a box that cannot enter it must hear so by name here, not eight
// variants in. See `cargo_road` for the host-cargo defect this closes.
// The SOLD variant consumes the commercial monetize-impl guest: refused by name
// — and only when it is built — if that checkout is absent. Before the road, so
// the refusal is the answer, not a container engine the open tree never needed.
let mut failed: Vec<String> = Vec::new();
let mut refusals: Vec<String> = Vec::new();
let chosen: Vec<_> = chosen
.into_iter()
.filter(|v| {
match holger_recipe::load::refuse_absent_commercial_donor(&set, &v.name, &root) {
Ok(()) => true,
Err(e) => {
eprintln!("✗ {e:#}");
functional_status("xtask/build", "assemble_variant", false, &format!("{e:#}"));
refusals.push(format!("{e:#}"));
failed.push(v.name.clone());
false
}
}
})
.collect();
if chosen.is_empty() && !refusals.is_empty() {
anyhow::bail!("{}", refusals.join("\n"));
}
let road = cargo_road(&root)?;
// Non-cargo kinds are reported and skipped, never counted as built.
let mut built: Vec<String> = Vec::new();
let mut skipped: Vec<String> = Vec::new();
for v in &chosen {
if !v.kind.is_cargo() {
skipped.push(format!(
"{} ({}) — {}",
v.name,
v.kind.as_str(),
media_door(&v.name, v.kind)
));
continue;
}
// A failure does NOT short-circuit: a red `full` must not hide a green
// `embedded`. Sequential BY DESIGN — each variant shells its own cargo and cargo
// already owns the parallelism (LAW 3: no fan-out here).
match assemble_one_tier(&road, &v.name, &root) {
Ok(true) => built.push(v.name.clone()),
Ok(false) => failed.push(v.name.clone()),
Err(e) => {
// An assemble that ERRORED never reached the per-variant row, so emit its
// red row here — silence is not success.
eprintln!("✗ variant '{}' failed to assemble: {e:#}", v.name);
functional_status(
"xtask/build",
"assemble_variant",
false,
&format!("variant '{}' failed to assemble: {e:#}", v.name),
);
failed.push(v.name.clone());
}
}
}
if !skipped.is_empty() {
eprintln!("not cargo builds, skipped — each is named with the door that DOES build it:");
for line in &skipped {
eprintln!(" · {line}");
}
}
let ok = failed.is_empty() && !built.is_empty();
println!(
"\n=== build --suite {suite}: {}/{} variant(s) assembled ({}) ===",
built.len(),
names.len(),
names.join(" · ")
);
functional_status(
"xtask/build",
"assemble_all",
ok,
&format!(
"{}/{} variants of '{suite}' assembled ({}){}",
built.len(),
names.len(),
names.join(" · "),
if failed.is_empty() {
String::new()
} else {
format!("; failed: {}", failed.join(", "))
}
),
);
if !failed.is_empty() {
anyhow::bail!(
"build --suite {suite}: variant(s) {} did not succeed",
failed.join(", ")
);
}
// Every variant of the delivery was a non-cargo kind ⇒ nothing was built. That is not
// a success, and reporting it as one is the exact failure this pass is about.
if built.is_empty() {
anyhow::bail!(
"build --suite {suite}: no cargo-buildable variant — all {} are media rows, and this \
verb shells cargo. Nothing was built; that is not a green. Use the door each row \
names:\n {}",
names.len(),
skipped.join("\n ")
);
}
Ok(())
}
/// **The door that DOES build a non-cargo variant, named.**
///
/// The `build` verb shells cargo, so a `container` / `installer` / `iso` row asked
/// of it can only be skipped. Skipping it in silence — or with a generic "use the
/// image/vm/iso builders", which is what stood here — sends the reader looking for
/// a verb by guesswork. holger's media rows have exactly three doors and each one
/// is a `cargo xtask` verb in this binary, so the refusal can simply say which.
///
/// Keyed on the KIND, with the row's name carried into the command line, so a
/// second iso or a second installer row needs no change here.
fn media_door(name: &str, kind: nornir_build_thing::variant::ArtifactKind) -> String {
use nornir_build_thing::variant::ArtifactKind;
match kind {
ArtifactKind::Iso => format!(
"built by `cargo xtask appliance-iso --variant {name} --kernel <bzImage>` \
(the LIVE medium: holger IS PID 1, nothing is written to a disk)"
),
ArtifactKind::Installer => format!(
"built by `cargo xtask installer-iso --variant {name} --kernel <bzImage>` \
(the medium that LAYS an appliance onto a disk — the estate's re-image door)"
),
ArtifactKind::Container => format!(
"built by `cargo xtask appliance-pack` + a container engine over the \
[[build.container]] cell '{name}'"
),
other => format!("kind '{}' has no door in this xtask", String::from(other)),
}
}
/// **Every verb this xtask has**, with one line of help. Dispatch reads this
/// table; an unknown verb (a typo, a retired verb) prints it and exits 2.
const VERBS: &[(&str, &str)] = &[
("fmt", "rustfmt over the whole tree (every .rs file git tracks, every workspace, generated proto code left alone): --check (default) lists the files that differ and exits 1, --write formats them"),
("k8s", "the Kubernetes flavour: image (holger and the scan-worker sidecar, static musl, FROM scratch, tagged holger.rs/nordisk/…), chart (helm lint + template, the pod checked), test (the pod played by podman: /readyz follows the sidecar; a local Holger serves its own image to podman pull), publish (the release's pushes to holger.rs, printed)"),
("sigstore-trust", "the release's Sigstore trust root: stage [--from <trusted_root.json>] [--out <dir>] [--signer-dir <dir>] [--valid-days N] (the pinned public-good root, fetched by its TUF digest, signed with the release trust identities into .sandbox-out/, beside the sandbox; HOL-OCI-EVIDENCE)"),
("scan-worker", "the scan sandbox's worker image: image [--bin <path>] (mint it, FROM scratch), save [--out <dir>] (an OCI archive + sha256 for the airgap), stage [--out <dir>] (the sandbox entries a main/twin medium carries: the worker rootfs, crun, ClamAV, the manifest), tests (the container arms)"),
("fast", "the fast test: Holger's box rows built, its container media, and monetize-fast's run of the estate in rootless containers (--out, --budget-s, --no-build); target/fast/receipt.txt"),
("ci", "the CI plan: lockcheck, the default tests (--quick); + lone_clone, pairing, fast, e2e, the suites, suite-check, MVP rows, sandbox, twin (full); + gate, bench (--nightly); one JSON receipt"),
("test", "the wasm guests, then `cargo test --workspace` (default, then --features metered,holger-server-lib/front); extra args go to cargo test"),
("build", "list or build declared variants: build --suite MVP [--variant <v>] [--list] [--features <f>] (`--features full` without `--variant`: the four products with everything)"),
("build-wasm-plugins", "build the declared wasm guest rows in the toolchain container (--list shows them)"),
("gate", "rules, rows, tests, bench drivers and rescue arms (--rules, --arms, --rows-check, --no-rows, --no-tests, --no-bench, --no-arms)"),
("rows-check", "alias of `gate --rows-check`: cargo check every declared cargo row"),
("bench", "measure through `nornir bench run holger` and prove the row landed; --local: every arm here, receipt + table + baseline check"),
("bench-landed", "the guard: the newest bench receipt has a warehouse row"),
("bench-readme", "the README's speed table from holperf on REAL packages: fetch --seeds <dir> (the real clients fill the sets of holperf/sets/), run --seeds <dir> --machine <name> [--holperf <bin>] (one result file under holperf/results/), write, check, compare [--threshold <pct>]"),
("siblings", "switch the estate's sibling patches on: .cargo/estate-siblings.toml to the uncommitted .cargo/siblings.toml (needs ../edda, ../Skidbladnir, …)"),
("twin", "each product (holger, holger-downstream, holger-cli; holger-ui when ../holger-ui is beside) and its `cargo install` line, both in the pinned image, compared byte for byte (--row <product>)"),
("lone-clone", "a clone of holger ALONE: cargo build --locked, cargo install --locked of every product here (holger, holger-downstream, holger-cli), boot, /healthz ok (`--stage` packages the unpublished crates from the siblings)"),
("free-tree", "open Holger links no paid crate: Cargo.lock, and the server's default and metered trees, name nothing from monetize-impl"),
("estate-media", "Holger's release media and live apps for the ONE box"),
("installtest", "the DEV main medium installed in KVM, its laid disk booted, cargo/pip/npm pushed and pulled; RED on any miss"),
("downstream-media", "a downstream's medium (holger-downstream-installer) with its declaration: --name --upstream --upstream-key --via front|wireguard --mirror [--ca] [--tls-name] --bearer-file --out"),
("downstream-oneway-proof", "the ONE-WAY downstream appliance proven in KVM: its medium composed with the fixture's trust, laid, booted with one restricted NIC, the admin's first-import grant, a HOLGERINBOX stick plugged in, the bundle imported and served to pip, the clean stop: --fixture --work --door [--net] [--iso] [--compose-only] [--mem-mb] [--install-min]"),
("downstream-vm", "a downstream's medium laid in KVM once, booted with one user-mode NIC, its door on 127.0.0.1:<door>; prints UP and stays up: --iso --work --door [--mem-mb] [--install-min]"),
("installer-iso", "compose and master the per-site installer ISO"),
("appliance-iso", "master the live appliance medium from the declared iso row"),
("appliance-pack", "pack a built server binary into the appliance app-.znippy"),
("release-attest", "the release statement over every shipped artifact (media, app archives, binaries), unsigned into target/release-attest/<release>/ (--release --commit --iso-out --out --to; --check <statement.json> before signing)"),
("gen-proto", "regenerate the committed proto Rust from proto/holger.proto"),
("products", "the README's guide \"Three products by hand\", run as written: the four products built from their crates, server + console + downstream (online), pip through the downstream, the signed bundle verified and imported on an airgapped downstream (--no-console skips the console bundle); target/products/receipt.json"),
("e2e", "the H6 end-to-end gate: a fake internet → upstream (pull, scan, two-person approval, signed sync) → USB → downstream → real pip, uv, cargo, mvn, skopeo, go, and an invalidation back; in the clients image with --network none (e2e [build|run] [--out DIR] [--image REF] [--host-target DIR]); target/e2e/receipt.json"),
("demo", "the 1.0 demo: demo airgap (online intake → signed export → offline secure side → pip install; a receipt) | demo tests (the real-pip and airgap tests)"),
];
fn usage() -> String {
let mut s = String::from("usage: cargo xtask <verb> [args]\n\nverbs:\n");
for (verb, help) in VERBS {
s.push_str(&format!(" {verb:<20} {help}\n"));
}
s
}
/// Print the verdict of a verb, emit its functional row and exit non-zero on red.
fn finish(name: &str, component: &str, check: &str, ok_detail: &str, result: anyhow::Result<()>) {
match result {
Ok(()) => functional_status(component, check, true, ok_detail),
Err(e) => {
eprintln!("\n✗ {name} failed: {e:#}");
functional_status(component, check, false, &format!("{e:#}"));
std::process::exit(1);
}
}
}
/// The `--features` of `cargo xtask test`'s metered run.
pub const METERED_SUITE_FEATURES: &str = "metered,holger-server-lib/front";
/// **`cargo xtask test`** — the everyday suite, with no manual step before it.
///
/// 1. Every declared wasm guest row is built with host cargo
/// (`traits::test_support::wasm_guest`: `cargo build --release --target
/// wasm32-unknown-unknown` into `<target>/wasm-guests`), the same build and
/// the same directory the guards use, so they find the modules warm. No
/// container and no podman socket.
/// 2. `cargo test --workspace --no-fail-fast`, then the same with
/// `--features metered,holger-server-lib/front` (the paid box as it ships, its page
/// included). Both always run; the verb is red if either is.
fn run_tests() -> anyhow::Result<()> {
let root = workspace_root();
let extra: Vec<String> = std::env::args().skip(2).collect();
let cargo = std::env::var_os("CARGO").unwrap_or_else(|| "cargo".into());
println!("=== wasm guests (host cargo, wasm32-unknown-unknown) ===");
for (row, pkg) in wasm_plugins::wasm_rows() {
let module = traits::test_support::wasm_guest(&pkg);
println!(" {row:<22} {}", module.display());
}
let mut red = Vec::new();
// The metered run is the paid box as it ships: `mvp-server-metered` names `front` (its
// public page), which left server-lib's `default` (A28 M14), so it is named here.
for (label, features) in [("default", None), ("metered", Some(METERED_SUITE_FEATURES))] {
let mut args: Vec<String> = ["test", "--workspace", "--no-fail-fast"]
.map(String::from)
.to_vec();
if let Some(f) = features {
args.extend(["--features".to_string(), f.to_string()]);
}
args.extend(extra.iter().cloned());
println!("\n=== cargo {} ===", args.join(" "));
let t0 = std::time::Instant::now();
let status = Command::new(&cargo)
.args(&args)
.current_dir(&root)
.status()?;
println!(
"=== {label}: {} in {:.0} s ===",
if status.success() { "green" } else { "RED" },
t0.elapsed().as_secs_f64()
);
if !status.success() {
red.push(label);
}
}
// The `estate/` workspace (H1): xtask, the build declaration, holger-fleet and
// holger-live. The root `--workspace` above does not reach it. estate-tests (the
// real ONE box) is the gate's (`cargo xtask gate`).
let mut args: Vec<String> = [
"test",
"--manifest-path",
"estate/Cargo.toml",
"--workspace",
"--exclude",
"holger-estate-tests",
"--no-fail-fast",
]
.map(String::from)
.to_vec();
args.extend(extra.iter().cloned());
println!("\n=== cargo {} ===", args.join(" "));
let t0 = std::time::Instant::now();
let status = Command::new(&cargo)
.args(&args)
.current_dir(&root)
.status()?;
println!(
"=== estate: {} in {:.0} s ===",
if status.success() { "green" } else { "RED" },
t0.elapsed().as_secs_f64()
);
if !status.success() {
red.push("estate");
}
anyhow::ensure!(red.is_empty(), "red suite(s): {}", red.join(", "));
Ok(())
}
fn main() {
let verb = std::env::args().nth(1).unwrap_or_default();
// The estate's sibling patches (2026-10-22, the lone clone): every `cargo xtask`
// in a checkout with the siblings beside it refreshes `.cargo/siblings.toml`, so
// the Build Thing, the installtest and the gate build what they built before the
// split. A lone clone has no siblings and gets none.
match siblings::refresh(&workspace_root()) {
Ok(siblings::Refresh::Written) => eprintln!("xtask: .cargo/siblings.toml written from .cargo/estate-siblings.toml (the sibling patches are ON)"),
Ok(_) => {}
Err(e) => eprintln!("xtask: could not refresh .cargo/siblings.toml: {e}"),
}
let has = |flag: &str| std::env::args().skip(2).any(|a| a == flag);
match verb.as_str() {
"ci" => {
let rest: Vec<String> = std::env::args().skip(2).collect();
std::process::exit(ci::run(&workspace_root(), &rest));
}
"fmt" => {
let rest: Vec<String> = std::env::args().skip(2).collect();
std::process::exit(fmt::run(&workspace_root(), &rest));
}
"fast" => {
let rest: Vec<String> = std::env::args().skip(2).collect();
finish("fast", "xtask/fast", "fast_test", "the fast test is green (target/fast/receipt.txt)", fast::run(&workspace_root(), &rest));
}
"test" => finish("test", "xtask/test", "workspace_tests", "default and metered suites green", run_tests()),
// `build` emits its own rows (per variant, and `build_list`); only a red is added here.
"build" => {
if let Err(e) = run_build() {
eprintln!("\n✗ build failed: {e:#}");
functional_status("xtask/build", "build_verb", false, &format!("{e:#}"));
std::process::exit(1);
}
}
"twin" => {
let rest: Vec<String> = std::env::args().skip(2).collect();
match twin::run(&workspace_root(), &rest) {
Ok(true) => functional_status("xtask/twin", "rows_equal_cargo_install", true, "every product row is its cargo install, byte for byte"),
Ok(false) => {
functional_status("xtask/twin", "rows_equal_cargo_install", false, "a row and its cargo install differ (named above)");
std::process::exit(1);
}
Err(e) => {
eprintln!("\n✗ twin: {e:#}");
functional_status("xtask/twin", "rows_equal_cargo_install", false, &format!("{e:#}"));
std::process::exit(1);
}
}
}
"build-wasm-plugins" if has("--list") => wasm_plugins::list(),
"build-wasm-plugins" => finish(
"build-wasm-plugins",
"xtask/build-wasm-plugins",
"wasm_plugin_build",
"every declared wasm package handler produced a non-empty module",
wasm_plugins::run(),
),
// `rows-check` stays as an alias: HOLGER-PLAN and the workspace plan name it.
"rows-check" => finish(
"rows-check",
"xtask/gate",
"rows-check",
"every declared cargo row compiles under its own features",
gate::rows_check(),
),
"gate" if has("--rows-check") => finish(
"gate --rows-check",
"xtask/gate",
"rows-check",
"every declared cargo row compiles under its own features",
gate::rows_check(),
),
"gate" => finish(
"gate",
"xtask/gate",
"gate",
"rules + shipped rows + suites + published bench drivers + every declared rescue arm RUN",
gate::run(),
),
// Answered by the launcher (`xtask/boot`) before this binary is built; here
// for `cargo run -p xtask -- siblings`, which refreshed above already.
"siblings" => match siblings::refresh(&workspace_root()) {
Ok(siblings::Refresh::Lone(missing)) => {
eprintln!("siblings: ../{missing} is not checked out; the sibling patches stay OFF");
std::process::exit(1);
}
Ok(_) => println!("siblings: {} is current (the sibling patches are ON)", siblings::COPY),
Err(e) => {
eprintln!("siblings: {e}");
std::process::exit(1);
}
},
"lone-clone" => match lone_clone::lone_clone(&workspace_root(), has("--stage")) {
lone_clone::LoneClone::Passed => functional_status(
"xtask/lone-clone",
"lone_clone",
true,
"a lone clone built and installed with plain cargo (--locked) and answered /healthz ok",
),
lone_clone::LoneClone::Failed(why) => {
eprintln!("\n✗ lone-clone: {why}");
functional_status("xtask/lone-clone", "lone_clone", false, &why);
std::process::exit(1);
}
},
"suite-check" if has("--list") => {
if let Err(e) = suite_check::list(&workspace_root()) {
eprintln!("suite-check: {e:#}");
std::process::exit(1);
}
}
"suite-check" => finish(
"suite-check",
"xtask/suite-check",
"mvp_suite_checked",
"every MVP row compiles, the MVP server rows' unit tests (paired.rs) pass, paired/appliance/secure_update build, holger-estate-front's suite and the sign-gated tests pass",
suite_check::run(&workspace_root()),
),
"free-tree" => finish(
"free-tree",
"xtask/free-tree",
"free_tree",
"open Holger (lock, default and metered server) links no paid monetize-impl crate",
paid_guard::run(&workspace_root(), &std::env::var("CARGO").unwrap_or_else(|_| "cargo".into())),
),
"estate-media" => finish(
"estate-media",
"xtask/estate-media",
"release_media",
"the Holger release media, live apps and receipt",
estate_media::run(),
),
"installtest" => finish(
"installtest",
"xtask/installtest",
"installed_main_serves",
"the DEV main medium installed in KVM, booted from its laid disk, cargo, pip and npm pushed and pulled back",
installtest::run(),
),
"downstream-media" => finish("downstream-media", "xtask/downstream-media", "downstream_medium_composed", "a downstream's medium composed with its declaration", downstream::run_media()),
"downstream-oneway-proof" => finish("downstream-oneway-proof", "xtask/downstream-oneway-proof", "downstream_oneway_proven", "the one-way downstream appliance booted without pairing, imported a stick's bundle and served pip", downstream::run_oneway_proof()),
"downstream-vm" => finish("downstream-vm", "xtask/downstream-vm", "downstream_vm_served", "a downstream VM served its door until it was stopped", downstream::run_vm()),
"installer-iso" => finish(
"installer-iso",
"xtask/installer-iso",
"installer_iso_mastered",
"per-site installer ISO composed + mastered through the shared seam",
installer_iso::run(),
),
"appliance-iso" => finish(
"appliance-iso",
"xtask/appliance-iso",
"appliance_iso_mastered",
"live appliance medium composed + mastered from the declared iso row",
appliance_iso::run(),
),
"release-attest" => finish(
"release-attest",
"xtask/release-attest",
"release_statement_complete",
"the release statement names every shipped artifact",
release_attest::run(&workspace_root(), &std::env::args().skip(2).collect::<Vec<_>>()),
),
"appliance-pack" => finish(
"appliance-pack",
"xtask/appliance-pack",
"app_znippy_packed",
"archive written, pin written, entry read back byte-identical",
appliance_pack::run(),
),
"demo" => run_demo(),
"k8s" => {
let rest: Vec<String> = std::env::args().skip(2).collect();
finish("k8s", "xtask/k8s", "k8s_flavour", "the Kubernetes flavour verb is green", k8s::main(&workspace_root(), &rest))
}
"e2e" => {
let args: Vec<String> = std::env::args().skip(2).collect();
let a = e2e::parse(&args).unwrap_or_else(|e| {
eprintln!("xtask e2e: {e}");
std::process::exit(2);
});
finish("e2e", "xtask/e2e", "e2e_gate", "internet → upstream → USB → downstream → every build system, and the invalidation back", e2e::run(&workspace_root(), &a))
}
"products" => {
let rest: Vec<String> = std::env::args().skip(2).collect();
finish("products", "xtask/products", "three_products_by_hand", "the README's guide ran to its end: server, console, downstream online, pip through it, and the airgap bundle", products::main(&workspace_root(), &rest))
}
"scan-worker" => {
let rest: Vec<String> = std::env::args().skip(2).collect();
finish("scan-worker", "xtask/scan-worker", "scan_worker", "the scan sandbox verb is green", scan_worker::main(&workspace_root(), &rest))
}
"sigstore-trust" => {
let rest: Vec<String> = std::env::args().skip(2).collect();
finish("sigstore-trust", "xtask/sigstore-trust", "sigstore_trust_stage", "the release's Sigstore trust root is staged, signed and pinned", sigstore_trust::run(&workspace_root(), &rest))
}
"bench-readme" => {
let rest: Vec<String> = std::env::args().skip(2).collect();
// the checkout it is run in (a built xtask runs on the host for `fetch`, whose
// clients are the host's), else the one it was built from
let root = std::env::current_dir()
.ok()
.filter(|d| d.join("holperf/sets").is_dir())
.unwrap_or_else(workspace_root);
std::process::exit(bench_readme::main(&root, &rest));
}
"bench" => run_bench(),
"bench-landed" => run_bench_landed(),
"gen-proto" => match gen_proto::run() {
Ok(path) => {
println!("\n✅ proto codegen done → {}", path.display());
functional_status("xtask/gen-proto", "proto_codegen", true, &format!("protox+tonic-build → {}", path.display()));
}
Err(e) => {
eprintln!("\n✗ gen-proto failed: {e:#}");
std::process::exit(1);
}
},
"" | "help" | "--help" | "-h" => {
print!("{}", usage());
if verb.is_empty() {
std::process::exit(2);
}
}
other => {
eprintln!("cargo xtask: unknown verb `{other}`\n\n{}", usage());
std::process::exit(2);
}
}
}
/// `demo` — the 1.0 demo ([`demo`]). Green only when every receipt check passed;
/// a NOT YET check is INCOMPLETE (exit 2), never green.
fn run_demo() {
let args: Vec<String> = std::env::args().skip(2).collect();
let a = demo::parse(&args).unwrap_or_else(|e| {
eprintln!("xtask demo: {e}");
std::process::exit(2);
});
let root = workspace_root();
match a.sub {
demo::Sub::Tests => finish(
"demo tests",
"xtask/demo",
"demo_tests",
"intake_serves_pip (real pip) and airgap_export_import green",
demo::tests(&root),
),
demo::Sub::Airgap => match demo::airgap(&root, &a) {
Ok(demo::Verdict::Pass { passed }) => {
println!("\n✅ demo airgap: every check passed ({passed})");
functional_status(
"xtask/demo",
"demo_airgap",
true,
&format!("{passed} checks passed"),
);
}
Ok(demo::Verdict::Incomplete { passed, pending }) => {
eprintln!("\n◐ demo airgap INCOMPLETE: {passed} checks passed, not yet landed:");
for p in &pending {
eprintln!(" {p}");
}
functional_status(
"xtask/demo",
"demo_airgap",
false,
&format!("incomplete: {}", pending.join("; ")),
);
std::process::exit(2);
}
Ok(demo::Verdict::Fail { failed }) => {
eprintln!("\n✗ demo airgap failed: {}", failed.join("; "));
functional_status("xtask/demo", "demo_airgap", false, &failed.join("; "));
std::process::exit(1);
}
Err(e) => {
eprintln!("\n✗ demo airgap: {e:#}");
functional_status("xtask/demo", "demo_airgap", false, &format!("{e:#}"));
std::process::exit(1);
}
},
}
}
/// `bench` — measure holger THROUGH the door that persists. The verb owns no
/// arm, no scale and no feature — those are the example's and the harness's.
/// It owns the config path, the environment passthrough and the proof that a
/// row landed. See [`bench`].
fn run_bench() {
let args: Vec<String> = std::env::args().skip(2).collect();
if args.iter().any(|a| a == "--local") {
let parsed = benchlocal::parse_args(&args).unwrap_or_else(|e| {
eprintln!("xtask bench: {e}");
std::process::exit(2);
});
match benchlocal::run(&workspace_root(), &parsed) {
Ok(true) => functional_status(
"xtask/bench",
"bench_local_green",
true,
"every arm ran; no tracked metric regressed past the baseline threshold",
),
Ok(false) => {
functional_status(
"xtask/bench",
"bench_local_green",
false,
"a tracked metric regressed past the baseline threshold",
);
eprintln!("\n✗ bench --local: REGRESSION (see bench-results/latest.txt)");
std::process::exit(1);
}
Err(e) => {
eprintln!("\n✗ bench --local: {e}");
functional_status("xtask/bench", "bench_local_green", false, &e);
std::process::exit(1);
}
}
return;
}
let parsed = bench::parse_args(&args).unwrap_or_else(|e| {
eprintln!("xtask bench: {e}");
std::process::exit(2);
});
match bench::run(&workspace_root(), &parsed) {
Ok(()) => functional_status(
"xtask/bench",
"bench_row_landed",
true,
"nornir bench run holger persisted a NEW bench_runs row",
),
Err(e) => {
eprintln!("\n✗ bench: {e}");
functional_status("xtask/bench", "bench_row_landed", false, &e);
std::process::exit(1);
}
}
}
/// `bench-landed` — the guard the 2026-08-12 gunnar incident produced: one
/// BenchRun is written twice (iceberg row + `bench_history.jsonl` receipt)
/// and two writes of one value can only stay honest if something checks.
fn run_bench_landed() {
let root = workspace_root();
let config =
bench::resolve_config(&root, std::env::args().nth(2).as_deref()).unwrap_or_else(|e| {
eprintln!("bench-landed: {e}");
std::process::exit(2);
});
// The receipt lives in the checkout nornir.toml NAMES, which is not
// necessarily this worktree: `nornir bench run` resolves the repo by name.
let measured = bench::measured_root(&config).unwrap_or_else(|e| {
eprintln!("bench-landed: {e}");
std::process::exit(2);
});
eprintln!(
"bench-landed: receipt {}/{} · warehouse per {}",
measured.display(),
benchland::RECEIPT,
config.display()
);
match benchland::run(&measured, &config) {
Ok(l) => {
eprintln!("bench-landed: {}", l.summary());
let red = l.is_red();
functional_status("xtask/bench", "bench_landed_guard", !red, &l.summary());
if red {
eprintln!(
"bench-landed: RED. Re-run through the door that writes BOTH:\n \
cargo xtask bench (or: nornir bench run holger --config {})",
config.display()
);
std::process::exit(1);
}
}
Err(e) => {
eprintln!("bench-landed: {e}");
functional_status("xtask/bench", "bench_landed_guard", false, &e);
std::process::exit(1);
}
}
}