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/cargo_container.rs

//! **The cargo kind builds in a container** — the leg it did not have.
//!
//! # The defect this module closes
//!
//! [`build_variant`](crate::provenance::build_variant) — "the one cargo-driving
//! loop in this crate" — is `Command::new("cargo")` in the host's environment
//! (`provenance.rs:473`). Everything the compile needs therefore comes from
//! whichever box the forge happens to run on: the rustc version, the installed
//! target set, the C compiler, `~/.cargo/config.toml`'s linker choice, the
//! registry cache. MEASURED 2026-08-25 on oden:
//!
//! ```text
//! $ dwarves buildthing gunnar --variant gunnar-server
//! error[E0463]: can't find crate for `core`
//! FAILED in 1.8 s
//! ```
//!
//! …because every gunnar variant targets `x86_64-unknown-linux-musl` and oden's
//! rustup had no musl std. Reproduced on t14s by naming a toolchain that lacks
//! the target (`RUSTUP_TOOLCHAIN=1.96.0 cargo build --target
//! x86_64-unknown-linux-musl` → `error[E0463]: can't find crate for std`): the
//! build's verdict was decided by the box, not by the declaration.
//!
//! The law was already written, in the sibling kind's image
//! (`containerfiles/kernel-toolchain.Containerfile:3-6`):
//!
//! > The host contributes a container engine socket and a workdir. NOTHING
//! > else… A build that only works on one box is a bug, not a build.
//!
//! The kernel kind obeys it ([`KernelContainerRunner`](crate::kernel::KernelContainerRunner)).
//! The cargo kind — the kind that builds nearly everything in the constellation
//! — had no image and no seam. This module is that seam, deliberately shaped
//! like the kernel one so there is one pattern and not two.
//!
//! # Declaration
//!
//! One table per repo, in `.nornir/build-variants.toml`. It is repo-level and
//! not per-variant on purpose: "which box can build this" is a property of the
//! repo's whole delivery, and a per-variant spelling would let one variant
//! quietly keep the host habit.
//!
//! ```toml
//! [build.toolchain]
//! # the image the cargo variants compile in
//! image = "nordisk-cargo-toolchain"
//! # PIN IT BY DIGEST — the MANIFEST digest (`podman image inspect --format
//! # '{{.Digest}}'`), not the image id. A named tag is a convenience, not a pin.
//! image_sha256 = "0d8caf1a…"
//! rust_version = "1.97.1"                 # what the image was built with
//! targets = ["x86_64-unknown-linux-gnu", "x86_64-unknown-linux-musl"]
//! # the bounds — a build container is a GUEST, never a host process:
//! mem_limit_mb = 8192                     # draupnir --memory; 0 is REFUSED
//! cpus = 8                                # draupnir --cpus
//! timeout_secs = 3600                     # overrun is a loud refusal, not a wait
//! network = false                         # self-contained image ⇒ --network none
//! # the SIBLING REPOS this repo's `path = "../../.."` deps reach into. gunnar
//! # has ten such deps; a container holding only this repo cannot see one of
//! # them. An escaping dep whose sibling is missing here is refused BY NAME,
//! # before the container starts, with the manifest line and the fix spelled:
//! siblings = ["edda", "znippy", "draupnir", "tunnr", "znippy-zoomies"]
//! ```
//!
//! # `--network none` and where the crates come from
//!
//! A self-contained image plus `network = false` means the compile cannot reach
//! crates.io, so the run adds `--offline --locked`. The dependency sources are
//! bind-mounted from a registry the HOST populated (`cargo fetch --locked`,
//! host-side, the same division of labour the kernel kind uses for its tarball:
//! fetch on the host in Rust, compile in the container). That is not the host
//! leaking back in — every one of those sources is checksum-pinned by
//! `Cargo.lock`, exactly as the kernel tarball is pinned by `tarball_sha256`.
//! `--locked` is what makes the pin load-bearing rather than decorative.
//!
//! # Byte-identity, and what is honestly reachable
//!
//! The gate this module exists to satisfy: *the same variant built on the host
//! and in the container must produce a byte-identical artifact.*
//!
//! **THREE inputs stand between a naive run and that gate, and every one of them
//! is a PATH, not code.** rustc bakes absolute directories into debug info and
//! panic locations, and the three that differ are:
//!
//! | input | host | container | remapped to |
//! |---|---|---|---|
//! | the checkout | `/home/<user>/git` | [`WORKROOT`] | [`REMAP_SRC`] |
//! | the registry | `<CARGO_HOME>/registry` | `/cargo/registry` | [`REMAP_REGISTRY`] |
//! | **the target dir** | `<CARGO_TARGET_DIR>` | [`TARGETDIR`] | [`REMAP_TARGET`] |
//!
//! The third is the one that is easy to miss, because it is not a source
//! directory: `OUT_DIR` lives under the target dir, so every line of
//! build-script-GENERATED code carries it. It cost a measurement to find —
//! `gunnar-server` with the first two remaps in place still differed by 6 808
//! bytes, and the entire difference was one generated file's path repeated
//! through DWARF.
//!
//! [`CargoToolchain::remap_paths`] (default **on**) gives both sides the same
//! synthetic prefixes; [`CargoToolchain::host_rustflags`] is the host half, so
//! the comparison is apples-to-apples instead of a weakened gate. See
//! [`byte_identity_verdict`] for the verdict type the gate reports, which names
//! the reason when identity is NOT reached rather than going quietly green.
//!
//! # …and why HOST-vs-container is the wrong gate for a real repo
//!
//! With all three paths remapped, a dependency-free crate goes byte-identical
//! (`d4da6c40…` / `7b85469a…`, measured). `gunnar-server` does not, and reading
//! the two artifacts turns up **two causes, neither of them the container's**:
//!
//! ```text
//! host:      GCC: (Ubuntu 15.2.0-16ubuntu1) 15.2.0    built 2026-08-25T22:43:39Z
//! container: GCC: (Debian 14.2.0-19) 14.2.0           built 2026-08-25T22:44:47Z
//! ```
//!
//! 1. **The C compilers are different**, and that is the POINT rather than a
//!    problem. gunnar links C (mimalloc, musl objects), the host's `cc` is
//!    whatever Ubuntu shipped, and the container's is the one the image pins.
//!    Demanding byte-identity with the host means demanding the container
//!    reproduce an environment nobody declared — it makes the UNPINNED side the
//!    reference. It is also direct evidence of the defect: the host WAS
//!    contributing a C toolchain to the artifact.
//! 2. **The repo stamps the wall clock into every build.**
//!    `gunnar/crates/gunnar-common/build.rs:43` runs `date -u +%Y-%m-%dT%H:%M:%SZ`
//!    and bakes it as `GUNNAR_BUILD_DATE`. At second resolution, two builds one
//!    second apart differ — on one box or two.
//!
//! So the gate that means something is **container-vs-container**: the same
//! digest-pinned image, twice, must produce the same bytes. That is what a
//! content-addressed build environment actually promises, and unlike host-vs-
//! container it does not treat one box's accidents as the specification.
//! [`byte_identity_with_control`] is that gate — and it still goes RED on
//! `gunnar-server`, for cause (2), which is a repo defect the container cannot
//! and should not paper over.

use anyhow::{Context, Result, anyhow};
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::path::{Path, PathBuf};
use std::time::Duration;

use crate::provenance::{BuildOutcome, BuildProvenance, HostInfo, Outcome, SourceRev, Toolchain};
use crate::variant::{BuildVariant, BuildVariantSet};

/// The image name the committed [`CARGO_TOOLCHAIN_CONTAINERFILE`] builds under.
/// A NAME, not a pin — see [`CargoToolchain::image_ref`].
pub const CARGO_TOOLCHAIN_IMAGE: &str = "nordisk-cargo-toolchain";

/// **The committed Containerfile for [`CARGO_TOOLCHAIN_IMAGE`]** — one
/// authority, embedded in the crate so no repo can ship a private twin of the
/// build environment. Every package in it names the STEP it serves.
pub const CARGO_TOOLCHAIN_CONTAINERFILE: &str =
    include_str!("containerfiles/cargo-toolchain.Containerfile");

/// The image name the committed [`CARGO_TEST_CONTAINERFILE`] builds under.
/// A NAME, not a pin — the same caveat [`CARGO_TOOLCHAIN_IMAGE`] carries.
pub const CARGO_TEST_IMAGE: &str = "nordisk-cargo-test";

/// **The committed Containerfile for [`CARGO_TEST_IMAGE`]** — the sibling of
/// [`CARGO_TOOLCHAIN_CONTAINERFILE`] for the road that RUNS a repo's tests
/// rather than compiling its variants.
///
/// It is a second image and not three more packages in the first one because
/// that file states the rule it would be breaking: nothing rides "just in
/// case", and an appliance build has no business carrying an ssh client. What
/// it carries instead is exactly what a test suite needs and a compile does
/// not — `openssh-client`, `git-lfs`, `cargo-deny` — each naming the tests it
/// unblocks.
///
/// MEASURED on oden 2026-09-12, gunnar's `cargo test --workspace`: 2064
/// passed / 13 failed as root in the plain toolchain image, 1972 / 110 as an
/// ordinary user in it (no ssh at all), and 2075 / 7 as an ordinary user in
/// this one. None of the differences were gunnar's code.
pub const CARGO_TEST_CONTAINERFILE: &str =
    include_str!("containerfiles/cargo-test.Containerfile");

/// **The `cargo-deny` release [`CARGO_TEST_CONTAINERFILE`] installs**, read out
/// of its own `ARG CARGO_DENY_VERSION` / `ARG CARGO_DENY_SHA256` lines:
/// `(version, sha256)`.
///
/// Read rather than restated, for the reason
/// [`cargo_toolchain_image_targets`] is read: the Containerfile is what puts
/// the binary in the image, so it is the only honest source for which bytes.
/// The host-side stager ([`stage_cargo_deny`]) fetches and verifies against
/// this, and the image verifies the staged file again in the layer that
/// installs it — the same digest checked on both sides of the context
/// boundary, so a tarball swapped in between is refused twice.
///
/// # Errors
///
/// Either line missing. Refused rather than defaulted: a default would mean
/// fetching an unpinned binary into an image everything else trusts.
pub fn cargo_test_cargo_deny_pin() -> Result<(String, String)> {
    let arg = |name: &str| -> Option<String> {
        CARGO_TEST_CONTAINERFILE
            .lines()
            .filter_map(|l| l.trim().strip_prefix(&format!("ARG {name}=")))
            .map(|v| v.trim().trim_matches('"').to_string())
            .next()
    };
    let version = arg("CARGO_DENY_VERSION").ok_or_else(|| {
        anyhow!("cargo-test.Containerfile has no `ARG CARGO_DENY_VERSION=` line to pin by")
    })?;
    let sha256 = arg("CARGO_DENY_SHA256").ok_or_else(|| {
        anyhow!("cargo-test.Containerfile has no `ARG CARGO_DENY_SHA256=` line to verify by")
    })?;
    Ok((version, sha256))
}

/// The `ARG` line [`cargo_test_containerfile_on`] rewrites. Spelled once.
const CARGO_TEST_BASE_ARG: &str = "ARG CARGO_TOOLCHAIN_REF=";

/// **[`CARGO_TEST_CONTAINERFILE`] with its base pinned to `toolchain_ref`.**
///
/// The base is expressed as an `ARG` with a tag default so a human can build
/// the image by hand, and the builder replaces that default with the reference
/// it was handed — normally `nordisk-cargo-toolchain@sha256:…`. Rewritten
/// rather than passed as `--build-arg` because the one container seam this
/// constellation has ([`draupnir::container::ContainerBoot`]) does not carry
/// build args, and teaching it one would be a second repo, a second publish
/// and a second thing to keep in step for a single string.
///
/// Exactly one line changes, and a missing line is a REFUSAL: silently
/// building on the tag default would produce an image whose base nobody can
/// name, which is the whole failure a pin exists to prevent.
///
/// # Errors
///
/// The embedded Containerfile has no `ARG CARGO_TOOLCHAIN_REF=` line.
pub fn cargo_test_containerfile_on(toolchain_ref: &str) -> Result<String> {
    let mut found = false;
    let out: Vec<String> = CARGO_TEST_CONTAINERFILE
        .lines()
        .map(|l| {
            if l.starts_with(CARGO_TEST_BASE_ARG) && !found {
                found = true;
                format!("{CARGO_TEST_BASE_ARG}{toolchain_ref}")
            } else {
                l.to_string()
            }
        })
        .collect();
    if !found {
        return Err(anyhow!(
            "cargo-test.Containerfile has no `{CARGO_TEST_BASE_ARG}` line, so the base image \
             cannot be pinned. Refusing to build on whatever the file's FROM resolves to."
        ));
    }
    Ok(format!("{}\n", out.join("\n")))
}

/// The URL the pinned `cargo-deny` tarball is fetched from. Derived from the
/// version in the Containerfile, so there is one place to change.
pub fn cargo_deny_url(version: &str) -> String {
    format!(
        "https://github.com/EmbarkStudios/cargo-deny/releases/download/{version}/\
         cargo-deny-{version}-x86_64-unknown-linux-musl.tar.gz"
    )
}

/// **Fetch the pinned `cargo-deny` tarball into `context_dir`, verified.**
///
/// Host-side and in pure Rust, the road
/// `cargo-toolchain.Containerfile`'s honest-gap section names for a tool
/// Debian does not package, and the one `kernel.rs` already takes for the
/// kernel source tarball. The file lands as `cargo-deny.tar.gz`, which is the
/// name the Containerfile `COPY`s.
///
/// An existing file that already matches the pin is left alone — a mint should
/// not re-download 4.9 MB it can prove it has. One that does NOT match is
/// removed and refetched, because a stale context file is exactly how an
/// unpinned binary gets into a pinned image.
///
/// # Errors
///
/// The pin cannot be read, the download fails, or the bytes do not match the
/// pin. The mismatch names both digests; nothing is left in the context.
pub fn stage_cargo_deny(fetcher: &dyn crate::kernel::TarballFetcher, context_dir: &Path) -> Result<PathBuf> {
    let (version, want) = cargo_test_cargo_deny_pin()?;
    let dest = context_dir.join("cargo-deny.tar.gz");
    if dest.is_file() && crate::kernel::sha256_file_hex(&dest)? == want {
        return Ok(dest);
    }
    let _ = std::fs::remove_file(&dest);
    let url = cargo_deny_url(&version);
    fetcher
        .fetch(&url, &dest)
        .with_context(|| format!("fetch cargo-deny {version}"))?;
    let got = crate::kernel::sha256_file_hex(&dest)?;
    if got != want {
        let _ = std::fs::remove_file(&dest);
        return Err(anyhow!(
            "cargo-deny {version} does not match its pin: the tarball at {url} hashes to \
             {got}, and cargo-test.Containerfile pins {want}. Nothing was staged. Either the \
             release was replaced — which is a supply-chain event, not a version bump — or \
             `ARG CARGO_DENY_SHA256` is stale and must be updated deliberately."
        ));
    }
    Ok(dest)
}

/// **The instant [`CARGO_TOOLCHAIN_CONTAINERFILE`] is minted at**, read out of
/// its own `ENV SOURCE_DATE_EPOCH` line — the one writer of that number.
///
/// It must reach two places: inside the image (`SOURCE_DATE_EPOCH`, honoured by
/// everything that would otherwise read the wall clock) and the BUILDER
/// (podman's `timestamp`, which sets the image config's `created` and every
/// layer's file timestamps — nothing in Dockerfile syntax can reach those).
/// [`DraupnirCargoRunner::build_toolchain_image`] hands it over via
/// `build_image_reproducible`. A missing line is REFUSED, not defaulted: a
/// default would silently mint an image whose id nobody else can reproduce.
///
/// The parse itself is [`crate::kernel::source_date_epoch_of`] — one parser for
/// both toolchain Containerfiles, so they cannot disagree on what the line means.
pub fn cargo_toolchain_source_date_epoch() -> Result<i64> {
    crate::kernel::source_date_epoch_of(CARGO_TOOLCHAIN_CONTAINERFILE)
}

/// **The target triples [`CARGO_TOOLCHAIN_CONTAINERFILE`] actually installs std
/// for**, read out of its own `ARG RUST_TARGETS` default.
///
/// Read rather than restated, because a second list would be a twin that drifts:
/// the Containerfile is the only thing that can put a std inside the image, so it
/// is the only honest source for what the image carries.
///
/// This is the half [`CargoToolchain::check_target`] cannot see. That check
/// compares a variant's `--target` against the DECLARATION's `targets` list, so
/// it catches a declaration that is too small — and passes a declaration that is
/// too big. MEASURED on oden 2026-08-27: the image built from this file was
/// `sha256:035814c4…` and had no wasm32 std whatsoever, yet
/// `rustc --print target-list` inside it printed `wasm32-unknown-unknown` among
/// 322 triples. Anyone adding that string to `targets` to "declare it" would
/// have turned a NAMED refusal an hour early into a bare `E0463` an hour late.
/// [`CargoToolchain::check_declared_targets`] is what refuses that.
pub fn cargo_toolchain_image_targets() -> Vec<String> {
    CARGO_TOOLCHAIN_CONTAINERFILE
        .lines()
        .filter_map(|l| l.trim().strip_prefix("ARG RUST_TARGETS="))
        .flat_map(|v| {
            v.trim()
                .trim_matches('"')
                .split_whitespace()
                .map(str::to_string)
                .collect::<Vec<_>>()
        })
        .collect()
}

/// The default build bound: 1 hour. A cargo build that has produced nothing in
/// an hour on this constellation's hardware is a hang, and a hang is a refusal,
/// never a wait. (The kernel kind's two hours is a KERNEL compile; a workspace
/// that legitimately needs longer raises its own `timeout_secs`.)
pub const DEFAULT_TIMEOUT_SECS: u64 = 60 * 60;
/// The default memory bound in MiB. Bounded by default for the reason recorded
/// in [`crate::kernel`]'s bounded-guest law: 2026-08-20 an unbounded build
/// reached 33 GB, the OOM killer took the service, and the box went down.
pub const DEFAULT_MEM_LIMIT_MB: u32 = 8192;
/// The default cpu bound in whole cores.
pub const DEFAULT_CPUS: u32 = 8;
/// **The container path the repo's PARENT is reproduced at**, not the repo.
///
/// The repo lands at `<WORKROOT>/<repo dir name>` and each declared sibling at
/// `<WORKROOT>/<sibling dir name>`, so the constellation's checkout layout —
/// sibling repos under one parent — survives into the container unchanged.
///
/// MEASURED 2026-08-26, and it is why this is not simply `/work`: binding the
/// repo alone at `/work` builds a leaf crate and cannot build gunnar.
///
/// ```text
/// error: failed to load manifest for workspace member `/work/crates/gunnar-store`
/// Caused by: failed to read `/znippy/git-storage-trait/Cargo.toml`
/// ```
///
/// `crates/gunnar-store/Cargo.toml:33` declares
/// `path = "../../../znippy/git-storage-trait"` — one of 10 such deps reaching
/// into `edda` and `znippy`. From `/work/crates/gunnar-store` those three `..`
/// walk clean out of the mount and land at `/`. From
/// `/work/gunnar/crates/gunnar-store` they land at `/work/znippy/…`, which is
/// where the sibling bind is. The depth is the fix.
pub const WORKROOT: &str = "/work";
/// The container path `CARGO_TARGET_DIR` points at.
pub const TARGETDIR: &str = "/target";
/// The container `CARGO_HOME`.
pub const CARGO_HOME: &str = "/cargo";

/// The synthetic prefix BOTH sides remap [`WORKROOT`] / the host repo's PARENT
/// to, so the source path baked into debug info is a property of the BUILD and
/// not of the checkout. It is the parent and not the repo because a sibling
/// repo's sources get baked in too, and remapping only the repo would leave
/// those pointing at two different places.
pub const REMAP_SRC: &str = "/nordisk/src";
/// The synthetic prefix BOTH sides remap the cargo registry to.
pub const REMAP_REGISTRY: &str = "/nordisk/registry";
/// The synthetic prefix BOTH sides remap the TARGET DIR to.
///
/// The third path input, and the one that is easy to miss because it is not a
/// source directory: `OUT_DIR` lives under the target dir, so every line of
/// build-script-GENERATED code carries that path. MEASURED 2026-08-26 —
/// gunnar-server, with the repo and registry already remapped, still differed by
/// 6 808 bytes, and the whole of it was one string:
///
/// ```text
/// host:      ~/scratch/…/gunnar-htarget/…/build/gunnar-proto-ec9b63…/out/gunnar.v1.rs
/// container: /target/…/build/gunnar-proto-ec9b63…/out/gunnar.v1.rs
/// ```
///
/// 31 characters of difference, ~220 times over in DWARF. It was the ONLY
/// host-specific absolute path left in the binary.
pub const REMAP_TARGET: &str = "/nordisk/target";

fn default_image() -> String {
    CARGO_TOOLCHAIN_IMAGE.to_string()
}
fn default_timeout_secs() -> u64 {
    DEFAULT_TIMEOUT_SECS
}
fn default_mem_limit_mb() -> u32 {
    DEFAULT_MEM_LIMIT_MB
}
fn default_cpus() -> u32 {
    DEFAULT_CPUS
}
fn default_remap_paths() -> bool {
    true
}
fn is_true(b: &bool) -> bool {
    *b
}
fn is_false(b: &bool) -> bool {
    !*b
}

/// **The `[build.toolchain]` declaration** — what image the repo's cargo
/// variants compile in, and the bounds the container runs under.
///
/// Absent ⇒ the repo still builds on the host, unchanged. Present ⇒ every cargo
/// variant in the repo goes through the container, because "some variants are
/// hermetic" is not a property anyone can audit.
/// **Closed, like the two structs beside it.** This table's whole job is to make
/// the build environment auditable, and a key it silently drops is the one thing
/// that would quietly un-audit it — a `siblings` typo'd to `sibling` would mount
/// nothing and fail an hour later inside cargo, and a misspelled `image_sha256`
/// would read as "unpinned" and be REFUSED for the wrong reason. MEASURED
/// 2026-08-26: gunnar is the only repo declaring `[build.toolchain]` and has zero
/// unknown keys, so this costs nothing today.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct CargoToolchain {
    /// The toolchain image name (default [`CARGO_TOOLCHAIN_IMAGE`]).
    #[serde(default = "default_image")]
    pub image: String,
    /// **The digest pin.** The MANIFEST digest, 64 lowercase hex, no `sha256:`
    /// prefix. Empty is accepted by the parser and REFUSED by
    /// [`validate`](Self::validate) — a build environment that can drift under
    /// you is not an environment, it is a weather report.
    #[serde(default, skip_serializing_if = "String::is_empty")]
    pub image_sha256: String,
    /// The rustc version the image was built with. Recorded so a provenance
    /// reader can tell two images apart, and compared against what the
    /// container actually reports (a mismatch is a NAMED refusal, not a shrug).
    #[serde(default, skip_serializing_if = "String::is_empty")]
    pub rust_version: String,
    /// The target triples the image carries std for. Declared so a variant
    /// naming a target the image cannot build is refused BY NAME at validation
    /// instead of one hour later with `E0463`.
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub targets: Vec<String>,
    /// The build bound in seconds ([`DEFAULT_TIMEOUT_SECS`]).
    #[serde(default = "default_timeout_secs")]
    pub timeout_secs: u64,
    /// The memory bound in MiB ([`DEFAULT_MEM_LIMIT_MB`]). `0` is refused.
    #[serde(default = "default_mem_limit_mb")]
    pub mem_limit_mb: u32,
    /// The cpu bound in whole cores ([`DEFAULT_CPUS`]). `0` is refused.
    #[serde(default = "default_cpus")]
    pub cpus: u32,
    /// Whether the compile container gets a network. `false` (the default) runs
    /// `--network none` and adds `--offline --locked`.
    #[serde(default, skip_serializing_if = "is_false")]
    pub network: bool,
    /// Remap the repo root and the registry to [`REMAP_SRC`] / [`REMAP_REGISTRY`]
    /// on BOTH sides (default **on**) — the two path inputs that otherwise make
    /// a host build and a container build differ in bytes while being identical
    /// in meaning.
    #[serde(default = "default_remap_paths", skip_serializing_if = "is_true")]
    pub remap_paths: bool,
    /// **The SIBLING REPOS this repo's `path = "../../.."` dependencies reach
    /// into**, by directory name under the repo's own parent — e.g.
    /// `siblings = ["edda", "znippy"]`.
    ///
    /// This constellation does not have leaf repos. gunnar declares 10 path
    /// dependencies that walk out of its own tree into `edda` and `znippy`
    /// (`crates/gunnar-store/Cargo.toml:33`, `crates/gunnar-server/Cargo.toml:171`,
    /// …), and a container holding only the repo cannot see any of them:
    ///
    /// ```text
    /// error: failed to load manifest for workspace member `/work/crates/gunnar-store`
    /// Caused by: failed to read `/znippy/git-storage-trait/Cargo.toml`
    /// ```
    ///
    /// Declared, not discovered, and that is the point: each name here is one
    /// more tree whose contents end up inside the artifact, so it belongs in the
    /// declaration where a reader can see it. A path dep escaping into a sibling
    /// that is NOT listed is a refusal BY NAME
    /// ([`check_escaping_path_deps`](Self::check_escaping_path_deps)) — the
    /// cargo error above, named before the container starts and with the
    /// manifest line that caused it.
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub siblings: Vec<String>,
}

