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.
omarchy-update-requires-free-space checks only /, never the ESP — a full /boot breaks booting with no warning
Reported by nanstey · filed Sep 26, 2026 · open at source
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?
- AreaOutside the audited area· Decided by agents · verified
- 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?
- Decided by agents and verified by a second, independent agent — see the decision.
Original report
Summary
omarchy-update-requires-free-space checks only /. It never checks /boot, which on a UKI + Limine install is the actual constrained resource. On my machine / had 1.7 TB free while the 2 GB ESP filled to the point where a kernel upgrade could not write its UKI, leaving the system unbootable. The guard cannot catch the failure mode it exists for.
Current behaviour
# /usr/share/omarchy/bin/omarchy-update-requires-free-space
elif read -r available_bytes < <(df --output=avail --block-size=1 / 2>/dev/null | tail -n 1) &&
[[ $available_bytes =~ ^[0-9]+$ ]] &&
(( available_bytes < 10 * 1024 * 1024 * 1024 )); then
echo "You need at least 10 GiB free to safely update Omarchy."/ only. A 10 GiB threshold on the root filesystem says nothing about an ESP that is typically 1–2 GB and holds objects in the hundreds of megabytes.
Why /boot is the real constraint
With limine-mkinitcpio, each kernel is a UKI in /boot/EFI/Linux/. limine-snapper-sync additionally retains one copy per snapshot in /boot/<machine-id>/limine_history/. So ESP demand is roughly:
(kernels + retained snapshots) x UKI sizeOn this system (Omarchy 4.0.3/4.0.4, desktop, RTX 4080 SUPER + Ryzen 7950X iGPU) the UKI was 280 MB because the initramfs bundled 245 MB of GPU firmware. With NUMBER_LIMIT=5 and MAX_SNAPSHOT_ENTRIES=6, steady-state demand is ~1.7 GB against a 2.0 GB ESP. It ran out.
Measured, before I intervened:
/dev/nvme0n1p1 2.0G 1.1G 933M 55% /boot
834M /boot/EFI/Linux
280M omarchy_linux.efi
277M recovery20260920_linux-omarchy.efi
277M recovery20260920_linux.efi
277M /boot/<machine-id>/limine_history/omarchy_linux.efi_sha256_...Observed consequence
The normal root became unbootable and I was forced onto a recovery subvolume. That has a compounding effect worth noting separately: while booted from recovery, /etc/default/limine in the recovery root pins rootflags=subvol=/@recovery-saved-… and sets BOOT_ORDER="linux-omarchy, …", so every subsequent pacman hook regenerates /boot/limine.conf pointing back at recovery — while /etc edits land in a subvolume the normal root never reads. The user-visible symptoms were "I always have to boot recovery", "my system config doesn't persist", and "snapshots stopped working" (snapshot sync silently stops when it cannot copy a UKI). One root cause, three symptoms, no diagnostic anywhere in the update path.
snapper -c root list showed exactly one snapshot from two weeks earlier against a configured NUMBER_LIMIT=5; sync had been failing silently that whole time.
Suggested fix
Extend the preflight to the ESP, sized against what the update will actually write rather than a fixed constant:
- Resolve the ESP via
ESP_PATH(/etc/default/limine, default/boot). - Require at least
largest existing UKI x (kernels to build + 1)free, or a conservative floor. - Account for
limine-snapper-syncretention (MAX_SNAPSHOT_ENTRIES, snapperNUMBER_LIMIT) when the ESP is shared withlimine_history. - Fail with a message naming
/bootand the shortfall, so the cause is obvious instead of surfacing later as an unbootable system.
A cheap partial win: warn whenever ESP free space is below the size of the current UKI, even if the update proceeds.
Environment
Omarchy 4.0.3 -> 4.0.4
kernel 7.2.3-arch1-3 / linux-omarchy 7.2.5-3
boot Limine 12.8.0, UKI, ESP 2.0 GB vfat
root btrfs @ on LUKS2, TPM2 auto-unlock (sd-encrypt)
hardware Ryzen 9 7950X (Raphael iGPU present, headless) + RTX 4080 SUPERView raw text
### Summary `omarchy-update-requires-free-space` checks only `/`. It never checks `/boot`, which on a UKI + Limine install is the actual constrained resource. On my machine `/` had 1.7 TB free while the 2 GB ESP filled to the point where a kernel upgrade could not write its UKI, leaving the system unbootable. The guard cannot catch the failure mode it exists for. ### Current behaviour ```bash # /usr/share/omarchy/bin/omarchy-update-requires-free-space elif read -r available_bytes < <(df --output=avail --block-size=1 / 2>/dev/null | tail -n 1) && [[ $available_bytes =~ ^[0-9]+$ ]] && (( available_bytes < 10 * 1024 * 1024 * 1024 )); then echo "You need at least 10 GiB free to safely update Omarchy." ``` `/` only. A 10 GiB threshold on the root filesystem says nothing about an ESP that is typically 1–2 GB and holds objects in the hundreds of megabytes. ### Why /boot is the real constraint With `limine-mkinitcpio`, each kernel is a UKI in `/boot/EFI/Linux/`. `limine-snapper-sync` additionally retains one **copy per snapshot** in `/boot/<machine-id>/limine_history/`. So ESP demand is roughly: ``` (kernels + retained snapshots) x UKI size ``` On this system (Omarchy 4.0.3/4.0.4, desktop, RTX 4080 SUPER + Ryzen 7950X iGPU) the UKI was **280 MB** because the initramfs bundled 245 MB of GPU firmware. With `NUMBER_LIMIT=5` and `MAX_SNAPSHOT_ENTRIES=6`, steady-state demand is ~1.7 GB against a 2.0 GB ESP. It ran out. Measured, before I intervened: ``` /dev/nvme0n1p1 2.0G 1.1G 933M 55% /boot 834M /boot/EFI/Linux 280M omarchy_linux.efi 277M recovery20260920_linux-omarchy.efi 277M recovery20260920_linux.efi 277M /boot/<machine-id>/limine_history/omarchy_linux.efi_sha256_... ``` ### Observed consequence The normal root became unbootable and I was forced onto a recovery subvolume. That has a compounding effect worth noting separately: while booted from recovery, `/etc/default/limine` in the recovery root pins `rootflags=subvol=/@recovery-saved-…` and sets `BOOT_ORDER="linux-omarchy, …"`, so every subsequent pacman hook regenerates `/boot/limine.conf` pointing back at recovery — while `/etc` edits land in a subvolume the normal root never reads. The user-visible symptoms were "I always have to boot recovery", "my system config doesn't persist", and "snapshots stopped working" (snapshot sync silently stops when it cannot copy a UKI). One root cause, three symptoms, no diagnostic anywhere in the update path. `snapper -c root list` showed exactly one snapshot from two weeks earlier against a configured `NUMBER_LIMIT=5`; sync had been failing silently that whole time. ### Suggested fix Extend the preflight to the ESP, sized against what the update will actually write rather than a fixed constant: - Resolve the ESP via `ESP_PATH` (`/etc/default/limine`, default `/boot`). - Require at least `largest existing UKI x (kernels to build + 1)` free, or a conservative floor. - Account for `limine-snapper-sync` retention (`MAX_SNAPSHOT_ENTRIES`, snapper `NUMBER_LIMIT`) when the ESP is shared with `limine_history`. - Fail with a message naming `/boot` and the shortfall, so the cause is obvious instead of surfacing later as an unbootable system. A cheap partial win: warn whenever ESP free space is below the size of the current UKI, even if the update proceeds. ### Environment ``` Omarchy 4.0.3 -> 4.0.4 kernel 7.2.3-arch1-3 / linux-omarchy 7.2.5-3 boot Limine 12.8.0, UKI, ESP 2.0 GB vfat root btrfs @ on LUKS2, TPM2 auto-unlock (sd-encrypt) hardware Ryzen 9 7950X (Raphael iGPU present, headless) + RTX 4080 SUPER ```
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.
- Out of scopeDecided by agents · verified · 2026-10-09 19:53 UTC