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/target/presets.rs

//! **Target presets** — the EXACT virtual-hardware shape of every cloud we may
//! deploy an appliance medium to, as one Rust const per cloud.
//!
//! A [`Target`](super::Target) says what a medium is built FOR (firmware,
//! consoles, buses, nic). A [`TargetPreset`] says what a NAMED machine — UpCloud,
//! GCE, AWS Nitro … — actually IS, with the facts a proof door needs on top of
//! the `target` group: the disk bus, the NIC model, the CPU model exposure, the
//! chipset, whether a UART sits at `0x3f8`, how a medium is brought, whether a
//! metadata service answers. Each preset ends in a verdict on **whether QEMU
//! can mimic it** ([`Mimic`]): the mimicable ones become `appliance-boot/<preset>`
//! rows the installtest measures; the rest are declared rows that stay
//! `Absent (needs real cloud)` so the matrix shows the gap instead of a green
//! nobody measured.
//!
//! # Why this is data in the engine and not a shell script
//!
//! The installer ISO shipped 2026-08-28 booted under OVMF with a captured UART
//! and died on UpCloud, whose QEMU has **no UART at 0x3f8** (`ttyS1`/`ttyS2` at
//! `0x2f8`/`0x3e8` exist), boots **SeaBIOS only**, attaches the ISO as an **IDE
//! cdrom**, the disk as **virtio-blk**, the NIC as **virtio-net**, and shows the
//! console over **VNC/VGA**. Not one of those facts lived in a test. This table
//! is where such facts live from now on; the model is written up in
//! `edda/.nornir/build-design.md` (f9) and the operator's side in
//! `edda/.nornir/build-guide.md`.
//!
//! Every field is honest about its confidence: [`Tri::Unknown`] where the
//! documentation is silent, never a guess dressed as a fact.
//!
//! # ONE roster (2026-08-29, oden lane B)
//!
//! [`PRESETS`] is the only list of named machines in the engine. The `target`
//! group's `preset = "<name>"` resolves HERE ([`preset`]), the emitted
//! `[[target-preset]]` roster ([`super::presets_toml`]) is rendered FROM these
//! consts through [`TargetPreset::target`], and the test matrix's
//! `appliance-boot/<name>` rows are floored by [`TargetPreset::status`]. There
//! is no second table of names anywhere, so a name cannot drift between the
//! toml, the validator and the matrix — one writer per fact.

use super::{Bus, Console, Cpu, Firmware, Nic, Target, UartPort};

/// A fact that may be documented true, documented false, or not documented.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Tri {
    Yes,
    No,
    /// The vendor's documentation is silent. Never treated as either.
    Unknown,
}

impl Tri {
    pub fn as_str(self) -> &'static str {
        match self {
            Tri::Yes => "yes",
            Tri::No => "no",
            Tri::Unknown => "unknown",
        }
    }
}

/// **Which legacy COM ports the guest really has** — the fact that decides
/// whether a `serial` console may exist and which `ttyS<n>` it is.
///
/// UpCloud is the reason this is a list and not a yes/no on `0x3f8`: nothing
/// sits at `0x3f8`, but `ttyS1`/`ttyS2` (`0x2f8`/`0x3e8`) are real, and a proof
/// rig that mimics the machine must create exactly those slots
/// (`-serial none -serial file:…`).
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Uarts {
    /// Measured or documented: exactly these ports, in COM order.
    Known(&'static [UartPort]),
    /// The vendor's documentation is silent. Spelled as NO port in the derived
    /// `target` group: a serial console nobody can prove exists is a dark boot
    /// waiting to happen, so the preset must not name `serial` either.
    Unknown,
}

impl Uarts {
    /// The ports as the `target` group spells them (`Unknown` = none).
    pub fn ports(self) -> &'static [UartPort] {
        match self {
            Uarts::Known(p) => p,
            Uarts::Unknown => &[],
        }
    }

    /// Is there a 16550 at `0x3f8` (`ttyS0`)? [`Tri::Unknown`] when undocumented.
    pub fn ttys0(self) -> Tri {
        match self {
            Uarts::Known(p) if p.contains(&UartPort::Com1) => Tri::Yes,
            Uarts::Known(_) => Tri::No,
            Uarts::Unknown => Tri::Unknown,
        }
    }

    /// qemu's `-serial` slots, COM1..COM4: `true` = a port exists there.
    pub fn slots(self) -> [bool; 4] {
        let mut out = [false; 4];
        for p in self.ports() {
            out[p.index()] = true;
        }
        out
    }
}

/// **Where a measurement was taken** — the fact that splits two claims that
/// shared one word for a year.
///
/// `upcloud` and `qemu-local-bios` were both `measured`, and they are not the
/// same evidence: one is a real UpCloud Cloud Server in se-sto1, the other is
/// `qemu-system-x86_64` on this box. A roster that calls both "measured" cannot
/// report its own progress honestly — "3 of 13 measured" reads as three clouds
/// when it is one cloud and two rigs.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MeasuredOn {
    /// A QEMU/KVM rig on our own proof box. Proves the MEDIUM and everything
    /// the mimic renders — never the platform, and never a device QEMU stood
    /// in for ([`MimicAxes::substitutions`]).
    QemuRig,
    /// The real platform: an instance of this cloud, booted and watched.
    RealCloud,
}

impl MeasuredOn {
    pub fn as_str(self) -> &'static str {
        match self {
            MeasuredOn::QemuRig => "qemu rig",
            MeasuredOn::RealCloud => "real cloud",
        }
    }
}

/// **The evidence behind a `measured` claim**: where it was taken and what was
/// seen. One value, so a preset cannot name a date without naming the machine
/// it was taken on.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Evidence {
    pub on: MeasuredOn,
    /// What was actually observed — dates, host, the lines that were read.
    pub what: &'static str,
}

impl Evidence {
    /// A QEMU-rig measurement on our own proof box.
    pub const fn rig(what: &'static str) -> Evidence {
        Evidence { on: MeasuredOn::QemuRig, what }
    }
    /// A measurement taken on the real platform.
    pub const fn cloud(what: &'static str) -> Evidence {
        Evidence { on: MeasuredOn::RealCloud, what }
    }
    /// The one string a report quotes — the evidence never travels without
    /// saying which kind it is.
    pub fn label(&self) -> String {
        format!("{}: {}", self.on.as_str(), self.what)
    }
}

/// How well a preset is known — DERIVED ([`TargetPreset::status`]), never
/// declared beside the facts it summarises.
///
/// **Two measured words, not one** (2026-09-05). `Measured` used to cover both
/// "someone booted a real UpCloud instance" and "someone ran QEMU here", and the
/// roster could not report progress honestly while those shared a word. The
/// split is derived from [`TargetPreset::measured`]'s own [`MeasuredOn`], so it
/// cannot be declared wrong.
///
/// `NeedsRealCloud` keeps its name and its meaning on purpose: it is the
/// variant other repos compare against (`gunnar/installtest/src/firmware.rs`
/// gates `--target` on `p.status() != PresetStatus::NeedsRealCloud`, i.e. "is
/// this renderable at all"), so the split is additive for every such caller.
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum PresetStatus {
    /// Booted on a QEMU rig here ([`MeasuredOn::QemuRig`]). Proves the medium
    /// and the shape; proves the PLATFORM only when
    /// [`MimicAxes::is_exact`] also holds.
    MimicMeasured,
    /// Booted on the real platform ([`MeasuredOn::RealCloud`]) — the only
    /// evidence that means the cloud itself.
    CloudMeasured,
    /// QEMU can mimic it ([`Mimic::Qemu`]) but nobody has booted it yet — the
    /// `appliance-boot/<name>` row is a hole a KVM proof can fill.
    Stub,
    /// QEMU cannot mimic it ([`Mimic::NeedsRealCloud`]): the row stays
    /// `Absent (needs real cloud)` until a real deploy measures it.
    NeedsRealCloud,
}

impl PresetStatus {
    pub fn as_str(self) -> &'static str {
        match self {
            PresetStatus::MimicMeasured => "mimic-measured",
            PresetStatus::CloudMeasured => "cloud-measured",
            PresetStatus::Stub => "stub",
            PresetStatus::NeedsRealCloud => "needs-real-cloud",
        }
    }

    /// Whether this status rests on a boot that actually happened — the
    /// question `Measured` used to answer, kept as a method so a caller that
    /// only wanted "has evidence" does not have to learn the split.
    pub fn is_measured(self) -> bool {
        matches!(self, PresetStatus::MimicMeasured | PresetStatus::CloudMeasured)
    }
}

/// Which firmware(s) the platform can start a guest with, and Secure Boot.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SecureBoot {
    /// No Secure Boot offered at all.
    None,
    /// Available but off unless asked for (AWS `uefi` + NitroTPM, GCE Shielded
    /// VM toggle, Azure Trusted Launch, OpenStack image property).
    Optional,
    /// On for the platform's default images (GCE Shielded VM on newer images).
    DefaultOn,
    Unknown,
}

/// How the customer reaches the guest's console.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ConsoleReach {
    /// A VGA framebuffer over VNC/noVNC — the ONLY console (UpCloud).
    VgaVnc,
    /// A serial console on `ttyS0` (EC2 Serial Console, GCE serial port 1,
    /// Azure Serial Console via boot diagnostics, Hetzner/Scaleway/OVH VNC
    /// that is really a serial-backed console are spelled per preset).
    Serial,
    /// Both a VGA path (VNC or a screenshot facility) and a serial console.
    Both,
    Unknown,
}

/// The bus the BOOT disk rides, as the guest kernel sees it.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DiskBus {
    /// `virtio-blk` (`/dev/vda`) — kernel `VIRTIO_BLK`.
    VirtioBlk,
    /// `virtio-scsi` (`/dev/sda`) — kernel `SCSI_VIRTIO SCSI BLK_DEV_SD`.
    VirtioScsi,
    /// NVMe (`/dev/nvme0n1`) — kernel `BLK_DEV_NVME`.
    Nvme,
    /// Legacy IDE/PIIX (`/dev/sda` via `ATA_PIIX`) — Azure gen1 OS disk.
    Ide,
    /// Hyper-V synthetic SCSI (`hv_storvsc`) — kernel `HYPERV_STORAGE`.
    HvScsi,
    /// Xen blkfront (`/dev/xvda`) — kernel `XEN_BLKDEV_FRONTEND`.
    XenBlk,
    /// Real hardware (bare metal): whatever the box has, typically NVMe/SATA.
    Metal,
}

impl DiskBus {
    pub fn as_str(self) -> &'static str {
        match self {
            DiskBus::VirtioBlk => "virtio-blk",
            DiskBus::VirtioScsi => "virtio-scsi",
            DiskBus::Nvme => "nvme",
            DiskBus::Ide => "ide",
            DiskBus::HvScsi => "hv-scsi",
            DiskBus::XenBlk => "xen-blk",
            DiskBus::Metal => "metal",
        }
    }

    /// The QEMU device model that presents this bus, or `None` when QEMU (under
    /// KVM, on this host) cannot present it: Hyper-V and Xen paravirtual devices
    /// need their own hypervisor.
    pub fn qemu_mimic(self) -> Option<&'static str> {
        match self {
            DiskBus::VirtioBlk => Some("virtio-blk-pci"),
            DiskBus::VirtioScsi => Some("virtio-scsi-pci"),
            DiskBus::Nvme => Some("nvme"),
            DiskBus::Ide => Some("ide-hd"),
            // **`xen-disk` is listed and not attachable — the listing was the
            // trap.** MEASURED on oden 2026-09-05, QEMU 10.2.1:
            //
            // ```text
            // $ qemu-system-x86_64 -device help | grep xen
            //   name "xen-disk", bus xen-bus, desc "Xen Disk Device"      ← it IS listed
            // $ qemu-system-x86_64 -machine q35 -device xen-disk
            //   No 'xen-bus' bus found for device 'xen-disk'              ← it is NOT attachable
            // $ qemu-system-x86_64 -accel help          → tcg mshv kvm    (no `xen`)
            // $ qemu-system-x86_64 -machine q35,xen-version=0x4000a
            //   Property 'pc-q35-10.2-machine.xen-version' not found      (no Xen emulation)
            // ```
            //
            // This arm briefly said `Some("xen-disk")` on the strength of the
            // `-device help` line alone, and called the year-old
            // `NeedsRealCloud("xen blkfront/netfront need a Xen hypervisor")`
            // sentence a lie. The sentence was RIGHT. `-device help` enumerates
            // every compiled-in model regardless of whether this build has a bus
            // to hang it on: without the `xen` accelerator or a machine with
            // `xen-version`, no `xen-bus` is ever created, so `xen-disk`,
            // `xen-net-device` and `xen-cdrom` cannot be instantiated and
            // `xen-platform` answers "requires a Xen guest".
            //
            // The guard that ratified the mistake is fixed with it: see
            // `the_device_words_are_attachable_on_this_qemu` below, which asks
            // QEMU to actually BUILD each device instead of grepping a listing.
            DiskBus::XenBlk | DiskBus::HvScsi | DiskBus::Metal => None,
        }
    }

    /// The `target.buses` word, where one exists.
    pub fn target_bus(self) -> Option<Bus> {
        match self {
            DiskBus::VirtioBlk => Some(Bus::VirtioBlk),
            DiskBus::VirtioScsi => Some(Bus::VirtioScsi),
            DiskBus::Nvme => Some(Bus::Nvme),
            DiskBus::HvScsi => Some(Bus::HvStorvsc),
            DiskBus::XenBlk => Some(Bus::XenBlk),
            // `ide` is the one bus left the group spells only as a CDROM (an
            // Azure Gen1 OS disk is a real IDE hard disk), and `metal` is not a
            // bus word at all.
            DiskBus::Ide | DiskBus::Metal => None,
        }
    }
}

