Documentation Index
Fetch the complete documentation index at: https://docs.ryoku.dev/llms.txt
Use this file to discover all available pages before exploring further.
Ryoku ISO Build Recipe (Working Offline Path)
Captures the working build / install / boot recipe for the Ryoku ISO as of 2026-04-27. Intended for: future contributors who want to add customizations without breaking the offline install path, and for the next time the install regresses. Niri transition note, 2026-05-02: the table below includes the last fully boot-tested Hyprland ISO result. The current source now targets Niri, bundles the shell into the ISO build, and validatesii-pixelplusniri.desktop; a new ISO build/boot verification is intentionally deferred to a follow-up session.
What is verified
| Stage | Verified | Notes |
|---|---|---|
| Build container builds the ISO | yes | iso/bin/ryoku-iso-make --local-source --no-boot-offer exits 0 on a clean cache and on a warm cache |
| Live ISO boots in QEMU/UEFI VM | yes | iso/bin/ryoku-iso-boot iso/release/ryoku-*-main.iso opens GTK + reaches the configurator UI |
archinstall pacstraps base from the offline mirror | yes | No internet needed to reach the configurator finish line |
Chroot install runs install/* to completion | yes | Exits with /mnt/var/tmp/ryoku-install-completed, VM auto-reboots |
| First-boot reaches branded boot + SDDM + Niri | pending | Niri source transition landed after the 2026-04-28 Hyprland ISO proof. Expected path: Limine boot menu -> Plymouth decrypt prompt -> shell-provided SDDM theme -> Niri session |
Online install (RYOKU_ONLINE_INSTALL=1 in chroot env) | NOT smoke-tested | The live ISO currently runs the chroot in offline mode; online path is intentional fallback only |
Local prerequisites
- Docker daemon running. The ISO is built inside
archlinux/archlinux:latest. qemu-fullandedk2-ovmfon the host.ryoku-iso-bootwill install them withryoku-pkg-addif missing.- ~6 GB free in
$HOME/.cache/ryokufor the warm-cache path. Cold rebuilds need extra room for the package downloads. - Wayland or X11 session.
ryoku-iso-bootopens a-display gtk,gl=onwindow.
Working build recipe
ssh -p 2222 root@localhost works once sshd starts inside the live env. If a previous QEMU is still running, the new boot will refuse to bind 2222 and exit; kill the stale qemu-system-x86_64 first.
Install flow (live ISO -> installed disk)
- SYSLINUX (BIOS) / GRUB (UEFI) loads kernel + initramfs from the live ISO.
- archiso live env boots, mounts squashfs root.
/root/.automated_script.shruns on tty1:use_ryoku_helpersexportsRYOKU_PATH/RYOKU_INSTALL.run_configuratorcollects user info intouser_configuration.json+user_credentials.json.install_archcallsarchinstall --silentagainst the configurator JSON, mounts/var/cache/ryoku/mirror/offlineinto/mnt, copies/root/ryokuinto/mnt/home/<user>/.local/share/, writes static/mnt/etc/resolv.conf(1.1.1.1 + 8.8.8.8).install_ryokurunsarch-chroot /mnt /bin/bash <user>'s install.shwithenv -i RYOKU_CHROOT_INSTALL=1.
- The chroot
install.shrunspreflight/all.shthenpackaging/all.shthenconfig/all.shthenlogin/all.shthenpost-install/all.sh.- In offline mode (
RYOKU_ONLINE_INSTALLunset, the default in the live ISO env),preflight/pacman.shandpreflight/yay-bootstrap.shexit early.packaging/aur-core.shno longer exits early: it pacman-installs every AUR PackageBase listed ininstall/ryoku-aur.packagesfrom the[offline]mirror (build-iso.sh bakes those packages into the mirror viaiso/builder/build-boot-overlay.sh). packaging/base.shinstalls everything ininstall/ryoku-base.packagesfrom the offline mirror’s[offline]repo. The mirror also contains everything listed ininstall/ryoku-other.packages(Vulkan/NVIDIA/Intel video drivers, kernel headers, broadcom-wl, thermald, linux-firmware-marvell, etc.) so the hardware-detection scripts ininstall/config/hardware/*.shcan pacman-install matching drivers without network. The AUR halves of those splits live ininstall/ryoku-aur.packages(default install) andiso/builder/ryoku-boot-overlay.packages(boot-critical + conditional hardware AUR drivers like asusctl, qmk-hid, nvidia-580xx).login/limine-snapper.shhard-fails iflimine,limine-snapper-sync,limine-mkinitcpio-hook, orlimine-updateis missing; runsmkinitcpio -P+limine-update; asserts/boot/EFI/Linux/ryoku_linux.efiand a^/+Ryokuentry in/boot/limine.conf.login/sddm.shrefuses to enable SDDM unless the shell-provided greeter theme + theniri.desktopsession file exist.post-install/pacman.shswaps/etc/pacman.confto the upstream-only config, dropping the temporary[offline]entry from the user’s installed system.post-install/finished.shwrites/mnt/var/tmp/ryoku-install-completedand triggers a reboot.
- In offline mode (
Errors that look scary but are fine (chroot install only)
These messages appear during the chroot install and do NOT abort it. They appear becauselimine-mkinitcpio-hook and limine-snapper-sync ship pacman hooks that detect they are running inside a chroot and refuse to write to the live system’s boot config:
detected chroot env, skippingkernel cmdline is not availablewarning: this does not update limine, use limine-mkinitcpioFailed to register keybind: $XDG_RUNTIME_DIR not set(or similar)
install.sh later runs mkinitcpio -P + limine-update explicitly against the installed kernel, so the boot config DOES end up correct on the installed disk. Keybinds register on first boot.
Fixes that have to stay applied
These commits make the offline path work. Reverting any of them re-breaks the install.| Commit | What it fixes |
|---|---|
74426a3 install: require branded boot and graphical parity | login/limine-snapper.sh and login/sddm.sh hard-fail instead of silently degrading. Preserves the .disabled mkinitcpio-hook restoration block; without it, kernel updates would not trigger initramfs rebuilds on the installed system. |
fcc38283 iso: embed offline boot overlay and clean install inputs | iso/builder/ryoku-boot-overlay.packages + iso/builder/build-boot-overlay.sh build limine-mkinitcpio-hook + limine-snapper-sync from AUR at ISO-build time. install/ryoku-base.packages adds them so packaging/base.sh pacstraps them. iso/configs/airootfs/root/configurator drops the bogus mirror.github.com/neur0map/ryoku-arch mirror. |
5a554eee install: re-attach offline overlay during chroot pacman swap | When the chroot runs in online mode (RYOKU_ONLINE_INSTALL=1), preflight/pacman.sh would otherwise drop [offline] after copying the upstream pacman.conf, and packaging/base.sh would no longer find the AUR-built boot packages. The fix appends [offline] to the swapped config. post-install/pacman.sh re-copies the clean config at install end so this never leaks. |
ad82fa7c iso: build-boot-overlay forces overwrite + chowns build root | mktemp -d produces a 0700 root-owned dir; the unprivileged builder user inside the build container couldn’t enter it for git clone and makepkg. The chown fixes that. makepkg --force is required for warm-cache rebuilds (otherwise A package has already been built. (use -f to overwrite)). |
fea59bfb iso: rebuild offline.db on every run so CSIZE matches actual file | repo-add --new skips packages already in the db, so an overlay package rebuilt with a different byte size between two runs (limine-mkinitcpio-hook and limine-snapper-sync are non-deterministic across makepkg invocations) carries the old %CSIZE%. pacman in the chroot then rejects the file as size-mismatched and aborts with failed retrieving file 'limine-snapper-sync...'. The fix removes offline.db.tar.gz + siblings before repo-add and drops the --new flag. |
d9abf47e install: drop broken resolv.conf symlink during chroot install | arch-chroot bind-mounts /etc/resolv.conf from the live ISO. ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf then errors with are the same file because both paths resolve to the same inode through the bind-mount. The verification check then required /etc/resolv.conf to be a symlink, which fails because the bind-mount surface is exposed as a regular file. The static /etc/resolv.conf (1.1.1.1 + 8.8.8.8) .automated_script.sh writes onto /mnt is what ends up on the installed disk and is enough for first-boot DNS. |
3932a787 boot: limine branding hex for limine 12 compatibility | Limine 12 changed interface_branding_color from an ANSI 0-7 index resolved via term_palette to a literal RRGGBB hex value. The shipped value 2 therefore stopped resolving to Ryoku orange on new installs (the offline overlay ships limine 12.0.2). Set interface_branding_color and interface_help_color to F25623 directly. |
03442325 iso: keep .git in --local-source dev builds for ryoku-update | iso/builder/sync-local-source.sh was tarring the dev tree with --exclude='./.git', so the installed system’s ~/.local/share/ryoku was a tar-extracted dir (not a git repo) and ryoku-update aborted with fatal: not a git repository. Production ISOs (built via git clone) already preserve .git through cp -r; dev --local-source builds need the explicit pass-through to match. With .git shipped, git pull from the public origin works without any GitHub auth (omarchy’s update mechanism relies on the same property). |
11fc74ae hypr: ship Adwaita cursor theme so first-login cursor is on-brand | default/hypr/envs.conf set XCURSOR_SIZE/HYPRCURSOR_SIZE but never selected an actual theme, so first-login users landed at the X11 fallback “X” cursor. Add adwaita-cursors to install/ryoku-base.packages and set XCURSOR_THEME=Adwaita + HYPRCURSOR_THEME=Adwaita explicitly. omarchy gets the same effect implicitly via gsettings; making it explicit here means Ryoku does not depend on a side-effect to land on a real cursor. |
fb6e5b03 update: bootstrap yay first run + skip AUR cleanly with no aur pkgs | First-time ryoku-update on a freshly installed offline-ISO system was printing “AUR is unavailable (so skipping updates)” because pacman -Qem >/dev/null exits 0 even with empty output (so the AUR block always entered) and yay was never bootstrapped (offline install gates preflight/yay-bootstrap.sh on RYOKU_ONLINE_INSTALL). Use [[ -n $(pacman -Qem) ]] to gate on actual installed AUR packages, and bootstrap yay at the top of ryoku-update-aur-pkgs once the network is up so subsequent AUR work can proceed without manual intervention. |
e4909ac0 iso: bundle GPU + hw drivers in offline mirror via ryoku-other.packages | The conditional hardware scripts (install/config/hardware/vulkan.sh, nvidia.sh, intel/video-acceleration.sh, fix-bcm43xx.sh, etc.) call ryoku-pkg-add vulkan-radeon / nvidia-open-dkms / etc. These packages are upstream Arch but were never explicitly named in any list the offline-mirror builder consumed, and their Required By is empty so pacman -Syw did not pull them as transitive deps. On a real machine with NVIDIA/AMD/Intel discrete graphics, an offline install would abort at the GPU detection step with “target not found”. Mirror omarchy’s split: install/ryoku-other.packages lists everything the hardware scripts may need, and iso/builder/build-iso.sh includes that list in the pacman -Syw of the offline mirror. |
35b8e22c iso: AUR hw drivers built into offline mirror via boot overlay | Closes the AUR-only hw driver gap from e4909ac0 for the common cases: legacy NVIDIA (nvidia-580xx-dkms + utils + lib32), tuxedo-drivers-nocompatcheck-dkms, yt6801-dkms, macbook12-spi-driver-dkms, intel-ipu7-camera. They are added to iso/builder/ryoku-boot-overlay.packages and built via iso/builder/build-boot-overlay.sh, which also enables [multilib] in the build container so lib32-* build deps resolve. Build cost: cold first build adds ~25-30 min for DKMS compiles. --force makes warm builds rebuild too. Apple T2 stack and linux-ptl are not in the overlay because they need a full kernel compile; tracked in docs/TODO.md. |
Customization safety rails
When adding things, mirror these patterns or expect a regression in the offline install path.- New base packages (official Arch). Add to
install/ryoku-base.packagesunder the matching section header (CLI, TUI, GUI app, desktop stack, fonts, etc.). They will be pulled from the offline mirror via the upstream Arch sync. - New AUR packages, default install (every machine gets them). Add to
install/ryoku-aur.packagesunder the matching section.aur-core.shreads this file and pacman-installs them from[offline];iso/builder/build-iso.shfeeds the same file into the AUR overlay builder so the packages end up in the mirror. - New AUR packages, conditional hardware drivers. Add to
iso/builder/ryoku-boot-overlay.packagesunder a hardware section. These don’t auto-install; the matchinginstall/packaging/{asus-rog,framework16}.shorinstall/config/hardware/*.shscript invokesryoku-pkg-addafter theryoku-hw-*probe. - New
install/login/*orinstall/post-install/*scripts. Don’t do anything that requires network unconditionally. Gate online-only work behind[[ -n ${RYOKU_ONLINE_INSTALL:-} ]]so the offline install keeps working. - Editing
login/limine-snapper.shorlogin/sddm.sh. Keep the hard-check guard at the top and the post-limine-updateverifications. They are the only thing keeping a silently broken boot from shipping. - Editing
iso/builder/build-iso.sh. Never reintroducerepo-add --new. Always rebuildoffline.dbfrom the current set of.pkg.tar.zstfiles. - Editing
install/config/hardware/network.sh. Don’t try to manipulate/etc/resolv.confinside the chroot. The bind-mount makes it a no-op at best and a hard error at worst.
Verification after adding customizations
After any non-trivial change, re-run the recipe. Warm cache makes this ~5-10 min:- Build container exits 0. Look for
[mkarchiso] INFO: Done!near the end of the build log, thenWriting to 'stdio:/out/...iso' completed successfully. - VM reaches the configurator UI without a kernel panic.
- Configurator + archinstall + chroot install reach
installation completedwithout aborting at aFailed script:line. - Reboot lands at the shell-provided SDDM greeter.
- Logging in reaches the Niri session.
View full log. Screenshot the Failed script: line + the error block above it; that points at the regressing script.
Known follow-ups (not blocking the recipe)
- Online-install path (
RYOKU_ONLINE_INSTALL=1) has not been smoke-tested end-to-end in the same way the offline path has. The fix in5a554eeeis in place but unproven against a real online install. - Direct EFI UKI normal-boot path (Task 3 of
2026-04-26-ryoku-iso-parity-implementation.md) is still pending. Limine is currently the normal path, which is fine, but the parity plan also wants a direct UKI option. limine-mkinitcpio-hookandlimine-snapper-syncpacman-hook noise during chroot install (“detected chroot env, skipping”) is harmless but could be suppressed by reorderingmkinitcpio -P+limine-updateso the user-facing install transcript stays clean.- (resolved 2026-04-28 by
11fc74ae, upgraded 2026-04-30) Cursor X-fallback issue is fixed by shippingadwaita-cursors; the active default is nowBibata-Modern-Classicviabibata-cursor-theme-bin, with Adwaita still installed as a fallback cursor family.

