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-553GitHub issuePublicDecided· Out of scope

limine-mkinitcpio's boot-entry cmdline is sourced from /proc/cmdline, not target config — breaks chroot/clone builds targeting a different root

Reported by pastorinj-pixel · filed Sep 15, 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

limine-mkinitcpio's boot-entry cmdline is sourced from /proc/cmdline, not target config — breaks chroot/clone builds targeting a different rootrevision 1 · captured 2026-09-28 21:23 UTC via poll

Summary

When building/updating boot entries for a different root than the one currently booted (chroot into another drive's mounted root, cloning a system to a second disk, restoring a Btrfs snapshot from a live emergency shell, etc.), limine-mkinitcpio writes boot-entry cmdline: values sourced from the live host's /proc/cmdline rather than the target root's own /etc/default/limine / /etc/kernel/cmdline — even when those target config files are correct.

Reproduction

  1. Have a working Omarchy install (system A) with LUKS+Btrfs+Limine/UKI, currently booted.
  2. Prepare a second LUKS+Btrfs filesystem (system B) with its own distinct /etc/kernel/cmdline and /etc/default/limine (different PARTUUID than system A).
  3. Bind-mount /dev /proc /sys from the live host into system B's mounted root, chroot in, and run limine-mkinitcpio.
  4. Inspect the resulting /boot/limine.conf (on system B's ESP): the new OS entry's cmdline: line contains system A's cryptdevice=PARTUUID=... (and any other live-only params, e.g. resume=/resume_offset= for system A's swapfile), not system B's.

Root cause (as far as I could trace it without the binary's source)

/usr/share/libalpm/scripts/limine-mkinitcpio-install's resolve_cmdline_file() calls limine-entry-tool --get-cmdline <kernel> --no-mutex --no-hooks, and this call correctly returns the chrooted target's own config (verified directly — matches /etc/default/limine inside the chroot). So the UKI's embedded cmdline is fine.

The boot-menu entry's displayed cmdline: field (written by the later limine-entry-tool --add-uki ... call in install_uki()) does not match what --get-cmdline returned — it matches /proc/cmdline byte-for-byte instead, which inside a chroot is bind-mounted from the live host, not the target. /usr/lib/limine/limine-entry-tool is a stripped ELF in this version (1.38.0-1.1) so I couldn't trace the exact internal code path, but the behavior is reproducible and the values line up exactly with /proc/cmdline.

This is presumably intentional for the normal use case (updating boot entries for the system you're actually running on, where /proc/cmdline correctly reflects that same root) but is actively wrong whenever the target root differs from the live host — chroots, clones, rescue-media builds, arch-chroot-based recovery, etc.

Impact

A boot entry can be silently built with another system's PARTUUID/cryptdevice/resume parameters baked in, producing a config that looks correct at a glance (files edited correctly, --get-cmdline tested standalone and correct) but fails at actual boot. This is the same failure class as omacom/omarchy#11878, just triggered by chroot/clone workflows instead of an update.

Workaround used

After running limine-mkinitcpio, diff the generated /boot/limine.conf cmdline: line(s) against the target's own /etc/kernel/cmdline//etc/default/limine, and hand-patch any mismatch before trusting the entry.

Suggestion

--add-uki/--add-kernel's cmdline-for-display logic should source from the same place --get-cmdline does (the target's own /etc/default/limine//etc/kernel/cmdline), not /proc/cmdline — or at minimum, should prefer the already-resolved CMDLINE_FILE that resolve_cmdline_file() produced earlier in the same script, rather than re-deriving it independently.

View raw text
## Summary
When building/updating boot entries for a **different root than the one currently booted** (chroot into another drive's mounted root, cloning a system to a second disk, restoring a Btrfs snapshot from a live emergency shell, etc.), `limine-mkinitcpio` writes boot-entry `cmdline:` values sourced from the *live host's* `/proc/cmdline` rather than the target root's own `/etc/default/limine` / `/etc/kernel/cmdline` — even when those target config files are correct.

## Reproduction
1. Have a working Omarchy install (system A) with LUKS+Btrfs+Limine/UKI, currently booted.
2. Prepare a second LUKS+Btrfs filesystem (system B) with its own distinct `/etc/kernel/cmdline` and `/etc/default/limine` (different PARTUUID than system A).
3. Bind-mount `/dev /proc /sys` from the live host into system B's mounted root, `chroot` in, and run `limine-mkinitcpio`.
4. Inspect the resulting `/boot/limine.conf` (on system B's ESP): the new OS entry's `cmdline:` line contains system A's `cryptdevice=PARTUUID=...` (and any other live-only params, e.g. `resume=`/`resume_offset=` for system A's swapfile), not system B's.

## Root cause (as far as I could trace it without the binary's source)
`/usr/share/libalpm/scripts/limine-mkinitcpio-install`'s `resolve_cmdline_file()` calls `limine-entry-tool --get-cmdline <kernel> --no-mutex --no-hooks`, and **this call correctly returns the chrooted target's own config** (verified directly — matches `/etc/default/limine` inside the chroot). So the UKI's *embedded* cmdline is fine.

The boot-menu entry's *displayed* `cmdline:` field (written by the later `limine-entry-tool --add-uki ...` call in `install_uki()`) does not match what `--get-cmdline` returned — it matches `/proc/cmdline` byte-for-byte instead, which inside a chroot is bind-mounted from the live host, not the target. `/usr/lib/limine/limine-entry-tool` is a stripped ELF in this version (1.38.0-1.1) so I couldn't trace the exact internal code path, but the behavior is reproducible and the values line up exactly with `/proc/cmdline`.

This is presumably intentional for the *normal* use case (updating boot entries for the system you're actually running on, where `/proc/cmdline` correctly reflects that same root) but is actively wrong whenever the target root differs from the live host — chroots, clones, rescue-media builds, `arch-chroot`-based recovery, etc.

## Impact
A boot entry can be silently built with another system's PARTUUID/cryptdevice/resume parameters baked in, producing a config that looks correct at a glance (files edited correctly, `--get-cmdline` tested standalone and correct) but fails at actual boot. This is the same failure class as omacom/omarchy#11878, just triggered by chroot/clone workflows instead of an update.

## Workaround used
After running `limine-mkinitcpio`, diff the generated `/boot/limine.conf` `cmdline:` line(s) against the target's own `/etc/kernel/cmdline`/`/etc/default/limine`, and hand-patch any mismatch before trusting the entry.

## Suggestion
`--add-uki`/`--add-kernel`'s cmdline-for-display logic should source from the same place `--get-cmdline` does (the target's own `/etc/default/limine`/`/etc/kernel/cmdline`), not `/proc/cmdline` — or at minimum, should prefer the already-resolved `CMDLINE_FILE` that `resolve_cmdline_file()` produced earlier in the same script, rather than re-deriving it independently.

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 13:33 UTC