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

nordisk/nornir

src/code_room/container.rs

//! **The container road** (dv2-b1-2, owner 2026-10-15: "have it build in
//! container/containers via draupnir"): every tool the Mímir consumer starts —
//! `cargo-mimir-dump` and the driver under it, `cargo metadata`,
//! `cargo --unit-graph`, `cargo clean`, `rustc --print` — runs in the pinned
//! toolchain IMAGE through draupnir's ONE OCI engine, never bare on the host.
//! A run boots ONE container of the image ([`BoxRoad`], 2026-10-17) and runs
//! every tool in it as its own exec (`ContainerControl::exec_streaming`);
//! when that container cannot boot, each tool gets a container of its own
//! (`BootSpec::container` → `ContainerBoot`, the road before).
//!
//! | setting | meaning |
//! |---|---|
//! | `NORNIR_MIMIR_CONTAINER_IMAGE` | the image (e.g. `nordisk-runa-toolchain:nightly-2026-10-05`): its nightly is the driver's, with clang + mold (the planner's linker set) |
//! | `NORNIR_MIMIR_CONTAINER_DRIVER` | a host dir holding `cargo-mimir-dump` + `mimir-driver` + `mimir-capture` BUILT FOR THE IMAGE (its libc, its nightly; `containers/mimir-driver/Containerfile` builds them); mounted at the same path |
//! | `NORNIR_MIMIR_CONTAINER_BINDS` | more host dirs to mount at the same path, comma-separated (the nornir home is always mounted: the code rooms' clones, the one target dir, the dumps) |
//!
//! Every mount keeps its absolute path, so a path a tool prints inside means
//! the same file outside. cargo's registry lives in
//! `<nornir home>/mimir-cargo-home` (a crate is downloaded once). The tool runs
//! as the server's own uid:gid on a rootful engine (what it writes is the
//! server's), as root on a rootless one (mapped to the invoking user).
//!
//! When the image is named and the road does not work — no engine socket, the
//! image missing, the driver not loading inside — the consumer says so in one
//! line and reads on the HOST road ([`super::driver::Settings::probe`]).

use std::collections::BTreeSet;
use std::os::unix::process::ExitStatusExt;
use std::path::PathBuf;
use std::sync::Mutex;
use std::sync::atomic::{AtomicU64, Ordering};

use mimir_ingest::{ToolCall, ToolRunner};

pub const ENV_IMAGE: &str = "NORNIR_MIMIR_CONTAINER_IMAGE";
pub const ENV_DRIVER_DIR: &str = "NORNIR_MIMIR_CONTAINER_DRIVER";
pub const ENV_BINDS: &str = "NORNIR_MIMIR_CONTAINER_BINDS";

/// The road's settings.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ContainerRoad {
    pub image: String,
    /// Host dir of the image-built driver pair (mounted).
    pub driver_dir: PathBuf,
    /// Host dirs mounted at the same path.
    pub binds: Vec<PathBuf>,
    /// cargo's home inside (and outside: it is under a mounted dir).
    pub cargo_home: PathBuf,
}

impl ContainerRoad {
    /// From the environment: `None` when no image is named (the host road).
    pub fn from_env() -> Option<Self> {
        let image = std::env::var(ENV_IMAGE).ok().map(|v| v.trim().to_string()).filter(|v| !v.is_empty())?;
        let home = crate::config::nornir_home();
        let driver_dir = std::env::var(ENV_DRIVER_DIR).ok().filter(|v| !v.trim().is_empty()).map(PathBuf::from).unwrap_or_else(|| home.join("mimir-driver-container"));
        let mut binds = vec![home.clone()];
        binds.extend(std::env::var(ENV_BINDS).unwrap_or_default().split(',').map(str::trim).filter(|b| !b.is_empty()).map(PathBuf::from));
        binds.push(driver_dir.clone());
        binds.dedup();
        Some(ContainerRoad { image, driver_dir, binds, cargo_home: home.join("mimir-cargo-home") })
    }

    /// `cargo-mimir-dump` as the image sees it.
    pub fn cargo_mimir_dump(&self) -> PathBuf {
        self.driver_dir.join("cargo-mimir-dump")
    }

    /// The uid:gid a tool runs as on `engine_url` (dwarves' `work_user` rule).
    pub fn user_for(engine_url: &str, status: &str) -> String {
        let path = engine_url.strip_prefix("unix://").unwrap_or(engine_url);
        if draupnir::container::is_user_scope_socket(std::path::Path::new(path)) {
            return "0:0".to_string();
        }
        let id = |key: &str| status.lines().find_map(|l| l.strip_prefix(key)).and_then(|v| v.split_whitespace().next()).unwrap_or("0").to_string();
        format!("{}:{}", id("Uid:"), id("Gid:"))
    }

    /// Where a tool run's exact stdout lands (under a mounted dir).
    pub fn capture_file(&self, name: &str) -> PathBuf {
        self.cargo_home.with_file_name("mimir-capture").join(format!("{name}.out"))
    }

    /// The draupnir spec of one tool run: the tool under `mimir-capture` (its
    /// stdout byte for byte into [`Self::capture_file`]; the engine's log
    /// frames cut long lines).
    pub fn spec(&self, call: &ToolCall, name: String, user: &str) -> draupnir::BootSpec {
        let mut argv = vec![self.driver_dir.join("mimir-capture").display().to_string(), self.capture_file(&name).display().to_string(), "--".to_string(), call.program.clone()];
        argv.extend(call.args.iter().cloned());
        let mut spec = draupnir::BootSpec::container(name, self.image.clone()).with_cmd(argv).with_user(user.to_string());
        for b in &self.binds {
            spec = spec.with_bind(format!("{0}:{0}", b.display()));
        }
        let home = self.cargo_home.display().to_string();
        spec = spec.with_env("CARGO_HOME", home.clone()).with_env("HOME", home);
        for (k, v) in road_env(std::env::var("CARGO_BUILD_JOBS").ok()) {
            spec = spec.with_env(k, v);
        }
        for (k, v) in &call.envs {
            spec = spec.with_env(k.clone(), v.clone());
        }
        if let Some(d) = &call.cwd {
            spec = spec.with_working_dir(d.display().to_string());
        }
        spec
    }
}

/// What every container this road boots is called: draupnir's `draupnir-`
/// before our `mimir-<pid>-<seq>`.
pub const NAME_PREFIX: &str = "draupnir-mimir-";

/// The containers this process has running right now (full engine names).
static LIVE: Mutex<BTreeSet<String>> = Mutex::new(BTreeSet::new());

/// One running container in [`LIVE`], out again when dropped.
pub struct Live(String);

impl Live {
    pub fn track(name: String) -> Self {
        LIVE.lock().unwrap_or_else(|p| p.into_inner()).insert(name.clone());
        Live(name)
    }
}

impl Drop for Live {
    fn drop(&mut self) {
        LIVE.lock().unwrap_or_else(|p| p.into_inner()).remove(&self.0);
    }
}

/// The containers this process has running right now.
pub fn live() -> Vec<String> {
    LIVE.lock().unwrap_or_else(|p| p.into_inner()).iter().cloned().collect()
}

/// The server pid a road container's name carries (`draupnir-mimir-<pid>-<seq>`).
pub fn owner_pid(name: &str) -> Option<u32> {
    let (pid, seq) = name.strip_prefix(NAME_PREFIX)?.split_once('-')?;
    if pid.is_empty() || seq.is_empty() || !pid.bytes().all(|b| b.is_ascii_digit()) {
        return None;
    }
    pid.parse().ok()
}

