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

systemd-oomd swap kill takes the whole session: everything launched from a terminal shares one app-*.scope (2,104 processes killed)

Reported by StefanMaron · filed Sep 2, 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

systemd-oomd swap kill takes the whole session: everything launched from a terminal shares one app-*.scope (2,104 processes killed)revision 1 · captured 2026-09-28 21:24 UTC via poll

Summary

omarchy-settings sets ManagedOOMSwap=kill on app.slice in /usr/lib/systemd/user/app.slice.d/10-oomd.conf. The comment in that file states the intent:

oomd takes the browser or terminal that caused the pressure, and the session survives to show the notification about it. One app misbehaving should not cost the whole session.

On my machine it did the opposite. systemd-oomd killed 2,104 processes in one unit, which was my entire working session.

Sep 02 13:07:24 systemd-oomd[885]: Considered 35 cgroups for killing, top candidates were:
Sep 02 13:07:24 systemd-oomd[885]:   Path: /user.slice/user-1000.slice/[email protected]/app.slice/app-graphical.slice/app-Hyprland-xdg\x2dterminal\x2dexec-0ae8dde6.scope
Sep 02 13:07:24 systemd-oomd[885]:           Swap Usage: 20.9G
Sep 02 13:07:24 systemd-oomd[885]: Marked /user.slice/.../app-Hyprland-xdg\x2dterminal\x2dexec-0ae8dde6.scope for killing
Sep 02 13:07:24 systemd[1075]: app-Hyprland-xdg\x2dterminal\x2dexec-0ae8dde6.scope: systemd-oomd killed 2104 process(es) in this unit.
Sep 02 13:07:24 systemd[1075]: app-Hyprland-xdg\x2dterminal\x2dexec-0ae8dde6.scope: Failed with result 'oom-kill'.

One scope holds the whole session

app-Hyprland-xdg-terminal-exec-*.scope is created for a single terminal launch, but everything started from inside that terminal stays in it. Live contents of that scope, measured a few hours before the kill:

bash x32, vivaldi-bin x45, claude x10, Microsoft.Dynamics.Nav.EditorServices.Host x8, al-call-hierarchy x4, dotnet x3, serena x3, al-lsp-wrapper x3, chrome_crashpad x3, python3 x2, herdr x2, plus ghostty, gh, node, VBCSCompiler, xdg-open and others.

The browser is in there because it was opened from the terminal. So "kill the app scope responsible for the pressure" becomes "kill the terminal and every program ever launched from it."

The swap trigger fires during normal zram operation

This kill came down the swap path, not the memory-pressure path. Swap here is zram (/dev/zram0, zstd, 31.2 GiB). zram is compressed RAM, so filling it is ordinary operation rather than a warning sign. Over a normal working day this machine sits between 76% and 98% zram usage with no stalling. At a 98.7% reading, PSI was memory some avg300=0.58 and io avg300=0.03.

SwapUsedLimit defaults to 90%. On disk swap, 90% used is a real signal. On zram it means the compressor is working. The swap-based kill therefore fires during normal operation and removes the largest cgroup with it.

Expected

Either change alone would prevent this:

  1. Give terminal-launched programs their own scopes, or exclude the terminal scope from oomd candidacy, so a kill removes one program instead of the session.
  2. Skip or raise the swap-based kill when swap is backed by zram. ManagedOOMSwap=kill at a 90% limit assumes disk swap.

System

  • omarchy 4.0.2-1, omarchy-settings 4.0.2-1
  • hyprland 0.56.2-1, quickshell 0.3.1-1
  • zram-generator 1.2.1-1, /dev/zram0 31.2 GiB, zstd
  • 31.25 GiB RAM, Linux 7.1.9-arch1-2

Related: #7522 covers zram-generator packaging.

Filed by Claude Opus 5 via Claude Code.

View raw text
## Summary

`omarchy-settings` sets `ManagedOOMSwap=kill` on `app.slice` in `/usr/lib/systemd/user/app.slice.d/10-oomd.conf`. The comment in that file states the intent:

> oomd takes the browser or terminal that caused the pressure, and the session survives to show the notification about it.
>
> One app misbehaving should not cost the whole session.

On my machine it did the opposite. systemd-oomd killed 2,104 processes in one unit, which was my entire working session.

```
Sep 02 13:07:24 systemd-oomd[885]: Considered 35 cgroups for killing, top candidates were:
Sep 02 13:07:24 systemd-oomd[885]:   Path: /user.slice/user-1000.slice/[email protected]/app.slice/app-graphical.slice/app-Hyprland-xdg\x2dterminal\x2dexec-0ae8dde6.scope
Sep 02 13:07:24 systemd-oomd[885]:           Swap Usage: 20.9G
Sep 02 13:07:24 systemd-oomd[885]: Marked /user.slice/.../app-Hyprland-xdg\x2dterminal\x2dexec-0ae8dde6.scope for killing
Sep 02 13:07:24 systemd[1075]: app-Hyprland-xdg\x2dterminal\x2dexec-0ae8dde6.scope: systemd-oomd killed 2104 process(es) in this unit.
Sep 02 13:07:24 systemd[1075]: app-Hyprland-xdg\x2dterminal\x2dexec-0ae8dde6.scope: Failed with result 'oom-kill'.
```

## One scope holds the whole session

`app-Hyprland-xdg-terminal-exec-*.scope` is created for a single terminal launch, but everything started from inside that terminal stays in it. Live contents of that scope, measured a few hours before the kill:

`bash` x32, `vivaldi-bin` x45, `claude` x10, `Microsoft.Dynamics.Nav.EditorServices.Host` x8, `al-call-hierarchy` x4, `dotnet` x3, `serena` x3, `al-lsp-wrapper` x3, `chrome_crashpad` x3, `python3` x2, `herdr` x2, plus `ghostty`, `gh`, `node`, `VBCSCompiler`, `xdg-open` and others.

The browser is in there because it was opened from the terminal. So "kill the app scope responsible for the pressure" becomes "kill the terminal and every program ever launched from it."

## The swap trigger fires during normal zram operation

This kill came down the swap path, not the memory-pressure path. Swap here is zram (`/dev/zram0`, zstd, 31.2 GiB). zram is compressed RAM, so filling it is ordinary operation rather than a warning sign. Over a normal working day this machine sits between 76% and 98% zram usage with no stalling. At a 98.7% reading, PSI was `memory some avg300=0.58` and `io avg300=0.03`.

`SwapUsedLimit` defaults to 90%. On disk swap, 90% used is a real signal. On zram it means the compressor is working. The swap-based kill therefore fires during normal operation and removes the largest cgroup with it.

## Expected

Either change alone would prevent this:

1. Give terminal-launched programs their own scopes, or exclude the terminal scope from oomd candidacy, so a kill removes one program instead of the session.
2. Skip or raise the swap-based kill when swap is backed by zram. `ManagedOOMSwap=kill` at a 90% limit assumes disk swap.

## System

- omarchy 4.0.2-1, omarchy-settings 4.0.2-1
- hyprland 0.56.2-1, quickshell 0.3.1-1
- zram-generator 1.2.1-1, `/dev/zram0` 31.2 GiB, zstd
- 31.25 GiB RAM, Linux 7.1.9-arch1-2

Related: #7522 covers zram-generator packaging.

Filed by Claude Opus 5 via Claude Code.

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

Not linked to any known issue, other report or change yet.

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 10:34 UTC