impl Default for CargoToolchain {
    fn default() -> Self {
        CargoToolchain {
            image: default_image(),
            image_sha256: String::new(),
            rust_version: String::new(),
            targets: Vec::new(),
            timeout_secs: default_timeout_secs(),
            mem_limit_mb: default_mem_limit_mb(),
            cpus: default_cpus(),
            network: false,
            remap_paths: default_remap_paths(),
            siblings: Vec::new(),
        }
    }
}

impl CargoToolchain {
    /// The effective image reference — digest-pinned when [`image_sha256`] is
    /// declared. Same spelling the kernel kind resolved to after the 2026-08-23
    /// correction: `<name>@sha256:<MANIFEST digest>` is addressable locally AND
    /// in a registry; an image id pasted there triggers a registry pull and
    /// fails.
    ///
    /// [`image_sha256`]: Self::image_sha256
    pub fn image_ref(&self) -> String {
        if self.image_sha256.is_empty() {
            return self.image.clone();
        }
        if self.image.is_empty() {
            return self.image_sha256.clone();
        }
        format!("{}@sha256:{}", self.image, self.image_sha256)
    }

    /// **Refuse an unauditable build environment BY NAME.** Every arm here is a
    /// thing that would otherwise surface as a confusing failure an hour into a
    /// compile, or — worse — as a green whose meaning nobody can reconstruct.
    pub fn validate(&self) -> Result<()> {
        if self.image.trim().is_empty() && self.image_sha256.trim().is_empty() {
            return Err(anyhow!(
                "[build.toolchain]: neither `image` nor `image_sha256` is declared — \
                 there is nothing for a container engine to run"
            ));
        }
        if self.image_sha256.is_empty() {
            return Err(anyhow!(
                "[build.toolchain] `{}`: no `image_sha256` — a named tag is a convenience, \
                 NOT a pin, and an unpinned build image can be replaced under you between \
                 two builds that report the same provenance",
                self.image
            ));
        }
        if !is_manifest_digest(&self.image_sha256) {
            return Err(anyhow!(
                "[build.toolchain] `{}`: `image_sha256` must be 64 lowercase hex characters \
                 (the MANIFEST digest, `podman image inspect --format '{{{{.Digest}}}}'`, \
                 with no `sha256:` prefix) — got `{}`",
                self.image,
                self.image_sha256
            ));
        }
        if self.mem_limit_mb == 0 {
            return Err(anyhow!(
                "[build.toolchain] `{}`: `mem_limit_mb = 0` — unbounded is not a bound. \
                 An unbounded build reached 33 GB on this constellation (2026-08-20), the \
                 OOM killer took the service, and the box went down",
                self.image
            ));
        }
        if self.cpus == 0 {
            return Err(anyhow!(
                "[build.toolchain] `{}`: `cpus = 0` — unbounded is not a bound",
                self.image
            ));
        }
        if self.timeout_secs == 0 {
            return Err(anyhow!(
                "[build.toolchain] `{}`: `timeout_secs = 0` — a build with no bound is a \
                 hang waiting to happen, and a hang is worse than a refusal",
                self.image
            ));
        }
        // The declaration is checked against the image's own recipe HERE, in the
        // one place every loader already goes through — a separate door nobody
        // walks through is how this crate's toolchain images spent a month
        // unbuildable.
        self.check_declared_targets()?;
        Ok(())
    }

    /// Refuse a variant whose `target` the image is not declared to carry —
    /// **at validation, not at `E0463`**. An empty [`targets`](Self::targets)
    /// is "undeclared", not "none": it accepts anything, exactly the way an
    /// empty `offers` does.
    pub fn check_target(&self, variant: &str, target: Option<&str>) -> Result<()> {
        let (Some(t), false) = (target, self.targets.is_empty()) else {
            return Ok(());
        };
        if self.targets.iter().any(|d| d == t) {
            return Ok(());
        }
        Err(anyhow!(
            "variant `{variant}` targets `{t}`, which the toolchain image `{}` does not \
             carry std for (it declares: {}). This is the `error[E0463]: can't find crate \
             for core` failure, named an hour earlier",
            self.image,
            self.targets.join(", ")
        ))
    }

    /// **Refuse a `targets` list the image cannot back.** The other direction of
    /// [`check_target`](Self::check_target), and the one that turns a named
    /// refusal back into a bare `E0463`.
    ///
    /// `check_target` trusts the declaration: a variant whose target is listed
    /// passes, and the compile then discovers inside the container that the std
    /// is not there. So the declaration is checked against the ONLY thing that
    /// can put a std in the image — its Containerfile's own `ARG RUST_TARGETS`
    /// ([`cargo_toolchain_image_targets`]).
    ///
    /// Skipped when the declared `image` is not [`CARGO_TOOLCHAIN_IMAGE`]: a repo
    /// naming some other image is naming an environment this crate does not
    /// build, and guessing at its contents would be worse than saying nothing.
    /// An empty `targets` is "undeclared" and accepts anything, same as
    /// `check_target`.
    pub fn check_declared_targets(&self) -> Result<()> {
        if self.targets.is_empty() || !self.image.contains(CARGO_TOOLCHAIN_IMAGE) {
            return Ok(());
        }
        let carried = cargo_toolchain_image_targets();
        let missing: Vec<&str> = self
            .targets
            .iter()
            .filter(|t| !carried.iter().any(|c| c == *t))
            .map(String::as_str)
            .collect();
        if missing.is_empty() {
            return Ok(());
        }
        Err(anyhow!(
            "[build.toolchain] `{}`: declares `targets` the image does NOT carry std for \
             ({}). The committed cargo-toolchain.Containerfile installs exactly: {}. \
             Declaring a triple does not install it — add it to `ARG RUST_TARGETS`, \
             rebuild the image and re-pin `image_sha256`, or drop it from `targets`. \
             Left as-is, `check_target` would wave the variant through and the compile \
             would die inside the container on `error[E0463]: can't find crate for std`",
            self.image,
            missing.join(", "),
            carried.join(", ")
        ))
    }

    /// The `RUSTFLAGS` the **container** side needs for a path-stable build.
    /// Empty when [`remap_paths`](Self::remap_paths) is off.
    pub fn container_rustflags(&self) -> String {
        if !self.remap_paths {
            return String::new();
        }
        format!(
            "--remap-path-prefix={WORKROOT}={REMAP_SRC} \
             --remap-path-prefix={CARGO_HOME}/registry={REMAP_REGISTRY} \
             --remap-path-prefix={TARGETDIR}={REMAP_TARGET}"
        )
    }

    /// The `RUSTFLAGS` the **host** side needs to be comparable with a container
    /// build of the same variant — the other half of the byte-identity gate.
    /// Without this the gate compares a binary that has `~/git/…`
    /// baked into it against one that has `/work/…`, calls them different, and
    /// blames the container for a difference the COMPARISON introduced.
    ///
    /// Takes the repo's PARENT, matching [`WORKROOT`] — a sibling repo's sources
    /// are baked in too, and remapping only the repo would leave those pointing
    /// at two different places.
    pub fn host_rustflags(
        &self,
        repo_root: &Path,
        cargo_home: &Path,
        target_dir: &Path,
    ) -> String {
        if !self.remap_paths {
            return String::new();
        }
        format!(
            "--remap-path-prefix={}={REMAP_SRC} \
             --remap-path-prefix={}/registry={REMAP_REGISTRY} \
             --remap-path-prefix={}={REMAP_TARGET}",
            checkout_parent(repo_root).display(),
            cargo_home.display(),
            target_dir.display()
        )
    }

    /// The container path the repo itself lands at: `<WORKROOT>/<repo dir name>`.
    /// The build's working directory.
    pub fn container_repo_dir(&self, repo_root: &Path) -> String {
        format!("{WORKROOT}/{}", repo_dir_name(repo_root))
    }

    /// The declared [`siblings`](Self::siblings) with NOTHING at their path beside
    /// the repo, as `(name, host path)` — what a forge may clone. A path that exists
    /// but is not a checkout is never in it: nothing is cloned over an existing dir.
    pub fn absent_siblings(&self, repo_root: &Path) -> Vec<(String, PathBuf)> {
        self.siblings
            .iter()
            .cloned()
            .zip(self.sibling_paths(repo_root))
            .filter(|(_, p)| std::fs::symlink_metadata(p).is_err())
            .collect()
    }

    /// The host paths of the declared [`siblings`](Self::siblings), resolved
    /// under the repo's parent.
    pub fn sibling_paths(&self, repo_root: &Path) -> Vec<PathBuf> {
        let parent = checkout_parent(repo_root);
        self.siblings.iter().map(|s| parent.join(s)).collect()
    }

    /// The bind mounts the run needs: the repo at
    /// [`container_repo_dir`](Self::container_repo_dir), each declared sibling
    /// beside it under [`WORKROOT`], the target dir at [`TARGETDIR`], and the
    /// host-fetched registry read-only under [`CARGO_HOME`].
    ///
    /// A sibling is mounted **read-only**: this build compiles it, it does not
    /// get to edit another repo's checkout.
    pub fn binds(
        &self,
        repo_root: &Path,
        target_dir: &Path,
        registry: Option<&Path>,
    ) -> Vec<String> {
        let mut b = vec![
            format!("{}:{}", repo_root.display(), self.container_repo_dir(repo_root)),
            format!("{}:{TARGETDIR}", target_dir.display()),
        ];
        for (name, host) in self.siblings.iter().zip(self.sibling_paths(repo_root)) {
            b.push(format!("{}:{WORKROOT}/{name}:ro", host.display()));
        }
        if let Some(r) = registry {
            // Read-only: the container COMPILES the pinned sources, it does not
            // get to edit the host's copy of them.
            b.push(format!("{}:{CARGO_HOME}/registry:ro", r.display()));
        }
        b
    }

    /// **Refuse a path dependency that walks out of the repo into a sibling
    /// nobody declared — BY NAME, before the container starts.**
    ///
    /// Without this the failure is cargo's, an hour or a second later, and it
    /// names the path it could not read rather than the manifest line that asked
    /// for it or the `siblings` entry that would fix it:
    ///
    /// ```text
    /// Caused by: failed to read `/znippy/git-storage-trait/Cargo.toml`
    /// ```
    ///
    /// A dep reaching ABOVE the parent (`../../../../elsewhere`) is refused
    /// too, and separately: a flat sibling mount cannot reproduce that layout,
    /// so declaring it would not help and pretending otherwise would be worse
    /// than the refusal.
    pub fn check_escaping_path_deps(&self, repo_root: &Path) -> Result<()> {
        self.check_escaping_path_deps_from(repo_root, repo_root)
    }

    /// **This declaration as `variant` builds under it.** A row that declares its
    /// own [`siblings`](crate::variant::BuildVariant::siblings) gets exactly those
    /// in place of the repo-wide list; a row that declares none gets the
    /// declaration unchanged. Everything else — image, pin, bounds — stays the
    /// toolchain's: a row chooses what it reaches, never what compiles it.
    pub fn for_variant(&self, v: &BuildVariant) -> CargoToolchain {
        if v.siblings.is_empty() {
            return self.clone();
        }
        CargoToolchain { siblings: v.siblings.clone(), ..self.clone() }
    }

    /// [`check_escaping_path_deps`](Self::check_escaping_path_deps), scanning the
    /// manifests under `scan_root` instead of the whole repo — the root a row's
    /// cargo actually loads ([`variant_manifest_root`]). A row built with
    /// `--manifest-path ../holger/Cargo.toml` never reads this repo's other
    /// manifests, so their path deps must not demand checkouts that row does not
    /// mount. The declared siblings still resolve beside `repo_root`, and a dep
    /// back into the repo itself (mounted as the workdir) is not an escape.
    pub fn check_escaping_path_deps_from(&self, repo_root: &Path, scan_root: &Path) -> Result<()> {
        let parent = checkout_parent(repo_root);
        let own = repo_dir_name(repo_root);
        // A declared sibling that is not on this box would surface as a bind
        // failure from the engine, naming a mount and not a declaration. Say it
        // here, where the reader is already looking at the list.
        let absent: Vec<String> = self
            .siblings
            .iter()
            .zip(self.sibling_paths(repo_root))
            .filter(|(_, p)| !p.is_dir())
            .map(|(n, p)| format!("{n} ({})", p.display()))
            .collect();
        if !absent.is_empty() {
            let missing: Vec<&str> = self
                .siblings
                .iter()
                .zip(self.sibling_paths(repo_root))
                .filter(|(_, p)| !p.is_dir())
                .map(|(n, _)| n.as_str())
                .collect();
            return Err(anyhow!(
                "[build.toolchain] `siblings` names {} repo(s) that are not checked out beside \
                 `{}` — the bind mount would fail, and the engine's error names a path rather \
                 than this declaration: {}. {}",
                absent.len(),
                repo_root.display(),
                absent.join(", "),
                clone_hint(&parent, &missing)
            ));
        }
        let mut missing: BTreeMap<String, Vec<String>> = BTreeMap::new();
        let mut unreachable: Vec<String> = Vec::new();
        // ★ The repo's OWN workspace either way: a directory below it whose `Cargo.toml`
        // declares its own `[workspace]` is a DETACHED crate cargo does not load when it builds
        // this repo's rows, so its path deps demand no checkout of theirs (5.3.2 receipt,
        // 2026-10-09: monetize-impl's toolchain was refused "Add `siblings = [\"gunnar\"]`" for
        // its detached `gunnar-front-commercial`, which only gunnar's own front rows build — and
        // those rows are checked against THAT workspace, with their own siblings).
        let escapes = workspace_escaping_path_deps(scan_root);
        for (manifest, dep, resolved) in escapes {
            let where_ = format!("{} → {dep}", manifest.display());
            match resolved.strip_prefix(&parent).ok().and_then(|r| {
                r.components().next().and_then(|c| c.as_os_str().to_str()).map(str::to_string)
            }) {
                Some(sib) if self.siblings.contains(&sib) || sib == own => {}
                Some(sib) => missing.entry(sib).or_default().push(where_),
                None => unreachable.push(where_),
            }
        }
        if !unreachable.is_empty() {
            return Err(anyhow!(
                "{} path dependenc{} reach ABOVE the repo's parent ({}), which a flat \
                 sibling mount cannot reproduce — the container would have to carry an \
                 unbounded slice of this box's filesystem: {}",
                unreachable.len(),
                if unreachable.len() == 1 { "y" } else { "ies" },
                parent.display(),
                unreachable.join("; ")
            ));
        }
        if !missing.is_empty() {
            let names: Vec<&str> = missing.keys().map(String::as_str).collect();
            let detail: Vec<String> = missing
                .iter()
                .map(|(s, w)| format!("{s} ({} dep(s), e.g. {})", w.len(), w[0]))
                .collect();
            return Err(anyhow!(
                "[build.toolchain]: path dependencies escape this repo into sibling \
                 repo(s) the declaration does not list — the build container would not \
                 have them and cargo would fail on `failed to read …/Cargo.toml`. Add \
                 `siblings = [{}]`. Escaping: {}",
                names.iter().map(|n| format!("\"{n}\"")).collect::<Vec<_>>().join(", "),
                detail.join("; ")
            ));
        }
        Ok(())
    }
}

/// **Where an absent sibling is cloned FROM** — read off this box, never guessed.
///
/// 2026-10-16 (loki, ⚒ Build tunnr): the refusal named `tunnr-mullvad` and
/// `tunnr-tailscale` and the path they were missing from, and nothing about where
/// they live — and they do not live where tunnr does (nordisk/, not mikronova/), so
/// "the same forge as this repo" would have been wrong. What the box DOES know is
/// where every checkout beside it came from: each neighbour's `origin`. Those
/// bases, deduplicated, are the candidates, and the hint spells the clone line for
/// each. A box whose neighbours name no remote says so instead of inventing one.
fn clone_hint(parent: &Path, missing: &[&str]) -> String {
    let bases = neighbour_bases(parent);
    if bases.is_empty() {
        return format!(
            "No checkout beside it names an `origin`, so where to clone {} from cannot be read off \
             this box.",
            missing.join(", ")
        );
    }
    let lines: Vec<String> = missing
        .iter()
        .flat_map(|n| bases.iter().map(move |b| format!("git clone {b}/{n} {}", parent.join(n).display())))
        .collect();
    format!(
        "Clone it beside the others — the checkouts there come from {}; one of: {}",
        bases.iter().cloned().collect::<Vec<_>>().join(", "),
        lines.join(" | ")
    )
}

/// A checkout's `origin` URL as its `.git/config` names it (no `.git`, no trailing
/// `/`); `None` for a dir that is not a checkout or names no `origin`.
fn origin_url(checkout: &Path) -> Option<String> {
    let cfg = std::fs::read_to_string(checkout.join(".git").join("config")).ok()?;
    let mut in_origin = false;
    for line in cfg.lines().map(str::trim) {
        if line.starts_with('[') {
            in_origin = line == "[remote \"origin\"]";
        } else if in_origin {
            if let Some(url) = line.strip_prefix("url").map(str::trim_start).and_then(|l| l.strip_prefix('=')) {
                return Some(url.trim().trim_end_matches('/').trim_end_matches(".git").to_string());
            }
        }
    }
    None
}

/// The base (`<host>/<namespace>`) an `origin` URL clones from: all but its last
/// segment.
fn base_of(url: &str) -> Option<&str> {
    url.rsplit_once('/').map(|(b, _)| b)
}

/// Every base the checkouts under `parent` come from (each neighbour's `origin`).
fn neighbour_bases(parent: &Path) -> std::collections::BTreeSet<String> {
    let mut bases = std::collections::BTreeSet::new();
    if let Ok(rd) = std::fs::read_dir(parent) {
        for e in rd.flatten() {
            if let Some(b) = origin_url(&e.path()).as_deref().and_then(base_of) {
                bases.insert(b.to_string());
            }
        }
    }
    bases
}

/// **Where an absent sibling `name` of `repo_root` is cloned FROM, best first** —
/// read off this box, never invented: the repo's own `origin` base (the same host
/// and namespace) first, then every other namespace the neighbouring checkouts come
/// from ON THAT HOST (a mikronova repo's sibling may live in nordisk: tunnr and
/// tunnr-mullvad, loki 2026-10-16). The caller tries them in order and the first
/// that clones is where it lives. A repo with no `origin` falls back to every base
/// its neighbours name; a box whose checkouts name no remote gives none.
pub fn sibling_clone_urls(repo_root: &Path, name: &str) -> Vec<String> {
    let neighbours = neighbour_bases(&checkout_parent(repo_root));
    let own = origin_url(repo_root).and_then(|u| base_of(&u).map(str::to_string));
    let mut out: Vec<String> = Vec::new();
    let mut push = |b: &str| {
        let url = format!("{b}/{name}");
        if !out.contains(&url) {
            out.push(url);
        }
    };
    match own {
        Some(own) => {
            push(&own);
            let host = base_of(&own).unwrap_or("");
            for b in neighbours.iter().filter(|b| base_of(b).unwrap_or("") == host) {
                push(b);
            }
        }
        None => neighbours.iter().for_each(|b| push(b)),
    }
    out
}

/// The repo's own directory name — the component reproduced under [`WORKROOT`].
fn repo_dir_name(repo_root: &Path) -> String {
    repo_root
        .file_name()
        .and_then(|s| s.to_str())
        .filter(|s| !s.is_empty())
        .unwrap_or("repo")
        .to_string()
}

/// The directory the repo and its siblings share. `~/git` for
/// `~/git/gunnar`.
fn checkout_parent(repo_root: &Path) -> PathBuf {
    repo_root.parent().map(Path::to_path_buf).unwrap_or_else(|| PathBuf::from("/"))
}

/// Every `path = "…"` dependency in the repo's manifests that resolves OUTSIDE
/// the repo root, as `(manifest, dep name, resolved path)`.
///
/// Read with a real TOML parser rather than a regex over the file: `path` also
/// appears in `[[bin]]`, in `[lib]` and inside prose, and a scan that cannot
/// tell those apart reports a dependency that does not exist. Only the four
/// dependency table shapes cargo actually resolves are visited.
pub fn escaping_path_deps(repo_root: &Path) -> Vec<(PathBuf, String, PathBuf)> {
    escaping_path_deps_scoped(repo_root, false)
}

/// [`escaping_path_deps`] of the ONE workspace rooted at `root`: a directory
/// below it whose `Cargo.toml` declares its own `[workspace]` is another
/// workspace cargo does not load when it builds this one, so its manifests are
/// not read. MEASURED 2026-09-28: holger excludes `holger-estate-front` (its own
/// workspace) and `cargo metadata` of holger loads neither `holger-ui` nor
/// `monetize`, while a whole-tree scan demanded both for holger's plugin row.
pub fn workspace_escaping_path_deps(root: &Path) -> Vec<(PathBuf, String, PathBuf)> {
    escaping_path_deps_scoped(root, true)
}

fn declares_workspace(dir: &Path) -> bool {
    std::fs::read_to_string(dir.join("Cargo.toml"))
        .ok()
        // A whole manifest is a TABLE: toml >= 0.9 parses `Value` as ONE value, so
        // `parse::<toml::Value>()` of a Cargo.toml fails and every workspace root
        // would read as "declares none" (2026-10-03, the release-3 merge onto toml 1).
        .and_then(|t| t.parse::<toml::Table>().ok())
        .is_some_and(|d| d.contains_key("workspace"))
}

