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.
Low battery notification never auto-dismisses and survives shell restarts (critical urgency ignores expire timeout)
Reported by elonmask · filed Oct 8, 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
What happened
The low-battery warning toast ("Time to recharge! Battery is down to 10%") never goes away on its own, and it comes back after every shell restart even when the laptop is plugged in again. It stays on screen indefinitely until manually clicked/dismissed.
What I expected
The toast to disappear after its 30-second timeout (), and/or to be dismissed when AC power is reconnected.
Steps to reproduce
- Discharge the battery to <= 10% (threshold is 10 in the battery service).
- The toast appears via , which sends it with urgency
criticaland-t 30000. - Observe: the toast never auto-expires. Plug in the charger — nothing dismisses it.
- Restart the shell ( or any restart during update): the toast is restored again (and again), because critical popups are treated as never-expiring.
Root cause analysis
In shell/plugins/notifications/Service.qml:
durationFor()returns0forNotificationUrgency.Critical, which means the popup has no lifetime at all — the countdown timer in the popup delegate (ticking: cardSlot.lifetime > 0 && !card.hovered) never runs, so the toast can only be removed by user interaction.- The
expireTimeoutthe sender explicitly requested (-t 30000= 30000 ms) is ignored for critical notifications —requestedDuration()is only consulted for low/normal urgency. - In
restorePopups(),popupExpired()treatsduration 0as "never expires and always survives restarts", so the toast is re-shown after every restart, even days later and while on AC power.
Additionally, nothing clears the low-battery warning when UPower.onBattery flips back to false (charging), so the notification outlives the condition it warns about.
Suggested directions (any one would resolve the user-facing issue):
- Honor a sender-provided positive expireTimeout even for critical urgency (perhaps with a floor, e.g. maxPopupDuration), so omarchy-battery-low's 30s timeout applies.
- Have the battery service (shell/plugins/services/battery/Service.qml) dismiss/replace its warning when AC power returns (e.g. via omarchy notification dismiss on onBatteryChanged).
Diagnostics
- Omarchy version: 4.0.4-1
- Kernel: 6.x omarchy build (
7.2.5-3-omarchy) - CPU: 13th Gen Intel Core i7-13620H
- GPU: Intel UHD (Raptor Lake-P) + NVIDIA RTX 5060 Max-Q (hybrid)
- Stale popup files observed in
~/.local/state/omarchy/notifications/for days-old low-battery toasts, confirming they persist and get restored across restarts.
Workaround for affected users: omarchy notification dismiss "Time to recharge" clears the stuck toast.
View raw text
## What happened
The low-battery warning toast ("Time to recharge! Battery is down to 10%") never goes away on its own, and it comes back after every shell restart even when the laptop is plugged in again. It stays on screen indefinitely until manually clicked/dismissed.
## What I expected
The toast to disappear after its 30-second timeout (), and/or to be dismissed when AC power is reconnected.
## Steps to reproduce
1. Discharge the battery to <= 10% (threshold is 10 in the battery service).
2. The toast appears via , which sends it with urgency `critical` and `-t 30000`.
3. Observe: the toast never auto-expires. Plug in the charger — nothing dismisses it.
4. Restart the shell ( or any restart during update): the toast is restored again (and again), because critical popups are treated as never-expiring.
## Root cause analysis
In `shell/plugins/notifications/Service.qml`:
- `durationFor()` returns `0` for `NotificationUrgency.Critical`, which means the popup has no lifetime at all — the countdown timer in the popup delegate (`ticking: cardSlot.lifetime > 0 && !card.hovered`) never runs, so the toast can only be removed by user interaction.
- The `expireTimeout` the sender explicitly requested (`-t 30000` = 30000 ms) is ignored for critical notifications — `requestedDuration()` is only consulted for low/normal urgency.
- In `restorePopups()`, `popupExpired()` treats `duration 0` as "never expires and always survives restarts", so the toast is re-shown after every restart, even days later and while on AC power.
Additionally, nothing clears the low-battery warning when `UPower.onBattery` flips back to false (charging), so the notification outlives the condition it warns about.
Suggested directions (any one would resolve the user-facing issue):
- Honor a sender-provided positive `expireTimeout` even for critical urgency (perhaps with a floor, e.g. `maxPopupDuration`), so `omarchy-battery-low`'s 30s timeout applies.
- Have the battery service (`shell/plugins/services/battery/Service.qml`) dismiss/replace its warning when AC power returns (e.g. via `omarchy notification dismiss` on `onBatteryChanged`).
## Diagnostics
- Omarchy version: 4.0.4-1
- Kernel: 6.x omarchy build (`7.2.5-3-omarchy`)
- CPU: 13th Gen Intel Core i7-13620H
- GPU: Intel UHD (Raptor Lake-P) + NVIDIA RTX 5060 Max-Q (hybrid)
- Stale popup files observed in `~/.local/state/omarchy/notifications/` for days-old low-battery toasts, confirming they persist and get restored across restarts.
Workaround for affected users: `omarchy notification dismiss "Time to recharge"` clears the stuck toast.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
- Fixed bypr/9790· 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.
- Out of scopeDecided by agents · verified · 2026-10-09 23:05 UTC