Proof Portal
Omarchy
ProbeLabsviewing a historical runA 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.
dmenu request lifecycle drops waiters on re-summon, on a busy resultProc, and for doneFile-only requests
Low-severity issue, currently open.
What this means for you
Plain-language impact — what this issue could mean for your users and your system, before any of the technical detail.
With this change, a second summon before you answer the previous one cancels the earlier request, and its caller exits. Pressing Super+K several times is one example. If the menu process dies while a caller waits, that caller still waits forever in the background, and its action never completes. Later menus still open and work.
Technical description
On upstream quattro, a second open without close() replaces selectionFile/doneFile/requestActive and writes nothing to the previous done file. The first caller then waits forever (SX26/C06/C07; openExistingMenu/openDmenu bodies). This is omacom/omarchy#9057. The behavioural reproducer test/reports/report-cmulr95nw0kqr1gw46i7f50xj.sh drives two real omarchy-menu-select callers through the real Menu.qml open/openDmenu/cancel bodies. On quattro the superseded caller never gets its done file and polls forever. Upstream e332dc97 has no cancel-prior guard; #9056 adds one, and on this mirror the reproducer exits 0.
On upstream quattro, finishRequest wipes requestActive and both paths BEFORE resultProc.running = true. Quickshell therefore ignores a command change while the previous write runs, and the new selection disappears (SX26/C14). #9056 head b7bd59c4 writes each answer through its own process, which fixes this leg on this mirror. Still open here: the empty-selectionFile redirect variant (SX26/C15 and HFY2/C36), the doneFile-only leg, and a caller whose menu process dies (omarchy-menu-select has no deadline).
Affected requirements
The requirement(s) this issue violates — click through to the spec.
Severity, explained
Why this is rated the way it is — and the scoring signals behind the rating (each ⓘ explains the term).
- why this rating
- Risk-rated
- risk area
- Correctness
- CVE surface
- None
How it's proven
The reproducer — an actual test that drives the real code and shows the issue happening. Run it yourself, or peek the test and the source it covers.
known_issue_reproducerpocs/menu-qml-static.sh
Reproduction steps
Technical steps for your engineers to confirm the issue by hand.
pocs/menu-qml-static.sh
What protects you, and the fix
What limits your exposure today, and the planned remediation.
What protects you now
With this change, a new summon answers a superseded caller as cancelled, and that caller exits. A burst of 20 summons leaves 0 callers waiting on head b7bd59c4, against 19 of 20 on quattro c05d9019. Nothing bounds the wait when the menu process dies, so that caller keeps polling forever. Later summons still work.
The fix
Finish (or sentinel) the outstanding request before replacing its files; queue the write when resultProc is running; treat a doneFile-only request as cancel-only. #9056 (head b7bd59c4) answers a superseded request and fixes the busy-writer race; a deadline in omarchy-menu-select is still needed for a dead menu process.
Blast radius
If you touch this issue, what else may need re-checking — the requirements it affects and the code and tests that hang off them. Historical view: authored trace links only — automatically derived links aren't reconstructible for past runs.
Touch this finding and you re-check 10 requirements · 3 code files · 2 tests.
- Menu.qml
- omarchy-menu-input
- omarchy-menu-select
- menu-dmenu-test.sh
- menu-test.sh
Per-requirement evidence
For each requirement this finding touches: the implementing code, verifying tests, and proof obligations that discharge it.
Per-requirement evidence
For each requirement this finding touches: the implementing code, verifying tests, and proof obligations that discharge it.
Evidence trail
The raw evidence manifests behind this finding — superseded by the resolved reproducer above, kept here for traceability.
Evidence trail
The raw evidence manifests behind this finding — superseded by the resolved reproducer above, kept here for traceability.
- pocs/menu-qml-static.sh
- proof/evidence/ki-menu-request-lifecycle.yaml
- test/reports/report-cmulr95nw0kqr1gw46i7f50xj.sh
Change history
Every recorded revision of this finding's source file — when it was added, edited, or re-classified, with the diff for each change.
Discussions
Discuss this with the proof team. Nothing changes in your audit automatically — you open a request and a staff member records any outcome inside the thread.