fn escaping_path_deps_scoped(repo_root: &Path, one_workspace: bool) -> Vec<(PathBuf, String, PathBuf)> {
    let mut out = Vec::new();
    let mut stack = vec![repo_root.to_path_buf()];
    while let Some(dir) = stack.pop() {
        let Ok(rd) = std::fs::read_dir(&dir) else { continue };
        for e in rd.flatten() {
            let p = e.path();
            let name = e.file_name();
            let name = name.to_string_lossy();
            if p.is_dir() {
                // `target` is build output and `.git` is history; neither
                // declares a dependency, and both are large.
                if name != "target" && !name.starts_with('.') && !(one_workspace && declares_workspace(&p)) {
                    stack.push(p);
                }
            } else if name == "Cargo.toml" {
                collect_escaping(&p, repo_root, &mut out);
            }
        }
    }
    out.sort();
    out
}

fn collect_escaping(manifest: &Path, repo_root: &Path, out: &mut Vec<(PathBuf, String, PathBuf)>) {
    let Ok(text) = std::fs::read_to_string(manifest) else { return };
    let Ok(doc) = text.parse::<toml::Table>().map(toml::Value::Table) else { return };
    let dir = manifest.parent().unwrap_or(Path::new("."));
    let mut tables: Vec<&toml::Value> = Vec::new();
    for key in ["dependencies", "dev-dependencies", "build-dependencies"] {
        if let Some(t) = doc.get(key) {
            tables.push(t);
        }
    }
    // `[target.<cfg>.dependencies]` and the workspace's own
    // `[workspace.dependencies]` — both resolve paths the same way.
    if let Some(t) = doc.get("target").and_then(toml::Value::as_table) {
        for v in t.values() {
            for key in ["dependencies", "dev-dependencies", "build-dependencies"] {
                if let Some(d) = v.get(key) {
                    tables.push(d);
                }
            }
        }
    }
    if let Some(d) = doc.get("workspace").and_then(|w| w.get("dependencies")) {
        tables.push(d);
    }
    for table in tables {
        let Some(t) = table.as_table() else { continue };
        for (dep, spec) in t {
            let Some(rel) = spec.get("path").and_then(toml::Value::as_str) else { continue };
            let resolved = normalize(&dir.join(rel));
            if !resolved.starts_with(repo_root) {
                out.push((manifest.to_path_buf(), dep.clone(), resolved));
            }
        }
    }
}

/// Lexical `..`/`.` resolution. NOT `canonicalize`: the target of a path dep may
/// not exist yet (that is one of the things being reported), and canonicalize
/// also resolves symlinks, which would silently rewrite a layout the operator
/// deliberately built out of links.
fn normalize(p: &Path) -> PathBuf {
    let mut out = PathBuf::new();
    for c in p.components() {
        match c {
            std::path::Component::ParentDir => {
                out.pop();
            }
            std::path::Component::CurDir => {}
            other => out.push(other.as_os_str()),
        }
    }
    out
}

/// **The two host paths the container run needs**, resolved in ONE place.
///
/// A consumer that re-reads `CARGO_TARGET_DIR` and `CARGO_HOME` itself becomes a
/// second env-reading twin, and the two drift the first time one of them learns
/// about a new fallback. dwarves already paid for that shape once
/// (`BuildRecordTarget::from_env`, "one resolution, not a second env-reading
/// twin").
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct HostPaths {
    /// The host directory bind-mounted at [`TARGETDIR`]. `CARGO_TARGET_DIR`, else
    /// `<repo_root>/target` — cargo's own ladder, in cargo's own order.
    ///
    /// NOTE this deliberately does NOT consult `~/.cargo/config.toml`'s
    /// `[build] target-dir`. Reading it would need cargo's whole config merge
    /// (hierarchical, per-directory), and half of that ladder is worse than none:
    /// the honest statement is "env or the conventional path", and a caller with
    /// a configured target dir exports the variable.
    pub target_dir: PathBuf,
    /// The host cargo registry bind-mounted read-only under [`CARGO_HOME`].
    /// `CARGO_HOME/registry`, else `~/.cargo/registry`.
    pub registry: PathBuf,
}

impl HostPaths {
    /// Resolve from the environment, relative to `repo_root`.
    pub fn from_env(repo_root: &Path) -> Self {
        let target_dir = std::env::var_os("CARGO_TARGET_DIR")
            .map(PathBuf::from)
            .unwrap_or_else(|| repo_root.join("target"));
        let cargo_home = std::env::var_os("CARGO_HOME").map(PathBuf::from).or_else(|| {
            std::env::var_os("HOME").map(|h| PathBuf::from(h).join(".cargo"))
        });
        let registry = cargo_home
            .unwrap_or_else(|| PathBuf::from("/nonexistent"))
            .join("registry");
        HostPaths { target_dir, registry }
    }

    /// The registry to bind, or `None` when it does not exist on this box. An
    /// absent registry is NOT an error here: with `network = true` the container
    /// fetches its own, and binding a path that is not there would fail the run
    /// for a reason that has nothing to do with the build.
    pub fn registry_bind(&self) -> Option<&Path> {
        self.registry.is_dir().then_some(self.registry.as_path())
    }
}

/// Is `s` a manifest digest — 64 lowercase hex characters, no prefix?
fn is_manifest_digest(s: &str) -> bool {
    s.len() == 64 && s.bytes().all(|c| c.is_ascii_digit() || (b'a'..=b'f').contains(&c))
}

/// The sentinel the build script prints before cargo runs, so the provenance
/// records the **container's** toolchain. Recording `Toolchain::detect()` for a
/// container build would attest to the host's rustc for a binary the host's
/// rustc never touched — a provenance that is precisely wrong.
pub const RUSTC_SENTINEL: &str = "##nordisk-rustc##";
/// The sentinel prefix for the cargo version line.
pub const CARGO_SENTINEL: &str = "##nordisk-cargo##";
/// The sentinel prefix for the container's resolved host triple.
pub const HOST_SENTINEL: &str = "##nordisk-host##";

/// **The engine-side name of one build container, scoped to its checkout.**
///
/// draupnir names a container `draupnir-<spec name>` and the name is global to
/// the USER's container engine. Before this, two builds of the same row from two
/// checkouts (two agents, two constellations: `cargo-build-holger-server` from
/// `~/a/holger` and from `~/b/holger`) asked for the same name: the second was
/// refused `[container-name-in-use]` while the first ran, and a crashed one's
/// leftover was reaped by the other's preflight. The name now carries 8 hex of
/// the sha256 of the run's HOST bind paths (checkout, target directory, stage):
/// the same checkout and target keep ONE name (a leftover of an interrupted run
/// is still reaped by the next run of the same place), two places get two.
pub fn scoped_container_name(label: &str, binds: &[String]) -> String {
    use sha2::{Digest, Sha256};
    let mut hosts: Vec<&str> = binds.iter().map(|b| b.split(':').next().unwrap_or("")).collect();
    hosts.sort_unstable();
    hosts.dedup();
    let d = Sha256::digest(hosts.join("\n").as_bytes());
    format!("{label}-{:02x}{:02x}{:02x}{:02x}", d[0], d[1], d[2], d[3])
}

/// **The request handed to the container seam** — everything the run needs and
/// nothing the runner has to guess.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CargoRunRequest {
    /// A short label for the container (the variant name).
    pub name: String,
    /// The pinned image reference ([`CargoToolchain::image_ref`]).
    pub image: String,
    /// The `sh -eu -c` script.
    pub script: String,
    /// Host bind mounts ([`CargoToolchain::binds`]).
    pub binds: Vec<String>,
    /// The bound; overrun stops the container and returns an error.
    pub timeout: Duration,
    /// `false` runs airgapped (`--network none`).
    pub network: bool,
    /// The memory bound in MiB — draupnir `--memory`. Never absent.
    pub mem_limit_mb: u32,
    /// The cpu bound in whole cores — draupnir `--cpus`.
    pub cpus: u32,
}

/// What came back from the container run. A non-zero exit is a VALUE here; the
/// ORCHESTRATOR turns it into a named refusal, so the policy lives in one place.
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct CargoRunOutcome {
    /// The container's exit code (`Some(0)` = clean), `None` if the engine
    /// reported none.
    pub exit_code: Option<i64>,
    /// Captured stdout lines — the `--message-format=json` stream plus the
    /// sentinels.
    pub stdout: Vec<String>,
    /// Captured stderr lines.
    pub stderr: Vec<String>,
}

/// **The container seam** the cargo builder drives — one method, so a test
/// injects a fake and proves the orchestration (and every red arm) with no
/// daemon. The production impl is [`DraupnirCargoRunner`] (feature
/// `cargo-container`), over draupnir's `backend-oci` bollard engine.
///
/// Shaped deliberately like [`KernelContainerRunner`](crate::kernel::KernelContainerRunner):
/// two kinds that both run a bounded container should not have two different
/// ideas of what that means.
pub trait CargoContainerRunner {
    /// Run the build container to completion within `req.timeout`.
    fn run(&self, req: &CargoRunRequest) -> Result<CargoRunOutcome>;
    /// The engine label the provenance records.
    fn engine(&self) -> &str {
        "draupnir-oci"
    }
}

/// **The file, under the bind-mounted target dir, that the container writes
/// cargo's json stream to** — the channel this crate actually reads the build
/// from. Named per variant so two builds sharing a target dir cannot overwrite
/// each other's evidence.
///
/// See [`build_script`] for why there is a file at all.
pub fn cargo_stream_file(variant: &str) -> String {
    format!(".nornir-cargo-{variant}.jsonl")
}

/// Build the `sh -eu -c` script for one variant.
///
/// It is generated, never hand-written per repo: the argv comes from
/// [`BuildVariant::cargo_args`](crate::variant::BuildVariant::cargo_args), the
/// SAME writer the host path uses, so the container cannot drift into building
/// a different thing than the forge claims it built.
///
/// # Why the output goes to a FILE and is only then echoed
///
/// **A container's stdout, as relayed by the engine, is not a channel you can
/// build a correctness decision on.** MEASURED on t14s 2026-09-12, rootless
/// podman 5.7: 20 runs of a container that printed 901 lines and exited
/// returned `exit_code = Some(0)` with 0, 0, 0 and 749 lines in four of them —
/// and asking the daemon afterwards for the container's whole log, in one
/// `follow=false` request while the container still existed, returned **the
/// same short answer**. The lines were not late; they were gone. The engine
/// simply does not always have what the container printed.
///
/// That matters here more than anywhere else in this crate, because cargo's
/// `--message-format=json` stream is the ONLY thing that says a binary was
/// produced (`"reason":"compiler-artifact"` with a non-null `executable`), and
/// that line is the second-to-last of ~900. A dropped tail is a build that
/// reports success and no binary — the gunnar appliance compose's step-3
/// failure that day.
///
/// So the script writes the sentinels and cargo's stream into
/// [`cargo_stream_file`] under [`TARGETDIR`], which is a HOST directory bound
/// into the container, and the host reads the file. No daemon in the middle.
/// It is still `cat`ed to stdout afterwards so an operator watching the run
/// sees what they always saw, and so the stdout copy remains a fallback.
///
/// The `if { … } > file; then … else … fi` shape is deliberate: the script runs
/// under `sh -eu`, where a plain non-zero cargo would abort before the `cat`
/// and take cargo's own diagnostics with it. A compound in an `if` condition is
/// exempt from `-e`, so a red build still gets its output echoed and still
/// exits with cargo's code.
pub fn build_script(
    tc: &CargoToolchain,
    workdir: &str,
    cargo_args: &[String],
    cfg: Option<&str>,
    stream_file: &str,
) -> String {
    build_script_with_env(tc, workdir, cargo_args, cfg, &RunEnv::new(), stream_file)
}

/// [`build_script`] **plus the environment a build script reads** — exported
/// after the fixed ones, each value single-quoted. A key that is not a plain
/// `[A-Za-z_][A-Za-z0-9_]*` name is dropped: it could not be exported anyway,
/// and must not reach the shell as text.
pub fn build_script_with_env(
    tc: &CargoToolchain,
    workdir: &str,
    cargo_args: &[String],
    cfg: Option<&str>,
    env: &RunEnv,
    stream_file: &str,
) -> String {
    let mut rustflags = tc.container_rustflags();
    if let Some(c) = cfg {
        // The variant's `cfg` rides the same RUSTFLAGS the host path builds
        // (`provenance.rs:477`) — one rule, two transports.
        if !rustflags.is_empty() {
            rustflags.push(' ');
        }
        rustflags.push_str("--cfg ");
        rustflags.push_str(c);
    }
    let mut args: Vec<String> = cargo_args.to_vec();
    args.push("--message-format=json".into());
    // `--locked` is what turns Cargo.lock from documentation into a pin, and it
    // is not optional in here: a container that is allowed to re-resolve has
    // reintroduced the drift the container exists to remove.
    args.push("--locked".into());
    if !tc.network {
        args.push("--offline".into());
    }
    let quoted: Vec<String> = args.iter().map(|a| shell_single_quote(a)).collect();
    let stream = shell_single_quote(&format!("{TARGETDIR}/{stream_file}"));
    let extra_env: String = env
        .iter()
        .filter(|(k, _)| {
            let mut c = k.chars();
            c.next().is_some_and(|f| f.is_ascii_alphabetic() || f == '_')
                && c.all(|ch| ch.is_ascii_alphanumeric() || ch == '_')
        })
        .map(|(k, v)| format!("export {k}={}\n", shell_single_quote(v)))
        .collect();
    // The image IS the pinned toolchain (`rust_version`). A repo's
    // `rust-toolchain.toml` names the HOST's toolchain, and when it asks for
    // anything the image does not carry (a component such as rustfmt or
    // clippy) rustup tries to download it — with no network, so the build dies
    // before cargo starts. MEASURED on loki 2026-09-26: korp-boot in tunnr
    // (whose file lists `components = ["rustfmt", "clippy"]`) failed with
    // "syncing channel updates for '1.97.1…' … name resolution". The same rule
    // `web_app` already applies; exported before the caller's env so a caller
    // can still override it.
    let toolchain_env = if tc.rust_version.is_empty() {
        String::new()
    } else {
        format!("export RUSTUP_TOOLCHAIN={}\n", shell_single_quote(&tc.rust_version))
    };
    format!(
        "export CARGO_HOME={CARGO_HOME}\n\
         export CARGO_TARGET_DIR={TARGETDIR}\n\
         export RUSTFLAGS={}\n\
         export CARGO_TERM_COLOR=never\n\
         {}\
         {}\
         cd {}\n\
         if {{\n\
         echo \"{RUSTC_SENTINEL}$(rustc --version)\"\n\
         echo \"{CARGO_SENTINEL}$(cargo --version)\"\n\
         echo \"{HOST_SENTINEL}$(rustc -vV | sed -n 's/^host: //p')\"\n\
         cargo {}\n\
         }} > {stream}; then rc=0; else rc=$?; fi\n\
         cat {stream} || true\n\
         exit $rc\n",
        shell_single_quote(&rustflags),
        toolchain_env,
        extra_env,
        shell_single_quote(workdir),
        quoted.join(" ")
    )
}

/// POSIX single-quoting. The script is assembled in Rust and handed to `sh -eu
/// -c` INSIDE the container — the same thing the kernel kind does — so a variant
/// name or feature string carrying a quote cannot rewrite the command.
fn shell_single_quote(s: &str) -> String {
    format!("'{}'", s.replace('\'', r"'\''"))
}

/// **The one container-driving loop.** Validate the declaration and the
/// variant, run the pinned image over `runner`, parse the SAME
/// `--message-format=json` stream the host path parses, map the artifact paths
/// back to the host, and capture provenance recording the CONTAINER's toolchain.
///
/// `target_dir` is the host directory bind-mounted at [`TARGETDIR`]; `registry`
/// is the host cargo registry bind-mounted read-only (`None` only makes sense
/// with `network = true`).
pub fn build_variant_in_container(
    set: &BuildVariantSet,
    name: &str,
    repo_root: &Path,
    target_dir: &Path,
    registry: Option<&Path>,
    tc: &CargoToolchain,
    runner: &dyn CargoContainerRunner,
) -> Result<BuildOutcome> {
    build_variant_in_container_diagnosed(set, name, repo_root, target_dir, registry, tc, runner, &mut None)
}

/// **What a container cargo run SAID**, for a caller that shows a build to a
/// person: cargo's real exit status, the compiler's rendered errors, and the
/// container's stderr tail (the reason when cargo emitted no diagnostic — a
/// missing system library, an OOM, a bad mount). [`build_variant_in_container`]
/// only printed these on the process's own stderr, so the ⚒ log said a red build
/// had "exited 0" with no error in sight (loki 2026-10-16: openssl, -lgraphblas).
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct ContainerDiagnostics {
    /// cargo's exit code inside the container; `None` = it never reported one.
    pub exit_code: Option<i64>,
    /// The compiler's rendered errors, in order.
    pub errors: Vec<String>,
    /// The last lines of the container's stderr (at most 30).
    pub stderr_tail: Vec<String>,
}

/// [`build_variant_in_container`] that also hands back what the run said
/// ([`ContainerDiagnostics`]) in `diag` — set whenever the container ran, green or
/// red.
#[allow(clippy::too_many_arguments)]
pub fn build_variant_in_container_diagnosed(
    set: &BuildVariantSet,
    name: &str,
    repo_root: &Path,
    target_dir: &Path,
    registry: Option<&Path>,
    tc: &CargoToolchain,
    runner: &dyn CargoContainerRunner,
    diag: &mut Option<ContainerDiagnostics>,
) -> Result<BuildOutcome> {
    tc.validate()?;
    let variant = set.require(name)?;
    set.validate(variant)?;
    // The row's own sibling checkouts, when it declares them (`siblings` on the
    // row): only those are mounted and only those must exist.
    let tc = &tc.for_variant(variant);
    tc.check_target(name, variant.target.as_deref())?;
    // Only a row that declares its own siblings is scanned from its own manifest
    // root, and only such a row RUNS there (its own `.cargo/config.toml`, e.g.
    // holger's sibling patches); every other row keeps the repo (a `manifest_dir`
    // inside the repo may belong to the repo's workspace).
    let own_root = (!variant.siblings.is_empty()).then(|| variant_manifest_root(repo_root, variant));
    let (cargo_args, workdir) = match own_root.as_deref().and_then(|r| container_dir_of(repo_root, r)) {
        Some(dir) => (manifest_path_at_root(variant.cargo_args()), Some(dir)),
        None => (variant.cargo_args(), None),
    };
    let run = run_cargo_in_container_scanning(
        tc,
        &CargoInvocation {
            label: name.to_string(),
            repo_root: repo_root.to_path_buf(),
            target_dir: target_dir.to_path_buf(),
            registry: registry.map(Path::to_path_buf),
            cargo_args,
            cfg: variant.cfg.clone(),
            env: host_job_limit(),
            extra_binds: Vec::new(),
        },
        runner,
        &own_root.clone().unwrap_or_else(|| repo_root.to_path_buf()),
        workdir.as_deref(),
    )?;
    let (out, parsed) = (run.outcome, run.parsed);
    let success = out.exit_code == Some(0);
    *diag = Some(ContainerDiagnostics {
        exit_code: out.exit_code,
        errors: parsed.errors.clone(),
        stderr_tail: out.stderr.iter().rev().take(30).rev().cloned().collect(),
    });
    // **The judge, shared with the host road** (`provenance::ensure_exe_was_produced`)
    // and applied BEFORE the provenance record is captured: a run that exited 0
    // and staged nothing must be refused HERE, in the words that name the cause,
    // not discovered by whoever later reaches for the file. It bites hardest on
    // this road, because here cargo's stdout is carried by the engine's log
    // stream — MEASURED on t14s 2026-09-12, 4 of 20 runs of a chatty container
    // came back with exit 0 and a truncated or EMPTY stdout (draupnir 0.1.13
    // closes that hole; this refuses what reaches here regardless of why).
    crate::provenance::ensure_exe_was_produced(
        variant,
        &format!("the container {}", tc.image_ref()),
        success,
        parsed.units,
        &parsed.artifacts,
    )?;
    let outcome = if success { Outcome::Success } else { Outcome::Failed };
    let record = BuildProvenance::capture(
        variant,
        &repo_name(repo_root),
        repo_root,
        // The CONTAINER's toolchain, read off the sentinels — not
        // `Toolchain::detect()`, which would attest to a rustc that never ran.
        Toolchain {
            rustc: parsed.rustc.clone(),
            host: parsed.host.clone(),
            cargo: parsed.cargo.clone(),
            ..Default::default()
        }
        // …and WHICH container it was. The sentinels give the rustc that ran;
        // only the recipe knows the image and its manifest digest, and that is
        // the pair the question "which artifacts were built with the wrong
        // toolchain image" is asked of. An unpinned digest stays `None` rather
        // than becoming an empty string that looks like an answer.
        .with_container_image(
            Some(tc.image.clone()),
            (!tc.image_sha256.is_empty()).then(|| tc.image_sha256.clone()),
        ),
        HostInfo::detect(),
        outcome,
        &parsed.artifacts,
    )?
    // Every tree this run compiled: the repo and each sibling it MOUNTED — the
    // container road is the one place that knows the set, because it is the
    // set it bound in (`siblings`). Without them a holger binary's provenance
    // named one of its twelve source repos.
    .with_sources(SourceRev::read_all(&repo_name(repo_root), repo_root, &tc.siblings));
    let attestation = record.attest()?;
    Ok(BuildOutcome {
        variant: name.to_string(),
        artifacts: parsed.artifacts,
        attestation,
        success,
    })
}

/// **One cargo invocation for the pinned image** that is not a declared
/// `[[build.variant]]` — a composer's own build (korp-installer's korp-boot and
/// its two PID-1s) — carrying exactly what [`build_variant_in_container`] would
/// otherwise read off the variant.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CargoInvocation {
    /// A short label: the container name suffix and the stream file's name.
    pub label: String,
    /// The repo mounted at [`CargoToolchain::container_repo_dir`]; cargo runs there.
    pub repo_root: PathBuf,
    /// The host dir bound at [`TARGETDIR`].
    pub target_dir: PathBuf,
    /// The host cargo registry, bound read-only.
    pub registry: Option<PathBuf>,
    /// cargo's arguments (`build --release …`). `--message-format=json`,
    /// `--locked` and (airgapped) `--offline` are appended by [`build_script`].
    pub cargo_args: Vec<String>,
    /// A `--cfg` riding RUSTFLAGS, as a variant's `cfg` does.
    pub cfg: Option<String>,
    /// Environment the build needs INSIDE the container (a build script's
    /// inputs). The container inherits nothing from the host, so this is the
    /// whole of it.
    pub env: RunEnv,
    /// Extra `host:container[:ro]` binds (an input file a build script reads).
    pub extra_binds: Vec<String>,
}

/// What [`run_cargo_in_container`] hands back: the engine's outcome and the
/// parsed stream (artifacts already mapped to host paths).
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CargoContainerRun {
    /// The engine's verdict and captured streams.
    pub outcome: CargoRunOutcome,
    /// The stream read back from the target dir.
    pub parsed: ParsedRun,
}

impl CargoContainerRun {
    /// `true` when the container exited 0.
    pub fn success(&self) -> bool {
        self.outcome.exit_code == Some(0)
    }
}

/// **The one container-driving loop.** Run `inv` in the pinned image over
/// `runner` and parse the SAME `--message-format=json` stream the host path
/// parses. [`build_variant_in_container`] is this plus a variant's judge and
/// provenance; a composer's ad-hoc build is this plus its own output checks.
/// A red build has its compiler errors and the stderr tail printed here.
pub fn run_cargo_in_container(
    tc: &CargoToolchain,
    inv: &CargoInvocation,
    runner: &dyn CargoContainerRunner,
) -> Result<CargoContainerRun> {
    run_cargo_in_container_scanning(tc, inv, runner, &inv.repo_root, None)
}

