Skip to main content

index

The Apple Silicon (Asahi Linux) installer path for TunaOS-family bootc images β€” and anyone else's (Dakota, Bluefin, Bazzite): a macOS-driven install flow for M1/M2 Macs.

The Bootsahi installer, screen by screen: welcome, choosing an image, account settings, the disk-space split, installation progress, and the recoveryOS hand-off.

Every frame is rendered in CI from the real SwiftUI views β€” see the step-by-step walkthrough.

Architecture (see docs/DESIGN.md): instead of one installer payload per variantΓ—desktop, we ship one minimal bootstrap payload whose first boot runs fisherman to bootc install the image ref the user picked in the macOS app. The catalog is just registry refs (bonito:gnome-asahi, …), so a new variant needs no installer change β€” but a ref must pass the Asahi golden-manifest harness before it is offered, and "appears without touching the installer" must never be read as "appears without being verified."

As of 2026-07-30 only bonito and grouper pass (36/36 each); the other six promoted *-asahi tags would leave a Mac unbootable (tunaOS#776). The catalog is an explicit allowlist: every CatalogEntry carries a verified field (false by default), and the macOS app only offers entries where it is true. The shipped catalog.json includes both bonito and grouper, marked verified: true. Adding a new variant requires both the image and a passing harness sweep β€” the field is the gate, and CI generation must consume harness results, not just tag enumeration (#41).

Status​

  • Design (docs/DESIGN.md)
  • D0 scaffold: scripts/make-payload.sh + build-payload.yml β€” package any asahi-capable bootc image as an asahi-installer zip + installer_data.json (wired with R2 upload step for download.tunaos.org/asahi)
  • D0 validated against a real asahi image (bonito:gnome-asahi, tunaOS#774)
  • D1 first-boot fisherman agent config (install-config.json β†’ unattended bootc install)
  • D2 asahi-installer --json machine mode (upstreamable)
  • D3 macOS app (SwiftUI, wraps the asahi-installer Python backend)
  • D4 recoveryOS walkthrough UX, LUKS, Wi-Fi handoff (RecoveryWalkthroughView QR & instructions; LUKS fail-closed #20/#47; Wi-Fi prompt at first boot #46)

What's tested and what it proves​

The project distinguishes two claims that are easy to conflate (see #27):

ClaimTestWhat it proves
"A payload boots"test-payload.sh + test-boot-payload.shThe kernel, DTBs, modules, and U-Boot EFI chain work. Any asahi-capable image passes this β€” it proves the packaging, not the product.
"The bootstrap handoff is green"test-agent.sh + test-agent-disk.sh + test-agent-install.shThe agent generates a valid recipe, the recipe passes real fisherman validate, and a real bootc install succeeds end-to-end (canaries on ESP / neighbour / bootstrap / target).
"The bootstrap image contains everything it needs"test-bootstrap-contents.shStatic verification: bootsahi-agent, enabled unit, fisherman, cosign, jq, nmcli, blkid β€” all present and accounted for. Also gates a negative fixture (agent removed β†’ must fail).
"The actual bootstrap image boots"test-bootstrap-boot.sh (opt-in)Build, package, and boot the repo's own bootstrap under qemu+U-Boot. The deepest fidelity achievable without Apple hardware. Needs aarch64 + qemu + u-boot-qemu.

Payload layout & installer_data.json schema modeled on fedora-asahi kiwi-descriptions and nixos-asahi-package. M1/M2 only β€” M3+ has no Asahi installer support yet.