/// The NIC model the guest sees.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NicModel {
    /// `virtio-net` — kernel `VIRTIO_NET`.
    VirtioNet,
    /// Intel e1000 — kernel `E1000`.
    E1000,
    /// Intel 82574L e1000e — kernel `E1000E`.
    E1000e,
    /// AWS Elastic Network Adapter — kernel `ENA_ETHERNET`. Nitro only.
    Ena,
    /// Google Virtual NIC — kernel `GVE`.
    Gvnic,
    /// Hyper-V synthetic NIC — kernel `HYPERV_NET`.
    HvNetvsc,
    /// Xen netfront — kernel `XEN_NETDEV_FRONTEND`.
    XenNetfront,
    /// Real hardware.
    Metal,
}

impl NicModel {
    pub fn as_str(self) -> &'static str {
        match self {
            NicModel::VirtioNet => "virtio-net",
            NicModel::E1000 => "e1000",
            NicModel::E1000e => "e1000e",
            NicModel::Ena => "ena",
            NicModel::Gvnic => "gvnic",
            NicModel::HvNetvsc => "hv-netvsc",
            NicModel::XenNetfront => "xen-netfront",
            NicModel::Metal => "metal",
        }
    }

    /// The QEMU `-device` model, or `None` when QEMU has no such NIC (ENA,
    /// gVNIC, hv_netvsc, xen-netfront outside Xen).
    pub fn qemu_mimic(self) -> Option<&'static str> {
        match self {
            NicModel::VirtioNet => Some("virtio-net-pci"),
            NicModel::E1000 => Some("e1000"),
            NicModel::E1000e => Some("e1000e"),
            // `xen-net-device` is listed by `-device help` and is NOT
            // attachable — the same measurement, and the same trap, as
            // `DiskBus::XenBlk`. Read that comment; it carries the transcript.
            NicModel::XenNetfront => None,
            // ENA and gVNIC are not even listed (`ena`, `ena-pci`, `gve`,
            // `gvnic`, `gve-pci` — none appear); hv_netvsc has no model though
            // `vmbus-bridge` and `hv-balloon` do.
            NicModel::Ena | NicModel::Gvnic | NicModel::HvNetvsc | NicModel::Metal => None,
        }
    }

    /// The `target.nic` word, where one exists.
    pub fn target_nic(self) -> Option<Nic> {
        match self {
            NicModel::VirtioNet => Some(Nic::Virtio),
            NicModel::E1000 | NicModel::E1000e => Some(Nic::E1000),
            NicModel::Ena => Some(Nic::Ena),
            NicModel::HvNetvsc => Some(Nic::HvNetvsc),
            NicModel::Gvnic => Some(Nic::Gvnic),
            NicModel::XenNetfront => Some(Nic::XenNetfront),
            // Bare metal has no model word: whatever the box has.
            NicModel::Metal => None,
        }
    }
}

/// How the platform exposes the CPU to the guest — decides RDRAND, AVX,
/// `/proc/cpuinfo`'s model name, and whether a build tuned `-C target-cpu`
/// survives.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CpuModel {
    /// `-cpu host`: the guest sees the host's own model and flags.
    HostPassthrough,
    /// A named QEMU model (`EPYC-Rome`, `Skylake-Server`, …): a fixed flag set
    /// regardless of the host, RDRAND included on every model named here.
    Named(&'static str),
    /// QEMU's own default (`qemu64` under KVM): NO RDRAND, no AVX. The shape
    /// every proof in this constellation booted before `-cpu` was a choice.
    QemuDefault,
    /// Not a QEMU host at all (Hyper-V, Xen, bare metal) — the guest sees what
    /// that hypervisor or the metal gives.
    Native,
    Unknown,
}

impl CpuModel {
    /// The `-cpu` argument to render, if any. `QemuDefault` and `Unknown`
    /// render nothing, which is the historical argv.
    pub fn qemu_arg(self) -> Option<&'static str> {
        match self {
            CpuModel::HostPassthrough => Some("host"),
            CpuModel::Named(m) => Some(m),
            CpuModel::QemuDefault | CpuModel::Native | CpuModel::Unknown => None,
        }
    }

    pub fn label(self) -> String {
        match self {
            CpuModel::HostPassthrough => "host".into(),
            CpuModel::Named(m) => m.to_string(),
            CpuModel::QemuDefault => "qemu64 (qemu default, no RDRAND)".into(),
            CpuModel::Native => "native (not qemu)".into(),
            CpuModel::Unknown => "unknown".into(),
        }
    }
}

/// The machine chipset the guest sees.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Chipset {
    /// i440FX + PIIX (`-machine pc`).
    Pc,
    /// Q35 + ICH9 (`-machine q35`).
    Q35,
    /// Hyper-V (no PCI bus on gen2 except SR-IOV VFs), Xen, or bare metal.
    NotQemu,
    Unknown,
}

impl Chipset {
    pub fn qemu_machine(self) -> Option<&'static str> {
        match self {
            Chipset::Pc => Some("pc"),
            Chipset::Q35 => Some("q35"),
            Chipset::NotQemu | Chipset::Unknown => None,
        }
    }
}