/// The root whose manifests a row's cargo loads: the repo, or — for a row with a
/// [`manifest_dir`](BuildVariant::manifest_dir) — that directory, resolved
/// lexically against the repo (`../holger` → the sibling checkout `holger`).
pub fn variant_manifest_root(repo_root: &Path, v: &BuildVariant) -> PathBuf {
    match v.manifest_dir.as_deref().map(str::trim).filter(|d| !d.is_empty()) {
        Some(d) => {
            let abs = std::path::absolute(repo_root).unwrap_or_else(|_| repo_root.to_path_buf());
            normalize(&abs.join(d))
        }
        None => repo_root.to_path_buf(),
    }
}

/// The container path of a host dir that is the repo, inside it, or a sibling
/// beside it (every one is mounted under [`WORKROOT`] by its name); `None` when
/// it is none of them.
fn container_dir_of(repo_root: &Path, dir: &Path) -> Option<String> {
    let repo = normalize(&std::path::absolute(repo_root).unwrap_or_else(|_| repo_root.to_path_buf()));
    let rel = dir.strip_prefix(repo.parent()?).ok()?;
    let rel = rel.to_str().filter(|r| !r.is_empty())?;
    Some(format!("{WORKROOT}/{rel}"))
}

/// cargo's arguments with `--manifest-path` naming the manifest of the directory
/// cargo runs in.
fn manifest_path_at_root(mut args: Vec<String>) -> Vec<String> {
    if let Some(i) = args.iter().position(|a| a == "--manifest-path") {
        if let Some(v) = args.get_mut(i + 1) {
            *v = "Cargo.toml".to_string();
        }
    }
    args
}

/// [`run_cargo_in_container`] with the escaping-path-dep check scoped to
/// `scan_root` (the row's manifest root) instead of the whole repo.
fn run_cargo_in_container_scanning(
    tc: &CargoToolchain,
    inv: &CargoInvocation,
    runner: &dyn CargoContainerRunner,
    scan_root: &Path,
    // The container dir cargo runs in when it is not the repo's: a row with its
    // own manifest root runs THERE, because cargo reads `.cargo/config.toml` from
    // its working directory and never from `--manifest-path`.
    workdir: Option<&str>,
) -> Result<CargoContainerRun> {
    tc.validate()?;
    let (name, repo_root, target_dir) = (inv.label.as_str(), inv.repo_root.as_path(), inv.target_dir.as_path());
    // Named BEFORE the container starts, because cargo's version of this failure
    // names a path it could not read and never the manifest line that asked for
    // it, nor the one-word declaration that fixes it.
    if scan_root == repo_root {
        tc.check_escaping_path_deps(repo_root)?;
    } else {
        let abs = std::path::absolute(repo_root).unwrap_or_else(|_| repo_root.to_path_buf());
        tc.check_escaping_path_deps_from(&normalize(&abs), scan_root)?;
    }

    let workdir = workdir.map(str::to_string).unwrap_or_else(|| tc.container_repo_dir(repo_root));
    // **Delete, run, read.** The stream file is the evidence this build is
    // judged on, so a leftover from a previous run of the same variant would be
    // the worst possible answer — a stale artifact path reported for a build
    // that produced nothing. Removing it first is what makes reading it sound.
    let stream_name = cargo_stream_file(name);
    let host_stream = target_dir.join(&stream_name);
    match std::fs::remove_file(&host_stream) {
        Ok(()) => {}
        Err(e) if e.kind() == std::io::ErrorKind::NotFound => {}
        Err(e) => {
            return Err(anyhow!(
                "clear the previous cargo stream at {}: {e} — it cannot be left in place, a \
                 stale one would be read as this build's evidence",
                host_stream.display()
            ))
        }
    }
    let script = build_script_with_env(tc, &workdir, &inv.cargo_args, inv.cfg.as_deref(), &inv.env, &stream_name);
    let req = CargoRunRequest {
        name: format!("cargo-build-{name}"),
        image: tc.image_ref(),
        script,
        binds: {
            let mut b = tc.binds(repo_root, target_dir, inv.registry.as_deref());
            b.extend(inv.extra_binds.iter().cloned());
            b
        },
        timeout: Duration::from_secs(tc.timeout_secs),
        network: tc.network,
        mem_limit_mb: tc.mem_limit_mb,
        cpus: tc.cpus,
    };

    let out = runner.run(&req)?;
    // **Read the FILE, not the engine's idea of the container's stdout.** See
    // `build_script` for the measurement: podman returned 0 lines for a
    // container that printed 901, and said the same when asked for the whole
    // log afterwards. The stdout copy is the fallback for a runner that writes
    // no file at all (every unit test's fake, and any future transport).
    let lines: Vec<String> = match std::fs::read_to_string(&host_stream) {
        Ok(text) if !text.trim().is_empty() => text.lines().map(str::to_string).collect(),
        _ => out.stdout.clone(),
    };
    let parsed = parse_container_stdout(&lines, target_dir);

    // A declared rust_version that the container does not actually carry is a
    // NAMED refusal. It is the one check that catches "the tag moved" even when
    // the digest pin is present but stale in the declaration.
    if !tc.rust_version.is_empty()
        && !parsed.rustc.is_empty()
        && !parsed.rustc.contains(&tc.rust_version)
    {
        return Err(anyhow!(
            "[build.toolchain] declares `rust_version = \"{}\"` but the image `{}` reports \
             `{}` — the declaration and the pinned image disagree about what compiled this",
            tc.rust_version,
            tc.image_ref(),
            parsed.rustc
        ));
    }

    let success = out.exit_code == Some(0);
    if !success {
        // **Say what the compiler said.** The host path gets this for free —
        // cargo's `json-render-diagnostics` prints straight to the operator's
        // terminal. Inside a container BOTH streams are captured, so a failed
        // build that does not re-emit them hands the caller `success = false`
        // and nothing else: a red with no reason, which is the shape that makes
        // people re-run a build to find out why it broke. Same one-line-per-fact
        // convention as `buildgate::run_cargo`'s announcement, on stderr so it
        // never mixes into a report on stdout.
        eprintln!(
            "[cargo-container] {name} FAILED (exit {:?}) in {}",
            out.exit_code,
            tc.image_ref()
        );
        for e in &parsed.errors {
            eprintln!("[cargo-container] {}", e.trim_end());
        }
        // The container's own stderr matters even when cargo emitted no
        // diagnostic at all — "no such file", a killed OOM, a bad bind mount.
        // Tail, not the whole thing: a runaway build must not bury the reason.
        for l in out.stderr.iter().rev().take(30).collect::<Vec<_>>().into_iter().rev() {
            eprintln!("[cargo-container] err: {}", l.trim_end());
        }
    }
    Ok(CargoContainerRun { outcome: out, parsed })
}

/// What [`parse_container_stdout`] recovers from the run's stdout.
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct ParsedRun {
    /// Host-side artifact paths (container `/target/…` rewritten).
    pub artifacts: Vec<PathBuf>,
    /// Compiler errors, rendered.
    pub errors: Vec<String>,
    /// The container's `rustc --version` line.
    pub rustc: String,
    /// The container's `cargo --version` line.
    pub cargo: String,
    /// The container's host triple.
    pub host: String,
    /// How many compiler artifacts the stream carried.
    pub units: usize,
}

/// Parse the container's stdout: the sentinels, then cargo's
/// `--message-format=json` stream.
///
/// **The path rewrite is the load-bearing part.** cargo reports executables as
/// `/target/release/foo` because that is where they are IN THE CONTAINER; the
/// host sees them at `<target_dir>/release/foo`. A caller handed the container's
/// path would hash a file that does not exist and report `0` artifacts for a
/// build that produced one — a green with nothing behind it.
pub fn parse_container_stdout(lines: &[String], target_dir: &Path) -> ParsedRun {
    let mut out = ParsedRun::default();
    for line in lines {
        let line = line.trim_end();
        if let Some(v) = line.strip_prefix(RUSTC_SENTINEL) {
            out.rustc = v.trim().to_string();
            continue;
        }
        if let Some(v) = line.strip_prefix(CARGO_SENTINEL) {
            out.cargo = v.trim().to_string();
            continue;
        }
        if let Some(v) = line.strip_prefix(HOST_SENTINEL) {
            out.host = v.trim().to_string();
            continue;
        }
        if !line.starts_with('{') {
            continue;
        }
        let Ok(msg) = serde_json::from_str::<serde_json::Value>(line) else {
            // A malformed line is not a reason to abandon the run: the artifacts
            // already collected are still evidence, and the exit code decides.
            continue;
        };
        match msg.get("reason").and_then(|r| r.as_str()) {
            Some("compiler-artifact") => {
                out.units += 1;
                if let Some(exe) = msg.get("executable").and_then(|e| e.as_str()) {
                    out.artifacts.push(rewrite_target_path(exe, target_dir));
                }
            }
            Some("compiler-message") => {
                let m = &msg["message"];
                if m.get("level").and_then(|l| l.as_str()) == Some("error") {
                    let rendered = m
                        .get("rendered")
                        .and_then(|r| r.as_str())
                        .or_else(|| m.get("message").and_then(|r| r.as_str()))
                        .unwrap_or("")
                        .to_string();
                    out.errors.push(rendered);
                }
            }
            _ => {}
        }
    }
    out
}

/// Map a container `/target/…` path onto the host target dir. A path that is
/// NOT under [`TARGETDIR`] is returned unchanged rather than silently rebased —
/// guessing would turn an unexpected layout into a wrong answer.
fn rewrite_target_path(container_path: &str, target_dir: &Path) -> PathBuf {
    match container_path.strip_prefix(&format!("{TARGETDIR}/")) {
        Some(rest) => target_dir.join(rest),
        None => PathBuf::from(container_path),
    }
}

fn repo_name(repo_root: &Path) -> String {
    repo_root
        .file_name()
        .and_then(|s| s.to_str())
        .unwrap_or("repo")
        .to_string()
}

// ── the byte-identity gate ───────────────────────────────────────────────────

/// **The verdict of the host-vs-container gate.** It is an enum and not a bool
/// because "not identical" has causes, and a gate that collapses them into
/// `false` teaches nobody anything — while one that collapses them into `true`
/// has been weakened into a lie.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ByteIdentity {
    /// Same sha256. The build is genuinely containerised.
    Identical {
        /// The shared sha256.
        sha256: String,
        /// Size in bytes.
        len: u64,
    },
    /// Different bytes. The build has been FORKED, not containerised — the two
    /// sides are running different compilations that merely share a name.
    Differs {
        /// The host artifact's sha256.
        host: String,
        /// The container artifact's sha256.
        container: String,
        /// Host size in bytes.
        host_len: u64,
        /// Container size in bytes.
        container_len: u64,
    },
    /// One of the two sides produced no artifact to compare. NOT a pass: a
    /// missing side is the strongest possible red.
    Missing {
        /// Which side, and why.
        why: String,
    },
    /// **The variant is not reproducible AT ALL**, proven by a control: two
    /// builds on the SAME side, same everything, came out different. The
    /// host-vs-container comparison is then meaningless — whatever it says, it
    /// is not saying anything about the container.
    ///
    /// Still a RED. The build is unauditable either way; this verdict only moves
    /// the blame to where it belongs, which is the repo.
    NotReproducible {
        /// First control build.
        first: String,
        /// Second control build, same side, same configuration.
        second: String,
        /// What was measured to differ, when that is known.
        cause: String,
    },
}

impl ByteIdentity {
    /// Is this the green? Only [`Identical`](Self::Identical) is.
    pub fn is_identical(&self) -> bool {
        matches!(self, ByteIdentity::Identical { .. })
    }

    /// The crisp one-liner: col-1 identifier, col-2 status, col-3 the tech
    /// detail that fills the rest of the line.
    pub fn line(&self, variant: &str) -> String {
        match self {
            ByteIdentity::Identical { sha256, len } => format!(
                "{variant:<14} DONE      host and container artifacts are the SAME BYTES — \
                 sha256 {} ({len} B); the build is containerised, not forked",
                &sha256[..16.min(sha256.len())]
            ),
            ByteIdentity::Differs { host, container, host_len, container_len } => format!(
                "{variant:<14} as dåligt host {}… ({host_len} B) != container {}… \
                 ({container_len} B) — two different compilations sharing a name",
                &host[..16.min(host.len())],
                &container[..16.min(container.len())]
            ),
            ByteIdentity::Missing { why } => {
                format!("{variant:<14} as dåligt no artifact to compare: {why}")
            }
            ByteIdentity::NotReproducible { first, second, cause } => format!(
                "{variant:<14} as dåligt NOT the container: two builds on the SAME side \
                 differ ({}… vs {}…) — {cause}. Byte-identity is unreachable for this \
                 variant until the repo stops making it so",
                &first[..16.min(first.len())],
                &second[..16.min(second.len())]
            ),
        }
    }
}

/// Compare a host artifact against a container artifact by sha256 — **the gate**.
///
/// Both paths are hashed with the shared `nornir_hash::sha256_file`, the same
/// hasher provenance seals with, so the gate and the receipt cannot disagree
/// about what a file's identity is.
pub fn byte_identity_verdict(host: &Path, container: &Path) -> ByteIdentity {
    let h = match hash_and_len(host) {
        Ok(v) => v,
        Err(e) => {
            return ByteIdentity::Missing { why: format!("host side: {e:#}") };
        }
    };
    let c = match hash_and_len(container) {
        Ok(v) => v,
        Err(e) => {
            return ByteIdentity::Missing { why: format!("container side: {e:#}") };
        }
    };
    if h.0 == c.0 {
        ByteIdentity::Identical { sha256: h.0, len: h.1 }
    } else {
        ByteIdentity::Differs {
            host: h.0,
            container: c.0,
            host_len: h.1,
            container_len: c.1,
        }
    }
}

/// **The gate, with a control** — the form to use on any variant whose build
/// might not be reproducible, which is to say all of them until measured.
///
/// `control_a` and `control_b` are two builds of the same variant on the SAME
/// side with the SAME configuration. If they differ, the variant is not
/// reproducible at all and the host-vs-container question cannot be answered:
/// the comparison would report a difference and silently attribute it to the
/// container.
///
/// MEASURED 2026-08-26, and this is why the verdict exists rather than being a
/// hypothetical: `gunnar-server` came out different on every build, and the
/// cause is in the repo, not in the container.
/// `gunnar/crates/gunnar-common/build.rs:43` runs
/// `date -u +%Y-%m-%dT%H:%M:%SZ` and bakes the result as `GUNNAR_BUILD_DATE`.
/// The two artifacts carried `2026-08-25T22:43:39Z` and `2026-08-25T22:44:47Z`.
/// It is a deliberate, documented identity stamp — and at second resolution off
/// the wall clock it makes two builds one second apart different binaries, on
/// one box or two. A gate without this control would have called that the
/// container's doing.
pub fn byte_identity_with_control(
    control_a: &Path,
    control_b: &Path,
    host: &Path,
    container: &Path,
    cause: &str,
) -> ByteIdentity {
    let (a, b) = match (hash_and_len(control_a), hash_and_len(control_b)) {
        (Ok(a), Ok(b)) => (a, b),
        (Err(e), _) | (_, Err(e)) => {
            return ByteIdentity::Missing { why: format!("control build: {e:#}") };
        }
    };
    if a.0 != b.0 {
        return ByteIdentity::NotReproducible {
            first: a.0,
            second: b.0,
            cause: if cause.is_empty() { "cause not identified".into() } else { cause.into() },
        };
    }
    byte_identity_verdict(host, container)
}

fn hash_and_len(p: &Path) -> Result<(String, u64)> {
    let len = std::fs::metadata(p)
        .with_context(|| format!("stat {}", p.display()))?
        .len();
    let sha = nornir_hash::sha256_file(p).with_context(|| format!("sha256 {}", p.display()))?;
    Ok((sha, len))
}

// ── minting the toolchain without moving anybody's name ─────────────────────

/// **The tag a mint of THIS crate's recipe lands under**:
/// `<image>:recipe-<first 16 hex of sha256(CARGO_TOOLCHAIN_CONTAINERFILE)>`.
///
/// Content-addressed by the recipe. The mint is reproducible, so one
/// Containerfile always lands one image, and two crates carrying two different
/// Containerfiles mint under two different tags: neither can move the other's
/// name. A floating `:live` is the opposite, and on 2026-10-05 it cost Build
/// Thing its image. holger's `cargo xtask build-wasm-plugins`, built against an
/// edda whose recipe had moved on (clang + llvm, manifest `668468e7…`, id
/// `88c4902987c2`), re-minted `nordisk-cargo-toolchain:live` onto that image.
/// The image gunnar and holger PIN (`3d5115ba…`) lost the only name it had, a
/// local `nordisk-cargo-toolchain@sha256:3d5115ba…` lookup needs a name under
/// that repository, and so the engine went to a registry for it: `403`.
#[must_use]
pub fn cargo_toolchain_recipe_tag(image: &str) -> String {
    let h = nornir_hash::sha256_hex(CARGO_TOOLCHAIN_CONTAINERFILE.as_bytes());
    format!("{image}:recipe-{}", &h[..16])
}

/// A recipe and the manifest digest its reproducible mint lands.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ToolchainPin {
    /// First 16 hex of `sha256(CARGO_TOOLCHAIN_CONTAINERFILE)` — the recipe minted.
    pub recipe: &'static str,
    /// The manifest digest (hex, no `sha256:`) that mint lands, on every box.
    pub digest: &'static str,
}

/// **THE pin of this crate's cargo toolchain recipe** — the digest declarations name
/// (`[build.toolchain] image_sha256`) when they build in THIS recipe's image, held
/// beside the recipe hash it was minted from. Change the Containerfile and
/// `toolchain_pin_tests::the_pin_names_this_recipe` goes red until the image is
/// re-minted (`cargo run -p nornir-build-thing --features cargo-container --example
/// mint_cargo_toolchain`) and both halves are moved — in one reviewed commit, with
/// the declarations that pin it.
///
/// **2026-10-16: `668468e7…` (recipe-a6a9f191…) → `86d575e8…` (recipe-53fec13a…)**,
/// the recipe that adds `libgraphblas-dev` (nornir's code room links `-lgraphblas`).
/// Minted on dwarf through `mint_cargo_toolchain` (reproducible; the probe build of
/// the same Containerfile landed the same image id `e97625105590`).
pub const CARGO_TOOLCHAIN_PIN: ToolchainPin = ToolchainPin {
    recipe: "53fec13a5c1c7f2c",
    digest: "86d575e874677da3eb9aff3ba6e38ca600781ee9b7948a9df43ef89a6213c762",
};

/// The repository half of an image reference: `name` from `name:tag`,
/// `localhost:5000/name` from `localhost:5000/name:tag`, `name` from
/// `name@sha256:…`.
fn image_repo_of(image_ref: &str) -> &str {
    let no_digest = image_ref.split_once('@').map_or(image_ref, |(r, _)| r);
    match no_digest.rsplit_once(':') {
        Some((repo, tag)) if !tag.contains('/') => repo,
        _ => no_digest,
    }
}

/// **What minting the toolchain asks of a container engine**: three
/// questions, behind a seam so the decision of WHICH name a mint may write
/// ([`ensure_declared_toolchain`], [`mint_toolchain_into`]) is provable by a
/// fake store with no socket. [`DraupnirCargoRunner`] is the live one.
pub trait ToolchainImageStore {
    /// Does the engine resolve `image_ref` (a tag, or `name@sha256:…`)
    /// locally? `Err` only when the engine could not be asked, never for
    /// "absent".
    fn image_present(&self, image_ref: &str) -> Result<bool>;
    /// The engine's image id for `image_ref`; `None` when it holds none.
    fn image_id_of(&self, image_ref: &str) -> Result<Option<String>>;
    /// Mint [`CARGO_TOOLCHAIN_CONTAINERFILE`] reproducibly; the build writes
    /// `tag`.
    fn mint_recipe(&self, context_dir: &Path, tag: &str) -> Result<()>;
}

/// What [`ensure_declared_toolchain`] did.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ToolchainMint {
    /// The pinned reference already resolved: nothing minted, no name written.
    AlreadyPresent,
    /// Minted under `tag`, and the pin resolves now.
    Minted {
        /// The tag the mint wrote.
        tag: String,
    },
}

/// **Step 1 of every cargo road: the declared pin is on this box, or is made
/// to be.** Present: nothing is minted and no name is written. Absent: the
/// embedded recipe is minted under [`cargo_toolchain_recipe_tag`], never under
/// a floating tag, and the pin must resolve afterwards; a recipe that mints
/// some other digest is refused by name, having moved no name anybody else's
/// build stands on.
pub fn ensure_declared_toolchain(
    store: &dyn ToolchainImageStore,
    context_dir: &Path,
    tc: &CargoToolchain,
) -> Result<ToolchainMint> {
    let pinned = tc.image_ref();
    if store.image_present(&pinned)? {
        return Ok(ToolchainMint::AlreadyPresent);
    }
    let tag = cargo_toolchain_recipe_tag(&tc.image);
    store.mint_recipe(context_dir, &tag)?;
    if !store.image_present(&pinned)? {
        let minted = store.image_id_of(&tag)?.unwrap_or_else(|| "?".to_string());
        return Err(anyhow!(
            "the declared pin `{pinned}` is not on this box, and this crate's recipe does not \
             mint it: it minted `{tag}` (image {minted}). The committed \
             cargo-toolchain.Containerfile and `[build.toolchain] image_sha256` disagree. \
             Re-pin the recipe to the manifest digest of `{tag}` (in the same commit as the \
             Containerfile it came from), or build once in an explicit image with \
             {TOOLCHAIN_IMAGE_OVERRIDE_ENV}=<image>@sha256:<digest>. No floating tag was \
             written."
        ));
    }
    Ok(ToolchainMint::Minted { tag })
}

/// **Mint the recipe into an explicit `tag`, never moving it off another
/// image.** Returns the tag.
///
/// The recipe is minted under [`cargo_toolchain_recipe_tag`] first. Then:
///
/// * `tag` IS the recipe tag: done.
/// * `tag` names nothing: it is written (a second mint of the same reproducible
///   recipe, answered from the layer cache), and must land the same image.
/// * `tag` already names the minted image: nothing to move.
/// * `tag` names ANOTHER image: refused, `tag` left where it is. Moving it
///   would un-name that image, and a pin on it would then resolve to a
///   registry. Creation time cannot say which image is "newer" here: every
///   recipe of this Containerfile carries the same `SOURCE_DATE_EPOCH`
///   (1783900800 in both `3d5115ba…` and `668468e7…`), so the ids decide and a
///   different id is a refusal.
pub fn mint_toolchain_into(
    store: &dyn ToolchainImageStore,
    context_dir: &Path,
    tag: &str,
) -> Result<String> {
    let recipe = cargo_toolchain_recipe_tag(image_repo_of(tag));
    store.mint_recipe(context_dir, &recipe)?;
    if tag == recipe {
        return Ok(recipe);
    }
    let minted = store.image_id_of(&recipe)?.ok_or_else(|| {
        anyhow!("the recipe was minted as `{recipe}` and the engine does not hold it")
    })?;
    match store.image_id_of(tag)? {
        Some(held) if held == minted => Ok(tag.to_string()),
        Some(held) => Err(anyhow!(
            "refused to move `{tag}`: it names image {held}, and this recipe mints image \
             {minted} (now tagged `{recipe}`). Moving `{tag}` would un-name {held}, and a \
             `name@sha256:` pin on it would then go to a registry and fail (2026-10-05, \
             Build Thing, 403). Build in `{recipe}`, or re-pin to its digest; `{tag}` is \
             left where it was."
        )),
        None => {
            store.mint_recipe(context_dir, tag)?;
            match store.image_id_of(tag)? {
                Some(id) if id == minted => Ok(tag.to_string()),
                other => Err(anyhow!(
                    "minted the recipe twice and got two images: `{recipe}` is {minted}, \
                     `{tag}` is {} — the recipe is not reproducible on this box",
                    other.unwrap_or_else(|| "absent".to_string())
                )),
            }
        }
    }
}

