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

hyprsunset is started unsupervised, so night light stays off for the rest of the session when it dies

Reported by samirpokharel · filed Aug 25, 2026 · open at source

Decided: Out of scope — decided by agents · verified 4 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

hyprsunset is started unsupervised, so night light stays off for the rest of the session when it diesrevision 1 · captured 2026-09-28 21:24 UTC via poll

What happened

A flapping HDMI connector (HDMI-A-1, Dell S2721HN) hotplugged four times in quick succession. Each disconnect destroyed that monitor's wl_output global, and libwayland-server then rejected every wl_registry.bind still in flight for it. XWayland printed the error verbatim:

XWAYLAND: wl_registry#2: error 0: global wl_output (73) is unavailable
(EE) failed to dispatch Wayland events: Protocol error

Thirteen Wayland clients died inside ~70 ms — Hyprland logged error in client communication for pids 1264, 1266, 1508, 1628, 1680, 1772, 4487, 10875, 215342 and 228982.

Omarchy recovered everything it supervises. The shell relaunched itself (Omarchy shell exited with status 255; relaunching.) and omarchy-fcitx5.service restarted on its own restart policy. hyprsunset did not come back, and night light stayed off for the rest of the session — 13 hours after the user had turned it on, and with no indication of why.

Why it doesn't recover

Omarchy starts hyprsunset as a bare transient scope with no restart policy, in two places:

  • bin/omarchy-toggle-nightlight:39 — setsid uwsm-app -- hyprsunset &
  • shell/plugins/services/nightlight/Service.qml:50 — the same thing, inlined into runApply

So any death is permanent for the session. Recovery requires the user to notice their screen went cold and toggle night light twice.

This also breaks the scheduled-profile path, which is the worse case. manual/13-toggles-idle-screensaver.md:55 documents o.launch_on_start("hyprsunset") as the way to get time-based profiles from ~/.config/hypr/hyprsunset.conf. That path is unsupervised too, so those users lose the entire schedule — not just a toggle — until they log out.

The hyprsunset package already ships a supervised unit at /usr/lib/systemd/user/hyprsunset.service:

PartOf=graphical-session.target
ConditionEnvironment=WAYLAND_DISPLAY
Restart=on-failure

That is the shape plans/remote.md already argues for in this repo ("The systemd user unit wins. It has restart-on-failure, journal logging, a clean is-active answer for guards and status"), and the workaround people converge on in #1434.

One wrinkle worth noting for whoever fixes this: restarting the process is necessary but not sufficient. A fresh hyprsunset re-reads hyprsunset.conf, whose shipped profile is identity = true, so it comes back neutral and the tint is still gone. The requested temperature has to be re-applied on restart, and it currently lives only in the shell's memory — which in this incident was lost too, since the shell restarted in the same event.

Steps to reproduce

omarchy toggle nightlight          # {"enabled":true,"temperature":4000}
pkill -x hyprsunset
omarchy-toggle-nightlight --status # {"enabled":false,"temperature":null}

Nothing brings it back. Verified on the machine above, and against the real crash (hyprsunset took SIGABRT in the hotplug event and was still gone ten minutes later).

Expected

hyprsunset is restarted when it dies, and the temperature it was holding is re-applied.

System

omarchy    4.0.0-1
hyprland   0.56.2-1
hyprsunset 0.4.0-3
aquamarine 0.14.0-2
wayland    1.26.0-1

Not part of this report

The crash that surfaced this was Google Chrome taking SIGTRAP in the same event. That half is upstream on both ends and is not Omarchy's: Chrome treats a Wayland protocol error as fatal by design, and destroying an output global while binds are in flight — rather than using a removal grace period, as wlroots does with wlr_global_destroy_safe() — is Hyprland's. Only the hyprsunset supervision gap is Omarchy's, which is why it is the only thing filed here.

View raw text
## What happened

A flapping HDMI connector (`HDMI-A-1`, Dell S2721HN) hotplugged four times in quick succession. Each disconnect destroyed that monitor's `wl_output` global, and libwayland-server then rejected every `wl_registry.bind` still in flight for it. XWayland printed the error verbatim:

```
XWAYLAND: wl_registry#2: error 0: global wl_output (73) is unavailable
(EE) failed to dispatch Wayland events: Protocol error
```

Thirteen Wayland clients died inside ~70 ms — Hyprland logged `error in client communication` for pids 1264, 1266, 1508, 1628, 1680, 1772, 4487, 10875, 215342 and 228982.

Omarchy recovered everything it supervises. The shell relaunched itself (`Omarchy shell exited with status 255; relaunching.`) and `omarchy-fcitx5.service` restarted on its own restart policy. **hyprsunset did not come back**, and night light stayed off for the rest of the session — 13 hours after the user had turned it on, and with no indication of why.

## Why it doesn't recover

Omarchy starts hyprsunset as a bare transient scope with no restart policy, in two places:

- `bin/omarchy-toggle-nightlight:39` — `setsid uwsm-app -- hyprsunset &`
- `shell/plugins/services/nightlight/Service.qml:50` — the same thing, inlined into `runApply`

So any death is permanent for the session. Recovery requires the user to notice their screen went cold and toggle night light twice.

This also breaks the scheduled-profile path, which is the worse case. `manual/13-toggles-idle-screensaver.md:55` documents `o.launch_on_start("hyprsunset")` as the way to get time-based profiles from `~/.config/hypr/hyprsunset.conf`. That path is unsupervised too, so those users lose the entire schedule — not just a toggle — until they log out.

The hyprsunset package already ships a supervised unit at `/usr/lib/systemd/user/hyprsunset.service`:

```ini
PartOf=graphical-session.target
ConditionEnvironment=WAYLAND_DISPLAY
Restart=on-failure
```

That is the shape `plans/remote.md` already argues for in this repo ("The systemd user unit wins. It has restart-on-failure, journal logging, a clean `is-active` answer for guards and status"), and the workaround people converge on in #1434.

One wrinkle worth noting for whoever fixes this: restarting the process is necessary but not sufficient. A fresh hyprsunset re-reads `hyprsunset.conf`, whose shipped profile is `identity = true`, so it comes back neutral and the tint is still gone. The requested temperature has to be re-applied on restart, and it currently lives only in the shell's memory — which in this incident was lost too, since the shell restarted in the same event.

## Steps to reproduce

```bash
omarchy toggle nightlight          # {"enabled":true,"temperature":4000}
pkill -x hyprsunset
omarchy-toggle-nightlight --status # {"enabled":false,"temperature":null}
```

Nothing brings it back. Verified on the machine above, and against the real crash (hyprsunset took `SIGABRT` in the hotplug event and was still gone ten minutes later).

## Expected

hyprsunset is restarted when it dies, and the temperature it was holding is re-applied.

## System

```
omarchy    4.0.0-1
hyprland   0.56.2-1
hyprsunset 0.4.0-3
aquamarine 0.14.0-2
wayland    1.26.0-1
```

## Not part of this report

The crash that surfaced this was Google Chrome taking `SIGTRAP` in the same event. That half is upstream on both ends and is not Omarchy's: Chrome treats a Wayland protocol error as fatal by design, and destroying an output global while binds are in flight — rather than using a removal grace period, as wlroots does with `wlr_global_destroy_safe()` — is Hyprland's. Only the hyprsunset supervision gap is Omarchy's, which is why it is the only thing filed here.

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/14347· 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 08:44 UTC