finish plan
Written 2026-08-01. Scope set by the maintainer: get dakota, composefs,
and btrfs green. Windows 10 Home/Enterprise/LTSC (#58) is explicitly
deprioritized ("pretty rare").
Historical (2026-08-11). The plan's main rungs are done: dakota (composefs full chain, run
30710282014) and bonito/btrfs (green twice, runs30713490009/30714683108) passed on the failure-ledger harness, and #28/#35/#33 are closed with their fixes inmain(7d99c45,8d964f4,2166d09,6b7c412,bffd284). Remaining: one non-dakota composefs family (marlin/flounder),tpm2-lukscell re-verification, and the full matrix re-sweep β tracked in the README build/test matrix and open issues. Read the README matrix for current status.
The project's green core is done: bluefin:lts (ostree/grub2/ext4-sealed)
passes the full Phase 1 β 2 β 3 chain, GUI-driven, 29/29. What separates
"working demo for one image family" from "finished installer" is the red
half of the build/test matrix, and almost all of it funnels through two
bugs: the composefs Phase-2 staging path (#28) and btrfs device readiness
(#35).
Where each red cell actually isβ
| Red cell | Funnel | Blocking defect |
|---|---|---|
dakota deploy β Phase 2 | #28 | early-cpio staging: incoherent ntfs-3g sourcing, unverified initrd |
marlin / flounder deploy | #28 | same composefs-native path (backend detection fixed in 96d1f5b) |
| btrfs sealed root | #35 | root device never becomes SYSTEMD_READY; sysroot.mount times out |
tpm2-luks | #33 | Phase-2 dracut regen fails on the LUKS root (independent track) |
| Matrix β s predating 2026-07-27 | harness | being re-run under the failure-ledger harness (already fixed in 3d7f9e2) |
What this branch fixes (code-side, container-verifiable)β
- One early-cpio implementation (
stage_wootc_overlay,stage_ntfs3g_closure,build_phase2_initrdindeploy.sh), used by all three prepend-cpio branches. The/mnt/sysrootphantom paths are gone. ntfs-3g is sourced coherently: the target deployment's own binary- libraries first; otherwise the deployer's binary as a complete
private closure (every
NEEDEDlib + the loader under/usr/lib/wootc/ntfs3g/, wrapper-invoked, exec-verified at stage time) β agent-lessons Β§8, mechanically enforced.
- libraries first; otherwise the deployer's binary as a complete
private closure (every
- The built Phase-2 initrd is verified by inspection: overlay
completeness (unit, wants edge, executable hook) before packing; the
base initrd is listed and must ship the hook's interpreter and tools
(
bash losetup udevadm mount) β fail closed on proof, warn on unlistable. Mutation-tested intests/unit/phase2-early-cpio.bats. - #45 fail-closed: a deploy whose installed root cannot be mounted and recognized exits 1 with the partition table, per-partition blkid, and bounded mount errors β it no longer advertises deploy-ready and reboots.
- #35 layered fix: btrfs deploys bake a
modules-load.dentry into the regenerated Phase-2 initramfs (early, dependency-resolved btrfs.ko load β no hook modprobe, honoring the Secure Boot lockdown lesson); the attach hook registers the just-attached partitions (btrfs device scan), re-triggers CHANGE events so udev's readiness import re-runs, and logsmodule loaded= SYSTEMD_READY=per btrfs partition so a persisting failure is diagnosable from one serial log.
What only the E2E rig can do (the actual finish line)β
Each rung is one KVM run; do them in this order, one change per run:
- btrfs re-run (
wootc.filesystem=btrfs, bonito:gnome): expect green; if not, the newbtrfs <part>: module loaded=β¦ SYSTEMD_READY=β¦serial line says which layer failed. When green twice, consider flipping the sealed default to btrfs (native fs-verity, reflinks) β a product call, not a bug fix; ext4 stays default until then. Not bluefin:lts: matrix run 30700616717 proved CentOS Stream 10 cannot load btrfs at all here β the module is out-of-tree, signed with a key the locked-down (Secure Boot) kernel rejects (Loading of module with unavailable key is rejected,module loaded=0), so that cell dies a layer before the #35 mount. The deployer now refuses such a deploy up front instead of proving it again over 25 minutes. - dakota full chain: deploy now runs the hardened staging; the
composefs Phase-2 boot (deployer kernel + patched UKI initrd +
root=UUID/composefs= kargs) is the first thing that has never been
proven end-to-end. Expect the next failure β if any β after attach,
in
bootc-root-setup/composefs pivot; the verify guards will name it. - marlin / flounder: same path as dakota post-96d1f5b; run after dakota is green so composefs failures aren't double-counted.
- Matrix re-sweep under the ledger harness to re-earn the pre-3d7f9e2 β s (already tracked in README).
- #33 tpm2-luks: independent; the regen now surfaces dracut's own output, so the next failing run carries its cause.
Definition of done for "support for dakota, composefs, btrfs"β
- dakota: Arm β Deploy β Phase-2 boot β seeded-file assertion green under the ledger harness (Phase-3 graduation is a follow-on rung).
- One non-dakota composefs-native family (marlin or flounder) green through Phase-2, proving the path is image-agnostic, not dakota-shaped.
- btrfs: bonito:gnome sealed-btrfs green through Phase-2 twice; #35 closed (fix: modules-load.d + udev re-trigger); ext4 stays the sealed default β btrfs is opt-in via wootc.filesystem=btrfs on supported kernels (bluefin:lts is not a candidate β its btrfs kmod is rejected under Secure Boot, and the deployer's btrfs preflight now says so at deploy time).
- All three keep their bats regression guards
(
phase2-early-cpio.bats,btrfs-phase2.bats) green in CI.