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

nordisk/edda

crates/nornir-build-thing/src/suite_cli.rs

//! **The ONE way to build a suite member** — `cargo xtask build --suite <s> [--variant <v>]`.
//!
//! (`--atom` is the deprecated spelling of `--variant` and is accepted forever —
//! the written laws cite it and muscle memory is not to be broken.)
//!
//! # Why this lives here and not in each repo's xtask
//!
//! Every member repo grew its own build tooling next to its declared build space,
//! and the two drifted. Measured 2026-08-01 across the constellation: `holger-build`
//! hardcodes three tier names and cannot see the other ten variants on disk;
//! `nornir-buildspec-holger` re-declares holger's variants in Rust (8 in code vs 13
//! in the TOML, and the Rust marks NO default at all while the TOML does);
//! `dwarves/src/service.rs` hand-writes `cargo build -p dwarves --bin dwarves-full
//! --features embed-nornir,server` while the declaration for that same binary says
//! `features = ["embed-all", "read-fat"]`; `korp/src/service.rs` does the same for
//! `korp-server` with a third feature set. Four hand-rolled build paths, four
//! different answers to "what is this binary".
//!
//! The fix is not a better copy. It is that there is ONE function, here, that turns
//! `(suite, atom)` into a cargo invocation by READING `.nornir/build-variants.toml`,
//! and every xtask in the house is three lines that call it.
//!
//! # Why it delegates to this crate rather than to dwarves
//!
//! dwarves is the FORGE that drives builds, and the obvious phrasing is "xtask calls
//! dwarves". It cannot: dwarves is the downstream-most member, it path-deps nornir,
//! and `nornir/tests/no_dwarves_edge.rs` exists specifically to keep nornir from
//! depending on it. An `xtask -> dwarves` edge in nornir (or in korp, which nornir's
//! graph also constrains) inverts the suite dep graph — the very rule
//! [`BuildVariantSet::validate_shape`](crate::variant::BuildVariantSet::validate_shape)
//! enforces on artifacts. So the shared code sits in `nornir-build-thing`, the
//! dep-light leaf BOTH dwarves and every member already depend on, and dwarves keeps
//! being the forge that CALLS it. One writer either way; this one is legal.
//!
//! # The suite is a PARAMETER
//!
//! `--suite` is not a flag some repos take and others reject. Every member tags its
//! atoms `suites = ["ORIGINAL"]` even though it ships one delivery, so
//! `cargo xtask build --suite ORIGINAL` works in korp, dwarves, nornir, modgunn and
//! holger alike, and holger's second delivery is `--suite MVP` with no new flag, no
//! new verb and no tooling that learns a special case. Adding a second delivery to
//! any of the others later is a DECLARATION change and nothing else.
//!
//! An unknown suite is a hard error that lists the declared ones. A selector that
//! quietly builds everything (or nothing) when it does not recognise its argument is
//! decorative, and decorative selectors are how a "we build the MVP nightly" claim
//! stays green while building the full product.

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

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

use crate::variant::{BuildVariant, BuildVariantSet, UNSUITED};

/// The parsed `build` verb.
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct BuildArgs {
    /// `--suite <name>`. `None` means the repo's single delivery, and is an ERROR
    /// the moment a repo declares more than one — see [`resolve`].
    pub suite: Option<String>,
    /// `--variant <name>` (deprecated alias: `--atom`). `None` builds every
    /// cargo-buildable variant of the suite.
    ///
    /// The FIELD keeps its legacy name on purpose: downstream constructs
    /// `BuildArgs { atom: … }` directly (nornir's bin, dwarves' forge), and the
    /// vocabulary fix is a CLI-surface rename, not an API break.
    pub atom: Option<String>,
    /// `--list` — resolve and print, build nothing. The guard tests use this to
    /// assert WHICH variants a suite selects without paying for a release link.
    pub list: bool,
    /// `--attest` — build the delivery so its receipt can be PROVEN.
    ///
    /// See [`attest_atom`]. Off by default: a developer's `xtask build` should
    /// not pay for a stripper and an attestation file, and a delivery should not
    /// be able to go out without one.
    pub attest: bool,
    /// Repeatable `--param name=value` — install-time inputs for iso/installer
    /// cells (see [`crate::params`]): kept RAW here (unparsed pairs) so the
    /// refusals — unknown name, secret-shaped name, wrong shape — come from
    /// the ONE validation path (`apply_cli_params`) at the point of use, next
    /// to the cell whose declaration they are checked against.
    pub params: Vec<String>,
    /// Repeatable `--opt name=on|off` — the OPT-OUT toggles an iso/installer
    /// variant DECLARES (see [`crate::options`]). Kept RAW here for the same
    /// reason `params` is: the refusals — an undeclared name, a spelling that
    /// is neither on nor off — come from the ONE resolution path, next to the
    /// declaration they are checked against.
    pub opts: Vec<String>,
    /// Repeatable `--build <path|coordinate>` — build the consumed build thing
    /// behind an EDGE of the variant's tree as a step of this build
    /// ([`crate::flags::Flag::Build`]; law C renders and parses it). Kept RAW
    /// like the others: resolving the target to an edge of the tree is the
    /// door's job — [`build_line`](BuildArgs::build_line) gives the three raw
    /// lists their ONE meaning ([`crate::build_dag::BuildLine`]), and
    /// [`BuildDag::derive`](crate::build_dag::BuildDag::derive) the ordered steps.
    /// A door that does not chain refuses the flag BY NAME with the DAG's own
    /// lines (the manual two-step, in the order the DAG would run it).
    pub builds: Vec<String>,
    /// `--features a,b` · `--no-default-features` · `--all-features` — the
    /// operator's cargo feature choice, applied on top of the chosen CARGO
    /// variant(s) and passed to cargo exactly as given
    /// ([`BuildVariant::with_cargo_features`]).
    pub cargo: crate::variant::CargoFeatures,
}

impl BuildArgs {
    /// **The `--build` line these arguments spell** — `opts`, `params` and
    /// `builds` folded into one canonical [`BuildLine`](crate::build_dag::BuildLine)
    /// (a `--build X { … }` typed on the prompt arrives in `builds` as one
    /// string and is parsed with its brace). Syntax only; resolving against the
    /// target variant's tree is [`BuildLine::canonical_in`](crate::build_dag::BuildLine::canonical_in).
    pub fn build_line(&self) -> Result<crate::build_dag::BuildLine> {
        crate::build_dag::BuildLine::from_args(&self.opts, &self.params, &self.builds)
    }
}