/// Is `name` a road container nobody reads any more? Its server is gone, or
/// it carries OUR pid but we did not boot it (the pid reused after a
/// restart). A live other process's (a CLI build) is not.
pub fn is_leftover(name: &str, own_pid: u32, alive: &dyn Fn(u32) -> bool, live: &BTreeSet<String>) -> bool {
    match owner_pid(name) {
        None => false,
        Some(p) if p == own_pid => !live.contains(name),
        Some(p) => !alive(p),
    }
}

/// Does process `pid` exist (in this pid namespace)?
pub fn pid_alive(pid: u32) -> bool {
    std::path::Path::new("/proc").join(pid.to_string()).exists()
}

/// Stop + remove these containers, all at once. draupnir's engine drives a
/// runtime of its own, so each runs on a thread in no runtime.
fn stop_all(names: &[String]) {
    use draupnir::container::ContainerControl;
    std::thread::scope(|s| {
        for n in names {
            s.spawn(move || {
                let m = draupnir::Machine { id: n.clone(), spec_name: n.trim_start_matches("draupnir-").to_string(), kind: draupnir::Kind::Container, power: draupnir::PowerState::On };
                draupnir::container::ContainerBoot::new().stop(&m);
            });
        }
    });
}

/// Stop every container this process has running (server shutdown).
pub fn stop_live() -> Vec<String> {
    let names = live();
    stop_all(&names);
    names
}

/// **Startup step**: stop + remove the road containers earlier servers left
/// running ([`is_leftover`]), and say so in one line. Nothing when the road
/// is not configured.
pub fn reap_at_start() {
    if ContainerRoad::from_env().is_none() {
        return;
    }
    let me = std::process::id();
    let listed = std::thread::scope(|s| {
        s.spawn(|| {
            use draupnir::container::ContainerControl;
            draupnir::container::ContainerBoot::new().list_containers(NAME_PREFIX)
        })
        .join()
    });
    let listed = match listed {
        Ok(Ok(l)) => l,
        Ok(Err(e)) => return eprintln!("mimir container road: could not list leftover build containers: {e}"),
        Err(_) => return eprintln!("mimir container road: could not list leftover build containers: the engine call panicked"),
    };
    let own: BTreeSet<String> = live().into_iter().collect();
    let gone: Vec<String> = listed.into_iter().map(|(n, _)| n).filter(|n| is_leftover(n, me, &pid_alive, &own)).collect();
    stop_all(&gone);
    if gone.is_empty() {
        eprintln!("mimir container road: no leftover build containers");
    } else {
        eprintln!("mimir container road: stopped {} leftover build container(s) of earlier servers: {}", gone.len(), gone.join(", "));
    }
}

/// Wait for SIGTERM / SIGINT, stop the live containers, then `exit(128 +
/// signal)` — what the unhandled signal did, minus the containers it left
/// compiling. The handlers are in place when this returns.
pub fn stop_on_terminate(exit: impl FnOnce(i32) + Send + 'static) -> std::io::Result<impl std::future::Future<Output = ()> + Send> {
    use tokio::signal::unix::{SignalKind, signal};
    let mut term = signal(SignalKind::terminate())?;
    let mut int = signal(SignalKind::interrupt())?;
    Ok(async move {
        let sig = tokio::select! {
            _ = term.recv() => libc::SIGTERM,
            _ = int.recv() => libc::SIGINT,
        };
        // off the runtime: the engine blocks on a runtime of its own
        let stopped = std::thread::spawn(stop_live).join().unwrap_or_default();
        if !stopped.is_empty() {
            eprintln!("mimir container road: signal {sig}, stopped {} build container(s): {}", stopped.len(), stopped.join(", "));
        }
        exit(128 + sig);
    })
}

// ── ONE container per run (owner 2026-10-17: "66 containers starting, that
// must not be very fast — … just one long-lived, fix it now") ──────────────
//
// Planning a 21-repo workspace started ~66 containers (the probe, `cargo
// metadata`, one `--unit-graph` per repo, `cargo clean`, the std dump, …),
// each a create + start + 200 ms state poll + log read + remove. Now the run
// boots ONE container of the image with the road's mounts, user and env (its
// main process only waits), and every tool runs inside it as its own exec
// (draupnir's `exec_streaming`), concurrently when the callers are. The box
// lives as long as the run's [`BoxRoad`] (the consumer's `DriverDumpers`):
// dropped, it is stopped; SIGTERM stops it ([`stop_live`]); a later server's
// boot reaper takes it if this process died ([`reap_at_start`]). A box that
// died is booted again on the next call. A box that cannot be booted at all
// sends the run back to one container per call, said in one line.

/// The env a call's every process carries (cargo, rustc, build scripts all
/// inherit it): `NORNIR_MIMIR_CALL=<server pid>-<call seq>`, unique per call —
/// what [`BoxRoad::kill`] finds that call's processes by inside the box, and
/// only them.
pub const CALL_TAG_ENV: &str = "NORNIR_MIMIR_CALL";

/// The box's main process: waits, reaps the orphans calls leave behind (it is
/// PID 1), ends on SIGTERM.
pub const BOX_MAIN: &str = "trap 'exit 0' TERM INT; while :; do sleep 5 & wait; done";