// ── the live leg ─────────────────────────────────────────────────────────────

/// The live [`CargoContainerRunner`]: draupnir's `backend-oci` bollard engine —
/// the SAME container leg dwarves and the kernel kind already drive, reused
/// rather than re-rolled. Call from a plain sync thread (draupnir owns its own
/// tokio runtime; `block_on` inside another runtime panics).
#[cfg(feature = "cargo-container")]
#[derive(Default)]
pub struct DraupnirCargoRunner {
    boot: draupnir::container::ContainerBoot,
}

#[cfg(feature = "cargo-container")]
impl DraupnirCargoRunner {
    /// A runner over a fresh draupnir container backend.
    pub fn new() -> Self {
        DraupnirCargoRunner { boot: draupnir::container::ContainerBoot::new() }
    }

    /// **Build the toolchain image** from the committed
    /// [`CARGO_TOOLCHAIN_CONTAINERFILE`] and return the tag it was built under.
    ///
    /// The Containerfile is written into `context_dir` from the crate's own
    /// embedded copy — a repo never gets to supply its own build environment,
    /// which is the whole point of embedding it.
    ///
    /// Since 2026-09-05 (lane bevis) it mints REPRODUCIBLY, the way the kernel
    /// runner has since 2026-08-30: the instant comes from
    /// [`cargo_toolchain_source_date_epoch`] and rides podman's `timestamp`
    /// build parameter through
    /// [`ContainerBoot::build_image_reproducible`](draupnir::container::ContainerBoot::build_image_reproducible).
    /// What stood here was the plain `build_image`, and MEASURED that day it
    /// gave gunnar's `[build.toolchain] image_sha256` pin a new value to chase
    /// on every re-mint — a pin on such an image names a minting event, not a
    /// recipe.
    ///
    /// Goes through [`mint_toolchain_into`]; see it for which names a mint may
    /// write.
    pub fn build_toolchain_image(&self, context_dir: &Path, tag: &str) -> Result<String> {
        mint_toolchain_into(self, context_dir, tag)
    }

    /// [`ensure_declared_toolchain`] on this engine: the cargo road's step 1.
    pub fn ensure_declared_toolchain(
        &self,
        context_dir: &Path,
        tc: &CargoToolchain,
    ) -> Result<ToolchainMint> {
        ensure_declared_toolchain(self, context_dir, tc)
    }

    /// **Build the TEST image** from the committed
    /// [`CARGO_TEST_CONTAINERFILE`], on top of `toolchain_ref`.
    ///
    /// `toolchain_ref` should be the **digest-pinned** reference of the
    /// toolchain image this test image is to witness runs against
    /// (`nordisk-cargo-toolchain@sha256:…`), for the reason a repo pins
    /// `[build.toolchain] image_sha256`: a test image built on a moving base
    /// says nothing about the run it was used for. A tag is accepted because a
    /// human building one by hand has one, and refusing it would only push
    /// them to a shell.
    ///
    /// The pinned `cargo-deny` tarball is fetched and verified into the
    /// context first ([`stage_cargo_deny`]); everything else comes from the
    /// snapshot the base already points apt at. The mint is reproducible the
    /// same way [`build_toolchain_image`](Self::build_toolchain_image) is, and
    /// off the SAME instant — the base is the one writer of it.
    ///
    /// # Errors
    ///
    /// The context cannot be written, the cargo-deny pin cannot be read or
    /// does not match what was fetched, or the image build itself fails.
    pub fn build_test_image(
        &self,
        fetcher: &dyn crate::kernel::TarballFetcher,
        context_dir: &Path,
        toolchain_ref: &str,
        tag: &str,
    ) -> Result<String> {
        std::fs::create_dir_all(context_dir)
            .with_context(|| format!("create build context {}", context_dir.display()))?;
        let cf = context_dir.join("cargo-test.Containerfile");
        std::fs::write(&cf, cargo_test_containerfile_on(toolchain_ref)?)
            .with_context(|| format!("write {}", cf.display()))?;
        stage_cargo_deny(fetcher, context_dir)?;
        let epoch = cargo_toolchain_source_date_epoch()?;
        self.boot
            .build_image_reproducible(context_dir, "cargo-test.Containerfile", tag, epoch)
            .map_err(|e| anyhow!("build cargo test image `{tag}` on `{toolchain_ref}`: {e}"))
    }
}

#[cfg(feature = "cargo-container")]
impl ToolchainImageStore for DraupnirCargoRunner {
    fn image_present(&self, image_ref: &str) -> Result<bool> {
        self.boot
            .image_present(image_ref)
            .map_err(|e| anyhow!("ask the engine for `{image_ref}`: {e}"))
    }

    /// Presence first, because draupnir's `image_id` folds "the engine could
    /// not be asked" into `None`, and a `None` read as "names nothing" is what
    /// lets a tag be written.
    fn image_id_of(&self, image_ref: &str) -> Result<Option<String>> {
        if !self.image_present(image_ref)? {
            return Ok(None);
        }
        let id = self
            .boot
            .image_id(image_ref)
            .map_err(|e| anyhow!("ask the engine for the id of `{image_ref}`: {e}"))?;
        id.map(Some).ok_or_else(|| {
            anyhow!("the engine holds `{image_ref}` and would not say which image it is")
        })
    }

    fn mint_recipe(&self, context_dir: &Path, tag: &str) -> Result<()> {
        std::fs::create_dir_all(context_dir)
            .with_context(|| format!("create build context {}", context_dir.display()))?;
        let cf = context_dir.join("cargo-toolchain.Containerfile");
        std::fs::write(&cf, CARGO_TOOLCHAIN_CONTAINERFILE)
            .with_context(|| format!("write {}", cf.display()))?;
        let epoch = cargo_toolchain_source_date_epoch()?;
        self.boot
            .build_image_reproducible(context_dir, "cargo-toolchain.Containerfile", tag, epoch)
            .map_err(|e| anyhow!("build cargo toolchain image `{tag}`: {e}"))?;
        Ok(())
    }
}

#[cfg(feature = "cargo-container")]
impl CargoContainerRunner for DraupnirCargoRunner {
    fn run(&self, req: &CargoRunRequest) -> Result<CargoRunOutcome> {
        let mut spec = draupnir::BootSpec::container(&scoped_container_name(&req.name, &req.binds), &req.image)
            .with_cmd(["/bin/sh", "-eu", "-c", req.script.as_str()]);
        if !req.network {
            spec = spec.with_net(draupnir::NetMode::None);
        }
        // The bounds ride the SAME draupnir builders every other bounded
        // container uses (`--cpus` → nano_cpus, `--memory` → memory); nothing
        // engine-specific is spelled twice here.
        spec = spec.with_cpus(f64::from(req.cpus)).with_mem_limit_mb(req.mem_limit_mb);
        spec.validate().map_err(|e| anyhow!("cargo container spec: {e}"))?;
        let opts =
            draupnir::container::RunOptions::bounded(req.timeout, Duration::from_secs(2));
        let out = self.boot.run_to_completion_with_binds(&spec, &opts, &req.binds);
        // draupnir may have had to clear the wreckage of an INTERRUPTED run to free
        // this job's deterministic container name. It is a library and prints
        // nothing; this is the consumer that owes the human the sentence, and it is
        // said whether the run then succeeded or failed.
        for reap in self.boot.drain_reaps() {
            eprintln!("[cargo-container] {reap}");
        }
        let out = out.map_err(|e| anyhow!("cargo build container `{}`: {e}", req.name))?;
        Ok(CargoRunOutcome { exit_code: out.exit_code, stdout: out.stdout, stderr: out.stderr })
    }
    fn engine(&self) -> &str {
        "draupnir-oci"
    }
}

/// Environment overrides a caller can thread through for a one-off run without
/// editing the declaration. Kept as a named type rather than a bare map so a
/// reader can see there is exactly one place ad-hoc environment enters.
pub type RunEnv = BTreeMap<String, String>;

/// The host's `CARGO_BUILD_JOBS`, carried into a variant's container when set.
///
/// `cpus` bounds the CPU QUOTA; on a box shared between lanes the operator also
/// caps the job count (`CARGO_BUILD_JOBS=4`), and before this the container
/// never saw it and ran `nproc` jobs inside the quota. A job count changes how
/// long a build takes, not its bytes, so it is not a provenance input.
pub fn host_job_limit() -> RunEnv {
    let mut env = RunEnv::new();
    if let Ok(j) = std::env::var("CARGO_BUILD_JOBS") {
        if !j.is_empty() && j.bytes().all(|b| b.is_ascii_digit()) {
            env.insert("CARGO_BUILD_JOBS".to_string(), j);
        }
    }
    env
}

/// **The one override of the declared toolchain image** — `<image>@sha256:<manifest
/// digest>`. For a run that must build in an image the declaration does not pin
/// YET (the image carrying a new std, proven before the repo's pin moves). A tag
/// is refused, same as in the declaration. The bounds, `rust_version` and
/// `siblings` stay the declaration's; `targets` becomes what the committed
/// Containerfile installs when the image is [`CARGO_TOOLCHAIN_IMAGE`], and
/// undeclared otherwise.
pub const TOOLCHAIN_IMAGE_OVERRIDE_ENV: &str = "NORDISK_CARGO_TOOLCHAIN_IMAGE";

/// `declared`, with [`TOOLCHAIN_IMAGE_OVERRIDE_ENV`] applied when it is set —
/// announced on stderr, because a build in an image the declaration does not
/// name must never be silent. Unset: `declared`, unchanged.
pub fn toolchain_with_override(declared: Option<CargoToolchain>) -> Result<Option<CargoToolchain>> {
    let Some(spec) = std::env::var(TOOLCHAIN_IMAGE_OVERRIDE_ENV).ok().filter(|s| !s.trim().is_empty()) else {
        return Ok(declared);
    };
    let tc = apply_image_override(declared.unwrap_or_default(), &spec)?;
    eprintln!(
        "[cargo-container] {TOOLCHAIN_IMAGE_OVERRIDE_ENV}: building in {} — NOT the declaration's pin",
        tc.image_ref()
    );
    Ok(Some(tc))
}

/// Apply one `<image>@sha256:<digest>` override to `tc` (see
/// [`TOOLCHAIN_IMAGE_OVERRIDE_ENV`]).
pub fn apply_image_override(mut tc: CargoToolchain, spec: &str) -> Result<CargoToolchain> {
    let spec = spec.trim();
    let Some((name, digest)) = spec.split_once("@sha256:") else {
        return Err(anyhow!(
            "{TOOLCHAIN_IMAGE_OVERRIDE_ENV}=`{spec}`: expected `<image>@sha256:<64 hex manifest digest>` — a tag is not a pin"
        ));
    };
    if name.is_empty() || !is_manifest_digest(digest) {
        return Err(anyhow!(
            "{TOOLCHAIN_IMAGE_OVERRIDE_ENV}=`{spec}`: the image name must be non-empty and the digest 64 lowercase hex"
        ));
    }
    tc.image = name.to_string();
    tc.image_sha256 = digest.to_string();
    tc.targets = if name.contains(CARGO_TOOLCHAIN_IMAGE) { cargo_toolchain_image_targets() } else { Vec::new() };
    Ok(tc)
}

/// **Every sibling repo a build of `repo_root` reaches, transitively** — the
/// `siblings` list for a repo whose own path deps walk into repos that walk into
/// more (edda → nornir → holger …). cargo loads every path manifest of a
/// workspace, so a container missing one fails on `failed to read`. Discovered
/// with the same lexical reader [`CargoToolchain::check_escaping_path_deps`]
/// uses; a dep into a directory that is not on this box is skipped (it is not
/// in the graph a host build resolves either). Sorted, `repo_root` excluded.
pub fn sibling_closure(repo_root: &Path) -> Vec<String> {
    let parent = checkout_parent(repo_root);
    let own = repo_dir_name(repo_root);
    let mut seen: std::collections::BTreeSet<String> = std::collections::BTreeSet::new();
    let mut queue = vec![repo_root.to_path_buf()];
    while let Some(r) = queue.pop() {
        for (_, _, resolved) in escaping_path_deps(&r) {
            let Some(name) = resolved
                .strip_prefix(&parent)
                .ok()
                .and_then(|p| p.components().next())
                .and_then(|c| c.as_os_str().to_str())
                .map(str::to_string)
            else {
                continue;
            };
            if name == own || seen.contains(&name) || !parent.join(&name).is_dir() {
                continue;
            }
            seen.insert(name.clone());
            queue.push(parent.join(&name));
        }
    }
    seen.into_iter().collect()
}

/// **The sibling checkouts a manifest's cargo actually loads**, read off `cargo
/// metadata` (`--locked`): every path package in the resolve, by the directory
/// under `checkouts` (the directory the checkouts share — a repo root's parent)
/// it lives in. Sorted, the manifest's own checkout INCLUDED (a row built from `../holger` mounts `holger` too; a caller drops
/// its own repo). This is the measured closure a per-row
/// [`siblings`](crate::variant::BuildVariant::siblings) list is held against —
/// [`sibling_closure`] is the lexical over-approximation of a whole tree, which
/// for a repo that builds two products' plugins is the union of both.
///
/// A path package outside the checkout parent is refused by name: a flat
/// sibling mount cannot carry it.
pub fn metadata_sibling_closure(manifest_path: &Path, checkouts: &Path) -> Result<Vec<String>> {
    let manifest = normalize(&std::path::absolute(manifest_path).unwrap_or_else(|_| manifest_path.to_path_buf()));
    let parent = normalize(&std::path::absolute(checkouts).unwrap_or_else(|_| checkouts.to_path_buf()));
    let md = cargo_metadata::MetadataCommand::new()
        .manifest_path(&manifest)
        .other_options(vec!["--locked".to_string()])
        .exec()
        .with_context(|| format!("cargo metadata --locked --manifest-path {}", manifest.display()))?;
    let mut out = std::collections::BTreeSet::new();
    let mut outside = Vec::new();
    for p in md.packages.iter().filter(|p| p.source.is_none()) {
        let mp = normalize(p.manifest_path.as_std_path());
        match mp.strip_prefix(&parent).ok().and_then(|r| r.components().next()) {
            Some(c) => {
                out.insert(c.as_os_str().to_string_lossy().into_owned());
            }
            None => outside.push(format!("{} ({})", p.name, mp.display())),
        }
    }
    if !outside.is_empty() {
        return Err(anyhow!(
            "{} path package(s) of {} live outside {} — a flat sibling mount cannot carry them: {}",
            outside.len(),
            manifest.display(),
            parent.display(),
            outside.join(", ")
        ));
    }
    Ok(out.into_iter().collect())
}

#[cfg(test)]
mod scoped_name_tests {
    use super::scoped_container_name;

