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-system-sleep-lock posts a new critical notification per failure, so a repeating fault leaves unbounded reboot-persistent toasts
Reported by Mahdi-Si · filed Sep 7, 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?
- 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. So far: partly in the audited area (lock) — decided by agents · verified; matches no known issue — decided by agents · verified. The outcome (valid, duplicate, not a bug, …) is not decided yet. See the decision.
Original report
What's wrong?
omarchy-system-sleep-lock is a first-party sender that can fire on a condition which repeats indefinitely, but it posts each failure as a brand-new critical notification instead of replacing the previous one. Because critical toasts are stored with expire_timeout: 0 and the live-popup directory is uncapped, a repeating fault accumulates permanent on-screen cards that are replayed on every shell start.
On this machine a 20-minute fault window left 38 never-expiring critical toasts that survived two reboots and were still on screen three days later.
report_unsecured() in bin/omarchy-system-sleep-lock:
omarchy-notification-send -u critical -g \
"Screen did not lock before suspend" \
"The session was left unlocked ($1)." >/dev/null 2>&1 || trueNo -r/--replace-id, even though omarchy-notification-send supports -r/--replace-id and -p/--print-id.
Two shell-side properties turn that from noisy into permanent:
- Critical notifications carry
expireTimeout: 0, so they never auto-dismiss and never leavepopupStateDiron their own. shell/plugins/notifications/Service.qmlcapshistoryDirathistoryLimit: 10, but `popupStateDir` has no equivalent cap. Live toasts are mirrored to~/.local/state/omarchy/notifications/*.jsonand replayed on every shell start.
Net effect: any repeating critical-urgency source grows the live-popup set without bound, and every card persists across reboots until dismissed by hand.
replaces_id does work — verified
Since #7834 concerns replacement hints being ignored, I verified the portable path actually functions in the shipped 4.0.2 shell before proposing it:
id=$(omarchy-notification-send -u critical -p "REPLACE-TEST" "first") # -> 4
omarchy-notification-send -u critical -r "$id" "REPLACE-TEST" "second"
omarchy-notification-send -u critical -r "$id" "REPLACE-TEST" "third"Result: exactly one file in popupStateDir, id 4, body third. replaces_id collapses correctly. The fix below is therefore verified rather than assumed.
Steps to reproduce
Any condition that makes the lock miss its budget repeatedly reproduces this. In my case:
- Laptop reaches critical battery with the lid closed.
- Machine enters a suspend/wake loop — suspend, spurious wake ~8s later, logind re-suspends ~24s later (45s period).
- Each cycle, the just-resumed Quickshell cannot reach
securewithinbudget_cap_ms=12000while amdgpu/xHCI are still re-initialising, soreport_unsecuredfires. - 28 cycles produced 28 identical critical toasts; 38 total with earlier ones.
- Reboot twice — every non-expiring critical is restored to the screen.
A synthetic repro needs no battery fault: call omarchy-notification-send -u critical in a loop and observe that nothing ever caps or coalesces the result.
Expected
A repeating identical failure collapses into one card (optionally with a count), and the persisted live-popup set is bounded the way history already is.
Actual
38 separate critical toasts, unbounded, restored across reboots, each requiring manual dismissal.
Suggested fix
In report_unsecured, persist the id from omarchy-notification-send -p (e.g. under ~/.local/state/omarchy/) and pass it back via -r on later failures, so repeats replace instead of accumulating. Verified working above.
Separately, consider bounding popupStateDir the way historyDir is bounded, so no repeating critical sender can grow it without limit.
Scope — what is not being claimed
- The trigger here was a dying battery. That is not Omarchy's fault, and the warning was correct: the session genuinely did suspend unlocked 28 times. I am not asking for the warning to be suppressed.
- The lock path on this machine is otherwise healthy — running
omarchy-system-sleep-lockdirectly returnssecure: true, exit0, in 0.65s against the 12000ms budget. - The report is only about the unbounded, non-coalescing, reboot-persistent notification behaviour for a repeating condition.
Related
- #7834 — replacement hints ignored by the 4.0 shell. That issue notes
replaces_idis the portable mechanism; this is a first-party sender not using it. Complementary, not duplicate. - #10145 — identical notifications no longer grouped since Quickshell replaced mako. Adjacent: daemon-side grouping would mask this symptom. Filed separately because the call-site fix is one line and independent of it, and because the uncapped
popupStateDiris its own failure mode. - #7280 —
omarchy-sleep-lock.servicerestart thrash while logind's sleep is in flight. I also observed this (restart counter reached 83,Failed to inhibit: ... already running), and am not re-reporting it; noting only that it co-occurs in the same fault window. - #10299 — stalled lock latches
lockRequested. Different failure, not what happened here:lock statusshowedlastEvent: "init"with no latch.
System details
| Omarchy | 4.0.2-1 (stable) |
| Kernel | 7.1.9-arch1-2 |
| CPU | AMD Ryzen 7 4800HS with Radeon Graphics |
| GPU | AMD Renoir (Radeon Vega) + NVIDIA GTX 1660 Ti Mobile |
| Quickshell | 0.3.1-1 |
| Hyprland | 0.56.2 |
| systemd | 261.2-1-arch |
report_unsecured on current quattro is byte-identical to the shipped 4.0.2 copy, so this is present on the default branch.
View raw text
### What's wrong? `omarchy-system-sleep-lock` is a first-party sender that can fire on a condition which repeats indefinitely, but it posts each failure as a brand-new critical notification instead of replacing the previous one. Because critical toasts are stored with `expire_timeout: 0` and the live-popup directory is uncapped, a repeating fault accumulates permanent on-screen cards that are replayed on every shell start. On this machine a 20-minute fault window left **38 never-expiring critical toasts** that survived two reboots and were still on screen three days later. `report_unsecured()` in `bin/omarchy-system-sleep-lock`: ```bash omarchy-notification-send -u critical -g \ "Screen did not lock before suspend" \ "The session was left unlocked ($1)." >/dev/null 2>&1 || true ``` No `-r`/`--replace-id`, even though `omarchy-notification-send` supports `-r/--replace-id` and `-p/--print-id`. Two shell-side properties turn that from noisy into permanent: 1. Critical notifications carry `expireTimeout: 0`, so they never auto-dismiss and never leave `popupStateDir` on their own. 2. `shell/plugins/notifications/Service.qml` caps `historyDir` at `historyLimit: 10`, but **`popupStateDir` has no equivalent cap**. Live toasts are mirrored to `~/.local/state/omarchy/notifications/*.json` and replayed on every shell start. Net effect: any repeating critical-urgency source grows the live-popup set without bound, and every card persists across reboots until dismissed by hand. ### `replaces_id` does work — verified Since #7834 concerns replacement hints being ignored, I verified the portable path actually functions in the shipped 4.0.2 shell before proposing it: ```bash id=$(omarchy-notification-send -u critical -p "REPLACE-TEST" "first") # -> 4 omarchy-notification-send -u critical -r "$id" "REPLACE-TEST" "second" omarchy-notification-send -u critical -r "$id" "REPLACE-TEST" "third" ``` Result: exactly one file in `popupStateDir`, id `4`, body `third`. `replaces_id` collapses correctly. The fix below is therefore verified rather than assumed. ### Steps to reproduce Any condition that makes the lock miss its budget repeatedly reproduces this. In my case: 1. Laptop reaches critical battery with the lid closed. 2. Machine enters a suspend/wake loop — suspend, spurious wake ~8s later, logind re-suspends ~24s later (45s period). 3. Each cycle, the just-resumed Quickshell cannot reach `secure` within `budget_cap_ms=12000` while amdgpu/xHCI are still re-initialising, so `report_unsecured` fires. 4. 28 cycles produced 28 identical critical toasts; 38 total with earlier ones. 5. Reboot twice — every non-expiring critical is restored to the screen. A synthetic repro needs no battery fault: call `omarchy-notification-send -u critical` in a loop and observe that nothing ever caps or coalesces the result. ### Expected A repeating identical failure collapses into one card (optionally with a count), and the persisted live-popup set is bounded the way history already is. ### Actual 38 separate critical toasts, unbounded, restored across reboots, each requiring manual dismissal. ### Suggested fix In `report_unsecured`, persist the id from `omarchy-notification-send -p` (e.g. under `~/.local/state/omarchy/`) and pass it back via `-r` on later failures, so repeats replace instead of accumulating. Verified working above. Separately, consider bounding `popupStateDir` the way `historyDir` is bounded, so no repeating critical sender can grow it without limit. ### Scope — what is *not* being claimed - The **trigger** here was a dying battery. That is not Omarchy's fault, and the warning was **correct**: the session genuinely did suspend unlocked 28 times. I am not asking for the warning to be suppressed. - The lock path on this machine is otherwise healthy — running `omarchy-system-sleep-lock` directly returns `secure: true`, exit `0`, in **0.65s** against the 12000ms budget. - The report is only about the **unbounded, non-coalescing, reboot-persistent notification behaviour** for a repeating condition. ### Related - **#7834** — replacement *hints* ignored by the 4.0 shell. That issue notes `replaces_id` is the portable mechanism; this is a first-party sender not using it. Complementary, not duplicate. - **#10145** — identical notifications no longer grouped since Quickshell replaced mako. Adjacent: daemon-side grouping would mask this symptom. Filed separately because the call-site fix is one line and independent of it, and because the uncapped `popupStateDir` is its own failure mode. - **#7280** — `omarchy-sleep-lock.service` restart thrash while logind's sleep is in flight. I also observed this (restart counter reached 83, `Failed to inhibit: ... already running`), and am **not** re-reporting it; noting only that it co-occurs in the same fault window. - **#10299** — stalled lock latches `lockRequested`. Different failure, not what happened here: `lock status` showed `lastEvent: "init"` with no latch. ### System details | | | |---|---| | Omarchy | 4.0.2-1 (stable) | | Kernel | 7.1.9-arch1-2 | | CPU | AMD Ryzen 7 4800HS with Radeon Graphics | | GPU | AMD Renoir (Radeon Vega) + NVIDIA GTX 1660 Ti Mobile | | Quickshell | 0.3.1-1 | | Hyprland | 0.56.2 | | systemd | 261.2-1-arch | `report_unsecured` on current `quattro` is byte-identical to the shipped 4.0.2 copy, so this is present on the default branch.
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
- Related PRpr/9790· confirmed
- Fixed bypr/10686· confirmed
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.
- Decided by agents · verified: partly in the audited area (lock)
- Decided by agents · verified: matches no known issue
The outcome (valid, duplicate, not a bug, …) is not decided yet.