/// SIGKILL every process in the box whose environment holds `$1` exactly (a
/// call's [`CALL_TAG_ENV`] pair) — that call's tree and nobody else's — until
/// none is left (a process forked between two scans is caught on the next).
pub const KILL_CALL: &str = r#"tag="$1"; n=0
while :; do
  hit=
  for d in /proc/[0-9]*; do
    p=${d#/proc/}
    [ "$p" = "$$" ] && continue
    if grep -qxzF -- "$tag" "$d/environ" 2>/dev/null; then kill -9 "$p" 2>/dev/null && hit=1; fi
  done
  [ -z "$hit" ] && exit 0
  n=$((n+1)); [ "$n" -ge 50 ] && exit 1
  sleep 0.1
done"#;

/// What the road needs of an OCI engine, by container NAME (the daemon-side
/// `draupnir-…` one). [`DraupnirEngine`] is the production one; a test drives
/// a fake that runs the processes on this box.
pub trait BoxEngine: Send + Sync {
    /// Boot `spec` detached; the daemon-side name.
    fn boot(&self, spec: &draupnir::BootSpec) -> Result<String, String>;
    /// Is the container `name` running?
    fn running(&self, name: &str) -> bool;
    /// One process inside the running `name`, its output to `sink` as it comes.
    fn exec(&self, name: &str, spec: &draupnir::container::ExecSpec, sink: &mut dyn FnMut(draupnir::container::LogStream, &[u8])) -> Result<draupnir::container::ExecRun, String>;
    /// Stop + remove `name` (idempotent).
    fn stop(&self, name: &str);
    /// The per-call road: boot `spec`, run it to its end, remove it.
    fn run_once(&self, spec: &draupnir::BootSpec, sink: &mut dyn FnMut(draupnir::container::LogStream, &str)) -> Result<draupnir::container::RunOutcome, String>;
}

/// draupnir's ONE OCI engine. It drives a runtime of its own, so every call
/// runs on a thread that is in no runtime (the consumer calls from inside the
/// lake's), output handed back over a channel as it comes.
#[derive(Clone, Default)]
pub struct DraupnirEngine(draupnir::container::ContainerBoot);

fn machine_of(name: &str) -> draupnir::Machine {
    draupnir::Machine { id: name.to_string(), spec_name: name.trim_start_matches("draupnir-").to_string(), kind: draupnir::Kind::Container, power: draupnir::PowerState::On }
}

/// `f` on a fresh thread (no tokio runtime there); its sends reach `each` on
/// this one while it runs.
fn off_runtime<T: Send, M: Send>(f: impl FnOnce(std::sync::mpsc::Sender<M>) -> T + Send, mut each: impl FnMut(M)) -> T {
    let (tx, rx) = std::sync::mpsc::channel::<M>();
    std::thread::scope(|s| {
        let worker = s.spawn(move || f(tx));
        for m in rx {
            each(m);
        }
        worker.join().unwrap_or_else(|p| std::panic::resume_unwind(p))
    })
}

impl BoxEngine for DraupnirEngine {
    fn boot(&self, spec: &draupnir::BootSpec) -> Result<String, String> {
        use draupnir::Boot;
        off_runtime(|_: std::sync::mpsc::Sender<()>| self.0.boot(spec).map(|m| m.id).map_err(|e| e.to_string()), |_| {})
    }

    fn running(&self, name: &str) -> bool {
        use draupnir::container::{ContainerControl, ContainerState};
        off_runtime(|_: std::sync::mpsc::Sender<()>| matches!(self.0.container_state(&machine_of(name)), ContainerState::Running), |_| {})
    }

    fn exec(&self, name: &str, spec: &draupnir::container::ExecSpec, sink: &mut dyn FnMut(draupnir::container::LogStream, &[u8])) -> Result<draupnir::container::ExecRun, String> {
        use draupnir::container::ContainerControl;
        off_runtime(
            |tx| self.0.exec_streaming(&machine_of(name), spec, &mut |st, b| drop(tx.send((st, b.to_vec())))).map_err(|e| e.to_string()),
            |(st, b): (draupnir::container::LogStream, Vec<u8>)| sink(st, &b),
        )
    }

    fn stop(&self, name: &str) {
        use draupnir::container::ContainerControl;
        off_runtime(|_: std::sync::mpsc::Sender<()>| self.0.stop(&machine_of(name)), |_| {})
    }

    fn run_once(&self, spec: &draupnir::BootSpec, sink: &mut dyn FnMut(draupnir::container::LogStream, &str)) -> Result<draupnir::container::RunOutcome, String> {
        use draupnir::container::RunOptions;
        off_runtime(
            |tx| self.0.run_to_completion_streaming(spec, &RunOptions::default(), &mut |st, l| drop(tx.send((st, l.to_string())))).map_err(|e| e.to_string()),
            |(st, l): (draupnir::container::LogStream, String)| sink(st, &l),
        )
    }
}

/// Which road a [`BoxRoad`] is on.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum BoxMode {
    /// No box yet (booted at the first call).
    Idle,
    /// Every call is an exec in this container (its daemon-side name).
    Up(String),
    /// The box could not be booted: one container per call.
    PerCall,
}

/// The run's ONE container and the calls running in it.
pub struct BoxRoad<E: BoxEngine = DraupnirEngine> {
    pub road: ContainerRoad,
    engine: E,
    /// uid:gid every process runs as.
    user: String,
    /// The box (and its [`Live`] entry) — held only to read or (re)boot it.
    state: Mutex<(BoxMode, Option<Live>)>,
    /// Running calls: seq → (program, the container it runs in, its tag).
    calls: Mutex<std::collections::BTreeMap<u64, (String, String, String)>>,
    /// How many containers this road has booted (the box, its restarts, and
    /// every per-call one).
    boots: AtomicU64,
}

impl BoxRoad<DraupnirEngine> {
    /// The road over draupnir's engine, running as the engine wants
    /// ([`ContainerRoad::user_for`]).
    pub fn new(road: ContainerRoad) -> Self {
        let user = ContainerRoad::user_for(&draupnir::container::engine_socket_url(), &std::fs::read_to_string("/proc/self/status").unwrap_or_default());
        Self::with_engine(road, DraupnirEngine::default(), user)
    }
}

/// One running call in [`BoxRoad::calls`], out again when dropped.
struct CallGuard<'a>(&'a Mutex<std::collections::BTreeMap<u64, (String, String, String)>>, u64);

impl Drop for CallGuard<'_> {
    fn drop(&mut self) {
        self.0.lock().unwrap_or_else(|p| p.into_inner()).remove(&self.1);
    }
}

/// Hands a byte stream to `line` one line at a time (no `\n` / `\r\n`), the
/// last unterminated one at [`Lines::finish`].
struct Lines(Vec<u8>);

impl Lines {
    fn push(&mut self, b: &[u8], line: &mut dyn FnMut(&str)) {
        // only the new bytes are searched: a one-line JSON of megabytes
        // (`cargo metadata`) arrives in thousands of chunks
        let seen = self.0.len();
        self.0.extend_from_slice(b);
        let mut start = 0;
        let mut from = seen;
        while let Some(i) = self.0[from..].iter().position(|&c| c == b'\n') {
            let end = from + i;
            line(String::from_utf8_lossy(&self.0[start..end]).trim_end_matches('\r'));
            start = end + 1;
            from = start;
        }
        self.0.drain(..start);
    }

    fn finish(&mut self, line: &mut dyn FnMut(&str)) {
        if !self.0.is_empty() {
            line(String::from_utf8_lossy(&self.0).trim_end_matches('\r'));
            self.0.clear();
        }
    }
}

impl<E: BoxEngine> BoxRoad<E> {
    pub fn with_engine(road: ContainerRoad, engine: E, user: String) -> Self {
        BoxRoad { road, engine, user, state: Mutex::new((BoxMode::Idle, None)), calls: Mutex::new(Default::default()), boots: AtomicU64::new(0) }
    }

    /// The road right now.
    pub fn mode(&self) -> BoxMode {
        self.state.lock().unwrap_or_else(|p| p.into_inner()).0.clone()
    }

    /// Containers booted so far.
    pub fn boots(&self) -> u64 {
        self.boots.load(Ordering::SeqCst)
    }

    /// The calls running now: (seq, program).
    pub fn calls(&self) -> Vec<(u64, String)> {
        self.calls.lock().unwrap_or_else(|p| p.into_inner()).iter().map(|(k, (p, _, _))| (*k, p.clone())).collect()
    }

    /// The box's spec: the image, every mount at its own path, cargo's home,
    /// the uid; its main process only waits ([`BOX_MAIN`]).
    pub fn box_spec(&self, name: String) -> draupnir::BootSpec {
        let mut spec = draupnir::BootSpec::container(name, self.road.image.clone()).with_cmd(vec!["sh".to_string(), "-c".to_string(), BOX_MAIN.to_string()]).with_user(self.user.clone());
        for b in &self.road.binds {
            spec = spec.with_bind(format!("{0}:{0}", b.display()));
        }
        let home = self.road.cargo_home.display().to_string();
        let mut spec = spec.with_env("CARGO_HOME", home.clone()).with_env("HOME", home);
        for (k, v) in road_env(std::env::var("CARGO_BUILD_JOBS").ok()) {
            spec = spec.with_env(k, v);
        }
        spec
    }