/// **The suite-level installer door (gap analysis item 19)** — the seam that
/// makes "master a per-site installer ISO" a SUITE capability instead of one
/// repo's xtask verb. nornir-build-thing owns the grammar (cell resolution,
/// `--param` refusals, provenance) but cannot own the COMPOSITION (korp-boot,
/// the PID-1s, the pinned kernel live in korp-installer, which depends on
/// this crate — the arrow points the other way), so the composition arrives
/// by injection: korp-installer's `ForgeComposer` implements this, and any
/// CLI (dwarves `buildthing`, a product xtask) passes it in.
pub trait InstallerComposer {
    /// **The fixtures this composition can mint** for a `--param name=@fixture`
    /// against the cell's declared `[build.installer.fixtures]`. Default: none
    /// — `@fixture` is then refused by name. The composition that lays a
    /// `hub.conf` onto P3 (korp-installer's `ForgeComposer`) is also the one
    /// that can mint the hub, so it overrides this; the seam is here rather
    /// than a crate feature because minting a WireGuard hub needs
    /// `wg-appliance-core`, which this dep-light crate does not pull.
    fn fixtures(&self) -> &dyn crate::params::FixtureSource {
        &crate::params::NoFixtures
    }

    /// Compose + master `cell` (params already applied) into an installer
    /// ISO. `kernel` is a real EFI-stub bzImage; `app` the product's packed
    /// `.znippy`. Returns the mastered ISO's path.
    fn compose_installer(
        &self,
        cell: &crate::installer::InstallerBuild,
        kernel: &Path,
        app: &Path,
        repo_root: &Path,
        repo_label: &str,
    ) -> Result<std::path::PathBuf>;
}

/// Resolve an installer CELL, apply `--param` values through the ONE
/// validation path, and hand the composition to `composer`. The suite-CLI
/// twin of a product's `installer-iso` verb: same refusals, same provenance
/// (applied params ride the cell into the attested descriptor).
pub fn run_installer(
    repo_root: &Path,
    repo_label: &str,
    cell_name: Option<&str>,
    kernel: &Path,
    app: &Path,
    raw_params: &[String],
    composer: &dyn InstallerComposer,
) -> Result<std::path::PathBuf> {
    run_installer_applied(repo_root, repo_label, cell_name, kernel, app, raw_params, composer)
        .map(|(iso, _)| iso)
}

/// What one installer run applied: the parameter record and the OPTION record.
/// Both ride the cell into the attested descriptor; this only surfaces them so
/// a door can print them and a pane can show them in the receipt.
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct AppliedSelection {
    /// The parameter values, in declaration order.
    pub params: Vec<crate::params::AppliedParam>,
    /// The option states, in declaration order.
    pub options: Vec<crate::options::AppliedOption>,
}

impl AppliedSelection {
    /// The lines a door prints, options first — a toggle changes what the
    /// binary IS, so it is read before the values that configure it.
    pub fn describe(&self) -> Vec<String> {
        self.options
            .iter()
            .map(|o| format!("opt   {}", o.describe()))
            .chain(self.params.iter().map(|p| format!("param {}", p.describe())))
            .collect()
    }
}

/// [`run_installer`], also handing back the APPLIED parameter record — what
/// a door prints beside the ISO path and what the pane's result head shows
/// (`AppliedParam::describe`: a fixture-filled value says so). The record is
/// the same one the attested descriptor carries; this only surfaces it.
pub fn run_installer_applied(
    repo_root: &Path,
    repo_label: &str,
    cell_name: Option<&str>,
    kernel: &Path,
    app: &Path,
    raw_params: &[String],
    composer: &dyn InstallerComposer,
) -> Result<(std::path::PathBuf, Vec<crate::params::AppliedParam>)> {
    run_installer_selected(repo_root, repo_label, cell_name, kernel, app, raw_params, &[], composer)
        .map(|(iso, applied)| (iso, applied.params))
}

/// [`run_installer_applied`] with the OPTION toggles as well — the full door.
///
/// The toggles are resolved and the values applied in one step
/// (`InstallerBuild::apply_cli_selection_with`), because the toggles decide
/// which values are required and which are refused; see that method for why
/// the order cannot be the caller's choice.
pub fn run_installer_selected(
    repo_root: &Path,
    repo_label: &str,
    cell_name: Option<&str>,
    kernel: &Path,
    app: &Path,
    raw_params: &[String],
    raw_opts: &[String],
    composer: &dyn InstallerComposer,
) -> Result<(std::path::PathBuf, AppliedSelection)> {
    let set = BuildVariantSet::discover(repo_root)?.ok_or_else(|| {
        anyhow!(
            "no {} — this repo declares no build space",
            BuildVariantSet::conventional_path(repo_root).display()
        )
    })?;
    let mut cell = match cell_name {
        Some(name) => set
            .installers
            .iter()
            .find(|i| i.name == name)
            .cloned()
            .ok_or_else(|| {
                anyhow!(
                    "no [[build.installer]] cell named '{name}' (declared: {})",
                    set.installers.iter().map(|i| i.name.as_str()).collect::<Vec<_>>().join(", ")
                )
            })?,
        None => match set.installers.as_slice() {
            [one] => one.clone(),
            [] => bail!("this repo declares no [[build.installer]] cell"),
            many => bail!(
                "this repo declares {} installer cells — name one: {}",
                many.len(),
                many.iter().map(|i| i.name.as_str()).collect::<Vec<_>>().join(", ")
            ),
        },
    };
    let supplied = crate::params::parse_cli_params(raw_params)?;
    // **The TREE splits the `--opt` line, not `parse_cli_options`.** That
    // function's return type is `name → bool`, so it answered every `--opt`
    // with "an option is on or off" — and this door is the one an operator's
    // `--opt kernel.preset=nuked` actually reached on the ISO-compose path
    // (`assemble_cell::compose_installer_row` hands the composer the UNSPLIT
    // line, correctly: the kernel choice is judged upstream against the
    // DONOR's declaration, and this door must simply not choke on it).
    // gunnar's BUILD-KEYED-INSTALLER.md carried a "do NOT add --opt
    // kernel.preset=" warning for that sentence instead of a fix.
    //
    // The tree already knows what each path IS: `dhcp` a feature, `data.fs` a
    // val with two choices, `kernel.preset` a val behind an EDGE — and the
    // three buckets are exactly the three things this door does with them.
    let tree = crate::tree::SettingsTree::of_installer(&cell, None);
    let split = tree.split_opts(raw_opts).map_err(|e| anyhow!("installer '{}': {e:#}", cell.name))?;
    // A val that belongs to a DECLARED GROUP lands on the group, through the
    // one writer both doors call (`InstallerBuild::apply_group_choices`).
    cell.apply_group_choices(&split.choices)?;
    cell.apply_cli_selection_with(&split.features, &supplied, composer.fixtures())?;
    let iso = composer.compose_installer(&cell, kernel, app, repo_root, repo_label)?;
    Ok((
        iso,
        AppliedSelection { params: cell.applied_params, options: cell.applied_options },
    ))
}

