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

nordisk/dwarves

.nornir/build-thing-target-facts.md

build thing — target facts (firmware · consoles · buses · nic) — design

Class: design · Function axis: f0 the target setting group · f1 where it is declared · f2 who consumes it and the typed consequence per typ · f3 the proof door Strict: states only what the target group IS. Refines build-thing-code-is-source-design.md (typed consequence, f2) and build-thing-model-design.md (settings tree, f1). Written 2026-08-29 after the UpCloud lanes: three platform facts were declared NOWHERE and each cost a blind lane against a SeaBIOS-only, UART-less, IDE-cdrom host.

An appliance medium is built FOR a machine shape, and that shape is a setting group on the installer variant, not folklore in a shell script. The facts are: which firmware starts the medium, which consoles exist, which buses carry the medium and the target disk, and which nic model the guest sees. Every one is a typed input to a build, and every one has a typed consequence.

The group (f0) — target.* on [[build.installer]]

path values default why the default
target.firmware uefi · seabios · both both today's medium boots both (edda 39cb702); nothing built today changes
target.consoles list of serial · vga (order = console= order, LAST is /dev/console) [vga, serial] today's cmdline console=tty0 console=ttyS0,115200
target.buses set of ide-cdrom · virtio-blk · virtio-scsi {ide-cdrom, virtio-blk} UpCloud attaches the ISO as IDE cdrom; the nuked kernel vetoes ATA, so the medium must ALSO ride virtio-blk
target.nic virtio · e1000 virtio the only NIC an appliance initramfs can drive today (VIRTIO_NET=y)

Where it is declared (f1)

One place: edda nornir-build-thing, installer.rs → InstallerBuild.target: Target (target.rs). #[serde(default)] and skipped when default, so a published 0.1.x reader loads an old recipe unchanged and an emitted toml only carries the row when something was chosen. Each repo's impl BuildThing sets it in Rust; the toml row [build.installer.target] firmware = "both" is the EMITTED description, never read back as authority. gunnar's mirror crate pins the published 0.1.10 and cannot spell the field until the pin advances — the same gap options/fixtures already live in — so until then gunnar's committed toml carries the row explicitly and recipe.rs names the gap.

Who consumes it, and the typed consequence (f2)

consumer toggle consequence (typed)
installer recipe (edda korp-installer::isocompose, the ONE composer) firmware=both El-Torito: EFI section (efiboot.img) and the real BIOS default entry (korp-boot-bios stage, patch table → vmlinuz + bios/initrd by LBA). Target disk gets MBR code + korpbios.bin on its ESP
firmware=uefi EFI section only; the BIOS default entry is the refusal stub (BIOSREF.BIN: "This medium boots UEFI only …") — SeaBIOS prints one sentence and halts instead of running FAT bytes. No BIOS stage staged, no MBR code laid
firmware=seabios BIOS stage laid; the ESP is still composed (the target disk's korpbios.bin lives there) but the medium's EFI El-Torito section is dropped — IsoFormat::Bios
consoles the console= tokens on the installer AND installed cmdline, in declared order; a list without serial puts tty0 last (= /dev/console), without vga puts ttyS0 alone. Empty list is refused by name (a boot nobody can see)
buses, nic the KVM install proof's attachment argv (kvm_disk_args + medium attachment): ide-cdrom → -cdrom; virtio-blk → the medium ALSO as a read-only virtio drive, target disk FIRST (vda); nic → the -device model
tunnr kernel recipe (Kconfig closure, when tunnr gets its impl) consoles ∋ serial SERIAL_8250 SERIAL_8250_CONSOLE in; absent → out
consoles ∋ vga VT VT_CONSOLE VGA_CONSOLE PRINTK in (VT selects INPUT); absent → out. kernel::PID1_BOOT_CONTRACT still refuses a .config with NEITHER console
buses ide-cdrom → ATA ATA_PIIX BLK_DEV_SR ISO9660_FS; virtio-blk → VIRTIO_BLK VIRTIO_PCI VIRTIO_PCI_LEGACY; virtio-scsi → SCSI_VIRTIO SCSI BLK_DEV_SD
nic virtio → VIRTIO_NET; e1000 → E1000
installtest (gunnar, the proof door) --firmware uefi|seabios the qemu MACHINE: q35 + OVMF pflash pair vs pc (SeaBIOS, no pflash). --serial none = no UART at all (UpCloud). Attachments follow buses: target virtio disk first, ISO as IDE cdrom AND virtio raw, nic count 2 (UpCloud: public + utility)

The consequence is measured, not asserted: firmware → which El-Torito entries the writer laid (IsoLayout.describe()); consoles → the cmdline read back off the installed ESP (korp/cmdline); kernel → the bzImage blake3 delta per group.

The proof door (f3) — gunnar-installtest installer --firmware seabios [--serial none] --iso PATH

B1 install (-boot d, -no-reboot ⇒ qemu exits at the installer's reboot; gate = INSTALL-OK on serial OR, with --serial none, the protective MBR + korp/cmdline read back off the target) → B2 boot the installed disk alone, probe SSH-2.0-gunnar on hostfwd :2222 and a TCP accept on :50051 → B3 SIGKILL (power cut), boot again, same probe. Timings per leg are the arm's stages. The boot doors are korp_installer::kvmproof (Machine = firmware + serial + memory → argv), the SAME writer the UEFI installer proof uses — one harness, two firmware shapes. The hand-rolled seabios-proof.sh this replaced is the measurement this door reproduces.

What is left, named