    /// The exec of one call: the tool under `mimir-capture` (stdout byte for
    /// byte into its capture file), the call's env + its tag, its tree.
    pub fn exec_spec(&self, call: &ToolCall, name: &str, tag: &str) -> draupnir::container::ExecSpec {
        let mut argv = vec![self.road.driver_dir.join("mimir-capture").display().to_string(), self.road.capture_file(name).display().to_string(), "--".to_string(), call.program.clone()];
        argv.extend(call.args.iter().cloned());
        let mut spec = draupnir::container::ExecSpec::new(argv).with_user(self.user.clone());
        for (k, v) in &call.envs {
            spec = spec.with_env(k.clone(), v.clone());
        }
        spec = spec.with_env(CALL_TAG_ENV, tag);
        if let Some(d) = &call.cwd {
            spec = spec.with_working_dir(d.display().to_string());
        }
        spec
    }

    /// The box to exec into: booted now when there is none (or `dead` names
    /// the one that died — removed, a new one booted). `None`: the run is on
    /// one container per call.
    fn ensure_box(&self, dead: Option<&str>) -> Option<String> {
        static BOX_SEQ: AtomicU64 = AtomicU64::new(0);
        let mut st = self.state.lock().unwrap_or_else(|p| p.into_inner());
        match (&st.0, dead) {
            (BoxMode::PerCall, _) => return None,
            (BoxMode::Up(n), Some(d)) if n == d => {
                self.engine.stop(n);
                *st = (BoxMode::Idle, None);
            }
            (BoxMode::Up(n), _) => return Some(n.clone()),
            (BoxMode::Idle, _) => {}
        }
        let restart = dead.is_some();
        let spec_name = format!("mimir-{}-box{}", std::process::id(), BOX_SEQ.fetch_add(1, Ordering::SeqCst));
        let full = draupnir::container::ContainerBoot::container_name_for(&spec_name);
        let live = Live::track(full.clone());
        self.boots.fetch_add(1, Ordering::SeqCst);
        match self.engine.boot(&self.box_spec(spec_name)) {
            Ok(name) => {
                if restart {
                    eprintln!("mimir container road: the run's container died, booted {name} in its place");
                }
                *st = (BoxMode::Up(name.clone()), Some(live));
                Some(name)
            }
            Err(e) => {
                // a box that failed to start may stay behind in state `created`
                self.engine.stop(&full);
                eprintln!("mimir container road: could not boot the run's one container ({e}); one container per tool call instead");
                *st = (BoxMode::PerCall, None);
                None
            }
        }
    }

    /// **Stop call `seq`** — its processes only (found by its tag), the
    /// other calls in the box run on; on the per-call road, its container.
    /// `false` when no such call runs.
    pub fn kill(&self, seq: u64) -> bool {
        let Some((_, container, tag)) = self.calls.lock().unwrap_or_else(|p| p.into_inner()).get(&seq).cloned() else {
            return false;
        };
        if tag.is_empty() {
            self.engine.stop(&container);
        } else {
            self.kill_tag(&container, &tag);
        }
        true
    }

    fn kill_tag(&self, container: &str, tag: &str) {
        let spec = draupnir::container::ExecSpec::new(vec!["sh".into(), "-c".into(), KILL_CALL.into(), "sh".into(), format!("{CALL_TAG_ENV}={tag}")]).with_user(self.user.clone());
        if let Err(e) = self.engine.exec(container, &spec, &mut |_, _| {}) {
            eprintln!("mimir container road: could not stop call {tag} in {container}: {e}");
        }
    }

    /// One call as an exec in the box. `Err((e, retry))`: `retry` when the
    /// box is not running and nothing of the call was handed on yet.
    fn run_in_box(&self, name: &str, call: &ToolCall, line: &mut dyn FnMut(&str)) -> Result<std::process::Output, (std::io::Error, bool)> {
        use draupnir::container::LogStream;
        static SEQ: AtomicU64 = AtomicU64::new(0);
        let seq = SEQ.fetch_add(1, Ordering::SeqCst);
        let call_name = format!("mimir-{}-{seq}", std::process::id());
        let tag = format!("{}-{seq}", std::process::id());
        let capture = self.road.capture_file(&call_name);
        if let Some(d) = capture.parent() {
            std::fs::create_dir_all(d).map_err(|e| (e, false))?;
        }
        self.calls.lock().unwrap_or_else(|p| p.into_inner()).insert(seq, (call.program.clone(), name.to_string(), tag.clone()));
        let _guard = CallGuard(&self.calls, seq);
        let spec = self.exec_spec(call, &call_name, &tag);
        let mut lines = Lines(Vec::new());
        let mut said = false;
        let run = self.engine.exec(name, &spec, &mut |st, b| {
            if matches!(st, LogStream::Stdout) && !b.is_empty() {
                said = true;
                lines.push(b, line);
            }
        });
        lines.finish(line);
        let stdout_file = std::fs::read(&capture).ok();
        let _ = std::fs::remove_file(&capture);
        match run {
            Ok(run) => {
                // a process the engine reported no code for is no success
                let code = run.exit_code.unwrap_or(255).clamp(0, 255) as i32;
                Ok(std::process::Output { status: std::process::ExitStatus::from_raw(code << 8), stdout: stdout_file.unwrap_or(run.stdout), stderr: run.stderr })
            }
            Err(e) => {
                let alive = self.engine.running(name);
                // the transport broke under a live box: the call's processes
                // must not compile on, read by nobody
                if alive {
                    self.kill_tag(name, &tag);
                }
                Err((std::io::Error::other(format!("{} in {} ({name}): {e}", call.program, self.road.image)), !alive && !said))
            }
        }
    }

    /// One call in a container of its own (the road before the box, and its
    /// fallback).
    fn run_per_call(&self, call: &ToolCall, line: &mut dyn FnMut(&str)) -> std::io::Result<std::process::Output> {
        use draupnir::container::LogStream;
        static SEQ: AtomicU64 = AtomicU64::new(0);
        let seq = SEQ.fetch_add(1, Ordering::SeqCst);
        let name = format!("mimir-{}-{seq}", std::process::id());
        let capture = self.road.capture_file(&name);
        if let Some(d) = capture.parent() {
            std::fs::create_dir_all(d)?;
        }
        let full = draupnir::container::ContainerBoot::container_name_for(&name);
        let _live = Live::track(full.clone());
        // the call map: per-call seqs live beside the box's, so mark them apart
        let key = u64::MAX - seq;
        self.calls.lock().unwrap_or_else(|p| p.into_inner()).insert(key, (call.program.clone(), full.clone(), String::new()));
        let _guard = CallGuard(&self.calls, key);
        let spec = self.road.spec(call, name, &self.user);
        self.boots.fetch_add(1, Ordering::SeqCst);
        let out = self.engine.run_once(&spec, &mut |st, l| {
            if matches!(st, LogStream::Stdout) {
                line(l);
            }
        });
        // a container that failed to start stays behind in state `created`
        if out.is_err() {
            self.engine.stop(&full);
        }
        let out = out.map_err(|e| std::io::Error::other(format!("{} in {}: {e}", call.program, self.road.image)))?;
        let join = |lines: Vec<String>| {
            let mut s = lines.join("\n");
            if !s.is_empty() {
                s.push('\n');
            }
            s.into_bytes()
        };
        // a container that vanished before it reported a code is no success
        let code = out.exit_code.unwrap_or(255).clamp(0, 255) as i32;
        // the exact stdout is the capture file's; the log copy only when there is none
        let stdout = match std::fs::read(&capture) {
            Ok(b) => {
                let _ = std::fs::remove_file(&capture);
                b
            }
            Err(_) => join(out.stdout),
        };
        Ok(std::process::Output { status: std::process::ExitStatus::from_raw(code << 8), stdout, stderr: join(out.stderr) })
    }