/// The usage banner. One string, so every repo's `--help` says the same words.
pub const USAGE: &str = "\
cargo xtask build [--suite <name>] [--variant <name>] [--list] [--attest] [--param k=v]... [--opt name=on|off]... [--build <path|repo/variant>]... [--features a,b] [--no-default-features] [--all-features]

  --suite <name>   the delivery (utgåva) to build. Required once a repo declares
                   more than one. An unknown name is an error, never a no-op.
  --variant <name> one declared build row (of any kind: exe · iso · installer ·
                   container …) of that delivery. Omitted = all of them.
                   `--atom` is the deprecated old spelling and still works.
  --list           resolve and print the variants; build nothing.
  --attest         build with the symbol table kept, AUDIT the receipt against
                   it, strip the delivery out of the audited binary, and write
                   <artifact>.attestation.json beside it. Fails the build when a
                   receipt is disproven, and when it could not be measured.
  --param k=v      repeatable: an install-time input a [[build.iso]] /
                   [[build.installer]] cell DECLARES (a hub public key, a site
                   name; `@path` reads the value from a file; `@fixture` fills
                   it from the fixture the cell declares for that name, e.g.
                   `[build.installer.fixtures] hub_conf = \"wg-hub\"`). Only
                   non-secret values — a secret-shaped name is refused by name.
                   The applied values ride the attested descriptor (the
                   provenance), a fixture-filled one saying so.
  --opt name=on|off
                   repeatable: an OPT-OUT an [[build.iso]] / [[build.installer]]
                   variant DECLARES (`--opt wireguard=off`). OFF removes the
                   cargo feature the option names from the APP binary this
                   medium packs, so the code is NOT COMPILED IN — not disabled
                   at runtime — and the audit reads that back out of the symbol
                   table. A toggle also decides which --param values apply: with
                   DHCP off the static address is required, with WireGuard off a
                   supplied hub_conf is refused by name. Omitted = the recipe's
                   declared default, which for an opt-out is ON.
  --build <path|repo/variant>
                   repeatable: BUILD the build thing behind a consumption EDGE
                   of the variant's tree (`--build kernel`, `--build
                   tunnr/tunnr-kernel`) as a step of this build. A target that
                   is no edge of the tree is refused by name; a door that does
                   not chain yet refuses the flag by name and spells the
                   two-step.
  --features a,b   repeatable: cargo features to build the chosen cargo
                   variant(s) WITH, on top of the declared ones — passed to
                   cargo exactly as given, and named by the provenance
                   (`inputs.features`). An image/iso/installer row has none.
  --no-default-features / --all-features
                   passed to cargo exactly as given.

Reads .nornir/build-variants.toml. There is no other build path.";

/// Parse the argv AFTER the `build` verb.
///
/// Hand-rolled rather than clap: this crate is dep-light on purpose (it compiles to
/// the wasm plugin sandbox), and the grammar is three flags.
pub fn parse<S: AsRef<str>>(args: &[S]) -> Result<BuildArgs> {
    let mut out = BuildArgs::default();
    let mut it = args.iter().map(|s| s.as_ref());
    while let Some(a) = it.next() {
        match a {
            "--suite" => {
                out.suite = Some(
                    it.next()
                        .ok_or_else(|| anyhow!("--suite needs a name\n\n{USAGE}"))?
                        .to_string(),
                )
            }
            "--variant" => {
                out.atom = Some(
                    it.next()
                        .ok_or_else(|| anyhow!("--variant needs a name\n\n{USAGE}"))?
                        .to_string(),
                )
            }
            // Deprecated spelling of `--variant`. NEVER an error: the written laws
            // cite `--atom` and muscle memory is not to be broken — a one-line note
            // is the whole deprecation.
            "--atom" => {
                eprintln!("note: `--atom` is the deprecated spelling of `--variant`; both work");
                out.atom = Some(
                    it.next()
                        .ok_or_else(|| anyhow!("--atom needs a name\n\n{USAGE}"))?
                        .to_string(),
                )
            }
            "--list" => out.list = true,
            "--attest" => out.attest = true,
            "--param" => out.params.push(
                it.next()
                    .ok_or_else(|| anyhow!("--param needs name=value\n\n{USAGE}"))?
                    .to_string(),
            ),
            "--opt" => out.opts.push(
                it.next()
                    .ok_or_else(|| anyhow!("--opt needs name=on|off\n\n{USAGE}"))?
                    .to_string(),
            ),
            "--features" => out.cargo.add_features([it
                .next()
                .ok_or_else(|| anyhow!("--features needs a name or a comma list\n\n{USAGE}"))?]),
            "--no-default-features" => out.cargo.no_default_features = true,
            "--all-features" => out.cargo.all_features = true,
            "--build" => out.builds.push(
                it.next()
                    .ok_or_else(|| anyhow!("--build needs a path or a repo/variant coordinate\n\n{USAGE}"))?
                    .to_string(),
            ),
            "-h" | "--help" => bail!("{USAGE}"),
            other if other.starts_with("--suite=") => {
                out.suite = Some(other["--suite=".len()..].to_string())
            }
            other if other.starts_with("--variant=") => {
                out.atom = Some(other["--variant=".len()..].to_string())
            }
            other if other.starts_with("--atom=") => {
                eprintln!("note: `--atom=` is the deprecated spelling of `--variant=`; both work");
                out.atom = Some(other["--atom=".len()..].to_string())
            }
            other if other.starts_with("--param=") => {
                out.params.push(other["--param=".len()..].to_string())
            }
            other if other.starts_with("--opt=") => {
                out.opts.push(other["--opt=".len()..].to_string())
            }
            other if other.starts_with("--features=") => out.cargo.add_features([&other["--features=".len()..]]),
            other if other.starts_with("--build=") => {
                out.builds.push(other["--build=".len()..].to_string())
            }
            other => bail!("unknown argument '{other}'\n\n{USAGE}"),
        }
    }
    if out.suite.as_deref().map(str::trim) == Some("") {
        bail!("--suite was given an empty name\n\n{USAGE}");
    }
    Ok(out)
}

/// **Resolve `(suite, variant)` to the variants that will be built**, in declaration order.
///
/// Every failure mode is LOUD:
///
/// * an unknown `--suite` names the declared deliveries;
/// * an omitted `--suite` in a repo with two deliveries refuses rather than picking;
/// * an unknown `--variant`, or one that exists but ships in a DIFFERENT delivery,
///   names the variants the chosen delivery actually has;
/// * a suite that resolves to zero buildable variants is an error, not an empty success
///   — "built 0 things" and "built everything" must never look alike to a caller.
pub fn resolve<'a>(
    set: &'a BuildVariantSet,
    args: &BuildArgs,
) -> Result<(&'a str, Vec<&'a crate::variant::BuildVariant>)> {
    let declared: Vec<&str> = set.suites();
    let suite: &str = match args.suite.as_deref().map(str::trim) {
        Some(want) => {
            // A repo that declares NO suite still answers to the name of its single
            // unnamed delivery only through UNSUITED, which is angle-bracketed and
            // unspellable on a command line. So: if the repo declares nothing, any
            // --suite is wrong, and the message must say that rather than list "".
            if declared.is_empty() {
                bail!(
                    "--suite {want}: this repo declares no deliveries at all \
                     (.nornir/build-variants.toml has no `suites = [...]` on any variant), \
                     so there is nothing to select. Drop --suite, or tag the variants."
                );
            }
            *declared.iter().find(|d| **d == want).ok_or_else(|| {
                anyhow!(
                    "--suite {want}: no such delivery. Declared: {}",
                    declared.join(", ")
                )
            })?
        }
        None => match declared.len() {
            0 => UNSUITED,
            1 => declared[0],
            _ => bail!(
                "this repo ships {} deliveries ({}) — say which one with --suite",
                declared.len(),
                declared.join(", ")
            ),
        },
    };

    let in_suite = set.in_suite(suite);
    let chosen: Vec<&crate::variant::BuildVariant> = match args.atom.as_deref().map(str::trim) {
        Some(want) => {
            let hit = in_suite
                .iter()
                .find(|v| v.name == want)
                .copied()
                .ok_or_else(|| {
                    let elsewhere = set.get(want).is_some();
                    let names: Vec<&str> = in_suite.iter().map(|v| v.name.as_str()).collect();
                    if elsewhere {
                        anyhow!(
                            "--variant {want}: declared, but not in delivery '{suite}'. \
                         '{suite}' has: {}",
                            names.join(", ")
                        )
                    } else {
                        anyhow!(
                            "--variant {want}: no such variant. '{suite}' has: {}",
                            names.join(", ")
                        )
                    }
                })?;
            vec![hit]
        }
        None => in_suite,
    };

    if chosen.is_empty() {
        bail!("delivery '{suite}' resolves to NO variants — an empty build is not a green one");
    }
    Ok((suite, chosen))
}

/// Resolve, then actually build — the whole verb.
///
/// Non-cargo kinds (container / vm / iso) are reported and skipped: they are built
/// by the image/vm/iso builders, not by `cargo build`, and silently pretending to
/// have built one is the failure this crate exists to prevent. The returned list is
/// the variants that were BUILT, so a caller can assert on it.
/// **The `--list` rendering, as VALUES.** The lines [`run`]'s `--list` leg prints —
/// returned rather than written, so a door that is not a terminal can serve the same
/// answer.
///
/// It was `println!` inline until 2026-09-20, which made this describe verb reachable
/// only from a terminal. An MCP tool that called [`run`] to answer "what does
/// `mvp-server` resolve to" got ONE line back and wrote the other three onto its own
/// stdio transport — i.e. into the middle of the JSON-RPC stream. A renderer that can
/// only print is a renderer that can only be used by one door, and copying it into the
/// second door is how two spellings of one build start.
///
/// [`run`] still prints, line for line, so the CLI output is unchanged.
pub fn list_lines(suite: &str, chosen: &[&crate::variant::BuildVariant]) -> Vec<String> {
    // The MATERIALIZED cargo command is rendered for every atom, not just its name.
    //
    // This is the whole value of a describe verb. A row saying `mvp-server · server ·
    // service · holger-mvp` tells you an atom exists; it does not tell you what will
    // be compiled, and "what features does this artifact actually get" is precisely
    // the question every hand-rolled build path in the house answered differently.
    //
    // Non-cargo kinds render their kind in place of a command: a container/vm/iso has
    // no cargo invocation, and inventing a plausible-looking one would be worse than
    // saying so.
    let mut out = vec![format!("delivery '{suite}' — {} variant(s):", chosen.len())];
    for v in chosen {
        out.push(format!(
            "  {:<24} {:<9} {:<8} {}",
            v.name,
            v.role.map(|r| r.as_str()).unwrap_or("-"),
            v.kind.as_str(),
            v.bin.as_deref().unwrap_or("<default bin>")
        ));
        if v.kind.is_cargo() {
            out.push(format!("      {}", v.command_line()));
        } else {
            out.push(format!(
                "      (not a cargo build — built by the {} builder)",
                v.kind.as_str()
            ));
        }
    }
    out
}