/// How a custom medium or image is brought to the platform.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MediumBring {
    /// Upload an ISO and attach it as a (IDE) cdrom; install onto the disk.
    IsoCdrom,
    /// Import a RAW disk image (the installed disk, pre-laid) — no ISO path.
    ImportRaw,
    /// Import qcow2 (OpenStack-style glance image).
    ImportQcow2,
    /// Import a fixed-size VHD (Azure).
    ImportVhd,
    /// Several of the above (AWS: raw/vhd/vmdk/ova via VM Import; GCE: raw
    /// tar.gz; Hetzner: ISO via the ISO library / snapshot from a rescue dd).
    Several(&'static str),
    /// Bare metal: PXE / vendor rescue + dd, or a real burned medium.
    Metal(&'static str),
    Unknown,
}

impl MediumBring {
    /// **How the medium arrives, in one phrase.** A door that refuses a preset
    /// because its medium cannot be attached has to be able to SAY which way
    /// this platform takes one, and the word belongs beside the variants rather
    /// than in every caller that needs it (LAW 5).
    pub fn describe(self) -> String {
        match self {
            MediumBring::IsoCdrom => "an ISO attached as an IDE cdrom".to_string(),
            MediumBring::ImportRaw => "an imported RAW disk image (no ISO attach)".to_string(),
            MediumBring::ImportQcow2 => "an imported qcow2 disk image (no ISO attach)".to_string(),
            MediumBring::ImportVhd => "an imported fixed-size VHD (no ISO attach)".to_string(),
            MediumBring::Several(how) => format!("one of several imports: {how}"),
            MediumBring::Metal(how) => format!("bare metal: {how}"),
            MediumBring::Unknown => "undocumented — nobody has written down how a medium reaches this platform".to_string(),
        }
    }

    /// Whether this platform takes an attached ISO at all. `false` means the
    /// INSTALLER path does not exist here: a proof of such a preset can only
    /// ever prove the INSTALLED disk boots on its device set.
    ///
    /// **A PLATFORM fact, and only that.** It decides what a DOOR does — the
    /// UpCloud deploy attaches two storages off this word, and
    /// [`crate::installer::InstallerBuild::cloud_medium_gap`] reads it to say
    /// that such a machine owes no import container, because the container its
    /// cloud takes is the `.iso` [`crate::iso_writer`] already wrote. It says
    /// NOTHING about the kernel: for that, ask
    /// [`kernel_medium_bus`](Self::kernel_medium_bus), whose answer for the
    /// same variant is `None`.
    pub fn is_iso_attach(self) -> bool {
        matches!(self, MediumBring::IsoCdrom)
    }

    /// **Which bus the RUNNING KERNEL must drive to READ the medium — `None`
    /// when it never reads one.**
    ///
    /// # This is NOT [`describe`](Self::describe)'s fact, and conflating them cost two lanes
    ///
    /// `MediumBring` says how the **platform** hands a medium over.
    /// [`crate::target::Target::buses`] says which **drivers the kernel must
    /// carry**. For a medium that rides twice those are not one fact, and until
    /// 2026-09-07 [`TargetPreset::target`] derived the second from the first:
    /// `IsoCdrom` inserted [`Bus::IdeCdrom`](crate::target::Bus::IdeCdrom),
    /// which puts `CONFIG_ATA` + `ATA_PIIX` + `BLK_DEV_SR` on the donor
    /// kernel's edge. The shared donor `tunnr/tunnr-kernel` is the `nuked`
    /// preset, whose fragment says `# CONFIG_ATA is not set`, so
    /// [`crate::kernel::KernelBuild::apply_requirements`] refused the build —
    /// *"a consumer requires what the preset vetoes"* — and four gunnar
    /// installer rows carried `preset: None` for a month rather than name the
    /// machine they had been running on.
    ///
    /// # The measurement that settles it
    ///
    /// **measured 2026-09-07, gunnar.rs on UpCloud (se-sto1):** the appliance
    /// serving that box runs `tunnr-kernel`, whose shipped `kernel.config` says
    /// `# CONFIG_ATA is not set` — and it booted from the ISO this crate
    /// composes. If the derivation described the medium, that kernel could not
    /// have started. It can, because the ISO is attached TWICE
    /// (`gunnar/deploy/upcloud/src/machine.rs`):
    ///
    /// * once as an **IDE cdrom**, which is what SeaBIOS boots — firmware
    ///   reading an El-Torito cdrom uses the BIOS' own INT 13h path and asks
    ///   Linux for no driver at all; and
    /// * once as a **virtio disk**, which is where Linux and `korp-installer`
    ///   find the ISO-9660 `CD001` magic. The installer probes ONLY virtio, so
    ///   a cdrom-only attach boots the kernel, starts PID 1 and dies with
    ///   `INSTALLER: volume: no block device carries the ISO-9660 magic
    ///   (CD001) … (probed: loop1 … vda)` — no `sr0` anywhere, because the
    ///   kernel has no ATA to make one (MEASURED 2026-08-15, and again on the
    ///   SeaBIOS rig leg B1).
    ///
    /// The virtio face needs no row here: it IS the machine's
    /// [`boot_disk`](TargetPreset::boot_disk), already the first entry of
    /// `buses`.
    ///
    /// # Why a `Bus` and not a `bool`
    ///
    /// So the day a platform hands a medium over on a device the kernel really
    /// must drive — a cdrom-ONLY attach, an installer that learns to read `sr0`
    /// — the answer is a bus word with a reason beside it, not a second table
    /// somewhere else. Every variant is `None` TODAY, and each arm below says
    /// why that is a finding rather than an oversight.
    pub fn kernel_medium_bus(self) -> Option<crate::target::Bus> {
        match self {
            // The firmware boots the cdrom. A kernel is not REQUIRED to read it:
            // the appliance donors do (tunnr 3f7c2ff, PIIX/AHCI + SR, a donor
            // choice), and a kernel without that stack reads the virtio twin, which
            // sits on the boot disk's own bus.
            MediumBring::IsoCdrom => None,
            // An imported disk is not a medium the running kernel opens at all:
            // the install is ALREADY laid on it, and the device it arrives on is
            // the machine's `boot_disk`, which owns that bus word.
            MediumBring::ImportRaw | MediumBring::ImportQcow2 | MediumBring::ImportVhd => None,
            // Several ways in, and every one of them in the roster is an import
            // (AWS VM Import, GCE's disk.raw tar.gz). Same answer, same reason.
            MediumBring::Several(_) => None,
            // Bare metal: a burned stick or a PXE image the vendor's firmware
            // reads, then the installed disk. `boot_disk` is `metal` and the
            // group refuses to spell it at all, so nothing reaches a kernel
            // edge from here.
            MediumBring::Metal(_) => None,
            // Nobody has written this platform down. An undocumented medium
            // gets the answer that changes nothing (`None`), never a guessed
            // driver: a wrong bus is a kernel that will not build, and this
            // crate refuses a guess wearing a derivation's clothes.
            MediumBring::Unknown => None,
        }
    }
}

/// The verdict: can QEMU on our proof box be shaped into this machine?
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Mimic {
    /// Yes — every device the guest must drive exists as a QEMU model, so the
    /// `appliance-boot/<preset>` row is MEASURED under KVM.
    Qemu,
    /// No — the named device/behaviour has no QEMU model (or the platform is
    /// not QEMU at all). The row is declared and stays `Absent (needs real
    /// cloud)` until a real deploy measures it.
    NeedsRealCloud(&'static str),
}

/// **What QEMU can do about ONE facet of a machine.**
///
/// The whole-machine [`Mimic`] verdict is a single word for five independent
/// facts, and a single word has to take the worst of them. That cost real
/// coverage: `aws-nitro` was `NeedsRealCloud` because ENA has no QEMU model, and
/// the verdict swallowed its firmware, its chipset, its medium and its **NVMe
/// boot disk** — which QEMU models exactly (`-device nvme`, measured on oden
/// 2026-09-05, QEMU 10.2.1) and which drives the guest's real
/// `CONFIG_BLK_DEV_NVME` path. Four facts went unproven because a fifth could
/// not be.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MimicAxis {
    /// QEMU models this facet exactly; the word is the `-device`/`-machine`
    /// value the door renders.
    Exact(&'static str),
    /// QEMU has no model for `missing`, but the door may render `with` in its
    /// place and still exercise everything the facet is not: the bus topology,
    /// the driver-independent boot, the address plumbing. A row proven this way
    /// **must carry the substitution** — see [`MimicAxes::substitutions`] —
    /// because a green that does not say what was swapped is the kind of green
    /// this crate exists to refuse.
    Substitute {
        /// The device the real machine presents.
        missing: &'static str,
        /// What QEMU is asked to present instead.
        with: &'static str,
    },
    /// Not renderable at all, with or without a substitution — bare metal, or a
    /// platform that is not a hypervisor QEMU can stand in for.
    Absent(&'static str),
}

impl MimicAxis {
    /// Whether QEMU models this facet as the real machine has it.
    pub fn is_exact(self) -> bool {
        matches!(self, MimicAxis::Exact(_))
    }
    /// Whether the door can render this facet at all (exactly or by standing in).
    pub fn is_renderable(self) -> bool {
        !matches!(self, MimicAxis::Absent(_))
    }
}

/// **The five facets of one machine, judged separately.**
///
/// Derived from the preset's own device words ([`TargetPreset::axes`]) rather
/// than declared, so it cannot drift from them the way the hand-written
/// [`Mimic`] field did.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct MimicAxes {
    /// UEFI vs SeaBIOS — QEMU renders both, so this is `Exact` unless the
    /// platform is not a QEMU-shaped machine at all.
    pub firmware: MimicAxis,
    /// The chipset (`-machine pc` / `q35`).
    pub chipset: MimicAxis,
    /// The boot disk's bus.
    pub disk: MimicAxis,
    /// The NIC model.
    pub nic: MimicAxis,
    /// How the medium arrives (an attached cdrom vs an imported disk image).
    pub medium: MimicAxis,
}

impl MimicAxes {
    /// The five, in a fixed order, each with the facet's name — so a caller
    /// reports them without re-listing the fields and getting the order wrong.
    pub fn each(&self) -> [(&'static str, MimicAxis); 5] {
        [
            ("firmware", self.firmware),
            ("chipset", self.chipset),
            ("disk", self.disk),
            ("nic", self.nic),
            ("medium", self.medium),
        ]
    }

    /// Every facet QEMU must stand in for, as `(facet, missing, with)`.
    ///
    /// **A proof row must print this.** An empty list is the only thing that
    /// makes a KVM green mean "this machine", and a non-empty one means the row
    /// proved a SHAPE — everything but the named devices.
    pub fn substitutions(&self) -> Vec<(&'static str, &'static str, &'static str)> {
        self.each()
            .into_iter()
            .filter_map(|(facet, axis)| match axis {
                MimicAxis::Substitute { missing, with } => Some((facet, missing, with)),
                _ => None,
            })
            .collect()
    }

    /// Every facet that cannot be rendered at all, as `(facet, why)`.
    pub fn absent(&self) -> Vec<(&'static str, &'static str)> {
        self.each()
            .into_iter()
            .filter_map(|(facet, axis)| match axis {
                MimicAxis::Absent(why) => Some((facet, why)),
                _ => None,
            })
            .collect()
    }

    /// Every facet is modelled exactly — a KVM green here means the machine.
    pub fn is_exact(&self) -> bool {
        self.each().into_iter().all(|(_, a)| a.is_exact())
    }

    /// The door can launch this shape (no facet is [`MimicAxis::Absent`]),
    /// though [`substitutions`](Self::substitutions) may be non-empty.
    pub fn is_renderable(&self) -> bool {
        self.each().into_iter().all(|(_, a)| a.is_renderable())
    }
}

/// **One cloud's machine shape.** Every field a proof door or a kernel recipe
/// asks about, with the vendor-documented answer or an honest `Unknown`.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct TargetPreset {
    /// The word on `--target <name>` and in the row `appliance-boot/<name>`.
    pub name: &'static str,
    /// The platform, for a human.
    pub cloud: &'static str,
    /// Which firmware starts the guest (a platform that offers both is
    /// `Both`; the door then runs the one the preset's `chipset` implies unless
    /// told otherwise).
    pub firmware: Firmware,
    pub secure_boot: SecureBoot,
    /// The consoles the guest HAS, in `console=` order (last = `/dev/console`).
    /// `serial` here means the FIRST port in `uarts`; naming it with no port
    /// is refused by `Target::validate` on the derived group.
    pub consoles: &'static [Console],
    /// The legacy COM ports that really exist.
    pub uarts: Uarts,
    pub console_reach: ConsoleReach,
    pub boot_disk: DiskBus,
    pub medium: MediumBring,
    pub nic: NicModel,
    /// How many NICs the guest gets by default (UpCloud: public + utility).
    pub nics: u8,
    pub cpu: CpuModel,
    pub chipset: Chipset,
    pub acpi: Tri,
    /// The metadata endpoint, when one exists (`169.254.169.254` almost
    /// everywhere; Azure also has the wireserver `168.63.129.16`).
    pub metadata: Option<&'static str>,
    /// Is IPv6 configured on the guest NIC by default? Our kernel has NO IPv6
    /// (the owner's ruling), so `Yes` here means DHCPv6/SLAAC traffic the
    /// appliance will ignore, never a feature it needs.
    pub ipv6_default: Tri,
    pub mimic: Mimic,
    /// **The evidence**: where and when this exact shape was booted, or `None`
    /// for a shape that is researched but not yet measured. The one input to
    /// [`TargetPreset::status`] that `mimic` does not decide — and since
    /// 2026-09-05 it also carries WHICH KIND of machine took the measurement
    /// ([`MeasuredOn`]), because "we booted UpCloud" and "we ran QEMU" are not
    /// the same claim.
    pub measured: Option<Evidence>,
    /// One line a report can quote.
    pub notes: &'static str,
}

impl TargetPreset {
    /// Whether a `console=` points at a UART — the kernel drives `SERIAL_8250`.
    pub fn has_serial(&self) -> bool {
        self.consoles.contains(&Console::Serial)
    }

    /// Whether the guest has a VGA text console — the door takes a QMP
    /// `screendump` for the proof when this is the only console.
    pub fn has_vga(&self) -> bool {
        self.consoles.contains(&Console::Vga)
    }

    /// Is there a 16550 UART at `0x3f8` (`ttyS0`)? Derived from [`Self::uarts`].
    pub fn uart_ttys0(&self) -> Tri {
        self.uarts.ttys0()
    }

    /// How well this shape is known: measured (on the cloud, or on a rig) >
    /// mimicable-but-unproven (stub) > not mimicable (needs a real cloud).
    /// Derived — including WHICH measurement it was, from the evidence's own
    /// [`MeasuredOn`], so the roster cannot claim a cloud boot for a rig run.
    pub fn status(&self) -> PresetStatus {
        match (self.measured, self.mimic) {
            (Some(e), _) => match e.on {
                MeasuredOn::QemuRig => PresetStatus::MimicMeasured,
                MeasuredOn::RealCloud => PresetStatus::CloudMeasured,
            },
            (None, Mimic::Qemu) => PresetStatus::Stub,
            (None, Mimic::NeedsRealCloud(_)) => PresetStatus::NeedsRealCloud,
        }
    }

    /// **The `target` group this preset IS** — the one derivation every
    /// consumer reads (`Target::effective`, the emitted roster, the Kconfig
    /// rows). `Err(why)` for a shape the group cannot spell yet (gVNIC,
    /// Hyper-V, Xen, bare metal): the group grows when the kernel recipe learns
    /// the Kconfig closure for that device, not before, and a row naming such a
    /// preset is refused by name rather than built for a wrong default. NVMe
    /// and ENA left that list on the aws-nitro lane — the closure now spells
    /// `Bus::Nvme`/`Nic::Ena`, so `AWS_NITRO.target()` is `Ok` (it stays
    /// `needs-real-cloud` because QEMU still cannot mimic the DEVICES).
    ///
    /// The derivation, fact by fact:
    /// * `buses` = the boot disk's bus word, plus the bus the KERNEL must drive
    ///   to read the medium when there is one ([`MediumBring::kernel_medium_bus`]
    ///   — today always `None`, and that method is where the reason lives). It
    ///   is NOT the way the platform hands the medium over: an ISO attached as
    ///   an IDE cdrom is booted by the FIRMWARE, and a kernel is not REQUIRED to
    ///   open it (the appliance donors do anyway since tunnr `3f7c2ff`, and
    ///   korp-installer ≥ 0.1.14 reads `sr0` first). The ISO's virtio twin, the
    ///   fallback for a kernel without that stack, is on the boot disk's own bus. Deriving `ide-cdrom` from `MediumBring::IsoCdrom` put
    ///   `CONFIG_ATA` on a donor that vetoes it and blocked four gunnar rows
    ///   for a month (2026-08-28 … 2026-09-07);
    /// * `uarts` = exactly the declared ports ([`Uarts::ports`]; `Unknown` =
    ///   none), so `serial` in `consoles` resolves to the first REAL port
    ///   (`ttyS1` on UpCloud, never a `ttyS0` that is not there);
    /// * `cpu` = the kernel's vendor half: an `EPYC*` model is `Cpu::Epyc`
    ///   (`CPU_SUP_AMD`); every other model, `host` passthrough and the qemu
    ///   default make no vendor claim (`Cpu::Generic`). The qemu `-cpu` word
    ///   stays the preset's own exact model ([`QemuShape::cpu`]);
    /// * `nics` is at least 1 (a machine with no NIC serves nobody).
    pub fn target(&self) -> Result<Target, String> {
        let disk = self
            .boot_disk
            .target_bus()
            .ok_or_else(|| format!("boot disk `{}` has no target.buses word yet", self.boot_disk.as_str()))?;
        let nic = self
            .nic
            .target_nic()
            .ok_or_else(|| format!("nic `{}` has no target.nic word yet", self.nic.as_str()))?;
        let mut buses = vec![disk];
        if let Some(b) = self.medium.kernel_medium_bus() {
            if !buses.contains(&b) {
                buses.insert(0, b);
            }
        }
        let cpu = match self.cpu {
            CpuModel::Named(m) if m.starts_with("EPYC") => Cpu::Epyc,
            _ => Cpu::Generic,
        };
        // `preset` stays `None`: this IS the shape, not a name pointing at one.
        Ok(Target {
            preset: None,
            firmware: self.firmware,
            consoles: self.consoles.to_vec(),
            uarts: self.uarts.ports().to_vec(),
            buses,
            nic,
            nics: self.nics.max(1),
            cpu,
        })
    }

    /// **The five facets, judged separately** — see [`MimicAxes`].
    ///
    /// DERIVED from this preset's own device words, never declared, so it cannot
    /// drift from them. That matters twice over: the hand-written [`Mimic`]
    /// field HAD drifted (`aws-xen-hvm` said Xen PV needs a Xen hypervisor while
    /// QEMU has modelled `xen-disk`/`xen-net-device` all along), and a
    /// second-source verdict is exactly the shape this crate refuses everywhere
    /// else. [`mimic_agrees_with_axes`](Self::mimic_agrees_with_axes) is the
    /// guard that keeps the two honest.
    pub fn axes(&self) -> MimicAxes {
        // Bare metal is the one platform nothing stands in for: the board is the
        // board, the firmware is the vendor's, the devices are soldered on.
        let metal = matches!(self.medium, MediumBring::Metal(_));

        let firmware = if metal {
            MimicAxis::Absent("bare metal: the vendor's own UEFI, not OVMF")
        } else {
            MimicAxis::Exact(match self.firmware {
                Firmware::Uefi => "OVMF",
                Firmware::SeaBios => "SeaBIOS",
                Firmware::Both => "OVMF or SeaBIOS",
            })
        };

        let chipset = match (metal, self.chipset.qemu_machine()) {
            (true, _) => MimicAxis::Absent("bare metal: the board is the board"),
            (false, Some(m)) => MimicAxis::Exact(m),
            // Hyper-V gen2 has no PCI bus and Xen HVM is its own platform, so
            // neither IS a QEMU machine type. A q35 guest still stands in for
            // everything the chipset is not — the firmware handoff, the memory
            // map, the boot order, the medium — which is the whole point of
            // judging this facet apart from the devices hanging off it.
            (false, None) => MimicAxis::Substitute {
                missing: match self.chipset {
                    // Hyper-V gen2 and Xen HVM really are other platforms.
                    Chipset::NotQemu => "the platform's own chipset",
                    // `Unknown` is not a claim that the chipset differs — it is
                    // that nobody wrote it down. It substitutes for the same
                    // reason (the door has to render SOMETHING) but a reader
                    // must be able to tell "we know it differs" from "we never
                    // looked", because only the second one is closed by
                    // research rather than by hardware.
                    _ => "an undocumented chipset",
                },
                with: "q35",
            },
        };

        let disk = match self.boot_disk.qemu_mimic() {
            Some(d) => MimicAxis::Exact(d),
            None if metal => MimicAxis::Absent("bare metal: real NVMe/SATA"),
            // `hv_storvsc` is a SCSI LLDD over VMBus and `virtio-scsi` is a SCSI
            // LLDD over virtio: the guest's `SCSI`/`BLK_DEV_SD` layers, the
            // partition scan and the root mount are the same code either way.
            // Only the transport differs, and that is what the substitution
            // says out loud.
            None => MimicAxis::Substitute {
                missing: self.boot_disk.as_str(),
                with: "virtio-scsi-pci",
            },
        };

        let nic = match self.nic.qemu_mimic() {
            Some(n) => MimicAxis::Exact(n),
            None if metal => MimicAxis::Absent("bare metal: a real NIC"),
            None => MimicAxis::Substitute {
                missing: self.nic.as_str(),
                with: "virtio-net-pci",
            },
        };

        let medium = match self.medium {
            MediumBring::Metal(how) => MimicAxis::Absent(how),
            MediumBring::Unknown => MimicAxis::Absent(
                "undocumented — nobody has written down how a medium reaches this platform",
            ),
            // An imported disk image is a plain `-drive`; an ISO is `-cdrom`.
            // Both are things QEMU does, which is why a cloud with "no ISO door"
            // is a PRODUCT-shape constraint and not a mimic constraint.
            m if m.is_iso_attach() => MimicAxis::Exact("-cdrom"),
            _ => MimicAxis::Exact("imported disk image as a -drive"),
        };

        MimicAxes { firmware, chipset, disk, nic, medium }
    }

    /// **Does the declared [`Mimic`] say the same thing the device words do?**
    ///
    /// `Mimic::Qemu` must mean every axis is [`MimicAxis::Exact`], and
    /// `Mimic::NeedsRealCloud` must mean at least one is not. Anything else is
    /// two sources of truth disagreeing, which is how `aws-xen-hvm` sat
    /// unprovable for a year on a sentence that was never true of this QEMU.
    pub fn mimic_agrees_with_axes(&self) -> bool {
        match self.mimic {
            Mimic::Qemu => self.axes().is_exact(),
            Mimic::NeedsRealCloud(_) => !self.axes().is_exact(),
        }
    }

    /// The QEMU rendering of this shape, when QEMU can mimic it.
    pub fn qemu_shape(&self) -> Option<QemuShape> {
        let Mimic::Qemu = self.mimic else { return None };
        Some(QemuShape {
            machine: self.chipset.qemu_machine()?,
            cpu: self.cpu.qemu_arg(),
            disk_device: self.boot_disk.qemu_mimic()?,
            nic_device: self.nic.qemu_mimic()?,
            nics: self.nics.max(1),
            uarts: self.uarts.slots(),
            serial: self.has_serial(),
            vga: self.has_vga(),
            firmware: self.firmware,
            medium_as_cdrom: self.medium.is_iso_attach(),
        })
    }

    /// The reason this preset cannot be measured under QEMU, if any.
    pub fn gap(&self) -> Option<&'static str> {
        match self.mimic {
            Mimic::Qemu => None,
            Mimic::NeedsRealCloud(why) => Some(why),
        }
    }
}

/// What the proof door hands `kvmproof::Machine` and the attachment writers.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct QemuShape {
    pub machine: &'static str,
    pub cpu: Option<&'static str>,
    pub disk_device: &'static str,
    pub nic_device: &'static str,
    pub nics: u8,
    /// The COM slots to create, COM1..COM4 — `kvmproof::Machine::uarts`: a
    /// present slot is captured to a file, an absent one is `-serial none`.
    /// UpCloud is `[false, true, true, false]`: nothing at 0x3f8, real
    /// ttyS1/ttyS2.
    pub uarts: [bool; 4],
    /// A `console=` names a UART — the guest's kernel WRITES to one, so the
    /// door may gate on the serial log. False = gate on applied output.
    pub serial: bool,
    /// A VGA adapter exists and the proof may `screendump` it.
    pub vga: bool,
    pub firmware: Firmware,
    /// The medium rides `-cdrom` (IDE) in addition to its virtio face.
    pub medium_as_cdrom: bool,
}