    /// Stop the box (the run is over). Idempotent.
    pub fn shut(&self) {
        let mut st = self.state.lock().unwrap_or_else(|p| p.into_inner());
        if let BoxMode::Up(n) = &st.0 {
            self.engine.stop(n);
        }
        *st = (BoxMode::Idle, None);
    }
}

impl<E: BoxEngine> Drop for BoxRoad<E> {
    fn drop(&mut self) {
        self.shut();
    }
}

impl<E: BoxEngine> ToolRunner for BoxRoad<E> {
    fn run(&self, call: &ToolCall, line: &mut dyn FnMut(&str)) -> std::io::Result<std::process::Output> {
        std::fs::create_dir_all(&self.road.cargo_home)?;
        let mut dead: Option<String> = None;
        loop {
            let Some(name) = self.ensure_box(dead.as_deref()) else {
                return self.run_per_call(call, line);
            };
            match self.run_in_box(&name, call, line) {
                Ok(o) => return Ok(o),
                // the box died before the call said anything: once more in a new one
                Err((_, true)) if dead.is_none() => dead = Some(name),
                Err((e, _)) => return Err(e),
            }
        }
    }

    fn describe(&self) -> String {
        format!("container {} (draupnir OCI, one container per run)", self.road.image)
    }
}

/// What the road's containers inherit from the server beyond the call's own
/// env: the host's cargo job bound (`CARGO_BUILD_JOBS`). Without it a dump's
/// compile in the container runs one rustc per core, and on a shared box the
/// MIR redump of 21 members drove the server's host into the OOM killer.
pub fn road_env(jobs: Option<String>) -> Vec<(String, String)> {
    jobs.filter(|j| !j.trim().is_empty()).map(|j| vec![("CARGO_BUILD_JOBS".to_string(), j)]).unwrap_or_default()
}

#[cfg(test)]
mod tests {
    /// RED before: the road passed no job bound, so a dump's compile in the
    /// container used every core of the host.
    #[test]
    fn the_road_carries_the_hosts_cargo_job_bound() {
        assert_eq!(super::road_env(Some("4".into())), vec![("CARGO_BUILD_JOBS".to_string(), "4".to_string())]);
        assert!(super::road_env(None).is_empty());
        assert!(super::road_env(Some(" ".into())).is_empty());
    }

    use super::*;

    /// One tool run → one draupnir container spec: the image, the argv, the
    /// tool's environment + cargo's home, every mount at its own path, the
    /// tree as the working dir, the uid the engine wants.
    #[test]
    fn a_tool_run_is_one_container_with_its_tree_mounts_and_env() {
        let road = ContainerRoad {
            image: "img:1".into(),
            driver_dir: "/n/drv".into(),
            binds: vec!["/n".into(), "/b".into()],
            cargo_home: "/n/mimir-cargo-home".into(),
        };
        let call = ToolCall { program: "cargo".into(), args: vec!["metadata".into()], envs: vec![("RUSTUP_TOOLCHAIN".into(), "nightly-x".into())], cwd: Some("/n/ws/builds/mimir_v2/clones/skade".into()) };
        let s = road.spec(&call, "mimir-1-0".into(), "103:103");
        let dbg = format!("{s:?}");
        for want in ["img:1", "/n/drv/mimir-capture", "/n/mimir-capture/mimir-1-0.out", "\"--\"", "\"cargo\"", "\"metadata\"", "/n:/n", "/b:/b", "RUSTUP_TOOLCHAIN", "CARGO_HOME", "/n/mimir-cargo-home", "/n/ws/builds/mimir_v2/clones/skade", "103:103"] {
            assert!(dbg.contains(want), "{want} missing from {dbg}");
        }
        assert_eq!(road.cargo_mimir_dump(), PathBuf::from("/n/drv/cargo-mimir-dump"));
        // rootful engine: the server's own ids; the status file says them
        assert_eq!(ContainerRoad::user_for("unix:///run/podman/podman.sock", "Uid:\t103\t103\t103\t103\nGid:\t103\t103\t103\t103\n"), "103:103");
    }

    /// Only `draupnir-mimir-<pid>-<seq>` names belong to the road; their pid
    /// is the server that booted them.
    #[test]
    fn a_road_container_name_carries_its_server_pid() {
        assert_eq!(owner_pid("draupnir-mimir-2866104-11"), Some(2866104));
        assert_eq!(owner_pid("draupnir-mimir-7-0"), Some(7));
        for other in ["draupnir-cargo-build-pid1-korp-start", "draupnir-mimir-x-1", "draupnir-mimir-12", "mimir-12-0", "draupnir-mimir--3"] {
            assert_eq!(owner_pid(other), None, "{other}");
        }
    }

    /// The live bug (2026-10-16): after a restart `draupnir-mimir-2866104-11`
    /// of the dead server kept compiling. A container is a leftover when its
    /// server is gone, or when it carries OUR pid but we did not boot it (a
    /// pid reused after a restart). A live other process's (a CLI build) is
    /// not; nor is ours; nor anything not the road's.
    #[test]
    fn leftovers_are_containers_whose_server_is_gone() {
        let me = 4242;
        let alive = |p: u32| p == 4242 || p == 5000;
        let mut live = BTreeSet::new();
        live.insert("draupnir-mimir-4242-3".to_string());
        assert!(is_leftover("draupnir-mimir-2866104-11", me, &alive, &live));
        assert!(is_leftover("draupnir-mimir-4242-9", me, &alive, &live));
        assert!(!is_leftover("draupnir-mimir-4242-3", me, &alive, &live));
        assert!(!is_leftover("draupnir-mimir-5000-0", me, &alive, &live));
        assert!(!is_leftover("draupnir-korp-start", me, &alive, &live));
    }

    /// A running container is in the registry for exactly as long as its
    /// guard lives — what SIGTERM stops.
    #[test]
    fn a_running_container_is_tracked_until_it_ends() {
        let name = format!("{NAME_PREFIX}{}-test-live", std::process::id());
        {
            let _g = Live::track(name.clone());
            assert!(live().contains(&name));
        }
        assert!(!live().contains(&name));
    }

    /// SIGTERM to the server: the live containers are stopped and the
    /// process ends with 128 + 15, as an unhandled SIGTERM would.
    #[test]
    fn sigterm_stops_and_exits_143() {
        let rt = tokio::runtime::Builder::new_current_thread().enable_all().build().unwrap();
        let (tx, rx) = std::sync::mpsc::channel();
        rt.block_on(async {
            let wait = stop_on_terminate(move |code| tx.send(code).unwrap()).unwrap();
            let task = tokio::spawn(wait);
            unsafe { libc::kill(std::process::id() as i32, libc::SIGTERM) };
            tokio::time::timeout(std::time::Duration::from_secs(10), task).await.unwrap().unwrap();
        });
        assert_eq!(rx.recv().unwrap(), 143);
    }


