Migrate scripts/iso-e2e.sh --luks from a raw sudo bootc install to-disk --block-setup tpm2-luks to sudo fisherman recipe.json — the same install
backend every TunaOS installer frontend uses (GUI installers, upstream
bootc-installer for gnome) — so the LUKS E2E workflow tests what
real users get, not a separate, untested code path. Per
docs/ci-troubleshooting.md's "Key takeaway": every raw bootc install to-disk call in this codebase should be replaced with fisherman.
A green run of the LUKS E2E GitHub Actions workflow (gh workflow run "LUKS E2E" -R tuna-os/tunaos --ref fix/r2-cost-reduction -f variant=<v> -f flavor=<f>) — conclusion: "success" — for at least one cell per distinct
install backend this branch touches:
- ostree/dnf, fisherman
bootcDirect+network-pull — one ofyellowfin:kde/yellowfin:niri/yellowfin:cosmic - gnome installer path (upstream
org.bootcinstaller.InstallerFlatpak, newly embedded this migration) —yellowfin:gnomeoralbacore:gnome, once the ostree/dnf backend above is confirmed - composefs/apt — any
grouper:*flavor, now blocked (see "Explicitly out of scope" below) — stretch goal, not required to call this done
Each checked box = a run ID with conclusion: success, recorded in
docs/ci-troubleshooting.md §4 or this file's Status section below.
- grouper networking gap (bug #17): no DHCP/network-config service ever runs in grouper's live squash — blocks SSH for every grouper flavor regardless of desktop. Pre-existing, unrelated to fisherman, needs its own investigation/fix in a separate branch or follow-up.
- grouper:xfce lightdm crash-loop (bug #15) and grouper:gnome missing wayland-session — pre-existing desktop packaging gaps.
- Embedded local OCI store: TunaOS's tacklebox pipeline doesn't embed
a local image store into the live squash the way
projectbluefin/dakota-isodoes. The current network-pull fix works but is slower; building a real embedded store is a separate, larger tacklebox feature, not required for this migration's finish condition. - Plymouth per-variant boot themes: unrelated side-task picked up
mid-session. Already done and merged into this branch (
git log --oneline --grep=plymouth) — not part of this goal's finish condition, mentioned here only so it isn't mistaken for unfinished work.
Full symptom → root cause → fix table lives in docs/ci-troubleshooting.md
§4 ("LUKS E2E fisherman rewrite — full bug chain") — read that before
re-diagnosing anything. Condensed pointer in memory:
luks-e2e-fisherman-migration.md (auto-loaded via MEMORY.md in future
sessions).
- 20 bugs found and fixed. Bug #20's first fix (guest-side MTU=1400
clamp, commit
9916836, PMTUD theory) was disproven: a retest run stalled on the exact same blob for the same ~29 minutes with the clamp applied. Checked the blob's size directly via GHCR's manifest API (skopeounavailable locally, usedcurl+ registry token endpoint) — 77MB, unremarkable next to several 200-400MB layers in the same image that pull fine, ruling out a size-triggered fragmentation cause. - New fix applied (not yet dispatched/confirmed): instead of
preventing the stall, made it recoverable —
scripts/iso-e2e.shnow pre-pulls the image viapodman pullin a 4-attempt retry loop (600s each) before invoking fisherman. Already-fetched layers are cached in local storage, so a retry only re-fetches what stalled; fisherman then finds the image local and skips its own pull. Seedocs/ci-troubleshooting.md§4 bug #20 for full detail. - No cell has passed yet. All three finish-condition boxes above are
unchecked. Next: dispatch a fresh
yellowfin:kde(or niri/cosmic) run to verify the retry-pull fix. - Bug #21 found (2026-07-17, PR #668):
tunaos-desktop-contract.serviceassertedis-active graphical.targetwhile being WantedBy that target — targets gain implicit After= on their wants, so the check self-deadlocks; the script exited silently underset -eand no marker ever reached ttyS0. This broke every variant Gate on main AND explains why LUKS E2E's installed-boot wait (which needs the contract marker from the pulled published image) could never pass: no published image emits a marker. Chain in flight: Build Yellowfin gnome (run 29614564619, branch fix/desktop-contract-gate) proves the Gate; Build Yellowfin kde (run 29614735371, twin branch fix/desktop-contract-gate-kde — twin needed because the concurrency group cancels same-ref dispatches) publishes a marker-emitting :kde; then dispatch LUKS E2E yellowfin:kde.
Use the ci-fix-loop skill (~/.pi/agent/skills/james/ci-fix-loop/SKILL.md):
narrow-dispatch the specific cell being tested, wait via ScheduleWakeup
(not manual polling), diagnose failures from real --log-failed output,
fix, append to docs/ci-troubleshooting.md §4, repeat. Don't dispatch the
full matrix — grouper is out of scope per above, and yellowfin's three
desktop flavors (kde/niri/cosmic) all exercise the same install backend, so
one passing is sufficient to check that box.
- Re-guess the fisherman image-ref problem (bugs #13/#14/#16/#18/#19 — five
attempts before landing on "query the live VM directly, network pull via
the
imagefield"). The current approach is correct given TunaOS's infra. - Retry indefinitely against what might be an external outage —
curlthe suspect URL directly first (session hit a false-alarmpkgs.tailscale.com504 that was runner-specific, confirmed by curling it directly). - Consider this goal met on "no failures yet" while a run is still
in_progress/queued— wait forconclusion: success.