/// **Resolve a `(suite, variant)` selection and RENDER it, writing nothing.** The
/// `--list` leg of [`run`] with the terminal taken out: the same
/// [`discover_validated`](BuildVariantSet::discover_validated) load, the same
/// [`resolve`], the same [`list_lines`]. For doors that must return an answer instead
/// of printing one (the forge's rpc, the MCP lens).
pub fn list_resolved(repo_root: &Path, args: &BuildArgs) -> Result<Vec<String>> {
    let set = BuildVariantSet::discover_validated(repo_root)?.ok_or_else(|| {
        anyhow!(
            "no {} — this repo declares no build space",
            BuildVariantSet::conventional_path(repo_root).display()
        )
    })?;
    let (suite, chosen) = resolve(&set, args)?;
    Ok(list_lines(suite, &chosen))
}

pub fn run(repo_root: &Path, args: &BuildArgs) -> Result<Vec<String>> {
    // The load path VALIDATES (audit-w2 #1): every shape rule, the on-disk
    // inputs, and every consumption edge type-checked against the donor beside
    // this checkout — a declaration this door acts on is refused at load, by
    // name, never first at the build it would have broken.
    let set = BuildVariantSet::discover_validated(repo_root)?.ok_or_else(|| {
        anyhow!(
            "no {} — this repo declares no build space, so there is nothing for \
             `xtask build` to read",
            BuildVariantSet::conventional_path(repo_root).display()
        )
    })?;
    // `--build <X>` (audit-w2 #18): this door assembles cargo variants of ONE
    // repo; chaining the build thing behind an edge — another checkout, its own
    // container, its pin — is the forge's (`dwarves buildthing`, the runner over
    // `build_dag::BuildDag`). Honoured or refused BY NAME, never swallowed: the
    // DAG is derived here so the refusal spells the exact lines in the order the
    // forge would run them. A target that is no edge, an unknown variant, a
    // cycle — each is the DAG's own refusal.
    if !args.builds.is_empty() {
        use crate::build_dag::{BesideCheckouts, BuildDag, Coordinate};
        let Some(variant) = args.atom.as_deref() else {
            bail!(
                "--build {}: say which variant the edge belongs to with --variant (`--build` chains the \
                 build thing behind an EDGE of that variant's tree)",
                args.builds.join(" --build ")
            );
        };
        let decls = BesideCheckouts::of(repo_root);
        let target = Coordinate::new(decls.own.clone(), variant);
        let dag = BuildDag::derive(&target, &args.build_line()?, &decls)?;
        bail!(
            "--build {}: `xtask build` assembles cargo variants of this repo and does not chain \
             a build across checkouts — the forge does. The steps, in the order the edge DAG runs \
             them:\n  {}",
            args.builds.join(" --build "),
            dag.lines().join("\n  ")
        );
    }
    // `--param` values are install-time inputs for [[build.iso]]/[[build.installer]]
    // cells, and THIS verb builds cargo atoms only (the iso/installer builders are
    // the library seam: `apply_cli_params` → `image_build::build_iso`). Refuse
    // rather than silently dropping a value the operator believes was baked in.
    if !args.params.is_empty() {
        bail!(
            "--param supplies install-time inputs for iso/installer cells, and `build` \
             assembles cargo variants — drive the product's iso/installer verb instead \
             (it parses these with params::parse_cli_params and lands them via \
             apply_cli_params; the applied values ride the attested descriptor)"
        );
    }
    let (suite, chosen) = resolve(&set, args)?;

    if args.list {
        // The MATERIALIZED cargo command is printed for every atom, not just its name.
        //
        // This is the whole value of a describe verb. A row saying `mvp-server · server ·
        // service · holger-mvp` tells you an atom exists; it does not tell you what will
        // be compiled, and "what features does this artifact actually get" is precisely
        // the question every hand-rolled build path in the house answered differently.
        // holger's retired `build --list` printed the command line and its test asserted
        // on it; moving the selector here would have silently dropped that, so it lives
        // here now and all five repos gain it rather than one keeping it.
        //
        // Non-cargo kinds print their kind in place of a command: a container/vm/iso has
        // no cargo invocation, and inventing a plausible-looking one would be worse than
        // saying so.
        for line in list_lines(suite, &chosen) {
            println!("{line}");
        }
        return Ok(chosen.iter().map(|v| v.name.clone()).collect());
    }

    let mut built = Vec::new();
    let mut skipped: BTreeSet<String> = BTreeSet::new();
    for v in &chosen {
        if !v.kind.is_cargo() {
            skipped.insert(format!("{} ({})", v.name, v.kind.as_str()));
            continue;
        }
        // the operator's cargo feature choice, on top of the declared row
        let v = &v.with_cargo_features(&args.cargo);
        let set = set.with_cargo_features(&v.name, &args.cargo)?;
        eprintln!("── {} · {} · {}", suite, v.name, v.command_line());
        if args.attest {
            attest_atom(&set, v, repo_root)?;
        } else {
            v.build(&set, repo_root)?;
        }
        built.push(v.name.clone());
    }
    if !skipped.is_empty() {
        eprintln!(
            "not cargo builds, skipped (use the image/vm/iso builders): {}",
            skipped.iter().cloned().collect::<Vec<_>>().join(", ")
        );
    }
    if built.is_empty() {
        bail!(
            "delivery '{suite}' has no cargo-buildable variant — every one of {} is a \
             container/vm/iso. Nothing was built; that is not a success.",
            chosen.len()
        );
    }
    Ok(built)
}

