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

mikronova/draupnir

.nornir/build-thing-design.md

draupnir's build thing — what the recipe declares, and why

The code is the source (lane AG, 2026-08-30). crates/draupnir-build-thing is draupnir's impl BuildThing; .nornir/build-variants.toml is emitted from it and read back as authority by nothing:

cargo run -p draupnir-build-thing -- emit      # regenerate the file
cargo run -p draupnir-build-thing -- toml      # the emission, on stdout
cargo run -p draupnir-build-thing -- --list    # the roster and its cargo argv

Editing the toml changes nothing; the next emit deletes the edit. tests/toml_parity.rs fails for any reason the file and the code differ.

What it declares

Three rows, and all three are the same artifact: draupnir ships no executable. It is one crate with one [lib] and no [[bin]] — the boot/provisioning library (BootSpec/Machine, validation, the three backend seams, the fleet fan-out) that jera and Skidbladnir link in-process.

variant features what it is
draupnir ⭐ — PURE std: trait surface, types, validation, fleet fan-out, zero dependencies
draupnir-seed seed plus the pure-Rust fatfs NoCloud seed-image authoring (the file-set render and seed-dir output are always compiled)
draupnir-tunnr backend-tunnr plus the live KVM wire over tunnr's boot_test; pulls seed, because the KVM adapter authors the seed image it attaches

Every row says linkage = "not-applicable". That is a declaration, not an omission: a library is linked by whoever consumes it and composes nothing, so the fat/thin axis has no answer — and an omitted key reads as the fat default, i.e. a self-containment claim nobody checked.

Why the recipe is this small

Because the build is. The 2026-07-30 suite inventory listed draupnir (CLI/server) and fleet_boot (daemon) as binaries; measured against the crate, neither exists. Those names are recorded in recipe.rs's doc comment rather than invented as phantom [[bin]] targets — an over-declared recipe is worse than none, because it lies with more detail. recipe.rs's own test no_row_declares_a_binary_because_this_repository_has_none holds that.

The four features nothing here builds

backend-oci, backend-youki, backend-redfish and redfish-server are real and no row turns them on. They are in [build.allow_unbuilt] with the reason, so the gap is a written decision rather than a silence. The reason is the same for the three backends — a backend is a consumer's choice about which wire it compiles in, and draupnir ships no artifact per backend to choose between. backend-tunnr has a row only because it is the one backend whose dependency is a PATH dep (tunnr-vm, not yet published), so whether it still compiles is a question about this repository. redfish-server is excused separately: it is a listening socket, deliberately not implied by backend-redfish, and a client-only build must not grow a server.

recipe.rs::every_offer_is_either_built_or_excused_by_name makes an unexcused gap impossible.