// ── the table ────────────────────────────────────────────────────────────────
//
// Sources and confidence per value: edda/.nornir/cloud-target-profiles.md.

/// Our own proof box, the shape every pre-2026-08-28 proof ran: q35 + OVMF,
/// UART captured, virtio-blk, virtio-net, qemu64.
///
/// **This preset IS `Target::default()`** (pinned by test): the medium is
/// laid for both firmwares (the box starts either; the Q35 chipset makes the
/// door pick OVMF), one NIC, COM1. An undeclared `target` group therefore
/// means "qemu-local" by construction, not by a second table.
pub const QEMU_LOCAL: TargetPreset = TargetPreset {
    name: "qemu-local",
    cloud: "this box: qemu-system-x86_64 + KVM, OVMF",
    firmware: Firmware::Both,
    secure_boot: SecureBoot::Optional,
    consoles: &[Console::Vga, Console::Serial],
    uarts: Uarts::Known(&[UartPort::Com1]),
    console_reach: ConsoleReach::Both,
    boot_disk: DiskBus::VirtioBlk,
    medium: MediumBring::IsoCdrom,
    nic: NicModel::VirtioNet,
    nics: 1,
    cpu: CpuModel::QemuDefault,
    chipset: Chipset::Q35,
    acpi: Tri::Yes,
    metadata: None,
    ipv6_default: Tri::No,
    mimic: Mimic::Qemu,
    measured: Some(Evidence::rig("every installer proof before 2026-08-28: OVMF, COM1 captured, virtio")),
    notes: "the historical proof shape; a green here proves the medium, not any cloud",
};

/// The same box under SeaBIOS (`-machine pc`), still with a UART.
pub const QEMU_LOCAL_BIOS: TargetPreset = TargetPreset {
    name: "qemu-local-bios",
    cloud: "this box: qemu-system-x86_64 + KVM, SeaBIOS",
    firmware: Firmware::SeaBios,
    secure_boot: SecureBoot::None,
    consoles: &[Console::Vga, Console::Serial],
    uarts: Uarts::Known(&[UartPort::Com1]),
    console_reach: ConsoleReach::Both,
    boot_disk: DiskBus::VirtioBlk,
    medium: MediumBring::IsoCdrom,
    nic: NicModel::VirtioNet,
    nics: 1,
    cpu: CpuModel::QemuDefault,
    chipset: Chipset::Pc,
    acpi: Tri::Yes,
    metadata: None,
    ipv6_default: Tri::No,
    mimic: Mimic::Qemu,
    measured: Some(Evidence::rig("2026-08-29 gunnar-installtest --firmware seabios: B1 2002 ms INSTALL-OK, B2 3820 ms, B3 2020 ms")),
    notes: "SeaBIOS with a UART: the half-way house that hid UpCloud's dark boot",
};

/// UpCloud Cloud Servers — measured 2026-08-28/29 on gunnar-appliance
/// (se-sto1) and confirmed by the docs where they speak.
pub const UPCLOUD: TargetPreset = TargetPreset {
    name: "upcloud",
    cloud: "UpCloud Cloud Servers",
    firmware: Firmware::SeaBios,
    secure_boot: SecureBoot::None,
    consoles: &[Console::Vga],
    uarts: Uarts::Known(&[UartPort::Com2, UartPort::Com3]),
    console_reach: ConsoleReach::VgaVnc,
    boot_disk: DiskBus::VirtioBlk,
    medium: MediumBring::IsoCdrom,
    nic: NicModel::VirtioNet,
    nics: 2,
    cpu: CpuModel::Named("EPYC-Rome"),
    chipset: Chipset::Pc,
    acpi: Tri::Yes,
    metadata: Some("169.254.169.254"),
    ipv6_default: Tri::Yes,
    mimic: Mimic::Qemu,
    measured: Some(Evidence::cloud("2026-08-28/29 gunnar-appliance se-sto1: SeaBIOS only, ISO as IDE cdrom, no ttyS0, VNC the only console")),
    notes: "no ttyS0 (ttyS1/ttyS2 at 0x2f8/0x3e8 exist), VNC is the only console, ISO = IDE cdrom, \
            disk = virtio-blk, public + utility NIC; cpu model is measured from the guest, not documented",
};

/// Scaleway Instances (DEV1 / PLAY2 / PRO2): KVM, virtio everywhere.
pub const SCALEWAY_INSTANCE: TargetPreset = TargetPreset {
    name: "scaleway-instance",
    cloud: "Scaleway Instances (DEV1, PLAY2, PRO2)",
    firmware: Firmware::Uefi,
    secure_boot: SecureBoot::Unknown,
    consoles: &[Console::Vga, Console::Serial],
    uarts: Uarts::Known(&[UartPort::Com1]),
    console_reach: ConsoleReach::Serial,
    boot_disk: DiskBus::VirtioBlk,
    medium: MediumBring::ImportQcow2,
    nic: NicModel::VirtioNet,
    nics: 1,
    cpu: CpuModel::Unknown,
    chipset: Chipset::Unknown,
    acpi: Tri::Yes,
    metadata: Some("169.254.42.42"),
    ipv6_default: Tri::No,
    mimic: Mimic::NeedsRealCloud(
        "no ISO attach: a custom image is a qcow2 snapshot import, so the INSTALLER path \
         does not exist on this platform — the installed disk must be imported pre-laid",
    ),
    measured: None,
    notes: "no ISO door; the appliance would ship as an imported disk image, a different product shape",
};

/// Scaleway Elastic Metal: real hardware.
pub const SCALEWAY_ELASTIC_METAL: TargetPreset = TargetPreset {
    name: "scaleway-elastic-metal",
    cloud: "Scaleway Elastic Metal",
    firmware: Firmware::Uefi,
    secure_boot: SecureBoot::Unknown,
    // No documented COM port → no `serial` console may be named (a serial
    // console nobody can prove exists is the dark boot).
    consoles: &[Console::Vga],
    uarts: Uarts::Unknown,
    console_reach: ConsoleReach::Serial,
    boot_disk: DiskBus::Metal,
    medium: MediumBring::Metal("rescue mode + dd / custom install via the console"),
    nic: NicModel::Metal,
    nics: 1,
    cpu: CpuModel::Native,
    chipset: Chipset::NotQemu,
    acpi: Tri::Yes,
    metadata: Some("169.254.42.42"),
    ipv6_default: Tri::No,
    mimic: Mimic::NeedsRealCloud("bare metal: real NVMe/SATA, real NIC, the vendor's UEFI"),
    measured: None,
    notes: "the iso-metal row of the chain matrix, not a KVM row",
};

/// AWS EC2 on the legacy Xen HVM families (m4, c4, t2, …).
pub const AWS_XEN_HVM: TargetPreset = TargetPreset {
    name: "aws-xen-hvm",
    cloud: "AWS EC2, Xen HVM instance families",
    firmware: Firmware::SeaBios,
    secure_boot: SecureBoot::None,
    consoles: &[Console::Vga, Console::Serial],
    uarts: Uarts::Known(&[UartPort::Com1]),
    console_reach: ConsoleReach::Both,
    boot_disk: DiskBus::XenBlk,
    medium: MediumBring::Several("VM Import (raw/vhd/vmdk/ova) → AMI; no ISO attach"),
    nic: NicModel::XenNetfront,
    nics: 1,
    cpu: CpuModel::Native,
    chipset: Chipset::NotQemu,
    acpi: Tri::Yes,
    metadata: Some("169.254.169.254"),
    ipv6_default: Tri::No,
    // RE-MEASURED and RE-CONFIRMED 2026-09-05 (see `DiskBus::qemu_mimic`): this
    // sentence was called a lie on the strength of a `-device help` line, and it
    // is not one. QEMU 10.2.1 on oden has no `xen` accelerator, no machine with
    // `xen-version`, and therefore no `xen-bus` — `-device xen-disk` answers
    // "No 'xen-bus' bus found". The listing shows a model; the bus is what a
    // guest binds against.
    mimic: Mimic::NeedsRealCloud("xen blkfront/netfront need a Xen hypervisor: this QEMU lists xen-disk/xen-net-device but has no xen accel and no xen-bus to attach them to"),
    measured: None,
    notes: "legacy; the serial console is the instance screenshot + get-console-output, not interactive",
};

/// AWS EC2 on Nitro (m5+, c5+, t3+, all Graviton on arm64).
pub const AWS_NITRO: TargetPreset = TargetPreset {
    name: "aws-nitro",
    cloud: "AWS EC2, Nitro instance families",
    firmware: Firmware::Both,
    secure_boot: SecureBoot::Optional,
    consoles: &[Console::Vga, Console::Serial],
    uarts: Uarts::Known(&[UartPort::Com1]),
    console_reach: ConsoleReach::Both,
    boot_disk: DiskBus::Nvme,
    medium: MediumBring::Several("VM Import (raw/vhd/vmdk/ova) or import-snapshot + register-image --boot-mode; no ISO attach"),
    nic: NicModel::Ena,
    nics: 1,
    cpu: CpuModel::Native,
    chipset: Chipset::NotQemu,
    acpi: Tri::Yes,
    metadata: Some("169.254.169.254"),
    ipv6_default: Tri::No,
    mimic: Mimic::NeedsRealCloud("ENA has no QEMU model; the NVMe controller is Nitro's own, not QEMU's"),
    measured: None,
    notes: "boot mode per AMI (legacy-bios | uefi | uefi-preferred); EC2 Serial Console = ttyS0",
};