    /// Two checkouts of one row get two names; the same checkout and target keep
    /// one (so the leftover of an interrupted run is still reaped by the next).
    #[test]
    fn a_build_container_name_is_scoped_to_its_checkout_and_target() {
        let a = vec!["/home/u/a/holger:/work:ro".to_string(), "/home/u/t-a:/target".to_string(), "/home/u/.cargo/registry:/registry:ro".to_string()];
        let b = vec!["/home/u/b/holger:/work:ro".to_string(), "/home/u/t-b:/target".to_string(), "/home/u/.cargo/registry:/registry:ro".to_string()];
        let na = scoped_container_name("cargo-build-holger-server", &a);
        let nb = scoped_container_name("cargo-build-holger-server", &b);
        assert_ne!(na, nb, "two constellations, two container names");
        assert!(na.starts_with("cargo-build-holger-server-") && na.len() == "cargo-build-holger-server-".len() + 8, "{na}");
        let mut a2 = a.clone();
        a2.reverse();
        assert_eq!(scoped_container_name("cargo-build-holger-server", &a2), na, "the same place, the same name, whatever the bind order");
        assert_ne!(scoped_container_name("cargo-build-other", &a), na, "another row, another name");
    }
}

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

    // ── the override, the env export and the sibling closure (lane I, 2026-09-15) ──

    /// A tag is not a pin on the override either; a digest override takes the
    /// committed Containerfile's targets (uefi included) and keeps the bounds.
    #[test]
    fn the_image_override_takes_a_digest_and_the_images_own_targets() {
        let mut declared = tc();
        declared.targets = vec!["x86_64-unknown-linux-musl".into()];
        declared.mem_limit_mb = 1234;
        let e = format!("{:#}", apply_image_override(declared.clone(), "nordisk-cargo-toolchain:live-uefi").unwrap_err());
        assert!(e.contains("not a pin"), "{e}");
        let d = "3d5115baa07d03ca51eb3e44ebb86b4e64e679bd88f38e156ef9da12c35d2143";
        let o = apply_image_override(declared, &format!("nordisk-cargo-toolchain@sha256:{d}")).unwrap();
        assert_eq!(o.image_ref(), format!("nordisk-cargo-toolchain@sha256:{d}"));
        assert!(o.targets.iter().any(|t| t == "x86_64-unknown-uefi"), "{:?}", o.targets);
        assert_eq!(o.mem_limit_mb, 1234, "the bounds stay the declaration's");
        o.validate().expect("the overridden declaration validates");
    }

    /// The env a build script reads reaches the container as quoted exports, and a
    /// key that is not a shell name never reaches the script at all.
    #[test]
    fn the_invocation_env_is_exported_quoted_and_bad_keys_are_dropped() {
        let mut env = RunEnv::new();
        env.insert("KORP_BAKED_CMDLINE".into(), "korp.entry=gunnar it's".into());
        env.insert("BAD;rm -rf".into(), "x".into());
        let s = build_script_with_env(&tc(), "/work/edda", &["build".into()], None, &env, "s.json");
        assert!(s.contains("export KORP_BAKED_CMDLINE='korp.entry=gunnar it'\\''s'\n"), "{s}");
        assert!(!s.contains("BAD"), "{s}");
        assert_eq!(build_script(&tc(), "/w", &["build".into()], None, "s.json"),
                   build_script_with_env(&tc(), "/w", &["build".into()], None, &RunEnv::new(), "s.json"));
    }

    /// edda → a → b: both siblings are mounted, a dep into a directory that is not
    /// on the box is skipped, and the repo itself is not its own sibling.
    #[test]
    fn the_sibling_closure_follows_siblings_of_siblings() {
        let root = scratch("closure");
        let _ = std::fs::remove_dir_all(&root);
        let w = |p: &str, deps: &str| {
            let d = root.join(p);
            std::fs::create_dir_all(&d).unwrap();
            std::fs::write(d.join("Cargo.toml"), format!("[package]\nname=\"x\"\n[dependencies]\n{deps}")).unwrap();
        };
        w("edda/crates/k", "a = { path = \"../../../a\" }\n");
        w("a", "b = { path = \"../b\" }\nk = { path = \"../edda/crates/k\" }\ngone = { path = \"../gone\" }\n");
        w("b", "");
        assert_eq!(sibling_closure(&root.join("edda")), vec!["a".to_string(), "b".to_string()]);
    }

    const PIN: &str = "0d8caf1a2b2312b1b76a7c26527b545ea9b5479bb95e2e97a6b3b0dcc4bd2f4c";

    fn tc() -> CargoToolchain {
        CargoToolchain { image_sha256: PIN.into(), ..CargoToolchain::default() }
    }

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

    /// A runner that records the request and answers with a canned stdout.
    struct Fake {
        seen: Mutex<Vec<CargoRunRequest>>,
        out: CargoRunOutcome,
    }
    impl Fake {
        fn new(out: CargoRunOutcome) -> Self {
            Fake { seen: Mutex::new(Vec::new()), out }
        }
    }
    impl CargoContainerRunner for Fake {
        fn run(&self, req: &CargoRunRequest) -> Result<CargoRunOutcome> {
            self.seen.lock().unwrap().push(req.clone());
            Ok(self.out.clone())
        }
    }

    /// A runner that also writes the stream file the way a real container does
    /// — into the bound target dir, DURING the run, after the road has cleared
    /// any previous one.
    struct WritesStream {
        inner: Fake,
        at: PathBuf,
        text: String,
    }
    impl CargoContainerRunner for WritesStream {
        fn run(&self, req: &CargoRunRequest) -> Result<CargoRunOutcome> {
            let out = self.inner.run(req)?;
            std::fs::write(&self.at, &self.text).unwrap();
            Ok(out)
        }
    }

    /// A lane-private scratch dir with a REAL file standing in for the produced
    /// binary. `BuildProvenance::capture` content-hashes what it is handed, so a
    /// test that passes a path to nothing is testing the error path by accident.
    fn scratch(sub: &str) -> PathBuf {
        let d = std::env::temp_dir().join("nbt-cargo-container").join(sub);
        std::fs::create_dir_all(&d).unwrap();
        d
    }

    /// A host target dir holding `debug/v` (or the given relative path), so the
    /// rewritten container path lands on a file that exists.
    fn target_with(sub: &str, rel: &str) -> PathBuf {
        let t = scratch(sub);
        let f = t.join(rel);
        std::fs::create_dir_all(f.parent().unwrap()).unwrap();
        std::fs::write(&f, b"\x7fELF pretend binary").unwrap();
        t
    }

    fn ok_stdout(exe: &str) -> CargoRunOutcome {
        CargoRunOutcome {
            exit_code: Some(0),
            stdout: vec![
                format!("{RUSTC_SENTINEL}rustc 1.97.1 (8bab26f4f 2026-07-14)"),
                format!("{CARGO_SENTINEL}cargo 1.97.1 (c980f4866 2026-06-30)"),
                format!("{HOST_SENTINEL}x86_64-unknown-linux-gnu"),
                format!(
                    r#"{{"reason":"compiler-artifact","executable":"{exe}","target":{{"name":"t"}}}}"#
                ),
            ],
            stderr: vec![],
        }
    }

    // ── the declaration refuses what cannot be audited ───────────────────────

    /// ★ RED-FIRST — **an unpinned build image is refused BY NAME.** Written
    /// against a `validate()` that did not exist: the declaration parsed, the
    /// build ran, and whatever `nordisk-cargo-toolchain:latest` happened to
    /// point at that day compiled the artifact — two builds reporting the same
    /// provenance out of two different environments.
    #[test]
    fn an_unpinned_toolchain_image_is_refused_by_name() {
        let t = CargoToolchain::default();
        let e = t.validate().expect_err("an unpinned image must be refused");
        let m = format!("{e}");
        assert!(m.contains("image_sha256"), "{m}");
        assert!(m.contains("NOT a pin"), "the refusal says why: {m}");
    }

    #[test]
    fn an_image_id_pasted_where_a_manifest_digest_belongs_is_refused() {
        for bad in ["abc", &PIN.to_uppercase(), &format!("sha256:{PIN}"), &format!("{PIN}00")] {
            let t = CargoToolchain { image_sha256: bad.to_string(), ..Default::default() };
            let e = t.validate().expect_err("malformed digest must be refused");
            assert!(format!("{e}").contains("64 lowercase hex"), "{e}");
        }
    }

    #[test]
    fn an_unbounded_container_is_refused_by_name() {
        let t = CargoToolchain { mem_limit_mb: 0, ..tc() };
        assert!(format!("{}", t.validate().unwrap_err()).contains("unbounded is not a bound"));
        let t = CargoToolchain { cpus: 0, ..tc() };
        assert!(format!("{}", t.validate().unwrap_err()).contains("unbounded is not a bound"));
        let t = CargoToolchain { timeout_secs: 0, ..tc() };
        assert!(format!("{}", t.validate().unwrap_err()).contains("hang"));
    }

    #[test]
    fn the_digest_pin_becomes_a_name_at_sha256_reference() {
        assert_eq!(tc().image_ref(), format!("{CARGO_TOOLCHAIN_IMAGE}@sha256:{PIN}"));
        let unpinned = CargoToolchain::default();
        assert_eq!(unpinned.image_ref(), CARGO_TOOLCHAIN_IMAGE, "no pin ⇒ the bare name");
    }

    /// ★ RED-FIRST — **the E0463 failure, named an hour earlier.** This is the
    /// oden measurement turned into a refusal: a variant targeting musl against
    /// an image that carries no musl std used to compile for however long it
    /// took to reach `can't find crate for core`.
    #[test]
    fn a_target_the_image_does_not_carry_is_refused_before_the_build() {
        let t = CargoToolchain {
            targets: vec!["x86_64-unknown-linux-gnu".into()],
            ..tc()
        };
        let e = t
            .check_target("gunnar-server", Some("x86_64-unknown-linux-musl"))
            .expect_err("a target the image lacks must be refused");
        let m = format!("{e}");
        assert!(m.contains("gunnar-server") && m.contains("x86_64-unknown-linux-musl"), "{m}");
        assert!(m.contains("E0463"), "the refusal names the failure it replaces: {m}");
    }

    #[test]
    fn an_undeclared_target_list_accepts_anything() {
        assert!(tc().check_target("v", Some("wasm32-unknown-unknown")).is_ok());
    }

    // ── the script ───────────────────────────────────────────────────────────

    /// The airgapped run must be airgapped IN CARGO TOO. `--network none` stops
    /// the socket; `--offline --locked` is what stops cargo from deciding it can
    /// re-resolve — without them the run fails deep inside a resolver instead of
    /// building the pinned graph.
    #[test]
    fn an_airgapped_run_is_offline_and_locked() {
        let s = build_script(&tc(), "/work/repo", &["build".into(), "--release".into()], None, "s.jsonl");
        assert!(s.contains("--locked"), "{s}");
        assert!(s.contains("--offline"), "{s}");
        assert!(s.contains(&format!("export CARGO_TARGET_DIR={TARGETDIR}")), "{s}");
        assert!(s.contains("cd '/work/repo'"), "{s}");
        let net = CargoToolchain { network: true, ..tc() };
        let s = build_script(&net, "/work/repo", &["build".into()], None, "s.jsonl");
        assert!(!s.contains("--offline"), "a networked run may resolve: {s}");
        assert!(s.contains("--locked"), "…but never re-lock: {s}");
    }

    /// The image's toolchain wins over the repo's `rust-toolchain.toml`: a file
    /// naming a component the image lacks must not send rustup to the network
    /// (tunnr's korp-boot, loki 2026-09-26).
    #[test]
    fn the_image_toolchain_overrides_rust_toolchain_toml() {
        let t = CargoToolchain { rust_version: "1.97.1".into(), ..tc() };
        let s = build_script(&t, "/work/repo", &["build".into()], None, "s.jsonl");
        assert!(s.contains(&format!("export RUSTUP_TOOLCHAIN='{}'\n", t.rust_version)), "{s}");
        assert!(s.find("RUSTUP_TOOLCHAIN").unwrap() < s.find("cd '/work/repo'").unwrap(), "{s}");
    }

    /// Both sides remap to the SAME synthetic prefixes, which is the only reason
    /// the byte-identity gate is comparing like with like.
    #[test]
    fn both_sides_remap_to_the_same_prefixes() {
        let t = tc();
        let c = t.container_rustflags();
        let h = t.host_rustflags(
            Path::new("/home/x/git/repo"),
            Path::new("/home/x/.cargo"),
            Path::new("/scratch/lane"),
        );
        assert!(c.contains(&format!("{WORKROOT}={REMAP_SRC}")), "{c}");
        assert!(h.contains(&format!("/home/x/git={REMAP_SRC}")), "{h}");
        assert!(c.contains(REMAP_REGISTRY) && h.contains(REMAP_REGISTRY), "{c} / {h}");
        let off = CargoToolchain { remap_paths: false, ..tc() };
        assert!(off.container_rustflags().is_empty());
    }

    #[test]
    fn a_variant_cfg_rides_the_same_rustflags_the_host_path_uses() {
        let s = build_script(&tc(), "/work/repo", &["build".into()], Some("holger_mvp"), "s.jsonl");
        assert!(s.contains("--cfg holger_mvp"), "{s}");
        assert!(s.contains(REMAP_SRC), "…alongside the remap, not instead of it: {s}");
    }

    #[test]
    fn a_quote_in_an_argument_cannot_rewrite_the_command() {
        let s = build_script(
            &tc(),
            "/work/repo",
            &["build".into(), "--features".into(), "a'; rm -rf /; '".into()],
            None,
            "s.jsonl",
        );
        // The dangerous half is the CLOSING quote the injection tries to smuggle
        // in. `'\''` closes, escapes a literal quote and reopens, so `rm -rf /`
        // stays a substring of one argument and never becomes a command.
        assert!(
            s.contains(r"'a'\''; rm -rf /; '\'''"),
            "the argument must survive as ONE single-quoted word: {s}"
        );
        assert!(
            !s.contains("\n; rm") && !s.contains("' ; rm"),
            "…and must not have escaped into command position: {s}"
        );
    }

    #[test]
    fn the_binds_are_a_workdir_its_output_and_the_pinned_sources() {
        let b = tc().binds(
            Path::new("/home/x/git/repo"),
            Path::new("/scratch/target"),
            Some(Path::new("/home/x/.cargo/registry")),
        );
        assert_eq!(b.len(), 3, "{b:?}");
        assert_eq!(b[0], format!("/home/x/git/repo:{WORKROOT}/repo"));
        assert_eq!(b[1], format!("/scratch/target:{TARGETDIR}"));
        assert!(b[2].ends_with(":ro"), "the registry is READ-ONLY: {}", b[2]);
    }

    // ── the stdout parse ─────────────────────────────────────────────────────

    /// ★ RED-FIRST — **the artifact path is rewritten back onto the host.**
    /// cargo says `/target/release/foo` because that is the path IN THE
    /// CONTAINER. Handing that to a caller makes it hash a file that does not
    /// exist: a build that produced a binary reports zero artifacts, and the
    /// byte-identity gate goes `Missing` on a run that actually succeeded.
    #[test]
    fn the_container_target_path_is_rewritten_onto_the_host() {
        let p = parse_container_stdout(
            &ok_stdout("/target/x86_64-unknown-linux-musl/release/gunnar").stdout,
            Path::new("/scratch/lane"),
        );
        assert_eq!(
            p.artifacts,
            vec![PathBuf::from("/scratch/lane/x86_64-unknown-linux-musl/release/gunnar")]
        );
        assert_eq!(p.rustc, "rustc 1.97.1 (8bab26f4f 2026-07-14)");
        assert_eq!(p.host, "x86_64-unknown-linux-gnu");
        assert_eq!(p.units, 1);
    }

    #[test]
    fn a_path_outside_the_target_mount_is_left_alone_not_guessed() {
        let p = parse_container_stdout(
            &[r#"{"reason":"compiler-artifact","executable":"/usr/local/bin/weird"}"#.to_string()],
            Path::new("/scratch/lane"),
        );
        assert_eq!(p.artifacts, vec![PathBuf::from("/usr/local/bin/weird")]);
    }

    #[test]
    fn compiler_errors_are_collected_and_a_malformed_line_does_not_abandon_the_run() {
        let lines = vec![
            "not json at all".to_string(),
            "{ this is not json either".to_string(),
            r#"{"reason":"compiler-message","message":{"level":"error","rendered":"error[E0463]: can't find crate for `core`"}}"#.to_string(),
            r#"{"reason":"compiler-artifact","executable":"/target/debug/x"}"#.to_string(),
        ];
        let p = parse_container_stdout(&lines, Path::new("/t"));
        assert_eq!(p.errors.len(), 1);
        assert!(p.errors[0].contains("E0463"));
        assert_eq!(p.artifacts.len(), 1, "the artifact after the junk was still collected");
    }

    // ── the orchestration ────────────────────────────────────────────────────

    #[test]
    fn the_run_carries_the_pinned_image_the_bounds_and_the_variants_own_argv() {
        let set = set_with(
            "[build]\n[[build.variant]]\nname = \"srv\"\npackage = \"gunnar-server\"\n\
             profile = \"release\"\ntarget = \"x86_64-unknown-linux-musl\"\n",
        );
        let fake = Fake::new(ok_stdout("/target/x86_64-unknown-linux-musl/release/gunnar-server"));
        let repo = scratch("repo-srv");
        let target =
            target_with("target-srv", "x86_64-unknown-linux-musl/release/gunnar-server");
        build_variant_in_container(
            &set,
            "srv",
            &repo,
            &target,
            Some(Path::new("/home/x/.cargo/registry")),
            &tc(),
            &fake,
        )
        .expect("build");
        let seen = fake.seen.lock().unwrap();
        let req = seen.first().expect("the runner was called");
        assert_eq!(req.image, format!("{CARGO_TOOLCHAIN_IMAGE}@sha256:{PIN}"));
        assert!(!req.network, "the default run is airgapped");
        assert_eq!(req.mem_limit_mb, DEFAULT_MEM_LIMIT_MB);
        assert_eq!(req.cpus, DEFAULT_CPUS);
        assert_eq!(req.timeout, Duration::from_secs(DEFAULT_TIMEOUT_SECS));
        // The variant's OWN argv — same writer as the host path, so the two
        // cannot drift into building different things.
        assert!(req.script.contains("-p' 'gunnar-server"), "{}", req.script);
        assert!(req.script.contains("--target' 'x86_64-unknown-linux-musl"), "{}", req.script);
        assert!(req.script.contains("--profile' 'release"), "{}", req.script);
    }

    /// ★ RED-FIRST — **the provenance records the CONTAINER's rustc.** The
    /// obvious implementation reuses `Toolchain::detect()`, which probes the
    /// HOST — attesting that this box's rustc built a binary this box's rustc
    /// never touched. A provenance that is precisely wrong is worse than none.
    #[test]
    fn the_provenance_attests_the_container_toolchain_not_the_hosts() {
        let set = set_with("[build]\n[[build.variant]]\nname = \"v\"\n");
        let mut out = ok_stdout("/target/debug/v");
        out.stdout[0] = format!("{RUSTC_SENTINEL}rustc 9.9.9 (deadbeef 2099-01-01)");
        let fake = Fake::new(out);
        let o = build_variant_in_container(
            &set,
            "v",
            &scratch("repo-prov"),
            &target_with("target-prov", "debug/v"),
            None,
            &tc(),
            &fake,
        )
        .expect("build");
        assert_eq!(o.attestation.record.toolchain.rustc, "rustc 9.9.9 (deadbeef 2099-01-01)");
        assert_ne!(
            o.attestation.record.toolchain.rustc,
            Toolchain::detect().rustc,
            "this must NOT be the host's rustc"
        );
    }

    /// A declared `rust_version` the image does not carry is a named refusal —
    /// the check that catches a stale declaration even when the digest is valid.
    #[test]
    fn a_declaration_that_disagrees_with_the_image_is_refused_by_name() {
        let set = set_with("[build]\n[[build.variant]]\nname = \"v\"\n");
        let fake = Fake::new(ok_stdout("/target/debug/v"));
        let t = CargoToolchain { rust_version: "1.90.0".into(), ..tc() };
        let repo = scratch("repo-ver");
        let target = target_with("target-ver", "debug/v");
        let e = build_variant_in_container(&set, "v", &repo, &target, None, &t, &fake)
            .expect_err("a version disagreement must refuse");
        let m = format!("{e}");
        assert!(m.contains("1.90.0") && m.contains("1.97.1"), "{m}");
    }

    /// ★ RED-FIRST — **a digest that cannot be resolved never degrades into the
    /// tag.** The pin's whole value is that it is the ONLY thing the engine is
    /// asked for; a road that answers "the digest did not resolve, I'll take the
    /// tag" gives back exactly the drift the pin was bought to stop, and gives
    /// it back silently, under a receipt that still names a digest.
    ///
    /// Measured through the runner rather than asserted about a string, because
    /// "no fallback" is a claim about what the ENGINE was asked to run. Two
    /// halves, and both matter:
    ///
    /// * a pinned declaration asks for `<name>@sha256:<digest>` and for nothing
    ///   else — the bare tag appears in no request;
    /// * an UNPINNED declaration never reaches the runner at all. It is refused
    ///   by name first, so there is no request in which a tag could stand in.
    ///   Before `validate()` was called at the top of
    ///   [`build_variant_in_container`], this second half was the live hole:
    ///   `image_ref()` answers the bare name when the pin is empty (by design —
    ///   it has nothing else to say), and every caller that skipped validation
    ///   turned that into a tag-resolved build wearing pinned-build clothes.
    #[test]
    fn an_unresolvable_pin_is_never_silently_replaced_by_the_tag() {
        let set = set_with("[build]\n[[build.variant]]\nname = \"v\"\n");

        // Half one: pinned ⇒ the engine is asked for the digest, only.
        let fake = Fake::new(ok_stdout("/target/debug/v"));
        let repo = scratch("repo-pin");
        let target = target_with("target-pin", "debug/v");
        build_variant_in_container(&set, "v", &repo, &target, None, &tc(), &fake)
            .expect("a pinned declaration builds");
        let seen = fake.seen.lock().unwrap();
        let asked = &seen.first().expect("the runner was asked to run").image;
        assert_eq!(asked, &format!("{CARGO_TOOLCHAIN_IMAGE}@sha256:{PIN}"), "{asked}");
        assert!(asked.contains('@'), "a bare tag reached the engine: {asked}");
        drop(seen);

        // Half two: unpinned ⇒ refused BY NAME, and the runner is never reached.
        let fake = Fake::new(ok_stdout("/target/debug/v"));
        let unpinned = CargoToolchain { image_sha256: String::new(), ..tc() };
        let e = build_variant_in_container(&set, "v", &repo, &target, None, &unpinned, &fake)
            .expect_err("an unresolvable pin must refuse, not fall back");
        let m = format!("{e}");
        assert!(m.contains("image_sha256") && m.contains("NOT a pin"), "{m}");
        assert!(m.contains(CARGO_TOOLCHAIN_IMAGE), "the refusal names the image: {m}");
        assert!(
            fake.seen.lock().unwrap().is_empty(),
            "the engine was asked to run something anyway — that is the fallback"
        );

        // Half three: a digest that is not a MANIFEST digest (an image ID pasted
        // where a repo digest belongs is the one that actually happened) is the
        // same refusal, not a shrug back onto the tag.
        let fake = Fake::new(ok_stdout("/target/debug/v"));
        let idish = CargoToolchain {
            image_sha256: "72abf41e32e24d1d0423598f4040b72bddaee5c5a62213edb188a513f19be66".into(),
            ..tc()
        };
        let e = build_variant_in_container(&set, "v", &repo, &target, None, &idish, &fake)
            .expect_err("a malformed digest must refuse");
        assert!(format!("{e}").contains("64 lowercase hex"), "{e}");
        assert!(fake.seen.lock().unwrap().is_empty(), "it ran anyway");
    }

    /// ★ RED-FIRST — **the build is read from the FILE the container wrote,
    /// not from the engine's idea of what it printed.**
    ///
    /// MEASURED on t14s 2026-09-12, rootless podman 5.7: 20 runs of a container
    /// that printed 901 lines and exited returned `exit_code = Some(0)` with 0,
    /// 0, 0 and 749 lines — and asking the daemon for the container's WHOLE log
    /// afterwards, in one `follow=false` request while it still existed,
    /// returned the same short answer. The lines were not late, they were gone.
    /// Cargo's `--message-format=json` stream is the only thing that reports a
    /// produced binary, so on this road the engine's log was a correctness
    /// channel that silently drops data.
    ///
    /// The fake runner here is the measured engine: it exits 0 and reports a
    /// stdout that has lost the tail, while the container wrote the whole
    /// stream to the bound target dir. The assertion is the ARTIFACT.
    #[test]
    fn the_stream_is_read_from_the_bound_file_when_the_engine_dropped_it() {
        let set = set_with("[build]\n[[build.variant]]\nname = \"v\"\n");
        let repo = scratch("repo-file");
        let target = target_with("target-file", "debug/v");

        // What the container really wrote, on the bind mount the host owns.
        let whole = format!(
            "{RUSTC_SENTINEL}rustc 1.97.1 (8bab26f4f 2026-07-14)\n\
             {CARGO_SENTINEL}cargo 1.97.1 (c980f4866 2026-06-30)\n\
             {HOST_SENTINEL}x86_64-unknown-linux-gnu\n\
             {{\"reason\":\"compiler-artifact\",\"executable\":null,\"target\":{{\"name\":\"dep\"}}}}\n\
             {{\"reason\":\"compiler-artifact\",\"executable\":\"{TARGETDIR}/debug/v\",\"target\":{{\"name\":\"v\"}}}}\n\
             {{\"reason\":\"build-finished\",\"success\":true}}\n"
        );
        // The fake WRITES it during the run, the way the container does — the
        // road removes any previous file first, so a test that wrote it up
        // front would be testing nothing.
        let fake = WritesStream {
            inner: Fake::new(CargoRunOutcome {
                exit_code: Some(0),
                // What the engine says it printed: the tail is simply missing.
                stdout: vec![format!("{RUSTC_SENTINEL}rustc 1.97.1 (8bab26f4f 2026-07-14)")],
                stderr: vec![],
            }),
            at: target.join(cargo_stream_file("v")),
            text: whole.clone(),
        };
        let o = build_variant_in_container(&set, "v", &repo, &target, None, &tc(), &fake)
            .expect("the file has the whole stream, so this is a real build");
        assert_eq!(
            o.artifacts,
            vec![target.join("debug/v")],
            "the build was judged on the engine's truncated stdout, not on the file"
        );
        assert_eq!(o.attestation.record.toolchain.cargo, "cargo 1.97.1 (c980f4866 2026-06-30)");

        // And the script really does route cargo through that file, so the two
        // halves of this cannot drift apart.
        let req = fake.inner.seen.lock().unwrap().first().cloned().expect("the runner ran");
        assert!(
            req.script.contains(&format!("{TARGETDIR}/{}", cargo_stream_file("v"))),
            "the script never wrote the stream anywhere the host can read: {}",
            req.script
        );

        // A STALE file from a previous run must not be read as this build's
        // evidence — it is removed before the run, so a container that writes
        // nothing leaves nothing to find, and the judge refuses.
        let stale = target.join(cargo_stream_file("v"));
        std::fs::write(&stale, &whole).unwrap();
        let silent =
            Fake::new(CargoRunOutcome { exit_code: Some(0), stdout: vec![], stderr: vec![] });
        let e = build_variant_in_container(&set, "v", &repo, &target, None, &tc(), &silent)
            .expect_err("a stale stream file must not become this build's artifact");
        assert!(format!("{e}").contains("no executable"), "{e}");
        assert!(!stale.exists(), "the stale file survived the run");
    }

    /// ★ RED-FIRST — **the container road refuses its own false green.**
    ///
    /// This is the appliance bug, MEASURED on t14s 2026-09-12 and reproduced
    /// here at the seam: a run that exits 0 and hands back no `executable`.
    /// Before the judge, this test's first half returned `Ok` with
    /// `artifacts == []` and `success == true`, and the operator met the failure
    /// two crates away as `chained variant 'gunnar-server' has kind 'Exe', which
    /// produced no single artifact to stage`.
    ///
    /// It asserts the ARTIFACT, never `success`: `success` is the exit code and
    /// was ALREADY true in the broken run, so a guard resting on it is exactly
    /// the check that could not fail.
    #[test]
    fn exit_zero_with_no_executable_is_refused_on_the_container_road() {
        let set = set_with("[build]\n[[build.variant]]\nname = \"v\"\n");
        let repo = scratch("repo-nothing");
        let target = target_with("target-nothing", "debug/v");

        // Half one: the TRANSPORT delivered nothing. 3 of 20 live runs of a
        // chatty container came back exactly like this — exit 0, zero stdout
        // lines — because the engine's log stream carries cargo's stdout here.
        let fake =
            Fake::new(CargoRunOutcome { exit_code: Some(0), stdout: vec![], stderr: vec![] });
        let e = build_variant_in_container(&set, "v", &repo, &target, None, &tc(), &fake)
            .expect_err("exit 0 with nothing staged must refuse HERE");
        let m = format!("{e}");
        assert!(m.contains("no executable"), "{m}");
        assert!(m.contains("0 compiler artifact"), "{m}");
        assert!(m.contains("transport"), "an empty stream is named as a transport cause: {m}");
        assert!(m.contains("bound target dir"), "the refusal names the channel it read: {m}");
        assert!(m.contains(PIN), "the refusal names the image it ran in: {m}");

        // Half two: the stream arrived and cargo really did build no binary.
        let mut out = ok_stdout("/target/debug/v");
        out.stdout.pop();
        out.stdout.push(
            r#"{"reason":"compiler-artifact","executable":null,"target":{"name":"t"}}"#.into(),
        );
        let fake = Fake::new(out);
        let e = build_variant_in_container(&set, "v", &repo, &target, None, &tc(), &fake)
            .expect_err("a build with no binary target must refuse too");
        let m = format!("{e}");
        assert!(m.contains("1 compiler artifact"), "the unit count is real: {m}");
        assert!(m.contains("no binary target"), "{m}");

        // …and the green is still green, asserted on the PATH cargo reported —
        // rewritten onto this host — and not on a boolean.
        let fake = Fake::new(ok_stdout("/target/debug/v"));
        let o = build_variant_in_container(&set, "v", &repo, &target, None, &tc(), &fake)
            .expect("a run that produced a binary builds");
        assert_eq!(o.artifacts, vec![target.join("debug/v")], "the staged path is the host's");
    }

    #[test]
    fn a_nonzero_exit_is_an_unsuccessful_outcome_not_an_error() {
        let set = set_with("[build]\n[[build.variant]]\nname = \"v\"\n");
        let mut out = ok_stdout("/target/debug/v");
        out.exit_code = Some(101);
        let fake = Fake::new(out);
        let repo = scratch("repo-red");
        let target = target_with("target-red", "debug/v");
        let o = build_variant_in_container(&set, "v", &repo, &target, None, &tc(), &fake)
            .expect("a failed build is a VALUE, not an Err");
        assert!(!o.success);
    }

    // ── the gate ─────────────────────────────────────────────────────────────

    #[test]
    fn the_gate_is_green_only_on_the_same_bytes() {
        let dir = std::env::temp_dir().join("nbt-byte-identity");
        std::fs::create_dir_all(&dir).unwrap();
        let a = dir.join("a");
        let b = dir.join("b");
        let c = dir.join("c");
        std::fs::write(&a, b"same").unwrap();
        std::fs::write(&b, b"same").unwrap();
        std::fs::write(&c, b"different").unwrap();

        let v = byte_identity_verdict(&a, &b);
        assert!(v.is_identical(), "{v:?}");
        assert!(v.line("v").contains("DONE"), "{}", v.line("v"));

        let v = byte_identity_verdict(&a, &c);
        assert!(!v.is_identical(), "{v:?}");
        assert!(matches!(v, ByteIdentity::Differs { .. }));
        assert!(v.line("v").contains("as dåligt"), "{}", v.line("v"));
    }

    /// ★ **A non-reproducible build is not the container's fault, and the gate
    /// must not say it is — nor go green.**
    ///
    /// MEASURED 2026-08-26 on `gunnar-server`: every build came out different.
    /// `gunnar/crates/gunnar-common/build.rs:43` runs
    /// `date -u +%Y-%m-%dT%H:%M:%SZ` and bakes it as `GUNNAR_BUILD_DATE`; the
    /// host and container artifacts carried `2026-08-25T22:43:39Z` and
    /// `2026-08-25T22:44:47Z`. A deliberate identity stamp, at second resolution
    /// off the wall clock — so two builds one second apart differ, on one box or
    /// two.
    ///
    /// Without the control the gate reports `Differs` and the reader concludes
    /// the container forked the build. It did not. The blame belongs to the
    /// repo, and it is still a red.
    #[test]
    fn a_build_that_is_not_reproducible_at_all_is_named_as_such_and_not_blamed_on_the_container() {
        let dir = scratch("control");
        let (a, b, host, cont) =
            (dir.join("a"), dir.join("b"), dir.join("h"), dir.join("c"));
        std::fs::write(&a, b"stamped 22:43:39").unwrap();
        std::fs::write(&b, b"stamped 22:44:47").unwrap();
        std::fs::write(&host, b"stamped 22:43:39").unwrap();
        std::fs::write(&cont, b"stamped 22:44:47").unwrap();

        let v = byte_identity_with_control(&a, &b, &host, &cont, "GUNNAR_BUILD_DATE");
        assert!(!v.is_identical(), "a non-reproducible build is never green: {v:?}");
        assert!(matches!(v, ByteIdentity::NotReproducible { .. }), "{v:?}");
        let line = v.line("gunnar-server");
        assert!(line.contains("NOT the container"), "{line}");
        assert!(line.contains("GUNNAR_BUILD_DATE"), "…and names the cause: {line}");

        // With a reproducible control, the SAME comparison is answerable again —
        // the control gates the question, it does not replace it.
        std::fs::write(&b, b"stamped 22:43:39").unwrap();
        let v = byte_identity_with_control(&a, &b, &host, &cont, "");
        assert!(matches!(v, ByteIdentity::Differs { .. }), "now it IS the container: {v:?}");
        std::fs::write(&cont, b"stamped 22:43:39").unwrap();
        assert!(byte_identity_with_control(&a, &b, &host, &cont, "").is_identical());
    }

    /// ★ **A missing side is a RED, never a pass.** The tempting shape is
    /// `host_sha == container_sha` over two `Option`s, where `None == None` is
    /// `true` — a gate that goes green loudest exactly when neither build
    /// produced anything.
    #[test]
    fn a_missing_artifact_is_red_and_not_a_vacuous_green() {
        let dir = std::env::temp_dir().join("nbt-byte-identity");
        std::fs::create_dir_all(&dir).unwrap();
        let there = dir.join("a");
        std::fs::write(&there, b"same").unwrap();
        let gone = dir.join("does-not-exist");

        let v = byte_identity_verdict(&there, &gone);
        assert!(!v.is_identical(), "{v:?}");
        assert!(matches!(v, ByteIdentity::Missing { .. }), "{v:?}");

        let v = byte_identity_verdict(&gone, &gone);
        assert!(!v.is_identical(), "neither side existing is the STRONGEST red: {v:?}");
    }

    /// The embedded Containerfile is the crate's own, and it states the law it
    /// obeys. A build image whose provenance is "someone's Dockerfile" is the
    /// thing this constant exists to prevent.
    #[test]
    fn the_committed_containerfile_states_the_host_free_law_and_names_every_step() {
        let cf = CARGO_TOOLCHAIN_CONTAINERFILE;
        assert!(cf.contains("NOTHING else"), "the host-free law is stated");
        assert!(cf.contains("E0463"), "…and the measurement it closes is named");
        for step in ["step: COMPILE", "step: LINK", "step: FETCH", "step: PROVENANCE"] {
            assert!(cf.contains(step), "every package names its STEP; missing `{step}`");
        }
        assert!(
            cf.contains("musl-tools"),
            "the musl C toolchain is IN the image, not on the host"
        );
        // mold appears ONLY as the named absence. The host's
        // `~/.cargo/config.toml` adds `-C link-arg=-fuse-ld=mold` for the gnu
        // target, and a host linker choice leaking into a container build is
        // precisely the drift this image removes — so the file says so, and
        // never installs it.
        assert!(cf.contains("mold is"), "the absent host linker is named: {cf}");
        assert!(
            !cf.lines().any(|l| l.trim_start().starts_with("mold")),
            "…and never installed as a package"
        );
    }

    /// `HostPaths` is cargo's own ladder in cargo's own order, and it does NOT
    /// invent a third place to look.
    #[test]
    fn the_host_paths_are_resolved_once_and_from_cargos_own_ladder() {
        // SAFETY-of-intent: these two are read-only lookups; the test sets them
        // for the process and asserts the resolution, not the environment.
        let repo = Path::new("/home/x/git/repo");
        unsafe {
            std::env::set_var("CARGO_TARGET_DIR", "/scratch/lane");
            std::env::set_var("CARGO_HOME", "/home/x/.cargo");
        }
        let p = HostPaths::from_env(repo);
        assert_eq!(p.target_dir, PathBuf::from("/scratch/lane"));
        assert_eq!(p.registry, PathBuf::from("/home/x/.cargo/registry"));
        unsafe {
            std::env::remove_var("CARGO_TARGET_DIR");
        }
        let p = HostPaths::from_env(repo);
        assert_eq!(p.target_dir, repo.join("target"), "the conventional fallback");
        assert_eq!(
            p.registry_bind(),
            None,
            "a registry that is not on this box is not bound, and that is not an error"
        );
    }

    /// **THE GATE, MEASURED — both arms, on t14s 2026-08-26.**
    ///
    /// This records what the live run produced, because the numbers are the
    /// argument and a prose claim of "reproducible" is not:
    ///
    /// | arm | host sha256 | container sha256 | verdict |
    /// |---|---|---|---|
    /// | host build with NO remap | `ae9e570e2ade15ed…` (610 688 B) | `7b85469ae1c483b7…` (610 696 B) | **Differs** |
    /// | host build with `host_rustflags` | `7b85469ae1c483b7…` (610 696 B) | `7b85469ae1c483b7…` (610 696 B) | **Identical** |
    ///
    /// Same crate, same variant (`--release --target x86_64-unknown-linux-musl`,
    /// 11 crates.io dependencies compiled from the read-only registry bind with
    /// `--network none --offline --locked`), same rustc 1.97.1 on both sides.
    /// The ONLY difference in the red arm is the paths rustc baked in — 8 bytes,
    /// the length delta between `~/…/redproof` and `/work`.
    ///
    /// So: **byte-identity is reachable, and it is reachable only because both
    /// sides remap.** Had the gate been run without
    /// [`host_rustflags`](CargoToolchain::host_rustflags) it would have gone red
    /// on a difference the COMPARISON introduced, and the honest response to
    /// that red would have been to weaken the gate. The two halves of the remap
    /// are therefore a load-bearing part of the gate, not a convenience — which
    /// is what this test pins.
    #[test]
    fn the_two_remap_halves_describe_the_same_rewrite_from_both_sides() {
        let t = tc();
        let repo = Path::new("/home/alice/git/gunnar");
        let home = Path::new("/home/alice/.cargo");
        let target = Path::new("/scratch/lane");
        let (c, h) = (t.container_rustflags(), t.host_rustflags(repo, home, target));
        // Both name the SAME two destinations. A gate whose two sides remap to
        // different synthetic prefixes compares two rewrites, not two builds.
        for dest in [REMAP_SRC, REMAP_REGISTRY, REMAP_TARGET] {
            assert_eq!(
                c.matches(dest).count(),
                1,
                "container side must remap to {dest} exactly once: {c}"
            );
            assert_eq!(
                h.matches(dest).count(),
                1,
                "host side must remap to {dest} exactly once: {h}"
            );
        }
        // …from the paths each side actually has.
        assert!(c.contains(WORKROOT) && !c.contains("/home/alice"), "{c}");
        assert!(h.contains("/home/alice/git=") && !h.contains(WORKROOT), "{h}");
    }

    // ── per-row siblings (2026-09-28: holger's plugin row must not need gunnar) ──

    /// A constellation shaped like monetize-impl's: the repo `mi` path-deps into
    /// `gunnar` (NOT checked out here), and its `hg` row builds `../holger`, which
    /// path-deps `edda`. The repo-wide list is the union; the row's own list is
    /// holger's closure.
    fn row_constellation(sub: &str) -> PathBuf {
        let root = scratch(sub);
        let _ = std::fs::remove_dir_all(&root);
        let w = |rel: &str, text: &str| {
            let p = root.join(rel);
            std::fs::create_dir_all(p.parent().unwrap()).unwrap();
            std::fs::write(p, text).unwrap();
        };
        w("mi/crates/g/Cargo.toml", "[package]\nname = \"g\"\n[dependencies]\ngx = { path = \"../../../gunnar/gx\" }\n");
        w("holger/Cargo.toml", "[package]\nname = \"hg\"\n[dependencies]\nex = { path = \"../edda/ex\" }\n");
        w("edda/ex/Cargo.toml", "[package]\nname = \"ex\"\n");
        // holger's own excluded workspace (holger-estate-front's shape): cargo
        // building holger never loads it, so its reach is not the row's.
        w("holger/front/Cargo.toml", "[package]\nname = \"front\"\n[workspace]\n[dependencies]\nui = { path = \"../../holger-ui/ui\" }\n");
        root
    }

    const ROW_SET: &str = "[build]\n\
        [[build.variant]]\nname = \"v\"\nmanifest_dir = \"../holger\"\nsiblings = [\"holger\", \"edda\"]\n\
        [[build.variant]]\nname = \"w\"\n";

    /// ★ The row's own `siblings` REPLACE the repo-wide list: holger's row builds
    /// with no gunnar checkout on the box, mounts holger and edda only, and the
    /// escape check reads holger's manifests, not the repo's.
    #[test]
    fn a_row_with_its_own_siblings_builds_without_the_repo_wide_union() {
        let root = row_constellation("row-siblings");
        let repo = root.join("mi");
        let set = set_with(ROW_SET);
        let union = CargoToolchain {
            siblings: vec!["edda".into(), "gunnar".into(), "holger".into()],
            ..tc()
        };
        let fake = Fake::new(ok_stdout("/target/debug/v"));
        let target = target_with("row-siblings-target", "debug/v");
        build_variant_in_container(&set, "v", &repo, &target, None, &union, &fake)
            .expect("holger's row needs no gunnar checkout");
        let seen = fake.seen.lock().unwrap();
        let binds = &seen[0].binds;
        assert!(binds.iter().any(|b| b.ends_with(&format!("{WORKROOT}/holger:ro"))), "{binds:?}");
        assert!(binds.iter().any(|b| b.ends_with(&format!("{WORKROOT}/edda:ro"))), "{binds:?}");
        assert!(!binds.iter().any(|b| b.contains("gunnar")), "gunnar mounted for holger's row: {binds:?}");
        assert!(!binds.iter().any(|b| b.contains("holger-ui")), "a nested workspace's reach was mounted: {binds:?}");
        drop(seen);

        // The row WITHOUT its own list keeps the repo-wide one — and on this box
        // that is refused by name, because gunnar is not checked out.
        let e = build_variant_in_container(&set, "w", &repo, &target, None, &union, &fake)
            .expect_err("the union needs gunnar");
        assert!(format!("{e:#}").contains("gunnar"), "{e:#}");
    }

    /// ★ **A row with its own manifest root runs cargo IN that root.** cargo finds
    /// `.cargo/config.toml` from the directory it runs in, never from
    /// `--manifest-path`. MEASURED 2026-10-23 on dwarf: monetize-impl's
    /// `holger-guest` ran in `/work/monetize-impl` with `--manifest-path
    /// ../holger/Cargo.toml`, so holger's sibling patches (`.cargo/siblings.toml`,
    /// included by its config) never loaded and the build answered "no matching
    /// package named `appliance-grow`".
    #[test]
    fn a_row_with_its_own_manifest_root_runs_cargo_there() {
        let root = row_constellation("row-cwd");
        let repo = root.join("mi");
        let set = set_with(ROW_SET);
        let fake = Fake::new(ok_stdout("/target/debug/v"));
        let target = target_with("row-cwd-target", "debug/v");
        build_variant_in_container(&set, "v", &repo, &target, None, &tc(), &fake).expect("the row builds");
        let seen = fake.seen.lock().unwrap();
        let script = &seen[0].script;
        assert!(script.contains(&format!("cd '{WORKROOT}/holger'")), "{script}");
        assert!(script.contains("'--manifest-path' 'Cargo.toml'"), "{script}");
        assert!(!script.contains("../holger/Cargo.toml"), "{script}");
    }

    /// ★ An ABSENT declared sibling is refused with WHERE TO CLONE IT FROM: every
    /// forge base the neighbouring checkouts' `origin`s name (tunnr is mikronova/,
    /// tunnr-mullvad is nordisk/ — 2026-10-16 on loki), never one guessed from this
    /// repo's own remote alone.
    #[test]
    fn an_absent_sibling_names_where_to_clone_it_from() {
        let root = scratch("absent-sibling-hint");
        let _ = std::fs::remove_dir_all(&root);
        let w = |rel: &str, text: &str| {
            let p = root.join(rel);
            std::fs::create_dir_all(p.parent().unwrap()).unwrap();
            std::fs::write(p, text).unwrap();
        };
        w("tunnr/Cargo.toml", "[package]\nname = \"tunnr\"\n");
        w("tunnr/.git/config", "[core]\n\tbare = false\n[remote \"origin\"]\n\turl = ssh://git@forge:2222/mikronova/tunnr\n\tfetch = +refs/heads/*:refs/remotes/origin/*\n");
        w("edda/.git/config", "[remote \"upstream\"]\n\turl = https://elsewhere/x/edda\n[remote \"origin\"]\n\turl = ssh://git@forge:2222/nordisk/edda.git\n");
        let t = CargoToolchain { siblings: vec!["edda".into(), "tunnr-mullvad".into()], ..tc() };
        let m = format!("{:#}", t.check_escaping_path_deps(&root.join("tunnr")).expect_err("tunnr-mullvad is absent"));
        assert!(m.contains("tunnr-mullvad"), "{m}");
        let want = root.join("tunnr-mullvad");
        for base in ["ssh://git@forge:2222/nordisk", "ssh://git@forge:2222/mikronova"] {
            assert!(m.contains(&format!("git clone {base}/tunnr-mullvad {}", want.display())), "missing {base}: {m}");
        }
        assert!(!m.contains("elsewhere"), "only `origin` is a source: {m}");
    }

    /// ★ **Where an absent sibling is cloned from, best first**: the repo's own host
    /// and namespace, then the other namespaces its neighbours come from on THAT host
    /// — never a base on another host, never a sibling already there.
    #[test]
    fn an_absent_siblings_sources_are_the_repos_own_namespace_then_the_neighbours() {
        let root = scratch("absent-sibling-urls");
        let _ = std::fs::remove_dir_all(&root);
        let w = |rel: &str, text: &str| {
            let p = root.join(rel);
            std::fs::create_dir_all(p.parent().unwrap()).unwrap();
            std::fs::write(p, text).unwrap();
        };
        let origin = |url: &str| format!("[remote \"origin\"]\n\turl = {url}\n");
        w("tunnr/.git/config", &origin("ssh://git@forge:2222/mikronova/tunnr"));
        w("edda/.git/config", &origin("ssh://git@forge:2222/nordisk/edda.git"));
        w("far/.git/config", &origin("https://elsewhere/x/far"));
        w("plain/README", "not a checkout\n");
        let urls = sibling_clone_urls(&root.join("tunnr"), "tunnr-mullvad");
        assert_eq!(urls, ["ssh://git@forge:2222/mikronova/tunnr-mullvad", "ssh://git@forge:2222/nordisk/tunnr-mullvad"]);
        let t = CargoToolchain { siblings: vec!["edda".into(), "tunnr-mullvad".into(), "plain".into()], ..tc() };
        let absent: Vec<String> = t.absent_siblings(&root.join("tunnr")).into_iter().map(|(n, _)| n).collect();
        assert_eq!(absent, ["tunnr-mullvad"], "a dir that is there — a checkout or not — is never cloned over");
    }

    /// A row's list that misses what ITS manifests reach is refused by name —
    /// the scan follows the row's manifest root.
    #[test]
    fn a_row_list_missing_its_own_reach_is_refused_by_name() {
        let root = row_constellation("row-siblings-missing");
        let repo = root.join("mi");
        let set = set_with(
            "[build]\n[[build.variant]]\nname = \"v\"\nmanifest_dir = \"../holger\"\nsiblings = [\"holger\"]\n",
        );
        let fake = Fake::new(ok_stdout("/target/debug/v"));
        let target = target_with("row-siblings-missing-target", "debug/v");
        let e = build_variant_in_container(&set, "v", &repo, &target, None, &tc(), &fake)
            .expect_err("edda is reached and not listed");
        let m = format!("{e:#}");
        assert!(m.contains("siblings = [\"edda\"]"), "{m}");
        assert!(fake.seen.lock().unwrap().is_empty(), "the container was started anyway");
    }

    /// The measured closure: `cargo metadata --locked` of `a` loads `b` (a path
    /// dep into a sibling checkout) and `a` itself — and nothing the tree merely
    /// mentions in a nested workspace.
    #[test]
    fn the_metadata_closure_is_what_cargo_loads() {
        let root = scratch("metadata-closure");
        let _ = std::fs::remove_dir_all(&root);
        let w = |rel: &str, text: &str| {
            let p = root.join(rel);
            std::fs::create_dir_all(p.parent().unwrap()).unwrap();
            std::fs::write(p, text).unwrap();
        };
        w("a/Cargo.toml", "[package]\nname = \"a\"\nversion = \"0.1.0\"\nedition = \"2021\"\n[workspace]\nexclude = [\"nested\"]\n[dependencies]\nb = { path = \"../b/b\" }\n");
        w("a/src/lib.rs", "");
        w("a/Cargo.lock", "version = 4\n\n[[package]]\nname = \"a\"\nversion = \"0.1.0\"\ndependencies = [\n \"b\",\n]\n\n[[package]]\nname = \"b\"\nversion = \"0.1.0\"\n");
        w("a/nested/Cargo.toml", "[package]\nname = \"n\"\nversion = \"0.1.0\"\n[workspace]\n[dependencies]\nc = { path = \"../../c\" }\n");
        w("b/b/Cargo.toml", "[package]\nname = \"b\"\nversion = \"0.1.0\"\nedition = \"2021\"\n");
        w("b/b/src/lib.rs", "");
        let c = metadata_sibling_closure(&root.join("a/Cargo.toml"), &root).expect("cargo metadata");
        assert_eq!(c, ["a", "b"]);
        assert!(
            workspace_escaping_path_deps(&root.join("a")).iter().all(|(_, d, _)| d != "c"),
            "the nested workspace's dep was scanned"
        );
        assert!(escaping_path_deps(&root.join("a")).iter().any(|(_, d, _)| d == "c"), "the whole-tree scan is unchanged");
    }

    /// `for_variant` touches the sibling list only, and only when the row says so.
    #[test]
    fn for_variant_replaces_only_the_siblings() {
        let set = set_with(ROW_SET);
        let t = CargoToolchain { siblings: vec!["gunnar".into()], mem_limit_mb: 77, ..tc() };
        let v = t.for_variant(set.require("v").unwrap());
        assert_eq!(v.siblings, ["holger", "edda"]);
        assert_eq!((v.image_ref(), v.mem_limit_mb), (t.image_ref(), 77));
        assert_eq!(t.for_variant(set.require("w").unwrap()), t);
        assert_eq!(
            variant_manifest_root(Path::new("/c/mi"), set.require("v").unwrap()),
            PathBuf::from("/c/holger")
        );
        assert_eq!(variant_manifest_root(Path::new("/c/mi"), set.require("w").unwrap()), PathBuf::from("/c/mi"));
    }

    /// The key round-trips, asks for schema 6, and a path or a duplicate is refused.
    #[test]
    fn row_siblings_parse_emit_and_validate() {
        let set = set_with(ROW_SET);
        let v = set.require("v").unwrap();
        set.validate(v).expect("valid");
        let text = crate::emit::recipe_toml("# t", &set).expect("emits and reads back");
        assert!(text.contains("siblings = [\n    \"holger\",") || text.contains("siblings = [\"holger\", \"edda\"]"), "{text}");
        assert!(text.contains("schema = 6"), "{text}");
        let (n, why) = crate::schema::required_by(&set);
        assert_eq!(n, 6, "{why:?}");
        assert!(why.iter().any(|w| w.contains("siblings") && w.contains("'v'")), "{why:?}");
        for bad in ["[\"../edda\"]", "[\"edda\", \"edda\"]", "[\"\"]"] {
            let s = set_with(&format!("[build]\n[[build.variant]]\nname = \"v\"\nsiblings = {bad}\n"));
            assert!(s.validate(s.require("v").unwrap()).is_err(), "{bad} was accepted");
        }
    }

    /// Build a fake checkout: `<root>/gunnar` with a crate whose manifest reaches
    /// `../../../znippy/git-storage-trait`, plus `<root>/znippy` beside it. This
    /// is gunnar's real shape, reduced to two files.
    fn fake_checkout(sub: &str) -> PathBuf {
        let root = scratch(sub);
        let _ = std::fs::remove_dir_all(&root);
        let crate_dir = root.join("gunnar/crates/gunnar-store");
        std::fs::create_dir_all(&crate_dir).unwrap();
        std::fs::create_dir_all(root.join("znippy/git-storage-trait")).unwrap();
        std::fs::write(
            crate_dir.join("Cargo.toml"),
            "[package]\nname = \"gunnar-store\"\n\
             [dependencies]\n\
             git-storage-trait = { version = \"0.1.0\", path = \"../../../znippy/git-storage-trait\" }\n\
             serde = \"1\"\n\
             [[bin]]\nname = \"x\"\npath = \"src/main.rs\"\n",
        )
        .unwrap();
        root
    }

    /// ★ RED-FIRST, MEASURED 2026-08-26 — **a single repo bind cannot build this
    /// constellation, and cargo's failure named the wrong thing.**
    ///
    /// Binding gunnar alone at `/work` and running its `gunnar-server` variant in
    /// the real image gave, in 2.7 s:
    ///
    /// ```text
    /// error: failed to load manifest for workspace member `/work/crates/gunnar-store`
    /// Caused by: failed to read `/znippy/git-storage-trait/Cargo.toml`
    /// ```
    ///
    /// Ten path dependencies in gunnar walk out of its own tree into `edda` and
    /// `znippy`. cargo's message names a path that does not exist, and neither
    /// the manifest line that asked for it nor the one word that fixes it. This
    /// is that failure, named before the container starts.
    #[test]
    fn a_path_dep_escaping_into_an_undeclared_sibling_is_refused_by_name() {
        let root = fake_checkout("escape");
        let repo = root.join("gunnar");

        let e = tc()
            .check_escaping_path_deps(&repo)
            .expect_err("an undeclared sibling must be refused, not discovered at runtime");
        let m = format!("{e}");
        assert!(m.contains("znippy"), "the refusal names the SIBLING: {m}");
        assert!(m.contains("siblings = [\"znippy\"]"), "…and the fix, spelled: {m}");
        assert!(m.contains("gunnar-store"), "…and the manifest that caused it: {m}");

        // Declared ⇒ green, and the bind that makes it true is present.
        let ok = CargoToolchain { siblings: vec!["znippy".into()], ..tc() };
        ok.check_escaping_path_deps(&repo).expect("a declared sibling is fine");
        let binds = ok.binds(&repo, Path::new("/scratch/t"), None);
        assert_eq!(binds[0], format!("{}:{WORKROOT}/gunnar", repo.display()));
        assert!(
            binds.iter().any(|b| b.ends_with(&format!("{WORKROOT}/znippy:ro"))),
            "the sibling is mounted BESIDE the repo, read-only: {binds:?}"
        );
        // …and from /work/gunnar/crates/gunnar-store the dep's own
        // `../../../znippy/…` lands inside that mount. The depth is the fix.
        assert_eq!(ok.container_repo_dir(&repo), format!("{WORKROOT}/gunnar"));
    }

    /// ★ **A detached crate in the repo demands nothing of the repo's own rows** (the 5.3.2
    /// receipt on the box, 2026-10-09): monetize-impl carries `gunnar-front-commercial`, its own
    /// `[workspace]`, path-depending on gunnar; monetize-impl's rows never load it, and its
    /// toolchain was refused "Add `siblings = [\"gunnar\"]`". The repo-wide pre-flight reads the
    /// repo's ONE workspace; the detached crate is checked as its own workspace, by the rows that
    /// build it, against their own list.
    #[test]
    fn a_detached_crate_in_the_repo_demands_no_sibling_of_the_repos_own_rows() {
        let root = fake_checkout("escape-detached");
        let repo = root.join("gunnar");
        let ok = CargoToolchain { siblings: vec!["znippy".into()], ..tc() };
        ok.check_escaping_path_deps(&repo).expect("the repo as it is");
        let d = repo.join("crates/front-commercial");
        std::fs::create_dir_all(&d).unwrap();
        std::fs::write(d.join("Cargo.toml"), "[package]\nname = \"fc\"\nversion = \"0.0.0\"\n[workspace]\n[dependencies]\nother = { path = \"../../../other/crates/x\" }\n").unwrap();
        ok.check_escaping_path_deps(&repo).expect("the detached crate's dep is not the repo's rows' business");
        // The rows that BUILD the detached crate see its dep, and need its sibling declared.
        let m = format!("{}", ok.check_escaping_path_deps_from(&repo, &d).unwrap_err());
        assert!(m.contains("siblings = [\"other\"]"), "{m}");
        let built = CargoToolchain { siblings: vec!["other".into()], ..tc() };
        let _ = std::fs::create_dir_all(root.join("other"));
        built.check_escaping_path_deps_from(&repo, &d).expect("declared for the row that builds it");
        // A crate of the repo's OWN workspace still demands its sibling.
        let own = repo.join("crates/own");
        std::fs::create_dir_all(&own).unwrap();
        std::fs::write(own.join("Cargo.toml"), "[package]\nname = \"o\"\nversion = \"0.0.0\"\n[dependencies]\nother = { path = \"../../../other/crates/x\" }\n").unwrap();
        let m = format!("{}", ok.check_escaping_path_deps(&repo).unwrap_err());
        assert!(m.contains("siblings = [\"other\"]"), "the repo's own crates are read as before: {m}");
    }

    /// A declared sibling that is not checked out is named HERE, where the
    /// reader is already looking at the list — not as a bind-mount failure from
    /// the engine, which names a path and has never heard of `siblings`.
    #[test]
    fn a_declared_sibling_that_is_not_checked_out_is_refused_by_name() {
        let root = fake_checkout("escape-absent");
        let repo = root.join("gunnar");
        let t = CargoToolchain { siblings: vec!["znippy".into(), "nope".into()], ..tc() };
        let m = format!("{}", t.check_escaping_path_deps(&repo).unwrap_err());
        assert!(m.contains("nope"), "the missing one is named: {m}");
        assert!(!m.contains("znippy ("), "…and the present one is not: {m}");
        assert!(m.contains("bind mount would fail"), "…with the consequence: {m}");
    }

    /// A dep reaching ABOVE the shared parent is refused separately: a flat
    /// sibling mount cannot reproduce that layout, so `siblings` would not help
    /// and implying it would is worse than the refusal.
    #[test]
    fn a_path_dep_reaching_above_the_parent_is_a_different_refusal() {
        let root = fake_checkout("escape-high");
        let repo = root.join("gunnar");
        std::fs::write(
            repo.join("crates/gunnar-store/Cargo.toml"),
            "[package]\nname = \"g\"\n[dependencies]\n\
             far = { path = \"../../../../../../../../../opt/far\" }\n",
        )
        .unwrap();
        let m = format!("{}", tc().check_escaping_path_deps(&repo).unwrap_err());
        assert!(m.contains("ABOVE the repo's parent"), "{m}");
        assert!(m.contains("unbounded slice"), "…and why that cannot be mounted: {m}");
    }

    /// The scan uses a real TOML parser, not a regex over the text: `path` also
    /// spells `[[bin]]` and `[lib]`, and a scan that cannot tell those apart
    /// reports dependencies that do not exist. The fixture's
    /// `[[bin]] path = "src/main.rs"` and its registry `serde` must both be
    /// invisible to it.
    #[test]
    fn the_scan_reads_dependency_tables_and_not_every_key_named_path() {
        let root = fake_checkout("escape-parse");
        let found = escaping_path_deps(&root.join("gunnar"));
        assert_eq!(found.len(), 1, "exactly the one escaping DEPENDENCY: {found:?}");
        assert_eq!(found[0].1, "git-storage-trait");
        assert!(found[0].2.ends_with("znippy/git-storage-trait"), "{:?}", found[0].2);
    }

    /// ★ **The real adopted declaration loads**, with every field reaching the
    /// struct. gunnar is the first repo to declare `[build.toolchain]`, and this
    /// pins the shape it actually wrote — including the five siblings measured off
    /// its own manifests — against the now-closed schema. A key this struct did not
    /// know used to be dropped in silence; `siblings` typo'd to `sibling` would
    /// have mounted nothing and failed an hour later inside cargo.
    #[test]
    fn the_declaration_shape_a_repo_actually_wrote_parses_whole() {
        let set = BuildVariantSet::from_toml_str(
            "[build]\n[build.toolchain]\n\
             image = \"nordisk-cargo-toolchain\"\n\
             image_sha256 = \"f29e517c1ba34b920c1234fbd628046d64c0f1072d85ae7dee52b5cce054a917\"\n\
             rust_version = \"1.97.1\"\n\
             targets = [\"x86_64-unknown-linux-gnu\", \"x86_64-unknown-linux-musl\"]\n\
             mem_limit_mb = 8192\ncpus = 8\ntimeout_secs = 3600\nnetwork = false\n\
             siblings = [\"edda\", \"znippy\", \"draupnir\", \"tunnr\", \"znippy-zoomies\"]\n\
             [[build.variant]]\nname = \"srv\"\ntarget = \"x86_64-unknown-linux-musl\"\n",
        )
        .expect("gunnar's real declaration must load");
        let t = set.toolchain.clone().expect("the table reached the struct");
        t.validate().expect("and it is a valid, pinned environment");
        assert_eq!(t.siblings.len(), 5, "{:?}", t.siblings);
        assert!(!t.network, "airgapped");
        t.check_target("srv", Some("x86_64-unknown-linux-musl")).expect("declared target");

        // …and a misspelling is a refusal, not a silent drop.
        let e = BuildVariantSet::from_toml_str(
            "[build]\n[build.toolchain]\nimage = \"x\"\nsibling = [\"edda\"]\n",
        )
        .expect_err("`sibling` is not `siblings`");
        assert!(format!("{e:#}").contains("sibling"), "{e:#}");
    }

    /// ★ **The image's target set is READ, not restated** — and the WASM road is
    /// in it.
    ///
    /// The refusal that opened this lane, verbatim from the chained build on oden
    /// 2026-08-27: `variant gunnar-build-thing-wasm targets
    /// wasm32-unknown-unknown, which the toolchain image nordisk-cargo-toolchain
    /// does not carry std for (it declares: x86_64-unknown-linux-gnu,
    /// x86_64-unknown-linux-musl)`. Correct then; this asserts the fix it named.
    #[test]
    fn the_containerfile_names_the_four_roads_it_installs_std_for() {
        let carried = cargo_toolchain_image_targets();
        assert_eq!(
            carried,
            vec![
                "x86_64-unknown-linux-gnu".to_string(),
                "x86_64-unknown-linux-musl".to_string(),
                "wasm32-unknown-unknown".to_string(),
                "x86_64-unknown-uefi".to_string(),
            ],
            "read out of ARG RUST_TARGETS, which is the only thing that installs a std"
        );
        // …and the parse is not a constant: a Containerfile with no such ARG
        // yields NOTHING, so a rename cannot leave this returning the old list.
        assert!(
            CARGO_TOOLCHAIN_CONTAINERFILE.contains("ARG RUST_TARGETS="),
            "the parse anchors on this exact spelling"
        );
        // The hollow check it replaced must be GONE from every EXECUTED line —
        // it survives only as the prose recording why (`# What stood here was`).
        let hollow: Vec<&str> = CARGO_TOOLCHAIN_CONTAINERFILE
            .lines()
            .filter(|l| !l.trim_start().starts_with('#'))
            .filter(|l| l.contains("--print target-list"))
            .collect();
        assert!(
            hollow.is_empty(),
            "target-list prints 322 triples in an image carrying 3 stds — it can never go \
             red, and it is still RUN here: {hollow:?}"
        );
        assert!(
            CARGO_TOOLCHAIN_CONTAINERFILE.contains("--print target-libdir"),
            "the image asserts the libdir rustup target add actually creates"
        );
    }

    /// ★ RED-FIRST on both sides. A declaration may not name a triple the image
    /// cannot build — that lie converts a named refusal into a bare `E0463` an
    /// hour into a compile, which is the whole failure mode this table exists to
    /// remove.
    #[test]
    fn a_declared_target_the_image_cannot_build_is_refused_by_name() {
        // RED: the three carried triples plus one nobody installed.
        let mut t = tc();
        t.targets = vec![
            "x86_64-unknown-linux-musl".into(),
            "wasm32-unknown-unknown".into(),
            "aarch64-unknown-linux-musl".into(),
        ];
        let e = format!("{:#}", t.check_declared_targets().expect_err("must refuse"));
        assert!(e.contains("aarch64-unknown-linux-musl"), "the offender is NAMED: {e}");
        assert!(!e.contains("(wasm32"), "…and the carried ones are not blamed: {e}");
        assert!(e.contains("E0463"), "…with the failure it prevents: {e}");
        // The same refusal must come out of `validate`, or the door has no caller.
        let e = format!("{:#}", t.validate().expect_err("validate carries it"));
        assert!(e.contains("aarch64-unknown-linux-musl"), "{e}");

        // GREEN, and not vacuously: every carried triple passes, INCLUDING the
        // wasm32 one that was a refusal before this lane.
        let mut ok = tc();
        ok.targets = cargo_toolchain_image_targets();
        ok.check_declared_targets().expect("the image's own list must pass");
        ok.validate().expect("and validate must accept it");
        ok.check_target("gunnar-build-thing-wasm", Some("wasm32-unknown-unknown"))
            .expect("the WASM road the chained build refused BY NAME is now declarable");

        // An UNDECLARED list stays permissive, and a foreign image is not guessed
        // at — two silent-refusal traps this must not spring.
        let mut undeclared = tc();
        undeclared.targets.clear();
        undeclared.check_declared_targets().expect("empty is undeclared, not none");
        let mut foreign = tc();
        foreign.image = "registry.example/some-other-toolchain".into();
        foreign.targets = vec!["riscv64gc-unknown-none-elf".into()];
        foreign
            .check_declared_targets()
            .expect("this crate does not build that image and must not claim to know it");
    }

    /// ★ RED-FIRST, and it cost a full image build to learn. The per-package
    /// rationale rides `` `# …` `` — a shell command substitution whose output is
    /// empty, which is how a `RUN apt-get install` line carries prose. A backtick
    /// INSIDE that prose closes the substitution early, and the rest of the
    /// comment becomes arguments to `apt-get install`. MEASURED 2026-08-25:
    /// three such comments (quoting `` `failed to find tool …` ``,
    /// `` `-C link-arg=-fuse-ld=mold` `` and `` `git = ` ``) made the whole image
    /// build die with `while running runtime: exit status 2` — a 30-line error
    /// that names the RUN step and not the backtick.
    ///
    /// The rule the file must hold: on any line carrying a backtick comment,
    /// backticks come in exactly one pair.
    #[test]
    fn no_comment_in_the_containerfile_nests_a_backtick() {
        for (i, line) in CARGO_TOOLCHAIN_CONTAINERFILE.lines().enumerate() {
            let n = line.matches('`').count();
            if n == 0 || !line.trim_start().starts_with('`') {
                continue;
            }
            assert_eq!(
                n,
                2,
                "line {} has {n} backticks — a nested one closes the `# …` \
                 substitution early and the prose becomes apt-get arguments: {line}",
                i + 1
            );
        }
    }

    /// The EXECUTED lines of a Containerfile — comments and blanks dropped —
    /// because a rule about what the image DOES must not be satisfied by prose
    /// recording why it once did something else.
    fn executed(cf: &str) -> Vec<&str> {
        cf.lines()
            .map(str::trim)
            .filter(|l| !l.is_empty() && !l.starts_with('#'))
            .collect()
    }

    /// ★ **The TEST image is the toolchain image plus exactly the tools a
    /// test road needs — and it is built ON the toolchain, not beside it.**
    ///
    /// The danger this guards is not a missing package; it is the test image
    /// drifting into a second build environment. A suite that passes in an
    /// image whose rustc, targets or libc differ from the one the artefact was
    /// compiled in has measured something else.
    #[test]
    fn the_test_image_is_the_toolchain_plus_the_test_road_and_nothing_else() {
        let test = executed(CARGO_TEST_CONTAINERFILE);

        // It is FROM the toolchain, through the ARG the builder pins.
        let from = test
            .iter()
            .find(|l| l.starts_with("FROM "))
            .expect("a Containerfile has a FROM");
        assert_eq!(
            *from, "FROM ${CARGO_TOOLCHAIN_REF}",
            "the test image must be built on the toolchain image, not on its own base: {from}"
        );
        assert!(
            test.iter().any(|l| l.starts_with(CARGO_TEST_BASE_ARG)),
            "there is no `{CARGO_TEST_BASE_ARG}` line for the builder to pin the base through"
        );

        // The three tools, each of which unblocks a named set of tests.
        for tool in ["openssh-client", "git-lfs", "cargo-deny", "libssl-dev", "rustup component add rustfmt clippy"] {
            assert!(
                test.iter().any(|l| l.contains(tool)),
                "the test image does not carry {tool}"
            );
        }

        // And NOT a compiler environment of its own: the moment this file
        // installs rust, sets RUSTUP_HOME or adds a target, there are two
        // toolchains and the suite stops witnessing the build.
        // `rustup component add` is allowed: it adds rustfmt/clippy to the
        // toolchain the image is FROM, and installs no rustc and no target.
        for forbidden in [
            "rustup toolchain",
            "rustup default",
            "rustup override",
            "rustup-init",
            "RUSTUP_HOME",
            "RUSTUP_TOOLCHAIN",
            "rustup target add",
            "ARG RUST_TARGETS",
            "ARG RUST_VERSION",
            "--toolchain",
        ] {
            assert!(
                !test.iter().any(|l| l.contains(forbidden)),
                "the test image defines its own toolchain ({forbidden}); it must inherit the \
                 one it is FROM, or a suite can pass against a rustc no artefact was built with"
            );
        }

        // The snapshot and the epoch are the BASE's, not restated here — one
        // writer for the instant, per the base's own reproducibility section.
        assert!(
            !test.iter().any(|l| l.starts_with("ENV SOURCE_DATE_EPOCH=")),
            "the test image restates SOURCE_DATE_EPOCH; it must inherit the base's, or the \
             two can drift"
        );
    }

    /// ★ **The base is pinned by rewriting one line, and a file that lost the
    /// line is refused rather than built on a tag.**
    #[test]
    fn the_test_containerfile_takes_the_pin_it_is_handed() {
        let pinned = cargo_test_containerfile_on("nordisk-cargo-toolchain@sha256:deadbeef")
            .expect("the committed file has the ARG");
        assert!(
            pinned.contains("ARG CARGO_TOOLCHAIN_REF=nordisk-cargo-toolchain@sha256:deadbeef"),
            "the pin did not reach the file"
        );
        // Exactly one line changed, and the default is GONE — a leftover tag
        // default under a pinned build is the ambiguity this closes.
        assert!(
            !pinned.contains("ARG CARGO_TOOLCHAIN_REF=nordisk-cargo-toolchain:live"),
            "the tag default survived the pin"
        );
        assert_eq!(
            pinned.lines().count(),
            CARGO_TEST_CONTAINERFILE.lines().count(),
            "the rewrite added or dropped lines"
        );
    }

    /// ★ **cargo-deny is pinned by version AND by digest, and the two sides of
    /// the context boundary check the same one.**
    ///
    /// A prebuilt binary fetched over the network into an image everything
    /// else trusts is exactly where an unpinned dependency hides, so the pin
    /// is read from the Containerfile (one writer), the host verifies what it
    /// fetched, and the image verifies what it was handed.
    #[test]
    fn the_cargo_deny_pin_is_read_from_the_containerfile_and_checked_twice() {
        let (version, sha) = cargo_test_cargo_deny_pin().expect("the file pins cargo-deny");
        assert!(!version.is_empty(), "no version");
        assert_eq!(sha.len(), 64, "a sha256 is 64 hex characters: {sha:?}");
        assert!(
            sha.chars().all(|c| c.is_ascii_hexdigit() && !c.is_ascii_uppercase()),
            "the pin is not lowercase hex: {sha:?}"
        );
        // The URL is derived from the same version, so a bump cannot leave the
        // fetch pointing at the old release.
        let url = cargo_deny_url(&version);
        assert!(url.contains(&version), "the URL does not name the pinned version: {url}");
        assert!(
            url.ends_with("x86_64-unknown-linux-musl.tar.gz"),
            "the fetched artefact must be the STATIC musl build, or the image gains a glibc \
             dependency the base may not satisfy: {url}"
        );
        // The image checks the same value it was pinned with.
        assert!(
            CARGO_TEST_CONTAINERFILE.contains("sha256sum -c -"),
            "the image does not verify the staged tarball"
        );
        assert!(
            CARGO_TEST_CONTAINERFILE.contains("${CARGO_DENY_SHA256}  /tmp/cargo-deny.tar.gz"),
            "the image verifies against something other than the pin"
        );
    }

    /// ★ **The two toolchain Containerfiles pin ONE world, and the cargo one
    /// pins it at all.**
    ///
    /// SEEN RED 2026-09-05 (lane bevis), the state this test was written
    /// against: `grep -c '^ENV SOURCE_DATE_EPOCH=' cargo-toolchain.Containerfile`
    /// → 0, `FROM debian:trixie` with no digest, apt against whatever the mirror
    /// said that day, and `build_toolchain_image` calling the plain `build_image`
    /// — while the kernel file had all four moves since 2026-08-30. gunnar moved
    /// its `[build.toolchain] image_sha256` pin twice that day chasing the
    /// re-mints. Every assert below fails against that tree.
    ///
    /// An OCI build has no include, so the two files must state the base digest,
    /// the snapshot instant and the epoch separately. This is the guard that
    /// makes the duplication safe: they may not disagree. Drift in either file
    /// alone — a base bumped in one, a snapshot moved in the other — fails
    /// here by name rather than as two toolchains quietly built from two
    /// Debians.
    #[test]
    fn the_two_toolchains_pin_one_world() {
        use crate::kernel::{kernel_toolchain_source_date_epoch, KERNEL_TOOLCHAIN_CONTAINERFILE};

        let cargo = executed(CARGO_TOOLCHAIN_CONTAINERFILE);
        let kernel = executed(KERNEL_TOOLCHAIN_CONTAINERFILE);

        // The BASE: one digest, not a tag someone can move. Executed lines only —
        // the prose above the FROM legitimately quotes the bare tag as history.
        let from = |lines: &[&str]| -> String {
            lines
                .iter()
                .find(|l| l.starts_with("FROM "))
                .map(|l| l.to_string())
                .expect("a Containerfile has a FROM")
        };
        let (cf, kf) = (from(&cargo), from(&kernel));
        assert!(
            cf.contains("@sha256:"),
            "the cargo toolchain's base is a moving tag, not a digest: {cf}"
        );
        assert_eq!(cf, kf, "the two toolchains are built on two different Debians");

        // The ARCHIVE: the same snapshot instant, or apt installs from two
        // different days and the packages differ under one `FROM`.
        let snapshot = |lines: &[&str]| -> Option<String> {
            lines.iter().find_map(|l| {
                let i = l.find("snapshot.debian.org/archive/debian/")?;
                let rest = &l[i..];
                let end = rest.find('\'').unwrap_or(rest.len());
                Some(rest[..end].to_string())
            })
        };
        let cs = snapshot(&cargo).expect("the cargo toolchain does not pin apt to a snapshot");
        let ks = snapshot(&kernel).expect("the kernel toolchain pins apt to a snapshot");
        assert_eq!(cs, ks, "the two toolchains install from two different snapshot instants");

        // The CLOCK: one epoch, read from each file's own line by the one parser,
        // and the cargo file's line is the one the value came from.
        let ce = cargo_toolchain_source_date_epoch()
            .expect("the cargo toolchain Containerfile declares the instant it is minted at");
        let ke = kernel_toolchain_source_date_epoch().expect("the kernel one already did");
        assert_eq!(ce, ke, "the two toolchains are minted at two different instants");
        assert!(
            cargo.iter().any(|l| *l == format!("ENV SOURCE_DATE_EPOCH={ce}")),
            "the epoch must be the Containerfile's own EXECUTED line, not a second constant"
        );

        // …and the clock's fingerprints are scrubbed in an executed line, not
        // merely described. Each of these files carries a wall-clock stamp.
        for stamp in ["/var/lib/apt/lists", "/var/log/apt", "/var/cache/ldconfig/aux-cache"] {
            assert!(
                cargo.iter().any(|l| l.contains("rm") && l.contains(stamp)),
                "{stamp} is left in the layer that made it — its mtime moves the image id"
            );
        }
    }
}