    /// Against the real engine (`NORNIR_MIMIR_CONTAINER_IMAGE` names an image
    /// with `sleep`): a dead server's container is reaped at start, ours is
    /// not; ours goes on stop.
    #[test]
    #[ignore = "needs an OCI engine + NORNIR_MIMIR_CONTAINER_IMAGE"]
    fn the_engine_reaps_leftovers_and_stops_ours() {
        use draupnir::Boot;
        use draupnir::container::{ContainerBoot, ContainerControl};
        let image = std::env::var(ENV_IMAGE).expect("NORNIR_MIMIR_CONTAINER_IMAGE");
        let boot = |n: &str| {
            let spec = draupnir::BootSpec::container(n.to_string(), image.clone()).with_cmd(vec!["sleep".to_string(), "600".to_string()]);
            std::thread::scope(|s| s.spawn(|| ContainerBoot::new().boot(&spec).unwrap()).join().unwrap());
            ContainerBoot::container_name_for(n)
        };
        let names = || -> Vec<String> {
            std::thread::scope(|s| s.spawn(|| ContainerBoot::new().list_containers(NAME_PREFIX).unwrap()).join().unwrap()).into_iter().map(|(n, _)| n).collect()
        };
        // beyond any pid_max: a server that cannot be alive
        let dead = boot("mimir-4194999-0");
        let ours = boot(&format!("mimir-{}-777", std::process::id()));
        let _g = Live::track(ours.clone());
        assert!(names().contains(&dead) && names().contains(&ours));
        reap_at_start();
        assert!(!names().contains(&dead), "the dead server's container is still there");
        assert!(names().contains(&ours), "ours was reaped");
        assert!(stop_live().contains(&ours));
        assert!(!names().contains(&ours), "ours outlived the stop");
    }


    /// A tool whose container cannot start (the driver dir missing) leaves no
    /// container behind (the e2e of 2026-10-16 found the probe's
    /// `draupnir-mimir-<pid>-0` corpse in state created).
    #[test]
    #[ignore = "needs an OCI engine + NORNIR_MIMIR_CONTAINER_IMAGE"]
    fn a_container_that_cannot_start_leaves_nothing() {
        use draupnir::container::{ContainerBoot, ContainerControl};
        let image = std::env::var(ENV_IMAGE).expect("NORNIR_MIMIR_CONTAINER_IMAGE");
        let tmp = tempfile::tempdir().unwrap();
        let road = BoxRoad::new(ContainerRoad { image, driver_dir: tmp.path().join("no-driver"), binds: vec![tmp.path().to_path_buf()], cargo_home: tmp.path().join("mimir-cargo-home") });
        let call = ToolCall { program: "rustc".into(), args: vec!["--version".into()], envs: vec![], cwd: None };
        // the box boots (its main needs no driver), the call fails in it; on
        // the per-call road the container fails to start
        let _ = road.run(&call, &mut |_| {});
        assert!(road.run_per_call(&call, &mut |_| {}).is_err());
        drop(road);
        let mine = format!("{NAME_PREFIX}{}-", std::process::id());
        let left: Vec<String> = std::thread::scope(|s| s.spawn(|| ContainerBoot::new().list_containers(&mine).unwrap()).join().unwrap()).into_iter().map(|(n, _)| n).collect();
        assert!(left.is_empty(), "left behind: {left:?}");
    }


    // ── the ONE box, against a fake engine that runs every process on this
    // box (an exec is a local child; `mimir-capture` is played by the fake) ──

    use draupnir::container::{ExecRun, ExecSpec, LogStream, RunOutcome};

    #[derive(Default)]
    struct Fake {
        /// containers up (daemon-side names)
        up: Mutex<BTreeSet<String>>,
        boots: AtomicU64,
        execs: AtomicU64,
        once: AtomicU64,
        refuse_boot: bool,
    }

    /// Run `argv` here with `env` in `dir`, chunks to `sink`; a leading
    /// `mimir-capture <file> --` is played (stdout also into the file).
    fn local(argv: &[String], env: &[(String, String)], dir: Option<&str>, sink: &mut dyn FnMut(LogStream, &[u8])) -> ExecRun {
        use std::io::Read;
        let (capture, argv) = if argv[0].ends_with("mimir-capture") { (Some(argv[1].clone()), &argv[3..]) } else { (None, argv) };
        let mut c = std::process::Command::new(&argv[0]);
        c.args(&argv[1..]).envs(env.iter().map(|(k, v)| (k, v))).stdout(std::process::Stdio::piped()).stderr(std::process::Stdio::piped());
        if let Some(d) = dir {
            c.current_dir(d);
        }
        let mut child = c.spawn().unwrap();
        let (mut out, mut err) = (child.stdout.take().unwrap(), child.stderr.take().unwrap());
        let errs = std::thread::spawn(move || {
            let mut b = Vec::new();
            err.read_to_end(&mut b).unwrap();
            b
        });
        let mut run = ExecRun::default();
        let mut buf = [0u8; 8192];
        loop {
            let n = out.read(&mut buf).unwrap();
            if n == 0 {
                break;
            }
            sink(LogStream::Stdout, &buf[..n]);
            run.stdout.extend_from_slice(&buf[..n]);
        }
        run.stderr = errs.join().unwrap();
        let st = child.wait().unwrap();
        run.exit_code = Some(st.code().unwrap_or_else(|| 128 + st.signal().unwrap_or(0)) as i64);
        if let Some(f) = capture {
            std::fs::write(f, &run.stdout).unwrap();
        }
        run
    }

    impl BoxEngine for Fake {
        fn boot(&self, spec: &draupnir::BootSpec) -> Result<String, String> {
            self.boots.fetch_add(1, Ordering::SeqCst);
            if self.refuse_boot {
                return Err("no such image".into());
            }
            let n = draupnir::container::ContainerBoot::container_name_for(&spec.name);
            self.up.lock().unwrap().insert(n.clone());
            Ok(n)
        }
        fn running(&self, name: &str) -> bool {
            self.up.lock().unwrap().contains(name)
        }
        fn exec(&self, name: &str, spec: &ExecSpec, sink: &mut dyn FnMut(LogStream, &[u8])) -> Result<ExecRun, String> {
            if !self.running(name) {
                return Err(format!("container {name} is not running"));
            }
            self.execs.fetch_add(1, Ordering::SeqCst);
            Ok(local(&spec.argv, &spec.env, spec.working_dir.as_deref(), sink))
        }
        fn stop(&self, name: &str) {
            self.up.lock().unwrap().remove(name);
        }
        fn run_once(&self, spec: &draupnir::BootSpec, sink: &mut dyn FnMut(LogStream, &str)) -> Result<RunOutcome, String> {
            self.boots.fetch_add(1, Ordering::SeqCst);
            self.once.fetch_add(1, Ordering::SeqCst);
            let env: Vec<(String, String)> = spec.env.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
            let run = local(&spec.cmd, &env, spec.working_dir.as_deref(), &mut |_, _| {});
            let lines = |b: &[u8]| String::from_utf8_lossy(b).lines().map(str::to_string).collect::<Vec<_>>();
            for l in lines(&run.stdout) {
                sink(LogStream::Stdout, &l);
            }
            Ok(RunOutcome { exit_code: run.exit_code, stdout: lines(&run.stdout), stderr: lines(&run.stderr) })
        }
    }

    fn fake_road(fake: Fake) -> (tempfile::TempDir, BoxRoad<Fake>) {
        let tmp = tempfile::tempdir().unwrap();
        let road = ContainerRoad { image: "img:1".into(), driver_dir: tmp.path().join("drv"), binds: vec![tmp.path().to_path_buf()], cargo_home: tmp.path().join("mimir-cargo-home") };
        (tmp, BoxRoad::with_engine(road, fake, "0:0".into()))
    }

    fn sh(script: &str) -> ToolCall {
        ToolCall { program: "sh".into(), args: vec!["-c".into(), script.into()], envs: vec![("CALL_ENV".into(), "x".into())], cwd: None }
    }