/// **The attesting delivery: compile with symbols, audit, strip, write it down.**
///
/// The caller for everything `history::deliver_stripped` and
/// `receipt_proof::audit_artifact` can do. Without this the audit was a library
/// nobody ran, which is exactly the state the receipt writer was in until
/// 2026-08-06 and the reason its first PLAN entry read "the writer exists in
/// edda, nothing calls it".
///
/// ```text
/// 1  cargo build, CARGO_PROFILE_<P>_STRIP=none    the audited binary
/// 2  copy it aside                                 target/ is about to be reused
/// 3  deliver_stripped(audited -> artifact path)    audit, then strip
/// 4  write <artifact>.attestation.json             the proof, as text
/// 5  refuse to return Ok on a receipt that lies
/// ```
///
/// Step 2 is not tidiness. Cargo writes one path per build point, so the
/// unstripped binary and the stripped delivery are the same file name; without
/// the copy, step 3 would strip its own input and then audit the result, and the
/// audit would report `NotMeasured` for a delivery it had just destroyed the
/// evidence of.
///
/// # What it does NOT do
///
/// Sign anything. The attestation says the artifact carries the program that was
/// audited; it says nothing about who built it. That distinction is in the
/// written-out `outsider` block of every proof.
///
/// # Errors
///
/// When the variant has no `bin` (the artifact path is unresolvable and a guessed
/// one is worse than none), when the build fails, when the artifact is not where
/// cargo said it would be, when the attestation is refused, and — loudly — when
/// the receipt does not hold. A delivery whose receipt is disproven must not
/// leave the build green.
pub fn attest_atom(set: &BuildVariantSet, v: &BuildVariant, repo_root: &Path) -> Result<PathBuf> {
    let under = v.artifact_under_target().ok_or_else(|| {
        anyhow!(
            "variant '{}' declares no `bin`, so its artifact path cannot be resolved without \
             cargo metadata — and an attestation over a guessed path would name the wrong \
             bytes",
            v.name
        )
    })?;

    // Cargo's per-profile override, spelled the way cargo spells it: the profile
    // NAME uppercased, non-alphanumerics to `_`. `dev` here is `DEV`, not `DEBUG`
    // — that mapping is the directory's, not the profile's.
    let profile = String::from(v.profile.clone());
    let key = format!(
        "CARGO_PROFILE_{}_STRIP",
        profile
            .chars()
            .map(|c| if c.is_ascii_alphanumeric() {
                c.to_ascii_uppercase()
            } else {
                '_'
            })
            .collect::<String>()
    );
    v.build_with_env(set, repo_root, &[(key.clone(), "none".to_string())])?;

    // Cargo's target directory, resolved the way cargo resolves it. A relative
    // `CARGO_TARGET_DIR` is relative to the directory cargo runs in, which is
    // `repo_root` because that is where `build_with_env` puts it.
    let produced = match std::env::var_os("CARGO_TARGET_DIR") {
        Some(dir) if !dir.is_empty() => repo_root.join(dir).join(&under),
        _ => repo_root.join("target").join(&under),
    };
    if !produced.is_file() {
        bail!(
            "variant '{}' built, but no artifact at {} — the attestation would be about a file \
             that is not there",
            v.name,
            produced.display()
        );
    }
    let audited = produced.with_extension("audited");
    std::fs::copy(&produced, &audited)
        .with_context(|| format!("keep the audited binary at {}", audited.display()))?;

    let attestation = crate::history::deliver_stripped(&audited, &produced)
        .map_err(|e| anyhow!("variant '{}': {e}", v.name))?;
    let proof = attestation
        .proof
        .as_ref()
        .ok_or_else(|| anyhow!("variant '{}': the delivery produced no proof", v.name))?;

    let json_path = produced.with_extension("attestation.json");
    std::fs::write(
        &json_path,
        serde_json::to_vec_pretty(&attestation)
            .with_context(|| format!("serialise the attestation for '{}'", v.name))?,
    )
    .with_context(|| format!("write {}", json_path.display()))?;

    for line in proof.lines() {
        eprintln!("   {line}");
    }
    eprintln!("   attestation: {}", json_path.display());

    if !attestation.proof_holds() {
        bail!(
            "variant '{}': its receipt does NOT survive its own symbol table. The attestation is \
             written to {} so the evidence is not lost, and the build is red.\n  {}",
            v.name,
            json_path.display(),
            proof.lines().join("\n  ")
        );
    }
    Ok(json_path)
}

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

    /// Item 19's seam, proven without the heavy composition: a fake composer
    /// records what arrives — the resolved cell WITH params applied — and the
    /// refusals (unknown cell, ambiguous cell-less call, unknown param) come
    /// from the shared paths, by name.
    #[test]
    fn the_installer_door_resolves_applies_params_and_refuses_by_name() {
        use std::sync::Mutex;
        struct Probe(Mutex<Option<crate::installer::InstallerBuild>>);
        impl InstallerComposer for Probe {
            fn compose_installer(
                &self,
                cell: &crate::installer::InstallerBuild,
                _kernel: &Path,
                _app: &Path,
                _root: &Path,
                _label: &str,
            ) -> Result<std::path::PathBuf> {
                *self.0.lock().unwrap() = Some(cell.clone());
                Ok(std::path::PathBuf::from("/fake.iso"))
            }
        }

        let dir = std::env::temp_dir().join(format!("suite-installer-{}", std::process::id()));
        let _ = std::fs::remove_dir_all(&dir);
        std::fs::create_dir_all(dir.join(".nornir")).unwrap();
        std::fs::write(
            dir.join(".nornir/build-variants.toml"),
            r#"
# `[[build.variants]]` until 2026-08-26 — PLURAL, and therefore not a key the
# schema has. It parsed to nothing, this fixture declared zero variants, and the
# test passed anyway because its subject is the installer. `deny_unknown_fields`
# on `BuildVariantSet` caught it on the first run.
[[build.variant]]
name = "probe"
kind = "exe"

[[build.installer]]
name = "probe-installer"
variant = ""
volume_id = "PROBE"
boot_params = ["korp.entry=probe"]

[[build.installer.params]]
name = "site"
label = "Site"
kind = "text"
required = false
boot_param = "korp.site"
"#,
        )
        .unwrap();

        let probe = Probe(Mutex::new(None));
        let iso = run_installer(
            &dir,
            "probe",
            None,
            Path::new("/k"),
            Path::new("/a"),
            &["site=oden-7".to_string()],
            &probe,
        )
        .expect("the single cell resolves without naming it");
        assert_eq!(iso, std::path::PathBuf::from("/fake.iso"));
        let seen = probe.0.lock().unwrap().clone().expect("the composer saw the cell");
        assert!(
            seen.effective_boot_params().iter().any(|t| t == "korp.site=oden-7"),
            "the param was APPLIED before composition: {:?}",
            seen.effective_boot_params()
        );

        // RED: unknown cell name, and an unknown param, each refused by name.
        let err = run_installer(&dir, "probe", Some("nope"), Path::new("/k"), Path::new("/a"), &[], &probe)
            .unwrap_err()
            .to_string();
        assert!(err.contains("nope") && err.contains("probe-installer"), "{err}");
        let err = run_installer(&dir, "probe", None, Path::new("/k"), Path::new("/a"), &["mystery=1".to_string()], &probe)
            .unwrap_err()
            .to_string();
        assert!(err.contains("mystery"), "{err}");
        let _ = std::fs::remove_dir_all(&dir);
    }


    const TWO: &str = r#"
