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

Apps started from the Super+Space menu inherit RLIMIT_RTTIME=0 (PipeWire + portal without rtkit) and are SIGKILLed once they get a real-time thread; since 4.0.4 this kills SteamVR

Reported by kh4rit-bot · filed Sep 18, 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

Apps started from the Super+Space menu inherit RLIMIT_RTTIME=0 (PipeWire + portal without rtkit) and are SIGKILLed once they get a real-time thread; since 4.0.4 this kills SteamVRrevision 1 · captured 2026-09-28 21:23 UTC via poll

System details

Lenovo Legion Pro 5 16ARX8, Ryzen 7 7745HX, RTX 4060 Laptop, Omarchy 4.0.4, linux-omarchy 7.2.5-3, PipeWire 1.6.8, quickshell 0.3.1

What's wrong?

Everything launched from the Omarchy menu runs with a hard real-time CPU limit of zero:

$ prlimit --pid $(pgrep -x quickshell) --rttime
RTTIME  timeout for real-time tasks  0  0  microsecs

The kernel kills a process with that limit (SIGKILL, no core dump, nothing in the journal) as soon as one of its threads runs SCHED_FIFO/RR. Since 4.0.4 that happens to SteamVR: on linux-omarchy its compositor is granted real-time threads, so with Steam started from the menu SteamVR fails with "SteamVR Fail (-203)" every time, about 10 ms after the compositor starts. Steam started from a terminal works. On the Arch kernel the real-time request was refused, which hid the problem.

Where the zero comes from. It is not something the shell does on purpose, it happens in every PipeWire client:

$ PIPEWIRE_DEBUG=mod.rt:5 pw-mon
mod.rt | failed to set realtime policy: Operation not permitted
mod.rt | initialized using RTKit
mod.rt | clamping rt.time.soft from 18446744073709551615 to 0 because of RTKit
mod.rt | set_rlimit() rt.time.soft:0 rt.time.hard:0

rtkit is not installed, so module-rt ends up at xdg-desktop-portal's Realtime interface, which reports RTTimeUSecMax=0, and module-rt applies that zero to its own process. quickshell is a PipeWire client and also the launcher, so its children inherit it. Apps started from a Hyprland keybinding or a terminal don't. 31 of 128 processes in my session carried the zero.

To reproduce

  1. Start any app from the menu, then grep realtime /proc/<pid>/limits. Compare with the same app started from a terminal.
  2. For the kill: prlimit --rttime=0:0 steam, start SteamVR. The compositor's log stops right after it sets its thread priority, vrserver reports it exited, SteamVR shows -203. Same with Steam started from the menu. (If a umu/Proton session such as Battle.net is already running, SteamVR starts its compositor inside that session's container instead, where real-time scheduling is refused, and it survives.)

What I tested as a fix

  • pacman -S rtkit plus systemctl --user restart xdg-desktop-portal: the portal then reports RTTimeUSecMax=200000, and a new PipeWire client gets a 200000/200000 limit instead of 0/0, which is what other distros run with. Processes that already have the hard zero (quickshell) keep it until they are restarted.
  • rtportal.enabled = false in the module-rt args of client.conf also keeps the limit unlimited.
  • Not verified: SteamVR started from the menu with the 200 ms limit. On my machine a running umu session (Battle.net) takes over SteamVR's compositor launch, so I could not get a clean run.

Without rtkit, PipeWire's own data-loop threads also run SCHED_OTHER here.

Related: #9390 reports the missing rtkit from the audio side, and #12428 installs it. That would fix this too, with one addition: the portal and the shell have to be restarted as well, see my comment there. Possibly the same cause: #11862.

View raw text
### System details

Lenovo Legion Pro 5 16ARX8, Ryzen 7 7745HX, RTX 4060 Laptop, Omarchy 4.0.4, linux-omarchy 7.2.5-3, PipeWire 1.6.8, quickshell 0.3.1

### What's wrong?

Everything launched from the Omarchy menu runs with a hard real-time CPU limit of zero:

```
$ prlimit --pid $(pgrep -x quickshell) --rttime
RTTIME  timeout for real-time tasks  0  0  microsecs
```

The kernel kills a process with that limit (SIGKILL, no core dump, nothing in the journal) as soon as one of its threads runs SCHED_FIFO/RR. Since 4.0.4 that happens to SteamVR: on linux-omarchy its compositor is granted real-time threads, so with Steam started from the menu SteamVR fails with "SteamVR Fail (-203)" every time, about 10 ms after the compositor starts. Steam started from a terminal works. On the Arch kernel the real-time request was refused, which hid the problem.

**Where the zero comes from.** It is not something the shell does on purpose, it happens in every PipeWire client:

```
$ PIPEWIRE_DEBUG=mod.rt:5 pw-mon
mod.rt | failed to set realtime policy: Operation not permitted
mod.rt | initialized using RTKit
mod.rt | clamping rt.time.soft from 18446744073709551615 to 0 because of RTKit
mod.rt | set_rlimit() rt.time.soft:0 rt.time.hard:0
```

rtkit is not installed, so module-rt ends up at xdg-desktop-portal's Realtime interface, which reports `RTTimeUSecMax=0`, and module-rt applies that zero to its own process. quickshell is a PipeWire client and also the launcher, so its children inherit it. Apps started from a Hyprland keybinding or a terminal don't. 31 of 128 processes in my session carried the zero.

**To reproduce**

1. Start any app from the menu, then `grep realtime /proc/<pid>/limits`. Compare with the same app started from a terminal.
2. For the kill: `prlimit --rttime=0:0 steam`, start SteamVR. The compositor's log stops right after it sets its thread priority, vrserver reports it exited, SteamVR shows -203. Same with Steam started from the menu. (If a umu/Proton session such as Battle.net is already running, SteamVR starts its compositor inside that session's container instead, where real-time scheduling is refused, and it survives.)

**What I tested as a fix**

- `pacman -S rtkit` plus `systemctl --user restart xdg-desktop-portal`: the portal then reports `RTTimeUSecMax=200000`, and a new PipeWire client gets a 200000/200000 limit instead of 0/0, which is what other distros run with. Processes that already have the hard zero (quickshell) keep it until they are restarted.
- `rtportal.enabled = false` in the module-rt args of `client.conf` also keeps the limit unlimited.
- Not verified: SteamVR started from the menu with the 200 ms limit. On my machine a running umu session (Battle.net) takes over SteamVR's compositor launch, so I could not get a clean run.

Without rtkit, PipeWire's own data-loop threads also run SCHED_OTHER here.

Related: #9390 reports the missing rtkit from the audio side, and #12428 installs it. That would fix this too, with one addition: the portal and the shell have to be restarted as well, see my comment there. Possibly the same cause: #11862.

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/7971· 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 15:39 UTC