    /// The owner's 66: many tool calls — some at once — boot exactly ONE
    /// container; each comes back with its own output.
    #[test]
    fn many_tool_calls_boot_one_container() {
        let (_t, road) = fake_road(Fake::default());
        for i in 0..12 {
            let o = road.run(&sh(&format!("echo call-{i} $CALL_ENV")), &mut |_| {}).unwrap();
            assert_eq!(o.stdout, format!("call-{i} x\n").into_bytes());
        }
        std::thread::scope(|s| {
            for i in 0..8 {
                let road = &road;
                s.spawn(move || assert_eq!(road.run(&sh(&format!("sleep 0.2; echo {i}")), &mut |_| {}).unwrap().stdout, format!("{i}\n").into_bytes()));
            }
        });
        assert_eq!(road.boots(), 1, "one container for 20 calls");
        assert_eq!(road.engine.boots.load(Ordering::SeqCst), 1);
        assert_eq!((road.engine.execs.load(Ordering::SeqCst), road.engine.once.load(Ordering::SeqCst)), (20, 0));
        assert!(matches!(road.mode(), BoxMode::Up(_)));
        assert_eq!(road.describe(), "container img:1 (draupnir OCI, one container per run)");
    }

    /// Exit codes and a line over 64 KB come back exactly: stdout byte for
    /// byte, the line whole to the live callback, stderr apart.
    #[test]
    fn exit_codes_and_long_lines_come_back_whole() {
        let (_t, road) = fake_road(Fake::default());
        let mut lines = Vec::new();
        let o = road.run(&sh("head -c 100000 /dev/zero | tr '\\0' a; echo; printf 'last'; echo oops >&2; exit 3"), &mut |l| lines.push(l.to_string())).unwrap();
        assert_eq!(o.status.code(), Some(3));
        assert_eq!(o.stdout.len(), 100_005);
        assert!(o.stdout[..100_000].iter().all(|&b| b == b'a') && o.stdout.ends_with(b"\nlast"));
        assert_eq!(o.stderr, b"oops\n");
        assert_eq!(lines.len(), 2);
        assert_eq!((lines[0].len(), lines[1].as_str()), (100_000, "last"));
        assert_eq!(road.run(&sh("exit 0"), &mut |_| {}).unwrap().status.code(), Some(0));
        assert_eq!(road.run(&sh("kill -9 $$"), &mut |_| {}).unwrap().status.code(), Some(137));
    }

    /// Stopping one call kills ITS processes (its children too) and nothing
    /// else: the call beside it in the same container ends normally.
    #[test]
    fn killing_one_call_leaves_the_others_running() {
        let (t, road) = fake_road(Fake::default());
        let mark = t.path().join("child-lived");
        let (a, b, victim) = std::thread::scope(|s| {
            let road = &road;
            let mark = &mark;
            let wait_for = |n: usize| {
                let t0 = std::time::Instant::now();
                while road.calls().len() < n {
                    assert!(t0.elapsed().as_secs() < 10, "{n} calls never ran");
                    std::thread::sleep(std::time::Duration::from_millis(20));
                }
                road.calls()
            };
            let a = s.spawn(move || road.run(&sh(&format!("(sleep 3; touch {}) & sleep 30; echo never", mark.display())), &mut |_| {}).unwrap());
            let victim = wait_for(1)[0].0;
            let b = s.spawn(move || road.run(&sh("sleep 2; echo ok"), &mut |_| {}).unwrap());
            wait_for(2);
            std::thread::sleep(std::time::Duration::from_millis(200));
            assert!(road.kill(victim));
            (a.join().unwrap(), b.join().unwrap(), victim)
        });
        assert_eq!(a.status.code(), Some(137), "the killed call");
        assert!(a.stdout.is_empty());
        assert_eq!((b.status.code(), b.stdout.as_slice()), (Some(0), &b"ok\n"[..]), "the other call");
        std::thread::sleep(std::time::Duration::from_secs(2));
        assert!(!mark.exists(), "the killed call's child lived on");
        assert!(!road.kill(victim), "a finished call is no call");
        assert_eq!(road.boots(), 1);
    }

    /// A box that died is booted again at the next call; the run's end stops
    /// the box and takes it out of the live list.
    #[test]
    fn a_dead_box_is_rebooted_and_the_end_stops_it() {
        let (_t, road) = fake_road(Fake::default());
        road.run(&sh("true"), &mut |_| {}).unwrap();
        let BoxMode::Up(first) = road.mode() else { panic!("no box") };
        assert!(live().contains(&first));
        road.engine.stop(&first); // killed from outside
        let o = road.run(&sh("echo again"), &mut |_| {}).unwrap();
        assert_eq!(o.stdout, b"again\n");
        let BoxMode::Up(second) = road.mode() else { panic!("no box") };
        assert_ne!(first, second);
        assert_eq!(road.boots(), 2);
        assert!(!live().contains(&first) && live().contains(&second));
        let up = || road.engine.up.lock().unwrap().clone();
        assert_eq!(up().into_iter().collect::<Vec<_>>(), vec![second.clone()]);
        road.shut();
        assert!(up().is_empty(), "the run's end left the box up");
        assert!(!live().contains(&second));
    }

    /// A box that cannot boot sends the run to one container per call — and
    /// the calls still answer.
    #[test]
    fn no_box_falls_back_to_a_container_per_call() {
        let (_t, road) = fake_road(Fake { refuse_boot: true, ..Fake::default() });
        for i in 0..3 {
            let o = road.run(&sh(&format!("echo {i}; exit {i}")), &mut |_| {}).unwrap();
            assert_eq!((o.status.code(), o.stdout), (Some(i), format!("{i}\n").into_bytes()));
        }
        assert_eq!(road.mode(), BoxMode::PerCall);
        assert_eq!(road.engine.once.load(Ordering::SeqCst), 3);
        assert_eq!(road.engine.boots.load(Ordering::SeqCst), 1 + 3, "one failed box, then one per call");
    }

    /// The box: the image, every mount at its own path, cargo's home, the uid,
    /// a main that only waits; a call: the tool under mimir-capture with its
    /// env, its tag and its tree.
    #[test]
    fn the_box_and_a_call_carry_the_roads_mounts_env_and_user() {
        let road = ContainerRoad { image: "img:1".into(), driver_dir: "/n/drv".into(), binds: vec!["/n".into(), "/b".into()], cargo_home: "/n/mimir-cargo-home".into() };
        let b = BoxRoad::with_engine(road, Fake::default(), "103:103".into());
        let dbg = format!("{:?}", b.box_spec("mimir-1-box0".into()));
        for want in ["img:1", "/n:/n", "/b:/b", "CARGO_HOME", "/n/mimir-cargo-home", "103:103", "while :; do sleep 5 & wait; done"] {
            assert!(dbg.contains(want), "{want} missing from {dbg}");
        }
        let call = ToolCall { program: "cargo".into(), args: vec!["metadata".into()], envs: vec![("RUSTUP_TOOLCHAIN".into(), "nightly-x".into())], cwd: Some("/n/ws/clones/skade".into()) };
        let e = b.exec_spec(&call, "mimir-1-7", "1-7");
        assert_eq!(e.argv, ["/n/drv/mimir-capture", "/n/mimir-capture/mimir-1-7.out", "--", "cargo", "metadata"]);
        assert_eq!(e.env, [("RUSTUP_TOOLCHAIN".to_string(), "nightly-x".to_string()), (CALL_TAG_ENV.to_string(), "1-7".to_string())]);
        assert_eq!((e.user.as_deref(), e.working_dir.as_deref()), (Some("103:103"), Some("/n/ws/clones/skade")));
    }