/// Google Compute Engine with virtio devices (PD on virtio-scsi, virtio-net).
pub const GCE_VIRTIO: TargetPreset = TargetPreset {
    name: "gce-virtio",
    cloud: "Google Compute Engine, virtio-net + virtio-scsi Persistent Disk",
    firmware: Firmware::Uefi,
    secure_boot: SecureBoot::Optional,
    consoles: &[Console::Vga, Console::Serial],
    uarts: Uarts::Known(&[UartPort::Com1]),
    console_reach: ConsoleReach::Both,
    boot_disk: DiskBus::VirtioScsi,
    medium: MediumBring::Several("raw disk.raw in a tar.gz → images create; no ISO attach"),
    nic: NicModel::VirtioNet,
    nics: 1,
    cpu: CpuModel::Named("Skylake-Server"),
    chipset: Chipset::Pc,
    acpi: Tri::Yes,
    metadata: Some("169.254.169.254"),
    ipv6_default: Tri::No,
    mimic: Mimic::Qemu,
    measured: None,
    notes: "the medium is a disk image, not an ISO; the qemu row proves the INSTALLED disk boots on \
            this device set, not that the installer runs there",
};

/// Google Compute Engine with gVNIC (default/required on gen3+ machine series).
pub const GCE_GVNIC: TargetPreset = TargetPreset {
    name: "gce-gvnic",
    cloud: "Google Compute Engine, gVNIC + NVMe (gen3+ series, Hyperdisk, Local SSD)",
    firmware: Firmware::Uefi,
    secure_boot: SecureBoot::DefaultOn,
    consoles: &[Console::Vga, Console::Serial],
    uarts: Uarts::Known(&[UartPort::Com1]),
    console_reach: ConsoleReach::Both,
    boot_disk: DiskBus::Nvme,
    medium: MediumBring::Several("raw disk.raw in a tar.gz → images create; no ISO attach"),
    nic: NicModel::Gvnic,
    nics: 1,
    cpu: CpuModel::Native,
    chipset: Chipset::Pc,
    acpi: Tri::Yes,
    metadata: Some("169.254.169.254"),
    ipv6_default: Tri::No,
    mimic: Mimic::NeedsRealCloud("gVNIC has no QEMU model; kernel needs GVE"),
    measured: None,
    notes: "C3/N4/C4 and newer require gVNIC; MTU 1460",
};

/// Azure Generation 1 (Hyper-V gen1).
pub const AZURE_GEN1: TargetPreset = TargetPreset {
    name: "azure-gen1",
    cloud: "Microsoft Azure, Generation 1 VM",
    firmware: Firmware::SeaBios,
    secure_boot: SecureBoot::None,
    consoles: &[Console::Vga, Console::Serial],
    uarts: Uarts::Known(&[UartPort::Com1]),
    console_reach: ConsoleReach::Both,
    boot_disk: DiskBus::Ide,
    medium: MediumBring::ImportVhd,
    nic: NicModel::HvNetvsc,
    nics: 1,
    cpu: CpuModel::Native,
    chipset: Chipset::NotQemu,
    acpi: Tri::Yes,
    metadata: Some("169.254.169.254"),
    ipv6_default: Tri::No,
    mimic: Mimic::NeedsRealCloud("Hyper-V synthetic NIC/SCSI (hv_netvsc, hv_storvsc) need Hyper-V"),
    measured: None,
    notes: "OS disk on IDE, data disks on hv_storvsc; fixed-size VHD only; serial via boot diagnostics",
};

/// Azure Generation 2 (Hyper-V gen2, UEFI).
pub const AZURE_GEN2: TargetPreset = TargetPreset {
    name: "azure-gen2",
    cloud: "Microsoft Azure, Generation 2 VM (Trusted Launch optional)",
    firmware: Firmware::Uefi,
    secure_boot: SecureBoot::Optional,
    consoles: &[Console::Vga, Console::Serial],
    uarts: Uarts::Known(&[UartPort::Com1]),
    console_reach: ConsoleReach::Both,
    boot_disk: DiskBus::HvScsi,
    medium: MediumBring::ImportVhd,
    nic: NicModel::HvNetvsc,
    nics: 1,
    cpu: CpuModel::Native,
    chipset: Chipset::NotQemu,
    acpi: Tri::Yes,
    metadata: Some("169.254.169.254"),
    ipv6_default: Tri::No,
    mimic: Mimic::NeedsRealCloud("Hyper-V gen2: no PCI bus, no IDE, hv_storvsc + hv_netvsc only"),
    measured: None,
    notes: "no legacy devices at all; framebuffer is hyperv_fb/hyperv_drm",
};

/// Hetzner Cloud.
pub const HETZNER_CLOUD: TargetPreset = TargetPreset {
    name: "hetzner-cloud",
    cloud: "Hetzner Cloud",
    firmware: Firmware::SeaBios,
    secure_boot: SecureBoot::None,
    consoles: &[Console::Vga, Console::Serial],
    uarts: Uarts::Known(&[UartPort::Com1]),
    console_reach: ConsoleReach::VgaVnc,
    boot_disk: DiskBus::VirtioBlk,
    medium: MediumBring::IsoCdrom,
    nic: NicModel::VirtioNet,
    nics: 1,
    cpu: CpuModel::Unknown,
    chipset: Chipset::Pc,
    acpi: Tri::Yes,
    metadata: Some("169.254.169.254"),
    ipv6_default: Tri::Yes,
    mimic: Mimic::Qemu,
    measured: None,
    notes: "ISO library + custom ISO on request, attached as cdrom; volumes ride virtio-scsi",
};

/// OVHcloud Public Cloud (OpenStack).
pub const OVH_PUBLIC_CLOUD: TargetPreset = TargetPreset {
    name: "ovh-public-cloud",
    cloud: "OVHcloud Public Cloud instances (OpenStack/KVM)",
    firmware: Firmware::SeaBios,
    secure_boot: SecureBoot::None,
    consoles: &[Console::Vga, Console::Serial],
    uarts: Uarts::Known(&[UartPort::Com1]),
    console_reach: ConsoleReach::VgaVnc,
    boot_disk: DiskBus::VirtioBlk,
    medium: MediumBring::ImportQcow2,
    nic: NicModel::VirtioNet,
    nics: 1,
    cpu: CpuModel::Unknown,
    chipset: Chipset::Pc,
    acpi: Tri::Yes,
    metadata: Some("169.254.169.254"),
    ipv6_default: Tri::Yes,
    mimic: Mimic::Qemu,
    measured: None,
    notes: "glance image (qcow2/raw) import; UEFI via hw_firmware_type=uefi image property",
};

/// **Every preset**, in report order — THE roster. `Target::validate` resolves
/// `preset = "<name>"` here, `super::presets_toml` emits it, and
/// [`boot_roster`] floors the test matrix's `appliance-boot/<name>` rows with
/// it. Add a machine = add a const above and a line here; nothing else.
pub const PRESETS: &[TargetPreset] = &[
    QEMU_LOCAL,
    QEMU_LOCAL_BIOS,
    UPCLOUD,
    SCALEWAY_INSTANCE,
    SCALEWAY_ELASTIC_METAL,
    AWS_XEN_HVM,
    AWS_NITRO,
    GCE_VIRTIO,
    GCE_GVNIC,
    AZURE_GEN1,
    AZURE_GEN2,
    HETZNER_CLOUD,
    OVH_PUBLIC_CLOUD,
];

/// Look a preset up by its word.
pub fn preset(name: &str) -> Option<&'static TargetPreset> {
    PRESETS.iter().find(|p| p.name == name)
}

/// The names, for a usage line or a roster check.
pub fn names() -> Vec<&'static str> {
    PRESETS.iter().map(|p| p.name).collect()
}