/// Which names a toolchain mint may write — driven over a fake engine store, no
/// socket. The store models what podman does with names: a tag names exactly one
/// image, a mint WRITES its tag (moving it off whatever it named), and
/// `name@sha256:<manifest>` resolves only while some tag under `name` still
/// names that image. That last rule is the 2026-10-05 `403`.
#[cfg(test)]
mod toolchain_mint_tests {
    use super::*;
    use std::cell::RefCell;

    const NAME: &str = "nordisk-cargo-toolchain";
    /// The pinned image gunnar and holger build in (id → manifest digest).
    const PINNED_ID: &str = "id-3d5115ba";
    const PINNED_DIGEST: &str = "3d5115baa07d03ca51eb3e44ebb86b4e64e679bd88f38e156ef9da12c35d2143";
    /// What THIS crate's recipe mints (the clang + llvm recipe).
    const RECIPE_ID: &str = "id-88c4902987c2";
    const RECIPE_DIGEST: &str = "668468e775ad80f32d700cbc9709d41cac726f40d00649461a0932f30d1b2067";

    struct FakeStore {
        /// tag → image id
        tags: RefCell<BTreeMap<String, String>>,
        /// image id → manifest digest
        images: RefCell<BTreeMap<String, String>>,
        /// every tag a mint wrote, in order
        mints: RefCell<Vec<String>>,

The file goes on; the console shows all of it.