Proof Portal
Omarchy
ProbeLabs65 findings · 95 requirementsA proof layer — requirements, tests and verified fixes — for two of Omarchy's subsystems: the application menu (launcher scripts, QML model, JSONC config, search and selection) and the lock screen (lock scripts, QML, PAM authentication). Scope is deliberately limited to those components of omacom/omarchy; the rest of the distribution is not covered.
Apple Silicon: GRUB migrations make encrypted (and btrfs) installs unbootable
Reported by severian-commits · filed Sep 22, 2026Closed upstream on 2026-10-08 by the bot omarchybot, as not planned.
At a glance
- 1 · What is claimed?
- Only the report text below — no validator has restated it as checkable claims yet.
- 2 · What does it affect?
- Not yet mapped to any requirement or component.
- 3 · Is it reproducible?
- No validation has been run yet.
- 4 · What remains unclear?
- Not validated yet: no claims, no reproducer.
- 5 · What happens next?
- Our staff decide whether the report is valid. Where this project allows it, agents decide whether it duplicates another report or a known issue. No decision has been recorded yet.
Original report
System details
M1 MacBook (Apple Silicon), Asahi/Arch Linux ARM, Omarchy 4.0.4 (omarchy-dev r7060.g2a47d45), LUKS2 + btrfs, busybox mkinitcpio
What's wrong?
Summary
Two independent bugs in the Apple Silicon GRUB migrations each leave the machine unable to boot after omarchy-update:
- Migration `1790003445` ("Quiet the GRUB boot on Apple Silicon") overwrites `GRUB_CMDLINE_LINUX_DEFAULT` wholesale. The installer puts
cryptdevice=…androotflags=subvol=@in that key, so both are deleted. The regeneratedgrub.cfghas nocryptdevice=, theencrypthook never prompts, and boot drops to the mkinitcpio emergency shell withdevice 'UUID=<btrfs uuid>' not found. - `install/hardware/apple/grub-console.sh` (migrations `1790030337` and `1790037110`) appends `rootflags=x-systemd.device-timeout=0` to `GRUB_CMDLINE_LINUX`. The Apple Silicon image boots a busybox mkinitcpio initramfs, not systemd, and its parser keeps only the last
rootflags=. grub-mkconfig emitsrootflags=subvol=@first, so the appended option replaces it. The root filesystem then mounts at the btrfs top level (subvolid 5) instead of@, and there is no init to run. This affects every Apple Silicon btrfs install, encrypted or not. The option also has no effect without systemd in the initramfs.
Environment
- M1 MacBook, Omarchy on Asahi (Arch Linux ARM), LUKS2 root with btrfs inside, busybox mkinitcpio (
HOOKS=(base asahi udev autodetect microcode modconf kms keyboard keymap consolefont block encrypt filesystems fsck)) omarchy-dev 4.0.4.r7060.g2a47d45-1,asahi-scripts 20260127.1-1,grub 2:2.14-1.1,mkinitcpio 42-1/bootis the ESP; GRUB is regenerated through Asahi'supdate-grub→grub-mkconfig
Bug 1: quiet-boot migration deletes the installer's cmdline
/etc/default/grub as installed (backup /etc/default/grub.bak.20260910165426):
GRUB_CMDLINE_LINUX_DEFAULT="cryptdevice=UUID=<luks-uuid>:root:allow-discards rootflags=subvol=@ loglevel=3 quiet"
GRUB_CMDLINE_LINUX=""1790003445.sh runs:
set_assignment GRUB_CMDLINE_LINUX_DEFAULT "$wanted_cmdline" # fixed string, replaces the whole value
sudo update-grubAfterwards:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash loglevel=0 systemd.show_status=false rd.udev.log_level=0 vt.global_cursor_default=0"
GRUB_CMDLINE_LINUX=""Resulting kernel command line (no cryptdevice=):
BOOT_IMAGE=/vmlinuz-linux-asahi root=UUID=<btrfs-uuid> rw rootflags=subvol=@ quiet splash loglevel=0 …On the next boot there is no passphrase prompt and you land in [rootfs ~]#. Manual recovery: cryptsetup open /dev/nvme0n1p5 root && mount -o rw,subvol=@ /dev/mapper/root /sysroot && exit.
Bug 2: rootflags=x-systemd.device-timeout=0 replaces subvol=@
grub-console.sh:
device_wait='rootflags=x-systemd.device-timeout=0'
…
grub_console_set GRUB_CMDLINE_LINUX "${cmdline:+$cmdline }$device_wait"Generated linux line:
linux /vmlinuz-linux-asahi root=UUID=<btrfs-uuid> rw rootflags=subvol=@ cryptdevice=… rootflags=x-systemd.device-timeout=0 quiet splash …mkinitcpio's parse_cmdline_item runs eval "$key"='${value:-y}' for every parameter, so the last value wins, and mount_handler runs mount -o "${rwopt},${rootflags}" with rootflags=x-systemd.device-timeout=0. The btrfs default subvolume is ID 5 (btrfs subvolume get-default / → ID 5 (FS_TREE)), so /new_root holds @, @home, @log… rather than a root filesystem.
Suggested fixes
- 1790003445 / the finalizer: edit only the tokens being changed, e.g. remove
loglevel=3and add the quiet flags, instead of assigning a fixed string. Or move the installer'scryptdevice=androotflags=subvol=@intoGRUB_CMDLINE_LINUX, where they belong because they're needed in every entry, recovery included. Before anyupdate-grub, refuse to regenerate if the root is on LUKS and nocryptdevice=/rd.luks.*survives. - grub-console.sh: drop
rootflags=x-systemd.device-timeout=0on busybox initramfs. For a busybox init, the root-wait equivalent isrootwaitorrootdelay=. If it has to stay, merge it into the existing flags (rootflags=subvol=@,x-systemd.device-timeout=0) rather than adding a secondrootflags=. - Since both bugs only show at the next reboot, a post-update check that every
linuxline has the unlock option and that its lastrootflags=containssubvol=would have caught each of them. I have one running locally (described below) and I'm happy to contribute it.
Local workaround
GRUB_CMDLINE_LINUX="cryptdevice=UUID=<luks-uuid>:root rootflags=x-systemd.device-timeout=0 rootflags=subvol=@"grub-console.sh finds its token and leaves the line alone, and subvol=@ stays last. Then run sudo grub-mkconfig -o /boot/grub/grub.cfg. I also run a guard (verify-boot-unlock) from a pacman PostTransaction hook and from a systemd .path unit on /boot/grub/grub.cfg. The path unit is needed because these migrations regenerate GRUB outside any pacman transaction, so a pacman hook alone never sees the change.
Related
#7222 is the same class of mismatch (a systemd-style option on a busybox encrypt initramfs) on the Quattro upgrade path, but through rd.luks.name rather than these GRUB migrations.
View raw text
### System details
M1 MacBook (Apple Silicon), Asahi/Arch Linux ARM, Omarchy 4.0.4 (omarchy-dev r7060.g2a47d45), LUKS2 + btrfs, busybox mkinitcpio
### What's wrong?
## Summary
Two independent bugs in the Apple Silicon GRUB migrations each leave the machine unable to boot after `omarchy-update`:
1. **Migration `1790003445` ("Quiet the GRUB boot on Apple Silicon") overwrites `GRUB_CMDLINE_LINUX_DEFAULT` wholesale.** The installer puts `cryptdevice=…` and `rootflags=subvol=@` in that key, so both are deleted. The regenerated `grub.cfg` has no `cryptdevice=`, the `encrypt` hook never prompts, and boot drops to the mkinitcpio emergency shell with `device 'UUID=<btrfs uuid>' not found`.
2. **`install/hardware/apple/grub-console.sh` (migrations `1790030337` and `1790037110`) appends `rootflags=x-systemd.device-timeout=0` to `GRUB_CMDLINE_LINUX`.** The Apple Silicon image boots a busybox mkinitcpio initramfs, not systemd, and its parser keeps only the **last** `rootflags=`. grub-mkconfig emits `rootflags=subvol=@` first, so the appended option replaces it. The root filesystem then mounts at the btrfs top level (subvolid 5) instead of `@`, and there is no init to run. This affects **every** Apple Silicon btrfs install, encrypted or not. The option also has no effect without systemd in the initramfs.
## Environment
- M1 MacBook, Omarchy on Asahi (Arch Linux ARM), LUKS2 root with btrfs inside, busybox mkinitcpio (`HOOKS=(base asahi udev autodetect microcode modconf kms keyboard keymap consolefont block encrypt filesystems fsck)`)
- `omarchy-dev 4.0.4.r7060.g2a47d45-1`, `asahi-scripts 20260127.1-1`, `grub 2:2.14-1.1`, `mkinitcpio 42-1`
- `/boot` is the ESP; GRUB is regenerated through Asahi's `update-grub` → `grub-mkconfig`
## Bug 1: quiet-boot migration deletes the installer's cmdline
`/etc/default/grub` as installed (backup `/etc/default/grub.bak.20260910165426`):
```
GRUB_CMDLINE_LINUX_DEFAULT="cryptdevice=UUID=<luks-uuid>:root:allow-discards rootflags=subvol=@ loglevel=3 quiet"
GRUB_CMDLINE_LINUX=""
```
`1790003445.sh` runs:
```bash
set_assignment GRUB_CMDLINE_LINUX_DEFAULT "$wanted_cmdline" # fixed string, replaces the whole value
sudo update-grub
```
Afterwards:
```
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash loglevel=0 systemd.show_status=false rd.udev.log_level=0 vt.global_cursor_default=0"
GRUB_CMDLINE_LINUX=""
```
Resulting kernel command line (no `cryptdevice=`):
```
BOOT_IMAGE=/vmlinuz-linux-asahi root=UUID=<btrfs-uuid> rw rootflags=subvol=@ quiet splash loglevel=0 …
```
On the next boot there is no passphrase prompt and you land in `[rootfs ~]#`. Manual recovery: `cryptsetup open /dev/nvme0n1p5 root && mount -o rw,subvol=@ /dev/mapper/root /sysroot && exit`.
## Bug 2: `rootflags=x-systemd.device-timeout=0` replaces `subvol=@`
`grub-console.sh`:
```bash
device_wait='rootflags=x-systemd.device-timeout=0'
…
grub_console_set GRUB_CMDLINE_LINUX "${cmdline:+$cmdline }$device_wait"
```
Generated `linux` line:
```
linux /vmlinuz-linux-asahi root=UUID=<btrfs-uuid> rw rootflags=subvol=@ cryptdevice=… rootflags=x-systemd.device-timeout=0 quiet splash …
```
mkinitcpio's `parse_cmdline_item` runs `eval "$key"='${value:-y}'` for every parameter, so the last value wins, and `mount_handler` runs `mount -o "${rwopt},${rootflags}"` with `rootflags=x-systemd.device-timeout=0`. The btrfs default subvolume is ID 5 (`btrfs subvolume get-default /` → `ID 5 (FS_TREE)`), so `/new_root` holds `@`, `@home`, `@log`… rather than a root filesystem.
## Suggested fixes
- **1790003445 / the finalizer:** edit only the tokens being changed, e.g. remove `loglevel=3` and add the quiet flags, instead of assigning a fixed string. Or move the installer's `cryptdevice=` and `rootflags=subvol=@` into `GRUB_CMDLINE_LINUX`, where they belong because they're needed in every entry, recovery included. Before any `update-grub`, refuse to regenerate if the root is on LUKS and no `cryptdevice=`/`rd.luks.*` survives.
- **grub-console.sh:** drop `rootflags=x-systemd.device-timeout=0` on busybox initramfs. For a busybox init, the root-wait equivalent is `rootwait` or `rootdelay=`. If it has to stay, merge it into the existing flags (`rootflags=subvol=@,x-systemd.device-timeout=0`) rather than adding a second `rootflags=`.
- Since both bugs only show at the next reboot, a post-update check that every `linux` line has the unlock option and that its last `rootflags=` contains `subvol=` would have caught each of them. I have one running locally (described below) and I'm happy to contribute it.
## Local workaround
```
GRUB_CMDLINE_LINUX="cryptdevice=UUID=<luks-uuid>:root rootflags=x-systemd.device-timeout=0 rootflags=subvol=@"
```
`grub-console.sh` finds its token and leaves the line alone, and `subvol=@` stays last. Then run `sudo grub-mkconfig -o /boot/grub/grub.cfg`. I also run a guard (`verify-boot-unlock`) from a pacman `PostTransaction` hook and from a systemd `.path` unit on `/boot/grub/grub.cfg`. The path unit is needed because these migrations regenerate GRUB outside any pacman transaction, so a pacman hook alone never sees the change.
## Related
#7222 is the same class of mismatch (a systemd-style option on a busybox `encrypt` initramfs) on the Quattro upgrade path, but through `rd.luks.name` rather than these GRUB migrations.
Validation
Not checked yet. A validator will restate this report as checkable claims, map it to the project's requirements and write a reproducer that the proof engine runs.
Linked
Not linked to any known issue, other report or change yet.
Decision
Decisions are recorded by our staff — or, where this project allows it, by agents: checked by a second, independent agent, or by a single agent where the project's policy says so. Any decision reached so far is shown below.
No decision has been recorded yet.