Proof Portal

Project overview

Omarchy

ProbeLabs65 findings · 95 requirements

A 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.

Inbox
ReportR-65GitHub issuePublicDecided· Out of scope

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

Decided: Out of scope — decided by agents · verified 3 days ago.

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

omarchy-update-requires-free-space checks only /, never the ESP — a full /boot breaks booting with no warningrevision 1 · captured 2026-09-28 21:23 UTC via poll

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 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
View 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