/// **The test matrix's `appliance-boot/<preset>` roster, emitted from the
/// code.** One row per preset; a mimicable preset is a KVM row (a hole the
/// installtest fills), a `NeedsRealCloud` preset is an `Absent (needs real
/// cloud: …)` row until a real deploy emits under that component name.
/// `nornir_testmatrix::appliance::ApplianceBootGrid` folds rows onto it.
/// Each row also carries the preset's SUBSTITUTIONS
/// ([`MimicAxes::substitutions`]) — the devices QEMU must stand in for. A KVM
/// green with a non-empty substitution list proved a SHAPE, not a machine, and
/// a row that does not say which devices were swapped is exactly the kind of
/// green this constellation refuses. `ApplianceBootGrid` enforces it: a `pass`
/// row for such a preset that does not NAME them is folded RED.
#[cfg(feature = "testmatrix")]
pub fn boot_roster() -> Vec<nornir_testmatrix::appliance::BootPreset> {
    use nornir_testmatrix::appliance::{BootPreset, BootReach, BootSubstitution};
    PRESETS
        .iter()
        .map(|p| BootPreset {
            name: p.name.to_string(),
            reach: match p.gap() {
                None => BootReach::Kvm,
                Some(why) => BootReach::RealCloud(why.to_string()),
            },
            // The evidence never travels without saying which kind it is —
            // `real cloud: …` vs `qemu rig: …`, from `MeasuredOn`.
            measured: p.measured.map(|e| e.label()),
            substitutions: p
                .axes()
                .substitutions()
                .into_iter()
                .map(|(facet, missing, with)| BootSubstitution {
                    facet: facet.to_string(),
                    missing: missing.to_string(),
                    with: with.to_string(),
                })
                .collect(),
        })
        .collect()
}

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

    #[test]
    fn names_are_unique_and_lookup_is_by_word() {
        let mut seen = std::collections::BTreeSet::new();
        for p in PRESETS {
            assert!(seen.insert(p.name), "duplicate preset name {}", p.name);
            assert_eq!(preset(p.name).map(|q| q.name), Some(p.name));
        }
        assert!(preset("coreboot-cloud").is_none());
    }

    /// Every preset that says QEMU can mimic it renders a full QEMU shape, and
    /// every one that says it cannot names its reason.
    #[test]
    fn mimicable_presets_render_a_qemu_shape_and_the_rest_name_the_gap() {
        for p in PRESETS {
            match p.mimic {
                Mimic::Qemu => {
                    let s = p.qemu_shape().unwrap_or_else(|| panic!("{}: claims Qemu but renders no shape", p.name));
                    assert!(!s.machine.is_empty());
                    assert_eq!(s.serial, p.has_serial());
                    assert!(p.gap().is_none());
                }
                Mimic::NeedsRealCloud(why) => {
                    assert!(p.qemu_shape().is_none(), "{}: NeedsRealCloud must not render", p.name);
                    assert_eq!(p.gap(), Some(why));
                    assert!(!why.is_empty());
                }
            }
            assert!(!p.consoles.is_empty(), "{}: a boot nobody can see", p.name);
        }
    }

    /// UpCloud is the shape that hurt: SeaBIOS, no UART, VGA only, IDE cdrom +
    /// virtio-blk, two virtio NICs — and it IS mimicable.
    #[test]
    fn upcloud_is_the_measured_shape() {
        let s = UPCLOUD.qemu_shape().unwrap();
        assert_eq!(s.machine, "pc");
        assert!(!s.serial && s.vga && s.medium_as_cdrom);
        assert_eq!(s.nics, 2);
        assert_eq!(s.disk_device, "virtio-blk-pci");
        assert_eq!(s.nic_device, "virtio-net-pci");
        assert_eq!(UPCLOUD.uart_ttys0(), Tri::No);
        assert_eq!(s.uarts, [false, true, true, false], "ttyS1/ttyS2 exist, ttyS0 does not");
        let t = UPCLOUD.target().unwrap();
        assert_eq!(t.firmware, Firmware::SeaBios);
        assert_eq!(t.consoles, vec![Console::Vga]);
        assert_eq!(t.uarts, vec![UartPort::Com2, UartPort::Com3]);
        assert_eq!(
            t.buses,
            vec![Bus::VirtioBlk],
            "the cdrom is how the PLATFORM hands the medium over, not a bus the preset requires the kernel to drive \
             (the appliance donors read it anyway since tunnr 3f7c2ff; the virtio twin is the fallback)"
        );
        assert_eq!(t.cpu, Cpu::Epyc);
        assert_eq!(t.nics, 2);
        t.validate("upcloud").unwrap();
        // The one preset whose evidence is a REAL instance, and the whole point
        // of splitting the word: this is not the same claim `qemu-local-bios`
        // makes.
        assert_eq!(UPCLOUD.status(), PresetStatus::CloudMeasured);
        assert_eq!(UPCLOUD.measured.unwrap().on, MeasuredOn::RealCloud);
        assert_eq!(QEMU_LOCAL_BIOS.status(), PresetStatus::MimicMeasured);
        assert_eq!(QEMU_LOCAL_BIOS.measured.unwrap().on, MeasuredOn::QemuRig);
    }

    /// The `target` group cannot spell gVNIC yet, and the preset says so with
    /// `None` rather than a wrong default. NVMe + ENA ARE spellable (the
    /// aws-nitro lane taught the closure), so `AWS_NITRO` derives a group —
    /// `nvme` on the bus, `ena` on the NIC — and since 2026-09-05 so does
    /// `AZURE_GEN2`: `hv-storvsc` on the bus, `hv-netvsc` on the NIC. `GCE_GVNIC`
    /// still fails, on its NIC (`nvme` disk is fine, `gvnic` is not), and
    /// `AZURE_GEN1` on its IDE OS disk — the group spells `ide-cdrom` only.
    #[test]
    fn a_shape_the_target_group_cannot_spell_yields_no_target() {
        let nitro = AWS_NITRO.target().expect("nvme + ena is spellable since the aws-nitro lane");
        assert!(nitro.has_bus(Bus::Nvme), "aws-nitro boot disk is nvme");
        assert_eq!(nitro.nic, Nic::Ena, "aws-nitro nic is ena");
        assert!(!nitro.has_bus(Bus::IdeCdrom), "the Nitro medium is an imported disk, never a cdrom");
        nitro.validate("aws-nitro").unwrap();
        let gen2 = AZURE_GEN2.target().expect("hv-storvsc + hv-netvsc is spellable since the azure lane");
        assert!(gen2.has_bus(Bus::HvStorvsc), "azure-gen2 boot disk is Hyper-V synthetic SCSI");
        assert_eq!(gen2.nic, Nic::HvNetvsc, "azure-gen2 nic is the synthetic NIC");
        assert!(!gen2.has_bus(Bus::IdeCdrom), "the Azure medium is an imported VHD, never a cdrom");
        gen2.validate("azure-gen2").unwrap();
        // The W2 lane (2026-09-05) taught the closure gVNIC and the two Xen
        // frontends, so these two derive a group now. Both stay
        // `needs-real-cloud`: the KERNEL can spell the device, QEMU still
        // cannot present it — the two questions the axes keep apart.
        let gvnic = GCE_GVNIC.target().expect("gvnic is spellable since the W2 device-words lane");
        assert!(gvnic.has_bus(Bus::Nvme), "gce-gvnic boots off NVMe");
        assert_eq!(gvnic.nic, Nic::Gvnic);
        gvnic.validate("gce-gvnic").unwrap();
        assert_eq!(GCE_GVNIC.status(), PresetStatus::NeedsRealCloud, "spellable is not mimicable");

        let xen = AWS_XEN_HVM.target().expect("xen blkfront + netfront are spellable since the W2 lane");
        assert!(xen.has_bus(Bus::XenBlk), "aws-xen-hvm boots off blkfront");
        assert_eq!(xen.nic, Nic::XenNetfront);
        assert!(!xen.has_bus(Bus::IdeCdrom), "the Xen HVM medium is an imported image, never a cdrom");
        xen.validate("aws-xen-hvm").unwrap();
        assert_eq!(AWS_XEN_HVM.status(), PresetStatus::NeedsRealCloud);

        // `azure-gen1` is the one shape still unspellable, and on its OS disk:
        // a Gen1 VM boots a real IDE HARD DISK, which the group spells only as
        // a cdrom. That is a genuine gap, not an oversight.
        assert!(AZURE_GEN1.target().unwrap_err().contains("ide"), "a Gen1 OS disk rides IDE, which the group spells only as a cdrom");
        assert!(GCE_VIRTIO.target().is_ok(), "virtio-scsi + virtio-net is spellable");
        assert!(QEMU_LOCAL.target().is_ok());
    }

    /// **Every preset's derivation holds**: a spellable one yields a `Target`
    /// that validates (no serial console without a port, a bus, a NIC), an
    /// unspellable one names the device the group cannot spell, and the
    /// status is derived — `measured` only ever on a mimicable shape.
    #[test]
    fn every_preset_derives_a_valid_target_or_names_why_not() {
        for p in PRESETS {
            match p.target() {
                Ok(t) => {
                    t.validate(p.name).unwrap_or_else(|e| panic!("{}: {e}", p.name));
                    assert_eq!(t.preset, None, "{}: a derived shape names no preset", p.name);
                    assert_eq!(t.uarts, p.uarts.ports().to_vec(), "{}: uarts are the declared ports", p.name);
                    assert_eq!(t.cpu == Cpu::Epyc, matches!(p.cpu, CpuModel::Named(m) if m.starts_with("EPYC")), "{}", p.name);
                    assert_eq!(
                        t.has_bus(Bus::IdeCdrom),
                        p.medium.kernel_medium_bus() == Some(Bus::IdeCdrom),
                        "{}: a bus in the derived group is a driver the KERNEL must carry, never the way the platform hands the medium over",
                        p.name
                    );
                }
                Err(why) => {
                    assert!(p.boot_disk.target_bus().is_none() || p.nic.target_nic().is_none(), "{}: {why}", p.name);
                    assert_eq!(p.gap().is_some(), true, "{}: unspellable implies not mimicable today", p.name);
                }
            }
            // A RIG measurement is only possible on a shape the rig can render;
            // a CLOUD measurement is possible on anything (that is the point of
            // a real deploy) and must NOT be gated on `Mimic::Qemu` — that
            // conflation is what the split undoes.
            if let Some(e) = p.measured {
                match e.on {
                    MeasuredOn::QemuRig => assert!(
                        p.axes().is_renderable(),
                        "{}: claims a qemu-rig measurement of a shape the rig cannot even launch",
                        p.name
                    ),
                    MeasuredOn::RealCloud => {}
                }
                assert!(!e.what.is_empty(), "{}: evidence with no observation", p.name);
            }
            assert_eq!(
                p.status(),
                match (p.measured.map(|e| e.on), p.mimic) {
                    (Some(MeasuredOn::QemuRig), _) => PresetStatus::MimicMeasured,
                    (Some(MeasuredOn::RealCloud), _) => PresetStatus::CloudMeasured,
                    (None, Mimic::Qemu) => PresetStatus::Stub,
                    _ => PresetStatus::NeedsRealCloud,
                }
            );
        }
        // **The split, pinned by name.** ONE cloud has actually been booted;
        // the other two "measured" rows are our own QEMU box. Before 2026-09-05
        // this read `measured = [qemu-local, qemu-local-bios, upcloud]` and
        // said "3 measured", which sounded like three clouds.
        let cloud: Vec<_> = PRESETS.iter().filter(|p| p.status() == PresetStatus::CloudMeasured).map(|p| p.name).collect();
        assert_eq!(cloud, vec!["upcloud"], "the machines we have actually booted on the real platform");
        let rig: Vec<_> = PRESETS.iter().filter(|p| p.status() == PresetStatus::MimicMeasured).map(|p| p.name).collect();
        assert_eq!(rig, vec!["qemu-local", "qemu-local-bios"], "the machines measured on our own QEMU");
        // And the old question still has an answer, for a caller that only
        // wants "is there evidence at all".
        let any: Vec<_> = PRESETS.iter().filter(|p| p.status().is_measured()).map(|p| p.name).collect();
        assert_eq!(any, vec!["qemu-local", "qemu-local-bios", "upcloud"]);
    }

    /// **The Kconfig consequence per preset** — what `Target::kconfig_needs`
    /// says for every spellable machine, symbol by symbol. UpCloud is the row
    /// that matters, and both of its surprises are 2026-09-07 rulings written
    /// down: `SERIAL_8250` is `y` (ttyS1/ttyS2 at 0x2f8/0x3e8 are REAL — only
    /// the ttyS0 nobody has is missing) while `SERIAL_8250_CONSOLE` is ABSENT
    /// (VNC is what anyone reads); and NO `ATA` REQUIREMENT, because the IDE
    /// cdrom is how the PLATFORM hands the medium over and the `nuked` donor
    /// would refuse a consumer row for it. The kernel reads that cdrom
    /// all the same: since tunnr `3f7c2ff` the donor carries PIIX/AHCI + SR in
    /// its own fragment. The virtio twin is the fallback. VT + VGA_CONSOLE, VIRTIO_BLK +
    /// VIRTIO_NET, CPU_SUP_AMD for the EPYC.
    #[test]
    fn kconfig_needs_per_preset() {
        // (preset, symbols that must be `y`, symbols that must be `n`, symbols that must be ABSENT)
        let table: &[(&str, &[&str], &[&str], &[&str])] = &[
            (
                "upcloud",
                &["CONFIG_SERIAL_8250", "CONFIG_SERIAL_EARLYCON", "CONFIG_VT", "CONFIG_VT_CONSOLE", "CONFIG_VGA_CONSOLE", "CONFIG_VIRTIO_BLK", "CONFIG_VIRTIO_PCI", "CONFIG_VIRTIO_NET", "CONFIG_CPU_SUP_AMD"],
                &[],
                &["CONFIG_SERIAL_8250_CONSOLE", "CONFIG_ATA", "CONFIG_ATA_PIIX", "CONFIG_BLK_DEV_SR", "CONFIG_ISO9660_FS", "CONFIG_E1000", "CONFIG_SCSI_VIRTIO"],
            ),
            (
                "qemu-local",
                &["CONFIG_SERIAL_8250", "CONFIG_SERIAL_8250_CONSOLE", "CONFIG_VT", "CONFIG_VGA_CONSOLE", "CONFIG_VIRTIO_BLK", "CONFIG_VIRTIO_NET"],
                &[],
                &["CONFIG_CPU_SUP_AMD", "CONFIG_E1000", "CONFIG_SCSI_VIRTIO", "CONFIG_ATA"],
            ),
            (
                "qemu-local-bios",
                &["CONFIG_SERIAL_8250", "CONFIG_VT", "CONFIG_VGA_CONSOLE", "CONFIG_VIRTIO_BLK", "CONFIG_VIRTIO_NET"],
                &[],
                &["CONFIG_CPU_SUP_AMD", "CONFIG_ATA"],
            ),
            (
                "gce-virtio",
                &["CONFIG_SERIAL_8250", "CONFIG_VT", "CONFIG_SCSI", "CONFIG_BLK_DEV_SD", "CONFIG_SCSI_VIRTIO", "CONFIG_VIRTIO_NET"],
                &[],
                &["CONFIG_ATA", "CONFIG_VIRTIO_BLK", "CONFIG_CPU_SUP_AMD"],
            ),
            (
                "hetzner-cloud",
                &["CONFIG_SERIAL_8250", "CONFIG_VT", "CONFIG_VIRTIO_BLK", "CONFIG_VIRTIO_NET"],
                &[],
                &["CONFIG_CPU_SUP_AMD", "CONFIG_SCSI_VIRTIO", "CONFIG_ATA"],
            ),
            (
                "ovh-public-cloud",
                &["CONFIG_SERIAL_8250", "CONFIG_VT", "CONFIG_VIRTIO_BLK", "CONFIG_VIRTIO_NET"],
                &[],
                &["CONFIG_ATA", "CONFIG_CPU_SUP_AMD"],
            ),
            (
                "scaleway-instance",
                &["CONFIG_SERIAL_8250", "CONFIG_VT", "CONFIG_VIRTIO_BLK", "CONFIG_VIRTIO_NET"],
                &[],
                &["CONFIG_ATA", "CONFIG_CPU_SUP_AMD"],
            ),
            (
                // The aws-nitro lane's row: NVMe block + ENA net, both `y`, and
                // NO virtio/scsi/ata/e1000 at all — Nitro has none of those
                // devices. Serial is real (ttyS0 = EC2 Serial Console), and the
                // cpu makes no vendor claim (Native ⇒ Generic, no CPU_SUP_AMD).
                "aws-nitro",
                &["CONFIG_SERIAL_8250", "CONFIG_SERIAL_8250_CONSOLE", "CONFIG_VT", "CONFIG_VGA_CONSOLE", "CONFIG_NVME_CORE", "CONFIG_BLK_DEV_NVME", "CONFIG_NET", "CONFIG_ETHERNET", "CONFIG_NET_VENDOR_AMAZON", "CONFIG_PCI_MSI", "CONFIG_ENA_ETHERNET", "CONFIG_EFI", "CONFIG_ACPI"],
                &[],
                &["CONFIG_ATA", "CONFIG_VIRTIO_BLK", "CONFIG_SCSI_VIRTIO", "CONFIG_VIRTIO_NET", "CONFIG_E1000", "CONFIG_VIRTIO_MENU", "CONFIG_CPU_SUP_AMD"],
            ),
            (
                // The azure lane's row (2026-09-05): Hyper-V synthetic SCSI +
                // synthetic NIC, both over VMBus (HYPERVISOR_GUEST + HYPERV),
                // and NO virtio/nvme/ata/e1000 — a Gen2 VM has none of those.
                // Serial is real (ttyS0 = Azure Serial Console), UEFI only.
                "azure-gen2",
                &["CONFIG_SERIAL_8250", "CONFIG_SERIAL_8250_CONSOLE", "CONFIG_VT", "CONFIG_VGA_CONSOLE", "CONFIG_HYPERVISOR_GUEST", "CONFIG_HYPERV", "CONFIG_SCSI", "CONFIG_BLK_DEV_SD", "CONFIG_HYPERV_STORAGE", "CONFIG_NET", "CONFIG_HYPERV_NET", "CONFIG_EFI", "CONFIG_ACPI"],
                &[],
                &["CONFIG_ATA", "CONFIG_VIRTIO_BLK", "CONFIG_SCSI_VIRTIO", "CONFIG_NVME_CORE", "CONFIG_VIRTIO_NET", "CONFIG_E1000", "CONFIG_ENA_ETHERNET", "CONFIG_VIRTIO_MENU", "CONFIG_CPU_SUP_AMD"],
            ),
            (
                // The W2 lane's first row (2026-09-05): NVMe boot disk + gVNIC.
                // The whole Kconfig MENU CHAIN above GVE is named, because
                // `olddefconfig` does not refuse a symbol whose parent is
                // missing — it drops it silently. MEASURED on the shipped
                // tunnr-kernel-hyperv config: PCI_MSI=n there, and CONFIG_GVE
                // is absent from the built .config ENTIRELY (not even
                // `# … is not set`), because `depends on PCI_MSI` left it
                // unoffered. NET_VENDOR_GOOGLE=y is in that same file.
                "gce-gvnic",
                &["CONFIG_SERIAL_8250", "CONFIG_SERIAL_8250_CONSOLE", "CONFIG_VT", "CONFIG_VGA_CONSOLE", "CONFIG_NVME_CORE", "CONFIG_BLK_DEV_NVME", "CONFIG_NET", "CONFIG_NETDEVICES", "CONFIG_ETHERNET", "CONFIG_NET_VENDOR_GOOGLE", "CONFIG_PCI_MSI", "CONFIG_GVE", "CONFIG_EFI", "CONFIG_ACPI"],
                &[],
                &["CONFIG_ATA", "CONFIG_VIRTIO_BLK", "CONFIG_SCSI_VIRTIO", "CONFIG_VIRTIO_NET", "CONFIG_E1000", "CONFIG_ENA_ETHERNET", "CONFIG_NET_VENDOR_AMAZON", "CONFIG_HYPERV", "CONFIG_XEN", "CONFIG_VIRTIO_MENU", "CONFIG_CPU_SUP_AMD"],
            ),
            (
                // The W2 lane's second row: the Xen PV frontends, and the guest
                // menu chain they hang off — HYPERVISOR_GUEST → PARAVIRT → XEN,
                // read off linux-6.12.104 (arch/x86/Kconfig:783/795,
                // arch/x86/xen/Kconfig:6). `# CONFIG_XEN is not set` appears in
                // the built tunnr-kernel-hyperv config, which proves XEN is
                // OFFERED there (its deps are met) and merely off — exactly the
                // symbol a requirement can turn on.
                //
                // NO ethernet-vendor rows: netfront is drivers/net/xen-netfront.c,
                // sourced straight from drivers/net/Kconfig, not under ETHERNET.
                "aws-xen-hvm",
                &["CONFIG_SERIAL_8250", "CONFIG_SERIAL_8250_CONSOLE", "CONFIG_VT", "CONFIG_VGA_CONSOLE", "CONFIG_HYPERVISOR_GUEST", "CONFIG_PARAVIRT", "CONFIG_XEN", "CONFIG_XEN_BLKDEV_FRONTEND", "CONFIG_NET", "CONFIG_NETDEVICES", "CONFIG_XEN_NETDEV_FRONTEND", "CONFIG_EFI", "CONFIG_ACPI"],
                &[],
                &["CONFIG_ATA", "CONFIG_VIRTIO_BLK", "CONFIG_SCSI_VIRTIO", "CONFIG_NVME_CORE", "CONFIG_VIRTIO_NET", "CONFIG_E1000", "CONFIG_ENA_ETHERNET", "CONFIG_ETHERNET", "CONFIG_HYPERV", "CONFIG_GVE", "CONFIG_VIRTIO_MENU", "CONFIG_CPU_SUP_AMD"],
            ),
        ];
        let mut covered = std::collections::BTreeSet::new();
        for (name, yes, no, absent) in table {
            covered.insert(*name);
            let needs = preset(name).unwrap().target().unwrap().kconfig_needs();
            let find = |s: &str| needs.iter().find(|(sym, _, _)| *sym == s).map(|(_, on, _)| *on);
            for s in *yes {
                assert_eq!(find(s), Some(true), "{name}: {s} must be y — rows: {needs:?}");
            }
            for s in *no {
                assert_eq!(find(s), Some(false), "{name}: {s} must be n — rows: {needs:?}");
            }
            for s in *absent {
                assert_eq!(find(s), None, "{name}: {s} must not be asked for — rows: {needs:?}");
            }
            for (sym, _, why) in &needs {
                assert!(!why.is_empty(), "{name}: {sym} has no why");
            }
            assert!(
                !needs.iter().any(|(s, _, _)| *s == "CONFIG_ISO9660_FS"),
                "{name}: the medium is ISO-9660 whichever DEVICE it arrives on — that row belongs to the appliance-boot contract, never to a bus, or a machine that reads the ISO off virtio silently loses it"
            );
        }
        // Every spellable preset has a row in this table; nothing is silently untested.
        let spellable: std::collections::BTreeSet<_> = PRESETS.iter().filter(|p| p.target().is_ok()).map(|p| p.name).collect();
        assert_eq!(spellable, covered, "a spellable preset without a Kconfig expectation");
    }

    /// **A preset whose closure the donor kernel vetoes is refused BY NAME.**
    ///
    /// The same shape as the `CONFIG_ATA` / ide-cdrom refusal in
    /// `requires.rs`, asserted here on the preset roster rather than on a
    /// hand-spelled `target` group. The `nuked` overlay states its absences
    /// (`# CONFIG_SCSI is not set`, `# CONFIG_ATA is not set`), and a
    /// requirement is never merged over a veto.
    ///
    /// Honest about what this can and cannot show (LAW 7): `nuked` vetoes
    /// `SCSI` and `ATA` and nothing else that these presets need, so
    /// **azure-gen2 is the only one of the three that this kernel can refuse**.
    /// For `gce-gvnic` and `aws-xen-hvm` the assertion is the other half of the
    /// same contract — that the closure NAMES the symbol at all, which is what
    /// makes a future veto refusable. A test that claimed all three were
    /// refused would be asserting a red that cannot fire.
    #[test]
    fn a_preset_closure_the_nuked_kernel_vetoes_is_refused_by_name() {
        use crate::kernel::KernelBuild;
        use crate::kernel_requires::{KconfigReq, KernelRequirements};

        // The closure of a preset, as the requirement machinery would place it.
        let reqs_of = |name: &str| {
            let t = preset(name).unwrap().target().unwrap();
            let mut r = KernelRequirements::default();
            for (sym, on, why) in t.kconfig_needs() {
                let req = if on { KconfigReq::y(sym, &why) } else { KconfigReq::n(sym, &why) };
                r.require(&format!("gunnar/{name}"), "target", &req);
            }
            r
        };
        let nuked = || KernelBuild {
            name: "tunnr-kernel".into(),
            version: "6.12.104".into(),
            tarball_sha256: "0".repeat(64),
            preset: "nuked".into(),
            ..Default::default()
        };

        // RED: azure-gen2 rides Hyper-V synthetic SCSI, and `nuked` says
        // `# CONFIG_SCSI is not set`. The refusal must NAME the symbol.
        let err = format!("{:#}", nuked().apply_requirements(&reqs_of("azure-gen2")).unwrap_err());
        assert!(err.contains("CONFIG_SCSI"), "the refusal must name the symbol: {err}");
        assert!(err.contains("nuked"), "the refusal must name the preset that vetoes it: {err}");

        // GREEN, same input, kernel that grants it: proof the red above is the
        // VETO firing and not the closure being malformed.
        let mut normal = KernelBuild { preset: "normal".into(), ..nuked() };
        normal.apply_requirements(&reqs_of("azure-gen2")).unwrap();
        assert!(normal.requirements.as_ref().unwrap().rows.contains_key("CONFIG_HYPERV_STORAGE"));

        // The other two: `nuked` vetoes nothing they need, so they are ACCEPTED
        // — stated out loud so nobody later reads this test as proving a
        // refusal it never saw.
        for (name, symbol) in [("gce-gvnic", "CONFIG_GVE"), ("aws-xen-hvm", "CONFIG_XEN_BLKDEV_FRONTEND")] {
            let r = reqs_of(name);
            assert!(r.rows.contains_key(symbol), "{name}: the closure must name {symbol}");
            let mut k = nuked();
            k.apply_requirements(&r).unwrap_or_else(|e| panic!("{name}: nuked vetoes none of its symbols, so this must pass: {e:#}"));
        }
    }

    /// The historical shape renders no `-cpu` at all (qemu64), so nothing
    /// built before presets changes its argv.
    #[test]
    fn qemu_local_has_no_cpu_flag() {
        assert_eq!(QEMU_LOCAL.qemu_shape().unwrap().cpu, None);
        assert_eq!(UPCLOUD.qemu_shape().unwrap().cpu, Some("EPYC-Rome"));
    }

    /// **The two verdicts must agree.** The declared `mimic` word and the axes
    /// derived from the preset's own device words are two sources of truth, and
    /// this is where they are made to face each other.
    ///
    /// It found a real lie the day it was written: `aws-xen-hvm` declared
    /// `NeedsRealCloud("xen blkfront/netfront need a Xen hypervisor, not
    /// QEMU/KVM")` while QEMU 10.2.1 on oden lists `xen-disk`, `xen-net-device`,
    /// `xen-cdrom`, `xen-console` and `xen-platform`. One row, unprovable for a
    /// year, on a sentence nobody re-measured.
    #[test]
    fn the_declared_mimic_agrees_with_the_derived_axes() {
        let mut wrong = Vec::new();
        for p in PRESETS {
            if !p.mimic_agrees_with_axes() {
                wrong.push(format!(
                    "{}: declared {:?} but axes are {:?} (substitutions {:?}, absent {:?})",
                    p.name,
                    p.mimic,
                    p.axes().is_exact(),
                    p.axes().substitutions(),
                    p.axes().absent(),
                ));
            }
        }
        assert!(wrong.is_empty(), "declared mimic disagrees with the device words:\n{}", wrong.join("\n"));
    }

    /// A preset QEMU models exactly must have NOTHING to substitute — that is
    /// what "exactly" means, and it is the property a KVM green rests on.
    #[test]
    fn an_exactly_mimicable_preset_substitutes_nothing() {
        for p in PRESETS {
            if p.axes().is_exact() {
                assert!(
                    p.axes().substitutions().is_empty(),
                    "{} is exact but substitutes {:?}",
                    p.name,
                    p.axes().substitutions()
                );
                assert!(p.axes().is_renderable(), "{} is exact but not renderable", p.name);
            }
        }
    }

    /// **Every substitution names a device QEMU really has.** A stand-in that is
    /// itself not a QEMU device would make a row claim a boot it cannot launch.
    /// The `with` words are checked against the ones the exact arms produce, so
    /// the two halves of the table cannot drift apart.
    #[test]
    fn every_substitute_names_a_device_qemu_actually_models() {
        let real: std::collections::BTreeSet<&str> = PRESETS
            .iter()
            .flat_map(|p| [p.boot_disk.qemu_mimic(), p.nic.qemu_mimic(), p.chipset.qemu_machine()])
            .flatten()
            .chain(["virtio-scsi-pci", "virtio-net-pci", "q35"])
            .collect();
        for p in PRESETS {
            for (facet, missing, with) in p.axes().substitutions() {
                assert!(
                    real.contains(with),
                    "{}: {facet} stands {missing} in as `{with}`, which is not a device this \
                     table ever renders",
                    p.name
                );
                assert_ne!(missing, with, "{}: {facet} substitutes a device for itself", p.name);
            }
        }
    }

    /// Bare metal is the one shape nothing stands in for, and it must say so on
    /// more than one axis — a `Metal` preset whose only complaint is its medium
    /// would read as "almost mimicable", which it is not.
    #[test]
    fn bare_metal_is_absent_not_substituted() {
        let metal = preset("scaleway-elastic-metal").expect("the metal row");
        let axes = metal.axes();
        assert!(!axes.is_renderable(), "metal cannot be rendered at all");
        assert!(
            axes.absent().len() >= 3,
            "firmware, chipset and the devices are all the vendor's: {:?}",
            axes.absent()
        );
        assert!(axes.substitutions().is_empty(), "nothing stands in for metal");
    }



    /// **The roster, pinned BY NAME.** Counts move for the wrong reasons — a
    /// row added, a row renamed — and `left: 7 / right: 6` says a number changed
    /// and nothing about WHICH machine did. These three sets are the answer to
    /// "what can this box actually prove", and the day one moves it should be
    /// because someone measured something.
    ///
    /// The shape as of 2026-09-05, and it is the whole argument of the proof
    /// ladder: **exactly one** preset cannot be rendered under QEMU at all.
    /// Every other cloud is reachable with its missing devices NAMED.
    #[test]
    fn the_mimicable_roster_is_pinned_by_name() {
        let exact: Vec<&str> = PRESETS.iter().filter(|p| p.axes().is_exact()).map(|p| p.name).collect();
        assert_eq!(
            exact,
            vec![
                "qemu-local",
                "qemu-local-bios",
                "upcloud",
                "gce-virtio",
                "hetzner-cloud",
                "ovh-public-cloud",
            ],
            "the machines a KVM green means literally"
        );

        let substituted: Vec<&str> = PRESETS
            .iter()
            .filter(|p| p.axes().is_renderable() && !p.axes().is_exact())
            .map(|p| p.name)
            .collect();
        assert_eq!(
            substituted,
            vec![
                "scaleway-instance",
                "aws-xen-hvm",
                "aws-nitro",
                "gce-gvnic",
                "azure-gen1",
                "azure-gen2",
            ],
            "the machines a KVM run proves the SHAPE of, substitutions named"
        );

        let absent: Vec<&str> = PRESETS.iter().filter(|p| !p.axes().is_renderable()).map(|p| p.name).collect();
        assert_eq!(absent, vec!["scaleway-elastic-metal"], "metal is the only true wall");
    }

    /// The two facts this rung rests on, each asserted alone so a regression
    /// names itself rather than moving a count.
    #[test]
    fn nitros_boot_disk_and_azures_are_proven_devices_not_stand_ins() {
        let nitro = preset("aws-nitro").unwrap().axes();
        assert_eq!(
            nitro.disk,
            MimicAxis::Exact("nvme"),
            "QEMU models NVMe; Nitro's boot disk drives the guest's real \
             CONFIG_BLK_DEV_NVME path and must never be counted as a stand-in"
        );
        assert!(
            nitro.substitutions().iter().any(|(f, m, _)| *f == "nic" && *m == "ena"),
            "ENA is the one Nitro device that genuinely needs the real cloud"
        );

        // **The correction OF the correction, measured 2026-09-05.** A previous
        // lane read `-device help`, saw `xen-disk` and `xen-net-device`, and
        // made both axes `Exact`. They are not: this QEMU has no `xen`
        // accelerator and no machine with `xen-version`, so no `xen-bus` is
        // ever created and neither device can be instantiated
        // (`No 'xen-bus' bus found for device 'xen-disk'`). A device in a
        // listing is not a device on a bus.
        let xen = preset("aws-xen-hvm").unwrap().axes();
        assert_eq!(xen.disk, MimicAxis::Substitute { missing: "xen-blk", with: "virtio-scsi-pci" });
        assert_eq!(xen.nic, MimicAxis::Substitute { missing: "xen-netfront", with: "virtio-net-pci" });
        assert_eq!(
            xen.substitutions().len(),
            3,
            "chipset, disk AND nic all stand in for aws-xen-hvm: {:?}",
            xen.substitutions()
        );
    }


    /// **Ask QEMU, do not trust the comment.**
    ///
    /// Every device word this table calls `Exact` must appear in the local
    /// `qemu-system-x86_64 -device help`, and every word it calls missing must
    /// NOT. This is the guard that would have caught `aws-xen-hvm` on the day it
    /// was written: its `NeedsRealCloud` sentence asserted a fact about QEMU
    /// that a one-line command disproves, and for a year nobody ran the command.
    ///
    /// `#[ignore]` because it needs a QEMU on PATH and this crate must build on
    /// hosts without one — but it SKIPs loudly rather than passing when QEMU is
    /// missing, so an absent binary can never look like a clean result.
    ///
    /// ```bash
    /// cargo test -p nornir-build-thing --lib target::presets -- --ignored --nocapture
    /// ```
    #[test]
    #[ignore = "needs qemu-system-x86_64 on PATH: asks the real binary which devices it models"]
    fn the_device_words_match_what_this_qemu_actually_models() {
        let out = match std::process::Command::new("qemu-system-x86_64")
            .arg("-device")
            .arg("help")
            .output()
        {
            Ok(o) => o,
            Err(e) => {
                eprintln!("SKIP: no qemu-system-x86_64 on PATH ({e})");
                return;
            }
        };
        let listing = format!(
            "{}{}",
            String::from_utf8_lossy(&out.stdout),
            String::from_utf8_lossy(&out.stderr)
        );
        assert!(
            listing.contains("name \""),
            "SKIP-PROOF: `-device help` produced nothing that looks like a device \
             listing, so a green here would mean nothing:\n{listing}"
        );
        let models = |dev: &str| listing.contains(&format!("name \"{dev}\""));

        /// Every name a device we call MISSING might appear under in
        /// `-device help`. Without this the probe can only confirm what we
        /// already claim, which is the shape of a guard that cannot report red.
        ///
        /// Measured on oden 2026-09-05 (QEMU 10.2.1): none of these exist, but
        /// `vmbus-bridge` and `hv-balloon` DO — the VMBus itself is emulated,
        /// so a guest can be proven to find and enumerate the bus even though
        /// neither synthetic leaf driver has a model. That is why Azure is two
        /// missing devices and not a missing platform.
        fn qemu_names_to_watch_for(missing: &str) -> &'static [&'static str] {
            match missing {
                "ena" => &["ena", "ena-pci"],
                "gvnic" => &["gve", "gvnic", "gve-pci"],
                "hv-netvsc" => &["netvsc", "hv-netvsc", "vmbus-netvsc"],
                "hv-scsi" => &["storvsc", "hv-storvsc", "vmbus-scsi", "hv-scsi"],
                _ => &[],
            }
        }

        // Machine types are not devices; the chipset axis is checked by
        // `-machine help` elsewhere and is deliberately not asserted here.
        for p in PRESETS {
            if let MimicAxis::Exact(d) = p.axes().disk {
                assert!(models(d), "{}: disk `{d}` is called Exact but this QEMU has no such device", p.name);
            }
            if let MimicAxis::Exact(n) = p.axes().nic {
                assert!(models(n), "{}: nic `{n}` is called Exact but this QEMU has no such device", p.name);
            }
            for (facet, missing, with) in p.axes().substitutions() {
                if facet == "chipset" {
                    continue;
                }
                assert!(models(with), "{}: stand-in `{with}` is not a device this QEMU has", p.name);
                // The word `missing` is OUR name for the device, not QEMU's, so
                // `!models(missing)` proves nothing on its own — that blind spot
                // is exactly how the Xen row survived. Check every name this
                // device could plausibly go by instead, so the day QEMU grows a
                // model the substitution stops being free.
                for candidate in qemu_names_to_watch_for(missing) {
                    assert!(
                        !models(candidate) || !attachable(candidate),
                        "{}: {facet} substitutes `{missing}` -> `{with}`, but THIS QEMU models \
                         `{candidate}` AND can attach it. The substitution is costing real \
                         coverage — measure it and make the axis Exact.",
                        p.name
                    );
                }
            }
        }
    }

    /// **A device in `-device help` is not a device on a bus.**
    ///
    /// This is the guard the listing-only probe above could never be, and the
    /// reason it exists is that the listing-only probe RATIFIED A LIE. On
    /// 2026-09-05 a lane grepped `-device help`, found `xen-disk` and
    /// `xen-net-device`, concluded that a year-old
    /// `NeedsRealCloud("xen blkfront/netfront need a Xen hypervisor")` sentence
    /// was folklore, and made both axes `Exact`. The listing was real and the
    /// conclusion was wrong: `-device help` enumerates every compiled-in model
    /// whether or not this build can create the bus it hangs on.
    ///
    /// MEASURED on oden, QEMU 10.2.1 (`-accel help` → `tcg mshv kvm`, no
    /// `xen`; `-machine q35,xen-version=…` → property not found):
    ///
    /// ```text
    /// -device virtio-blk-pci,zzprobe=1 → Property 'virtio-blk-pci.zzprobe' not found   ← attachable
    /// -device xen-disk,zzprobe=1       → No 'xen-bus' bus found for device 'xen-disk'  ← NOT
    /// ```
    ///
    /// So the probe asks QEMU to actually BUILD each device, with a property
    /// name that cannot exist. A device that resolves its bus gets as far as
    /// rejecting the property; one that does not, names the missing bus. The
    /// bogus property is what makes this fast and side-effect-free — QEMU exits
    /// on the error instead of starting a machine.
    ///
    /// `#[ignore]` for the same reason as its sibling: it needs a QEMU on PATH,
    /// and it SKIPs loudly rather than passing when there is none.
    ///
    /// ```bash
    /// cargo test -p nornir-build-thing --lib target::presets -- --ignored --nocapture
    /// ```
    #[test]
    #[ignore = "needs qemu-system-x86_64 on PATH: asks the real binary to attach each device"]
    fn the_device_words_are_attachable_on_this_qemu() {
        if qemu_device_help().is_none() {
            eprintln!("SKIP: no qemu-system-x86_64 on PATH");
            return;
        }
        // Self-check FIRST: the probe must be able to say both words. If
        // `virtio-blk-pci` (a device this QEMU certainly has) does not come back
        // attachable, the probe is broken and every green below is meaningless
        // — the exact failure mode that let the Xen row through.
        assert!(
            attachable("virtio-blk-pci"),
            "PROBE-PROOF: virtio-blk-pci must be attachable on any QEMU; the probe cannot report green"
        );
        assert!(
            !attachable("no-such-device-zz"),
            "PROBE-PROOF: a device that does not exist must not read as attachable"
        );

        for p in PRESETS {
            if let MimicAxis::Exact(d) = p.axes().disk {
                assert!(
                    attachable(d),
                    "{}: disk `{d}` is called Exact but this QEMU cannot attach it — a model in \
                     `-device help` with no bus is not a device a guest can bind to",
                    p.name
                );
            }
            if let MimicAxis::Exact(n) = p.axes().nic {
                assert!(attachable(n), "{}: nic `{n}` is called Exact but this QEMU cannot attach it", p.name);
            }
            for (facet, _missing, with) in p.axes().substitutions() {
                if facet == "chipset" {
                    continue;
                }
                assert!(attachable(with), "{}: stand-in `{with}` cannot be attached on this QEMU", p.name);
            }
        }
    }


    /// **A dual-attach medium is a PLATFORM fact; `target.buses` is a KERNEL
    /// fact. Deriving the second from the first is what this pins against.**
    ///
    /// RED until 2026-09-07: [`TargetPreset::target`] inserted `Bus::IdeCdrom`
    /// for every `MediumBring::IsoCdrom` row, so naming such a machine put
    /// `CONFIG_ATA`, `ATA_PIIX` and `BLK_DEV_SR` on the donor kernel's edge —
    /// and the shared donor `tunnr/tunnr-kernel` is the `nuked` preset, whose
    /// fragment says `# CONFIG_ATA is not set`. The build did not get a bigger
    /// kernel; it got *"a consumer requires what the preset vetoes"* and
    /// stopped. Four gunnar installer rows carried `preset: None` for a month
    /// because of it.
    ///
    /// **The live appliance is the disproof.** `tunnr-kernel`'s shipped
    /// `kernel.config` says `# CONFIG_ATA is not set`, and that kernel booted
    /// off this very ISO on UpCloud (measured 2026-09-07, gunnar.rs). It can,
    /// because the medium rides TWICE: as an IDE cdrom, which only SeaBIOS ever
    /// reads — firmware reading an El-Torito cdrom needs no kernel driver at
    /// all — and as a second copy of the same ISO on virtio, which is where
    /// Linux and `korp-installer` find the ISO-9660 `CD001` magic
    /// (`gunnar/deploy/upcloud/src/machine.rs`: the installer probes ONLY
    /// virtio, and `INSTALLER: volume: no block device carries the ISO-9660
    /// magic (CD001) … (probed: loop1 … vda)` is what a cdrom-only attach
    /// prints before it dies).
    ///
    /// **That was the state until 2026-09-21, and what still holds of it is
    /// the requirement, not the kernel.** The probe never looked only at virtio;
    /// what was missing was the kernel. Since tunnr `3f7c2ff` the appliance
    /// donors carry `ATA_PIIX`, `SATA_AHCI` and `BLK_DEV_SR` in their OWN
    /// fragment. That is a donor choice merged after the preset, not a consumer
    /// row, so the `nuked` veto is not contradicted. korp-installer ≥ 0.1.14 asks
    /// `sr*` first, and a cdrom-only medium installs under `-machine pc` (IDE)
    /// and q35 (AHCI) on mock-upcloud-kvm. The virtio copy remains a fallback
    /// for older media. What this test pins is unchanged and still true: no
    /// PRESET derives `ide-cdrom`, so no consumer places ATA against `nuked`.
    #[test]
    fn an_iso_attach_medium_asks_the_kernel_for_no_ata() {
        // The bus the kernel must drive to read the medium — `None` for every
        // way a medium reaches a platform today, and each arm says why.
        assert_eq!(MediumBring::IsoCdrom.kernel_medium_bus(), None);
        assert_eq!(MediumBring::ImportQcow2.kernel_medium_bus(), None);
        assert_eq!(MediumBring::Metal("dd").kernel_medium_bus(), None);

        // UpCloud: the machine that cost the two lanes. virtio-blk alone.
        let t = UPCLOUD.target().unwrap();
        assert_eq!(t.buses, vec![Bus::VirtioBlk], "the cdrom is the firmware's, not the kernel's");
        for (sym, on, _) in t.kconfig_needs() {
            assert!(
                !matches!(sym, "CONFIG_ATA" | "CONFIG_ATA_PIIX" | "CONFIG_BLK_DEV_SR"),
                "{sym} = {on} would meet the `nuked` donor's veto"
            );
        }

        // And it is not one row's exemption: NO preset derives an ide-cdrom
        // from the way its platform hands a medium over.
        for p in PRESETS {
            if let Ok(t) = p.target() {
                assert!(
                    !t.has_bus(Bus::IdeCdrom),
                    "{}: `{}` is how the PLATFORM brings the medium, not a driver the kernel carries",
                    p.name,
                    p.medium.describe()
                );
            }
        }

        // The platform fact itself is UNCHANGED and still asked by name — the
        // deploy door attaches two storages off exactly this word.
        assert!(UPCLOUD.medium.is_iso_attach() && UPCLOUD.qemu_shape().unwrap().medium_as_cdrom);
    }
    /// `-device help`, or `None` when there is no QEMU to ask.
    #[cfg(test)]
    fn qemu_device_help() -> Option<String> {
        let out = std::process::Command::new("qemu-system-x86_64").arg("-device").arg("help").output().ok()?;
        let listing = format!("{}{}", String::from_utf8_lossy(&out.stdout), String::from_utf8_lossy(&out.stderr));
        listing.contains("name \"").then_some(listing)
    }

    /// **Can this QEMU actually create the device?** Asks it to, with a
    /// property that cannot exist, and reads which error comes back:
    /// a `Property '<dev>.zzprobe' not found` means the device resolved its bus
    /// and got as far as its properties; anything else (`No '<x>-bus' bus
    /// found`, `requires a Xen guest`, an unknown device) means it did not.
    #[cfg(test)]
    fn attachable(device: &str) -> bool {
        let Ok(out) = std::process::Command::new("qemu-system-x86_64")
            .args(["-machine", "q35", "-display", "none", "-S", "-monitor", "none", "-serial", "none"])
            .arg("-device")
            .arg(format!("{device},zzprobe=1"))
            .output()
        else {
            return false;
        };
        let said = format!("{}{}", String::from_utf8_lossy(&out.stdout), String::from_utf8_lossy(&out.stderr));
        said.contains(&format!("Property '{device}.zzprobe' not found"))
    }
}