[build]
base_suite = "full"
[[build.variant]]
name = "server-full"
package = "holger"
bin = "holger-server"
role = "server"
default = true
suites = ["full"]
features = ["registry", "gui"]
[[build.variant]]
name = "server-mvp"
package = "holger"
bin = "holger-server"
role = "server"
default = true
suites = ["mvp"]
features = ["registry"]
"#;

    const ONE: &str = r#"
[build]
base_suite = "ORIGINAL"
[[build.variant]]
name = "korp-server"
package = "korp"
bin = "korp-server"
role = "server"
default = true
suites = ["ORIGINAL"]
[[build.variant]]
name = "korp-ui"
package = "korp"
bin = "korp-ui"
role = "client"
default = true
suites = ["ORIGINAL"]
"#;

    fn set(t: &str) -> BuildVariantSet {
        BuildVariantSet::from_toml_str(t).expect("parse")
    }

    /// ★ **RED-FIRST 2026-08-20 — the vocabulary is `--variant`.** A declared build
    /// row is a VARIANT with a KIND; "atom" is retired prose (see the crate docs).
    /// `--variant X` and `--atom X` must produce the SAME `BuildArgs`, `--atom` stays
    /// accepted forever (the written laws cite `cargo xtask build --suite ORIGINAL
    /// --atom dwarves-server` and muscle memory is not to be broken), and the help
    /// text must teach the new word.
    #[test]
    fn variant_is_the_flag_and_atom_stays_its_alias() {
        let v = parse(&["--suite", "MVP", "--variant", "ui"]).expect("--variant parses");
        let a = parse(&["--suite", "MVP", "--atom", "ui"]).expect("--atom still parses");
        assert_eq!(v, a, "the two spellings must resolve IDENTICALLY");
        assert_eq!(v.atom.as_deref(), Some("ui"));
        let v2 = parse(&["--variant=ui"]).expect("--variant= parses");
        let a2 = parse(&["--atom=ui"]).expect("--atom= still parses");
        assert_eq!(v2, a2);
        assert_eq!(v2.atom.as_deref(), Some("ui"));
        assert!(
            parse(&["--variant"]).is_err(),
            "a flag with no value must not pass"
        );
        assert!(USAGE.contains("--variant"), "USAGE must teach --variant");
        assert!(
            USAGE.contains("--atom"),
            "USAGE must still admit the deprecated alias so a reader of an old law \
             is not stranded"
        );
    }

    /// `--build <path|coordinate>` (law C's fourth flag) parses in both shell
    /// shapes, in order, raw — resolving it to an edge is the door's job.
    #[test]
    fn build_flags_parse_raw_in_both_shell_shapes() {
        let a = parse(&["--build", "kernel", "--build=tunnr/tunnr-kernel", "--opt", "dhcp=off"]).expect("parse");
        assert_eq!(a.builds, ["kernel", "tunnr/tunnr-kernel"]);
        // The three raw lists have ONE meaning: the canonical --build line (wave 3).
        assert_eq!(
            a.build_line().unwrap().render(),
            "--opt dhcp=off --build kernel --build tunnr/tunnr-kernel"
        );
        let braced = parse(&["--build", "kernel { --opt unix=off }", "--opt", "dhcp=off"]).expect("parse");
        assert_eq!(braced.build_line().unwrap().render(), "--opt dhcp=off --build kernel --opt kernel.unix=off");
        assert_eq!(a.opts, ["dhcp=off"]);
        let e = format!("{:#}", parse(&["--build"]).unwrap_err());
        assert!(e.contains("--build needs a path"), "{e}");
        assert!(USAGE.contains("--build <path|repo/variant>"), "USAGE must teach --build");
    }

    #[test]
    fn flags_parse_in_both_spellings() {
        let a = parse(&["--suite", "MVP", "--atom", "ui", "--list"]).expect("parse");
        assert_eq!(a.suite.as_deref(), Some("MVP"));
        assert_eq!(a.atom.as_deref(), Some("ui"));
        assert!(a.list);
        let b = parse(&["--suite=MVP", "--atom=ui"]).expect("parse");
        assert_eq!(b.suite.as_deref(), Some("MVP"));
        assert_eq!(b.atom.as_deref(), Some("ui"));
        assert!(
            parse(&["--suite"]).is_err(),
            "a flag with no value must not pass"
        );
        assert!(parse(&["--nope"]).is_err());
    }

    /// ★ **THE NON-VACUOUS ANCHOR: `--suite` must SELECT.** Two deliveries, and the
    /// same command with a different suite must produce a DIFFERENT build. If both
    /// resolved to the same atom the parameter would be decorative.
    #[test]
    fn suite_actually_selects_a_different_build() {
        let s = set(TWO);
        let (n1, full) = resolve(&s, &parse(&["--suite", "full"]).unwrap()).expect("full");
        let (n2, mvp) = resolve(&s, &parse(&["--suite", "mvp"]).unwrap()).expect("mvp");
        assert_eq!((n1, n2), ("full", "mvp"));
        assert_eq!(full.len(), 1);
        assert_eq!(mvp.len(), 1);
        assert_ne!(
            full[0].name, mvp[0].name,
            "the two deliveries picked the same atom"
        );
        // …and the DIFFERENCE reaches cargo, not just the name.
        assert!(full[0].features.contains(&"gui".to_string()));
        assert!(!mvp[0].features.contains(&"gui".to_string()));
        assert_ne!(full[0].command_line(), mvp[0].command_line());
    }

    /// An unknown suite FAILS and names the real ones. A selector that shrugs is the
    /// silent-green shape.
    #[test]
    fn an_unknown_suite_fails_loudly() {
        let s = set(TWO);
        let e = resolve(&s, &parse(&["--suite", "NOPE"]).unwrap()).expect_err("must fail");
        let m = format!("{e}");
        assert!(m.contains("no such delivery"), "{m}");
        assert!(
            m.contains("full") && m.contains("mvp"),
            "it must list the real ones: {m}"
        );

        // And on a ONE-delivery repo it is just as loud.
        let one = set(ONE);
        let e = resolve(&one, &parse(&["--suite", "NOPE"]).unwrap()).expect_err("must fail");
        assert!(format!("{e}").contains("ORIGINAL"), "{e}");
    }

    /// Omitting `--suite` with two deliveries refuses instead of guessing.
    #[test]
    fn two_deliveries_and_no_suite_refuses() {
        let e = resolve(&set(TWO), &BuildArgs::default()).expect_err("must fail");
        assert!(format!("{e}").contains("ships 2 deliveries"), "{e}");
    }

    /// One delivery: `--suite ORIGINAL` and no flag resolve to the SAME set, so the
    /// uniform command shape costs a one-delivery repo nothing.
    #[test]
    fn one_delivery_answers_to_its_name_and_to_silence() {
        let s = set(ONE);
        let (a, xs) = resolve(&s, &parse(&["--suite", "ORIGINAL"]).unwrap()).expect("named");
        let (b, ys) = resolve(&s, &BuildArgs::default()).expect("bare");
        assert_eq!((a, b), ("ORIGINAL", "ORIGINAL"));
        let names = |v: &Vec<&crate::variant::BuildVariant>| -> Vec<String> {
            v.iter().map(|x| x.name.clone()).collect()
        };
        assert_eq!(names(&xs), names(&ys));
        assert_eq!(names(&xs), vec!["korp-server", "korp-ui"]);
    }

    /// ★ **`--list` must print the MATERIALIZED cargo command, not only the name.**
    ///
    /// A describe verb that names atoms without saying what they compile cannot answer
    /// the one question that matters — "what features does this artifact get" — which is
    /// exactly what four hand-rolled build paths each answered differently. The two
    /// deliveries of [`TWO`] build the SAME bin (`holger-server`) from the same package
    /// and differ ONLY in features, so a row without the command line is literally
    /// identical for both: that is the non-vacuous anchor here.
    ///
    /// Asserted on `command_line()` rather than on captured stdout because `println!`
    /// is not capturable from a unit test; the printed line is that exact string, and
    /// the test therefore asserts the thing that IS printed rather than a restatement.
    #[test]
    fn the_command_line_distinguishes_two_atoms_a_name_row_cannot() {
        let s = set(TWO);
        let (_, full) = resolve(&s, &parse(&["--suite", "full"]).unwrap()).expect("full");
        let (_, mvp) = resolve(&s, &parse(&["--suite", "mvp"]).unwrap()).expect("mvp");

        // The NAME-ONLY row is identical for both: same role, same kind, same bin. If
        // this assert ever fails the fixture drifted and the point below is moot.
        let name_row = |v: &crate::variant::BuildVariant| {
            format!(
                "{} {} {}",
                v.role.map(|r| r.as_str()).unwrap_or("-"),
                v.kind.as_str(),
                v.bin.as_deref().unwrap_or("<default bin>")
            )
        };
        assert_eq!(
            name_row(full[0]),
            name_row(mvp[0]),
            "fixture must have two atoms whose name-row is indistinguishable"
        );

        // The command line is what tells them apart, and it names the real features.
        let cf = full[0].command_line();
        let cm = mvp[0].command_line();
        assert_ne!(cf, cm, "the command line must distinguish them: {cf}");
        assert!(cf.contains("--features") && cf.contains("gui"), "{cf}");
        assert!(!cm.contains("gui"), "the mvp delivery has no gui: {cm}");
        assert!(
            cf.contains("holger-server") && cm.contains("holger-server"),
            "{cf} / {cm}"
        );
    }

    /// A non-cargo atom has NO cargo command, and `--list` must say so rather than
    /// print a plausible-looking invocation nobody will run.
    #[test]
    fn a_non_cargo_atom_has_no_cargo_command() {
        let s = BuildVariantSet::from_toml_str(
            "[build]\nbase_suite = \"ORIGINAL\"\n\
             [[build.variant]]\nname = \"img\"\nkind = \"container\"\n\
             suites = [\"ORIGINAL\"]\ndefault = true\n",
        )
        .expect("parse");
        let (_, chosen) = resolve(&s, &parse(&["--suite", "ORIGINAL"]).unwrap()).expect("resolve");
        assert_eq!(chosen.len(), 1);
        assert!(
            !chosen[0].kind.is_cargo(),
            "the fixture must be a NON-cargo kind or this test proves nothing"
        );
    }

    /// A `kind = "kernel"` variant rides the delivery selector like the other
    /// non-cargo kinds: `--list` shows it with its kind and never invents a
    /// cargo argv for it (it is built by the kernel builder seam).
    #[test]
    fn a_kernel_variant_resolves_and_lists_as_a_non_cargo_kind() {
        let s = BuildVariantSet::from_toml_str(
            "[build]\nbase_suite = \"ORIGINAL\"\n\
             [[build.variant]]\nname = \"lil-kernel\"\nkind = \"kernel\"\n\
             suites = [\"ORIGINAL\"]\ndefault = true\n",
        )
        .expect("parse");
        let (_, chosen) =
            resolve(&s, &parse(&["--suite", "ORIGINAL"]).unwrap()).expect("resolve");
        assert_eq!(chosen.len(), 1);
        assert_eq!(chosen[0].kind.as_str(), "kernel");
        assert!(
            !chosen[0].kind.is_cargo(),
            "a kernel is built by the kernel builder, never by cargo"
        );
    }

    /// A variant that exists but belongs to the OTHER delivery is rejected with a
    /// message that says which — not "no such variant", which would send the caller
    /// looking for a typo that is not there.
    #[test]
    fn a_variant_from_another_delivery_says_so() {
        let s = set(TWO);
        let e = resolve(
            &s,
            &parse(&["--suite", "mvp", "--atom", "server-full"]).unwrap(),
        )
        .expect_err("must fail");
        let m = format!("{e}");
        assert!(m.contains("not in delivery 'mvp'"), "{m}");
        assert!(m.contains("server-mvp"), "{m}");

        let e = resolve(&s, &parse(&["--suite", "mvp", "--atom", "typo"]).unwrap())
            .expect_err("must fail");
        assert!(format!("{e}").contains("no such variant"), "{e}");
    }


    /// **The compose door takes a CHOICE and a DONOR's pair without choking** —
    /// the `--opt kernel.preset=` fix, and `--opt data.fs=` reaching the row.
    ///
    /// Seen red on this exact door before the tree split it: `parse_cli_options`
    /// refused BOTH pairs with `--opt kernel.preset=nuked: an option is on or
    /// off (on|off, true|false, yes|no, 1|0)`, which is why gunnar's
    /// `BUILD-KEYED-INSTALLER.md` told operators not to type the flag. The
    /// donor's pair belongs to the DONOR's door (`resolve_kernel_cli`, judged
    /// upstream against its declaration), so this door's job is to route it, not
    /// to read it; the group's choice is this door's and lands on the row.
    #[test]
    fn a_choice_and_a_donors_pair_pass_this_door_and_the_group_lands_on_the_row() {
        use std::sync::Mutex;
        struct Probe(Mutex<Option<crate::installer::InstallerBuild>>);
        impl InstallerComposer for Probe {
            fn compose_installer(
                &self,
                cell: &crate::installer::InstallerBuild,
                _kernel: &Path,
                _app: &Path,
                _root: &Path,
                _label: &str,
            ) -> Result<std::path::PathBuf> {
                *self.0.lock().unwrap() = Some(cell.clone());
                Ok(std::path::PathBuf::from("/fake.iso"))
            }
        }
        let dir = std::env::temp_dir().join(format!("suite-groupopt-{}", std::process::id()));
        let _ = std::fs::remove_dir_all(&dir);
        std::fs::create_dir_all(dir.join(".nornir")).unwrap();
        std::fs::write(
            dir.join(".nornir/build-variants.toml"),
            r#"
[[build.variant]]
name = "probe"
kind = "exe"
no_default_features = true
features = ["wg-client"]

[[build.installer]]
name = "probe-installer"
variant = "probe"
volume_id = "PROBE"

[build.installer.kernel_donor]
repo = "tunnr"
kernel = "tunnr-kernel"

[build.installer.data]
fs = "xfs"

[[build.installer.options]]
name = "wireguard"
default = true
feature = "wg-client"
"#,
        )
        .unwrap();

        let probe = Probe(Mutex::new(None));
        run_installer_selected(
            &dir,
            "probe",
            None,
            Path::new("/k"),
            Path::new("/a"),
            &[],
            &["kernel.preset=nuked".to_string(), "data.fs=fat".to_string(), "wireguard=off".to_string()],
            &probe,
        )
        .expect("a donor pair, a group choice and a toggle on one line");
        let seen = probe.0.lock().unwrap().clone().expect("the composer saw the cell");
        assert_eq!(seen.data.fs, crate::data::DataFs::Fat, "--opt data.fs=fat moved the DECLARED xfs");
        assert!(seen.applied_options.iter().any(|o| o.name == "wireguard" && !o.on), "{:?}", seen.applied_options);

        // RED, still: a value that is not on the val's roster, and a toggle
        // given a choice — each named, each with the roster or the shape.
        let e = format!(
            "{:#}",
            run_installer_selected(&dir, "probe", None, Path::new("/k"), Path::new("/a"), &[], &["data.fs=ext4".to_string()], &probe)
                .unwrap_err()
        );
        assert!(e.contains("data.fs") && e.contains("fat") && e.contains("xfs"), "{e}");
        let e = format!(
            "{:#}",
            run_installer_selected(&dir, "probe", None, Path::new("/k"), Path::new("/a"), &[], &["wireguard=nuked".to_string()], &probe)
                .unwrap_err()
        );
        assert!(e.contains("on or off"), "{e}");
        let _ = std::fs::remove_dir_all(&dir);
    }
}