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-4611GitHub issuePublicFixed

Saving a file under ~/.config/omarchy/plugins/ while locked strands the session, and omarchy-restart-shell refuses to help

Reported by omarchybot · filed Aug 16, 2026Closed upstream on 2026-09-20 by bjarneo via an automated message, as a duplicate of #6888 (R-1855). GitHub close reason: completed.

Received and recorded verbatim. Nothing has been checked yet.

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?
Not yet mapped to any requirement or component.
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. No decision has been recorded yet.

Original report

Saving a file under ~/.config/omarchy/plugins/ while locked strands the session, and omarchy-restart-shell refuses to helprevision 1 · captured 2026-10-04 12:03 UTC via poll

System details: Omarchy quattro @ 7488eade (post-4.0.0), QEMU/KVM VM, Hyprland session. Found by an automated QA pass; reproduced twice on a disposable worker VM, once from a clean boot.

Saving any file under ~/.config/omarchy/plugins/ while the screen is locked strands the session: the screen stays locked, no password prompt is drawn, and omarchy-restart-shell refuses to help.

unloadPluginServices() at shell/shell.qml:748-756 destroys every plugin service unconditionally:

function unloadPluginServices() {
  for (var existingId in _services) {
    var inst = _services[existingId]
    if (inst && typeof inst.destroy === "function") inst.destroy()
  }
  _services = ({})
}

omarchy.lock is one of those services and it owns the live WlSessionLock. Its manifest sets keepLoaded: true, but that is honoured for panels only (shell.qml:620,625) and ignored for services entirely.

The trigger is the part worth noting: reloadPlugins() is reached not just from shell rescanPlugins but from PluginRegistry's inotifywait -m -r -e close_write,create,delete,move on the plugins directory (shell/services/PluginRegistry.qml:636-655). So a plugin writing a cache file next to its own source, omarchy plugin add/enable/update, or a git pull in a plugin checkout is enough — no crash required.

$ omarchy-shell lock lock
ok
$ omarchy-shell lock status
{"locked":true,"requested":true,"pending":false,"sessionLocked":true,"secure":true,...}

$ mkdir -p ~/.config/omarchy/plugins/demo && touch ~/.config/omarchy/plugins/demo/cache.txt
$ sleep 6
$ omarchy-shell lock status
{"locked":true,"requested":true,"pending":true,"sessionLocked":false,"secure":true,
 "lastEvent":"lock-pending: screen-stabilizing"}

$ sleep 20; omarchy-shell lock status
... "lastEvent":"lock-pending: screen-stabilizing"   # frozen; still frozen 9 min later

$ omarchy-restart-shell
Refusing to restart Omarchy shell while the session is locked.
$ echo $?
1

The lock log shows the recreated service finding the orphaned compositor lock and parking:

lock-requested
lock-pending: screen-stabilizing
secure=true
lock-stranded: recovering
lock-requested
lock-pending: screen-stabilizing     <- forever

The stall itself is the mechanism #6888 describes — requestSessionLock() early-returns on sessionLock.secure at shell/plugins/lock/Service.qml:64. What is new here is that it is reachable from a routine plugin file write with no crash involved, and that omarchy-restart-shell reads the stale secure:true and declines. A fresh quickshell process does recover the lock, but only from a TTY or SSH — which is not somewhere a locked-out user can get to.

Even unlocked, every plugin-directory write momentarily destroys the notification daemon, the polkit agent, the idle service and the media service, all of which are keepLoaded: true.


Correction, after an independent review of this report:

Narrower than filed. The trigger is a non-hidden, non-.git plugin change or an explicit rescan -- not any filesystem write, and plain omarchy plugin enable does not reload. omarchy-restart-shell also refuses when either secure or requested is true, so attributing the refusal solely to a stale secure is incomplete.

View raw text
**System details:** Omarchy `quattro` @ 7488eade (post-4.0.0), QEMU/KVM VM, Hyprland session. Found by an automated QA pass; reproduced twice on a disposable worker VM, once from a clean boot.

Saving any file under `~/.config/omarchy/plugins/` while the screen is locked strands the session: the screen stays locked, no password prompt is drawn, and `omarchy-restart-shell` refuses to help.

`unloadPluginServices()` at `shell/shell.qml:748-756` destroys **every** plugin service unconditionally:

```js
function unloadPluginServices() {
  for (var existingId in _services) {
    var inst = _services[existingId]
    if (inst && typeof inst.destroy === "function") inst.destroy()
  }
  _services = ({})
}
```

`omarchy.lock` is one of those services and it owns the live `WlSessionLock`. Its manifest sets `keepLoaded: true`, but that is honoured for *panels* only (`shell.qml:620,625`) and ignored for services entirely.

The trigger is the part worth noting: `reloadPlugins()` is reached not just from `shell rescanPlugins` but from `PluginRegistry`'s `inotifywait -m -r -e close_write,create,delete,move` on the plugins directory (`shell/services/PluginRegistry.qml:636-655`). So a plugin writing a cache file next to its own source, `omarchy plugin add/enable/update`, or a `git pull` in a plugin checkout is enough — no crash required.

```
$ omarchy-shell lock lock
ok
$ omarchy-shell lock status
{"locked":true,"requested":true,"pending":false,"sessionLocked":true,"secure":true,...}

$ mkdir -p ~/.config/omarchy/plugins/demo && touch ~/.config/omarchy/plugins/demo/cache.txt
$ sleep 6
$ omarchy-shell lock status
{"locked":true,"requested":true,"pending":true,"sessionLocked":false,"secure":true,
 "lastEvent":"lock-pending: screen-stabilizing"}

$ sleep 20; omarchy-shell lock status
... "lastEvent":"lock-pending: screen-stabilizing"   # frozen; still frozen 9 min later

$ omarchy-restart-shell
Refusing to restart Omarchy shell while the session is locked.
$ echo $?
1
```

The lock log shows the recreated service finding the orphaned compositor lock and parking:

```
lock-requested
lock-pending: screen-stabilizing
secure=true
lock-stranded: recovering
lock-requested
lock-pending: screen-stabilizing     <- forever
```

The stall itself is the mechanism #6888 describes — `requestSessionLock()` early-returns on `sessionLock.secure` at `shell/plugins/lock/Service.qml:64`. What is new here is that it is reachable from a routine plugin file write with no crash involved, and that `omarchy-restart-shell` reads the stale `secure:true` and declines. A fresh quickshell *process* does recover the lock, but only from a TTY or SSH — which is not somewhere a locked-out user can get to.

Even unlocked, every plugin-directory write momentarily destroys the notification daemon, the polkit agent, the idle service and the media service, all of which are `keepLoaded: true`.

---

**Correction, after an independent review of this report:**

Narrower than filed. The trigger is a non-hidden, non-`.git` plugin change or an explicit rescan -- not any filesystem write, and plain `omarchy plugin enable` does not reload. `omarchy-restart-shell` also refuses when either `secure` or `requested` is true, so attributing the refusal solely to a stale `secure` is incomplete.

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/7169· confirmed
  • Related PRpr/7572· confirmed
  • Fixed bypr/8930· 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.

No decision has been recorded yet.