build thing model — the plan (2026-08-26)
The dated plan for closing the gaps in build-thing-model-design.md. Waves, not a backlog: each wave is one or two lanes with a named acceptance, and a wave starts when the wave it builds on has pushed. Vocabulary: variant → features on the variant → settings / sub-settings → typ. Never "cell".
Wave 0 — done today
| what | where | proof |
| the bijection laws A–E in the trait, every impl gated | edda laws.rs 0.1.9 (published), holger / gunnar (both mirrors) / dwarves / knut |
assert_bijective green in each suite |
| the kernel donor edge, both doors | edda InstallerBuild.kernel_donor + resolve_built_kernel; dwarves CLI + ⚒ |
live refusal: "pin preset 'nuked' (d437b919…) ≠ choice (bd2d9dbc…)"; with the veto: resolved |
| the kernel leaf absent until a kernel answer | facett NavState.absent, dwarves leaf_absent |
robot_the_kernel_leaf_does_not_exist_in_the_shipped_shell_until_declared |
| the embed budget gate tells the truth | nornir embed.rs |
draupnir committed 17.6 min vs 21.5 projected |
| the model written down | this directory | — |
Wave 1 — running (started 2026-08-26 evening)
Lane edda — the tree and the ABI (gaps #1, #2, law C)
- types first: one recursive node, kinds feature / setting / val, paths as ids, edges; derived from today's flat
OptionSpec/ParamSpec/kernel_donorwith no toml change; flat names accepted as unambiguous aliases. Pushed early so the ⚒ lane can build on it. - the trait answers:
options(path),try_toggle(path, on)(the kernel cascade is tunnr's answer),actions(kind)(the kind → verb table as data) — with defaults, over the wasm ABI, plus the one host importfetch(coordinate) → bytes; a test proves native and wasm32 give identical answers. - law C as path ↔ flag, law B as tree node ↔ declaration row. Acceptance: 0.1.10 (not published), all existing gates green, holger green.
Lane ⚒ — the pane reads the code (gaps #9, #6, #7, honesty) A. ⚒ loads and CALLS the build thing's wasm through the same loader as the CLI; a repo without a build-thing crate is refused by name (the toml is the named fallback, never a silent second path). Law B proven across the two doors. B. the settings tree renderer — every node shows its path and the flag it equals; kärna is a node whose detail is the kconfig canvas; the kernel leaf retired as a concept; the four shapes (nothing / library / donor / own kernel) re-proven. C. the honesty label on the canvas (edda's ~80 fragment symbols, prefix edges); verbs off the receipt's typ via actions(kind). D. options / try_toggle / actions over wasm wired; fetch fulfilled by the host, refused by name otherwise. Acceptance: release binaries rebuilt into ~/.local/bin (dwarves-ui-gpu, dwarves-ui); Rickard's four clicks.
Lane korp — lawful (gap #8, free-standing) korp-build-thing crate in korp, both mirrors held by parity, assert_bijective in its suite; korp-appliance-iso still names no kernel edge (that is Rickard's product decision — the refusal says so).
Wave 2 — after edda stage 2 has pushed
Lane edges (gap #3): the consumption edge generalised — any feature bound to repo/variant : typ, type-checked at declaration time; IsoBuild gets the same edge so gunnar-appliance-iso consumes tunnr/tunnr-kernel; korp's iso stays edgeless until told; the ONE reader stays one.
Lane presets (gap #5): val at a variant's root (preset = airgap = a bundle of choices); pin lookup for a preset's built kernel in the suite warehouse / ledger instead of tunnr/.kernel-out; picking a preset with no vetoes costs no build.
Wave 3 — after wave 2
Lane --build (gap #4): --build <path|coordinate> builds the consumed build thing as a step with its own --opt, in ⚒ and on the prompt; the order is the edge DAG and runa runs it (the build-pipeline DAG already exists — see build-pipeline-dag.md); the step console shows the donor build honestly (minutes cold, ~145 s cached). The "never builds the donor's kernel" rule is retired the day this lands.
Two rules over every wave (Rickard, 2026-08-26 evening)
- Benches, not only tests. Tree derivation,
resolve(path)at Kconfig scale, the wasm ABI call latency vs native,check_bijectiveover a large tree; in ⚒ the graph frame time (gunnar scale, kconfig scale, 20k synthetic), maximise/restore, fold/unfold, wasm load+call cold/warm. Numbers in the reports; problems appended to the bench log per this box's protocol. - The CLI builds everything ⚒ builds.
dwarves buildthinggoes through the same wasm-loaded build thing, the same tree flags (flags_ofis the line the node menu shows), in the same container; proven by a robot that runs that line through the CLI door and compares receipts/decision fragments with BYGG (law B/C across doors). - Integration tests build through the CLI. Each repo's
tests/*.rscarries a matrix that walks every variant fromvariants(): the dry gate (--list) always, the real build in the toolchain container when the box enables it, asserting the receipt (typ, sha, fragment) and emitting one nornir-testmatrix row per variant — law E proven on real builds, and the 16 Absent gunnar/korp cells filled. - Commit, rebase, push often. Every green sub-step, in the repo's voice; never more than ~30 minutes uncommitted. A dead session (token limit, API drop) loses only what was not pushed — three lanes proved it on 2026-08-26.
- Containers build things — never the host's libs. Every build ⚒ or the CLI starts (a build-thing crate to wasm32, a donor kernel, a variant) runs in the declared toolchain container (
nordisk-cargo-toolchain, draupnir/skidbladnir). Thefetch(coordinate)host import is fulfilled by a container by default; a host path is a named exception the refusal can spell, never a silent fallback.
Rickard's decisions, still open
- #10 a kernel column in the five-column matrix (gunnar-kernel).
- korp's product pinned to a kernel (edge on
korp-appliance-iso). - real Kconfig from fetched source (a container round-trip per resolve) vs. edda's curated fragments — when the honesty label is allowed to come down.
Landings
(append-only: date · lane · SHA · what)
- 2026-08-26 · gunnar 0.1.9 fold-in ·
16fd859· pin → 0.1.9, gate in the default suite, mirror carries donor/fixtures/options/toolchain/allow_unbuilt_bins. - 2026-08-26 · model ·
c3f5c9b3c1e36d· the design and this plan. - 2026-08-26 · korp lawful ·
8a6f570· korp-build-thing crate, both mirrors held by parity (0 differing fields), assert_bijective in the default suite, iso edgeless by named refusal. - 2026-08-26 · nornir ·
c5bd222· mimir_lens::subclone rides the vector feature; nornir with default-features=false compiles again (korp's dev-dep). - 2026-08-26 · edda wave 1 ·
8d6110fdd1af625c5b7cb· the settings tree IS the model (rows ↔ tree identity, law A); options/try_toggle/actions on BuildThing and over the wasm ABI (ops 11/12/13),nordisk::fetchwith the container contract (ContainerFetchRunner seam for dwarves); laws B/C/D over the tree, flat law checks deleted; 0.1.10 unpublished. Benches: 20k-node derive 10.8 ms, check_bijective 20k 374 ms, wasm options 389 µs vs native 158 µs, plugin load 1.3 s. Still reading flat rows: declaration-time spelling validation only (validate_options/specs/fixtures, apply_params_with). - 2026-08-26 · korp lane 2 ·
fc0fdf47467b1d74e9d42· gate on the tree laws (16 green), cdylib + export_build_thing + native==wasm identity (host-built module, named; container road refused: no [build.toolchain]), cli_matrix: 9/9 dry gates green with testmatrix rows, real tier refused by name. Coupling: korp's iso mirror names edda's uncommitted IsoBuild.kernel_donor/edges — wave 2 owns keeping those names. - 2026-08-26 · holger lane 2 · edda
25d7e199fa82f2, holger5671634d002b8cc188940· mirror recopied (byte-equal, 13-day drift closed), drift guard walks the whole serialized set; holger-side gatebuild-space/tests/edda_mirror_no_drift.rsvia path dev-dep; installer declares no features (env-runtime, not compile-time — evidence in the mirror test); "cell" 39→0 in holger toml; cli matrix 18/18 dry rows green over both deliveries; real tier refused by name (no [build.toolchain]). - 2026-08-26 · gunnar lane 2 ·
b6916b31fd09c803c1cdb497eea8f94caee· tree laws over the installer tree (4 roots / 25 nodes / 50 flags, 0 problems) behind --features tree-laws until 0.1.10 publishes; cdylib + native==wasm identity (11 trees, 104 toggles); "cell" 321→4 in code (kept: the receipt wire key "cell", a receipt-version decision); cli_matrix 8/8 dry + REAL build of gunnar-cli in the toolchain container (5m23, receipt typ exe · sha c9a4fc6c…). Refusal: the image has no wasm32 target, so build-thing modules are host-built and say so. - 2026-08-27 · wave 3, resurrected · edda
23676e4, dwarvesfba8384fa12f88, gunnar6ca015f· all four wave-3 lanes died ~00:15 on a FULL DISK (/ at 100 %, dead lanes' target dirs ~350 G; holger/knut/gunnar Cargo.lock truncated to 0 bytes — restored from HEAD). Their trees were committed the morning after, aftercargo check --all-targetsand the lanes' own gates. edda:build_dag.rs(the--buildgrammar, brace ≡ flat,BuildDag::derivedonors first, cycles refused),KernelResolution::NeedsBuild{step}(the reader hands back the step instead of deciding), edges on container/kernel/vm rows,BuildVariant.applied_preset,suite_clireadsbuildsand refuses by name,discover_validatedas the door's load path; 524 unit + all suites green. dwarves:build_steps.rs(resolve → plan →run_build_chainthrough runa,ForgeBackend.with_steps), a real edge accepted atrefuse_build_flags,--list --build= dry pass; audit #4 #9 #11 #16 taken. ⚒:BYGG <kant>on edge nodes, the step console (five states), robots 7/7 — butDeclaredForge::build_edgestill returnsmissing_runner(): the click plans and refuses, the runner exists one crate over and is not wired. Cross-lane bug found and fixed: the dry pass planned, then handedbuildsto edda's non-chainingsuite_cli::run, which refused the same line. gunnar:tests/iso_edge_linked.rsRED on purpose (0.1.9 pin dropsIsoBuild.kernel_donor). Wave 3 is not done: ⚒ not wired to the chain runner, no real chained build measured, audit #1/#3 (type check at load from every door) landed only asdiscover_validated— no door calls it yet, #17 open, 0.1.10 unpublished. - 2026-08-27 · W6, the old reds · dwarves
fe2a3b03d366b96a427cc· the three red integration targets incargo test -p dwarves, each fixed or NAMED; default suite now 374 passed / 0 failed / 14 ignored over 31 binaries, cargo exit 0. (1)dark_lib_tests_guard: thegalois-axisarm recorded 9 lib unit tests andfeature_axis_source.rscarries 12 — the three arrived withbb961f1/06c41ceand neither touched the record; bumped only after RUNNING the arm (12/12 green in it; whole arm 207 passed / 0 failed / 4 ignored). (2)installer_required_param_door:compose_installer_rowis two functions, one perappliance-isoarm, and the 2026-08-26 "refuse a missing param before the 18 m 29 s build" fix landed in the COMPOSING half only — so the arm a defaultcargo testcompiles answered "you need --features appliance-iso" to an operator who had also forgottenadmin_key. Gate hoisted intoassemble_cell's Installer arm above the feature gate, beside the option gate that is there for the same stated reason; one spelling, both forges (default 2/2,--features appliance-iso2/2,installer_build_door11/11 unmoved). (3)code_roadlaw-B leg#[ignore]d, NAMED:bisyncis 100 % yanked on crates.io — all seven versions (0.1.0 0.2.0 0.2.1 0.2.2 0.2.3 0.3.0 0.3.1) — reached vianornir-build-thing → nornir-git ^0.1.5 → gix 0.86.0 → gix-protocol 0.64.0 → bisync ^0.3.0. Measured with a bare probe crate: 0.1.9 AND the freshly published 0.1.10 both fail identically, so publishing did not lift it. The escape is one crate upstream and is not dwarves':gix-protocol 0.65.1droppedbisync, reachable only throughgix 0.87.1, sonornir-gitmust gogix = "^0.86"→"^0.87"and be republished. Headline: from a cold registry cache no publishednornir-build-thingback to 0.1.5 resolves today. - 2026-08-27 · W6, audit #20 (never run before) · dwarves · features test
--features kernel-build,holgerCOMPILES and is green: 376 passed / 0 failed / 14 ignored over 31 binaries (+2 over default).examples/bench_kernel_ledgerreleased and run, first numbers for the kernel ledger — bzImage 13 MiB, 10 000 index rows:ledger_key_of12.18 µs (merge + sha256) · record the build 18.07 ms (3 files + 1 index row) · index load JSONL cold 5.76 ms for 10 000 rows · lookup COLD 14.17 ms (materialise 13 MiB + pin parse + sha256 + fragment compare) · lookup WARM 8.34 ms (verify only) · local.kernel-out, no ledger, 8.30 ms. Two readings: the ledger costs 0.04 ms (0.5 %) over the donor's own directory when warm, so the ledger is not the expense — and the whole verification is dominated by the sha256 over the bzImage, not by the index (the HashMap lookup does not show among 10 000 rows). Against a kernel build at minutes cold / ~145 s cached, a hit trades ~145 s for ~14 ms. - 2026-08-27 · W4, ⚒ runs the chain · dwarves
d94d2930f8ea2b, edda04cdcd6·DeclaredForge::build_edgereturnedmissing_runner()on BOTH arms and namedBuildRun::spawn_chain, a function that has never existed in any crate; the real runner had landed one crate over infba8384. The click now walks the CLI door's own road, inbuild_cells' order and with nothing written twice:refuse_build_flags→expand_opts_for→resolve_kernel_axis→plan_build_steps→describe_plan→run_build_chain_watchedon a worker thread. ⚒ is a second READER of that chain, never a second runner. New seam incrates/dwarves:run_build_chain_watched(…, ChainWatch)(the same registry, the same runa;run_build_chainis that call withNone),StepProgress::{Started,Settled}, andStepRegistry::settledas the one place an outcome is printed, watched and filed. The console shows only what the runner said: the DECLARED image while a step runs, the pin's own path + fragment when nothing was built, the receipt's shas when it was, the step's own sentence when it went red — and, when the step's variant declares no toolchain, that the build takes the HOST's environment (blocker B1 on screen, not hidden). The forge answers the plan it STARTED, so a donor that is itself a consumer brings its donor along and the rows are the rows runa was given; each row carries the planner's own line verbatim. RED first:robot_bygg_edgefailed on the consumer's coordinate, and its refusal changed from a missing runner's name toresolve kernel donor checkout 'tunnr': no checkout found. - 2026-08-27 · W7, one door's judgement · dwarves
e725b7e· the plan's premise was wrong in a way worth recording:build_forge.rs:2036BuildVariantSet::discoveris inside#[cfg(test)], and the shipped forge never had a second LOADER — ⚒ and the prompt have sharedbuild_thing::code::takeand the namedBuildRoadtoml fallback since gap #9. What was not shared was the JUDGE:read_through_codehas refused an invalid set since35729c2(dwarves-buildthing-4) while the pane loaded the same set down the same road and asked nothing, so a declaration the prompt refuses rendered here as a matrix.menu_fornow calls that door's own gate (buildthing::refuse_unvalidated, lifted out ofread_through_code); the refusal is on the road line, in the note, and every build verb refuses by it. Proof:robot_two_doors::the_chain_the_pane_plans_is_the_chain_the_prompt_plansdrives ⚒'s dry pass (plan_edge, the dry twin — its own method, because a parameter deciding whether minutes of kernel compute happen is one somebody passes wrong) on gunnar's REAL declaration and compares it withplan_build_steps+describe_plancalled directly: same coordinates, same order (tunnr/tunnr-kernel→gunnar/gunnar-installer), every row carrying the prompt's line verbatim. - 2026-08-27 · W4/W7, two drifts the comparison found · edda
04cdcd6, dwarvese725b7e· (1)kernel_nodesrenderspresetANDprofileas vals, ⚒ hands BYGG every flag the tree spells, and both readers below disagreed with the tree that drew them:resolve_kernel_clijudged--opt kernel.profile=vanillaas a symbol row ("a symbol row takes on|off") andkernel_decisiontook the profile off the DECLARATION and ignored a chosen one. Two vals side by side, one of them a choice. Both now take it like the preset — refused by name when unknown or given twice — and the guard asserts the hardened and vanilla FRAGMENTS differ, since a profile that changes nothing in the fragment is a control that does nothing. This madeBYGG kärnanunrunnable on gunnar's real declaration. (2) the ⚒ door collected its--optline through aBTreeSet, which SORTED it; the kernel grammar applies the line in order, cascade and contract refusals included, so the prompt got the declaration's order and ⚒ an alphabetical one. Now first-appearance order with the consuming step's line leading, and the robot compares the two lines verbatim rather than as sets. - 2026-08-27 · W4 benches (⚒, release, headless, oden 32 cores) ·
dwarves.step_console_frame_500.893 ms/frame over a 50-step synthetic DAG (120 iters);dwarves.hammer_graph_frame_gunnar0.672 ms/frame, graph paint 41 µs, 28 nodes, 120 iters, 1BYGG <kant>verb on the menu. Both fromcargo run -p dwarves-gui --release --example step-console-bench. No wave-3 ⚒ numbers existed before this line. - 2026-08-27 · W4 binaries ·
dwarves-uianddwarves-ui-gpubuilt at the declared variants' own features and profile (vm-boot/gpu,vm-boot, release) and installed into~/.local/bin; both stampdwarves v0.1.4 (5623aaf13c4d)— this lane's pushed HEAD. NOT DONE: no mapped window under Xvfb :99 (the process starts and logs its host,import -window rootcomes back blank — no GL adapter there), so the on-screen evidence for this lane is the robots' rendered assertions (label_visibleon the refusal line and the CLI line), not a screenshot of the installed binary. - 2026-08-27 · wave 3 W1/W3 · dwarves
35729c27881fd7, eddaedd279d7030901· the build door validates at load (validate_all_in, errcode dwarves-buildthing-4, red:read_through_codereturned Ok withvalid: truefor an edge whose typ the donor contradicts); andplan_build_stepsbecame a CONSUMER ofBuildDag::derive— its own Kahn ordering is gone, so the donor's donor is planned, deepest first (red: the old planner against the fixed edda planned["mellan/mellan-rootfs"]alone). Found on the way: a[[build.container]]/[[build.vm]]consumption edge was INVISIBLE — bothedges_ofandSettingsTree::of_setlet the required delegating[[build.variant]]row shadow the descriptor; the two dispatch orders are now guarded against drifting apart again. - 2026-08-27 · wave 3 W2 · THE CHAIN RAN.
dwarves buildthing gunnar --variant gunnar-appliance-iso --build kernel --opt kernel.preset=nuked: kernel step COLD 64.6 s (real container build, linux-6.12.104, digest 765513a223dbeeef, artifacts bzImage + kernel.config + kernel-pin.json) → CACHED 0.1 s, "BY PIN — built nothing". The receipt's fragmentbd2d9dbc10f3d7b5…is exactly what the dry pass predicted for the preset, so law D is asserted on a real artifact rather than on a state. ⚠ Two of this plan's own numbers were wrong in the direction that matters: cached is 0.1 s, not ~145 s, and cold is 64.6 s for this preset, not "minutes". - 2026-08-27 · the containers rule made OPERABLE · edda
1ad1b77cbfbef6, tunnr8d17408· Both toolchain images had a complete engine, a committed Containerfile and no way for an operator to produce them:DraupnirCargoRunner::build_toolchain_imagehad ZERO callers andDraupnirKernelRunnerhad no image-build method at all. So[[build.kernel]]fell through to baredebian:trixie, which apt-installs its compiler — and a real chain died there after 263.2 s onTemporary failure resolving 'deb.debian.org'. Both images now have a door and a live gate:nordisk-cargo-toolchainsha256:035814c4… (39.8 s),nordisk-kernel-toolchainsha256:f573ca0a… (61.8 s), the latter asserted to hold gcc/make/flex/bison/bc with the network off. ⚠ A digest pin is not satisfiable by REBUILDING — gunnar pins f29e517c… and this box builds 035814c4… — soimage_sha256is a per-box fact until the image is pulled from a shared registry. ⚠ Corrected 2026-08-30 (lane AV): that is a property of an unpinned RECIPE, not a law of container images. Edda'skernel-toolchain.Containerfilenow pins its base by digest, installs from a Debian snapshot, pins every pip version, declaresSOURCE_DATE_EPOCHand is handed the same instant by the builder — four mints into four fresh empty stores gave ONE image id3f632569f198…and ONE manifest digest78eaa55a651d…, and the bollard door agreed with the CLI door once the manifest FORMAT was pinned to OCI as well. So for that image a rebuild DOES satisfy the pin, and a registry is a way to skip 50 s and 1.2 GB rather than the only way to make a pin true. The claim still stands fornordisk-cargo-toolchain, which has had none of that work. Gate: eddatoolchain_images_live.rs::two_mints_of_the_kernel_toolchain_are_measured_against_each_other. - 2026-08-27 ·
localhost/CORRECTION · edda · podman 5.7.0 readslocalhost/as a REGISTRY HOST: bothlocalhost/<name>:tagandlocalhost/<name>@sha256:…fail withpinging container registry localhost: dial tcp 127.0.0.1:443: connection refused, through podman AND through draupnir. The BARE name works in both spellings. This corrects kernel.rs's own note, itself dated as a correction. - 2026-08-27 · bisync · edda
c456c76,nornir-git 0.1.8PUBLISHED ·bisyncis yanked on crates.io — all seven versions — and reached via nornir-build-thing → nornir-git → gix 0.86 → gix-protocol 0.64. So from a cold registry cache no published nornir-build-thing resolved, including 0.1.10. Fixed one crate upstream (gix 0.87→gix-protocol 0.65.1). Applied-output proof: a bare crate onnornir-build-thing = "0.1.10"now resolves nornir-git 0.1.8 + gix 0.87.1 and zero bisync. Still named: nornir-docgen, nornir-release-core, nornir-workspace and gunnar-pack pin gix 0.86, so bisync remains in THEIR published graphs. - 2026-08-27 ·
nornir-build-thing 0.1.10PUBLISHED to crates.io on Rickard's order. gunnar's pin bumped,iso_edge_linkedgreen BY THE PIN (red seen on 0.1.9 by downgrading the lock in place). W2's remaining open ends: the wasm code road is refused BY NAME becausenordisk-cargo-toolchaincarries no wasm32 std (fix named in the refusal:rustup target add wasm32-unknown-unknown+targets = [...]under[build.toolchain]), and the ISO step needs a forge built with--features appliance-iso. - 2026-08-30 · lane AK · WAVE 3 CLOSED, AND THE SILENCE UNDER IT. The chain runs at DEPTH 2 on the real declarations (lane AF's toolchain surface):
step 1/2 kernel.toolchain → tunnr/nordisk-kernel-toolchain : container→step 2/2 kernel → tunnr/tunnr-kernel : kernel · after tunnr/nordisk-kernel-toolchain,chain · passed · 3/3 runa step(s)— toolchain 0.3 s · kernel 78.5 s cold / 0.1 s BY PIN · installer 232.3 s. The planner needed no change (it has consumedBuildDag::derivesince7881fd7) and the ⚒ pane needed none (it has walkedrun_build_chain_watchedsince0f8ea2b) — the ledger row saying otherwise was stale. What the chain is FOR: the sameslimrow is a different kernel down the two roads — standalone 0 requirer rows, no CONFIG_XFS_FS, 2 208 768 B; through gunnar's edge 66 symbols required by 5 features, CONFIG_XFS_FS=y, 2 413 568 B. So lane AH's B2 failure (mount /dev/vda3 on /data as xfs: ENODEV) was never a preset fact. BOOT-PROVEN through the chain,gunnar-installtest installer, B1 install + B2 serve + B3 power-cut reboot, ALL PASS: slim (bzImage 2 413 568 B, ISO 38 903 808 B) and nuked (2 376 704 B, 38 836 224 B) — the firstslimappliance that has ever booted. normal and full are REFUSED at build time through the closure and that is the right answer:# CONFIG_FS_POSIX_ACL is not setand# CONFIG_MULTIUSER is not setcrept back in, because both presets are defconfig-based and carry filesystems whose Kconfig selects POSIX ACL straight back, while gunnar'sdata.fs = xfsdeclares a ONE-USER /data. The canary now names the requirer, the feature and the reason for each. Matrix (#18): the chained nuked medium passesqemu-local,qemu-local-bios,hetzner-cloudandupcloudon top of the default shape;gce-virtioHANGS the door — itsboot_disk = VirtioScsiagainst a recipe whosetarget.busesare ide-cdrom + virtio-blk, so the appliance refuses correctly on the UART (hwdetect: no usable target disk — every fixed disk carries the installer medium) andgunnar-installtest installerdoes not gate on it;ovh-public-cloudhangs with no serial captured, undiagnosed. - 2026-08-27 · WAVE 3'S PRODUCT GOAL, REACHED ·
chain · passed · 2/2 runa step(s), exit 0. ONE command —dwarves buildthing gunnar --variant gunnar-appliance-iso --build kernel --opt kernel.preset=nuked— builds the donor kernel with the customer's choice and then the ISO that boots it. Step 1tunnr/tunnr-kernelBY PIN 0.0 s, fragmentbd2d9dbc10f3d7b5…(the fragment the dry pass named for the preset). Step 2gunnar/gunnar-appliance-isoBUILT in 12.5 s, consuming the PINNED kernel through the DECLARED edge (blake3 9820a8012442b96f). The artifact is real and asserted as an artifact:.iso-out/gunnar-appliance-iso.iso, 16 646 144 B,ISO 9660 CD-ROM filesystem data 'GUNNAR_APPLIANCE' (bootable), sha256 e9c08210…, composed app 23 247 408 B → znippy 8 695 774 B (pin 6c31cf6057d79486), initramfs 10 075 631 B, ESP 16 598 528 B. Full COLD chain ≈ 77 s (kernel 64.6 s + iso 12.5 s). Three things had to be closed on the way, each one a thing declared but not operable: the two toolchain images had no door, so the kernel fell through to a base image that apt-installs its compiler;localhost/in a declaration turns a local image into a registry pull; and the pinned path refused the kernel config sitting beside the bzImage because it derived a DISTRO name (config-<version>) while[[build.kernel]]writeskernel.config— one artifact, two names. The medium needsKORP_ROOT_SIGNING_KEYto be bootable-with-an-anchor; run with=devhere, which the composer names as proving the path and NOT an authenticity anchor. Still open, both named by their own refusals: the wasm code road has nowasm32std innordisk-cargo-toolchain, andforge.rsis behind#[cfg(feature = "forge")]so none of its 236 tests compile in a defaultcargo test.