    /// Against the real engine (`NORNIR_MIMIR_CONTAINER_IMAGE`, and
    /// `NORNIR_MIMIR_CONTAINER_DRIVER` holding a `mimir-capture` built for the
    /// image): many calls are ONE container; exit codes and a 200 KB line come
    /// back exact; one call killed, the other lives; a killed box is booted
    /// again; the end stops it.
    #[test]
    #[ignore = "needs an OCI engine + NORNIR_MIMIR_CONTAINER_IMAGE + NORNIR_MIMIR_CONTAINER_DRIVER (mimir-capture)"]
    fn the_engine_runs_a_run_in_one_container() {
        let road = ContainerRoad::from_env().expect("NORNIR_MIMIR_CONTAINER_IMAGE");
        let mine = format!("{NAME_PREFIX}{}-", std::process::id());
        let ours = || -> Vec<String> {
            use draupnir::container::{ContainerBoot, ContainerControl};
            std::thread::scope(|s| s.spawn(|| ContainerBoot::new().list_containers(&mine).unwrap()).join().unwrap()).into_iter().map(|(n, _)| n).collect()
        };
        let b = BoxRoad::new(road);
        let t = std::time::Instant::now();
        for i in 0..10 {
            let o = b.run(&sh(&format!("echo {i}; exit {i}")), &mut |_| {}).unwrap();
            assert_eq!((o.status.code(), o.stdout), (Some(i), format!("{i}\n").into_bytes()));
        }
        eprintln!("10 calls in one box: {:?}", t.elapsed());
        assert_eq!((b.boots(), ours().len()), (1, 1));
        let o = b.run(&sh("head -c 200000 /dev/zero | tr '\\0' a; echo; echo err >&2; exit 4"), &mut |_| {}).unwrap();
        assert_eq!((o.status.code(), o.stdout.len(), o.stderr.as_slice()), (Some(4), 200_001, &b"err\n"[..]));
        let (a, c) = std::thread::scope(|s| {
            let b = &b;
            let wait_for = |n: usize| {
                while b.calls().len() < n {
                    std::thread::sleep(std::time::Duration::from_millis(20));
                }
                b.calls()
            };
            let a = s.spawn(move || b.run(&sh("sleep 60; echo never"), &mut |_| {}).unwrap());
            let victim = wait_for(1)[0].0;
            let c = s.spawn(move || b.run(&sh("sleep 3; echo ok"), &mut |_| {}).unwrap());
            wait_for(2);
            std::thread::sleep(std::time::Duration::from_millis(500));
            assert!(b.kill(victim));
            (a.join().unwrap(), c.join().unwrap())
        });
        assert_eq!(a.status.code(), Some(137));
        assert_eq!((c.status.code(), c.stdout.as_slice()), (Some(0), &b"ok\n"[..]));
        let BoxMode::Up(first) = b.mode() else { panic!("no box") };
        b.engine.stop(&first);
        assert_eq!(b.run(&sh("echo back"), &mut |_| {}).unwrap().stdout, b"back\n");
        assert_eq!((b.boots(), ours().len()), (2, 1));
        drop(b);
        assert!(ours().is_empty(), "the end left {:?}", ours());
    }

    /// **MEASURE** the planning step's tool calls, one container per call vs
    /// the run's one box: per repo of `NORNIR_ONEBOX_BENCH_REPOS` (comma-
    /// separated trees) `cargo metadata` and `cargo check --unit-graph`, after
    /// the probe's `rustc -vV` + `rustc --print sysroot`; the same calls in the
    /// same order on both roads, the answers compared.
    #[test]
    #[ignore = "bench: needs an OCI engine + the image + the driver dir + NORNIR_ONEBOX_BENCH_REPOS"]
    fn bench_planning_per_call_vs_one_box() {
        let road = ContainerRoad::from_env().expect("NORNIR_MIMIR_CONTAINER_IMAGE");
        let tc = std::env::var("NORNIR_ONEBOX_BENCH_TOOLCHAIN").unwrap_or_else(|_| mimir_ingest::pinned_toolchain().to_string());
        let repos: Vec<PathBuf> = std::env::var("NORNIR_ONEBOX_BENCH_REPOS").expect("NORNIR_ONEBOX_BENCH_REPOS").split(',').filter(|s| !s.is_empty()).map(PathBuf::from).collect();
        let env = vec![("RUSTUP_TOOLCHAIN".to_string(), tc)];
        let mut calls = vec![
            ToolCall { program: "rustc".into(), args: vec!["-vV".into()], envs: env.clone(), cwd: None },
            ToolCall { program: "rustc".into(), args: vec!["--print".into(), "sysroot".into()], envs: env.clone(), cwd: None },
        ];
        for r in &repos {
            let m = r.join("Cargo.toml").display().to_string();
            calls.push(ToolCall { program: "cargo".into(), args: vec!["metadata".into(), "--format-version".into(), "1".into()], envs: env.clone(), cwd: Some(r.clone()) });
            calls.push(ToolCall { program: "cargo".into(), args: ["check", "--manifest-path", &m, "--workspace", "--all-targets", "--unit-graph", "-Z", "unstable-options"].map(String::from).to_vec(), envs: env.clone(), cwd: Some(r.clone()) });
        }
        let b = BoxRoad::new(road);
        // per call, one box, and both again: the first round warms cargo's registry
        let mut answers: Vec<Vec<std::process::Output>> = Vec::new();
        let mut rows = Vec::new();
        for round in 0..2 {
            for one_box in [false, true] {
                let (t, before) = (std::time::Instant::now(), b.boots());
                let outs: Vec<_> = calls.iter().map(|c| if one_box { b.run(c, &mut |_| {}) } else { b.run_per_call(c, &mut |_| {}) }.unwrap()).collect();
                rows.push(format!("round {round} {}: {:.2?} with {} container start(s)", if one_box { "one box" } else { "per call" }, t.elapsed(), b.boots() - before));
                answers.push(outs);
            }
        }
        for r in &rows {
            eprintln!("BENCH {r}");
        }
        // the warm round answers alike on both roads (round 0 fills the
        // registry, so its first answers may differ)
        for ((c, p), o) in calls.iter().zip(&answers[2]).zip(&answers[3]) {
            assert_eq!((p.status.code(), p.stdout.len()), (o.status.code(), o.stdout.len()), "{} {:?} in {:?} answered apart", c.program, c.args, c.cwd);
        }
        let ok = answers[3].iter().filter(|o| o.status.success()).count();
        eprintln!("BENCH planning {} repos, {} calls ({ok} ok)", repos.len(), calls.len());
    }

    /// A one-line JSON of megabytes in thousands of chunks (`cargo metadata`
    /// through the attach stream) is split in linear time: the bench of
    /// 2026-10-17 found the box SLOWER than a container per call (85 s vs
    /// 27 s for 44 calls) while every chunk rescanned the whole line.
    #[test]
    fn a_huge_line_in_small_chunks_is_split_in_linear_time() {
        let mut l = Lines(Vec::new());
        let mut got: Vec<usize> = Vec::new();
        let chunk = vec![b'x'; 4096];
        let t = std::time::Instant::now();
        for _ in 0..4096 {
            l.push(&chunk, &mut |s| got.push(s.len()));
        }
        l.push(b"\nend\r\n", &mut |s| got.push(s.len()));
        l.finish(&mut |s| got.push(s.len()));
        assert_eq!(got, vec![4096 * 4096, 3]);
        assert!(t.elapsed() < std::time::Duration::from_secs(2), "16 MB in 4 KB chunks took {:?}", t.elapsed());
    }
}