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-4914GitHub issuePublicReceived

Cloned service plugins are invisible to firstPartyServiceFor() (breaks Stay Awake indicator after cloning omarchy.idle)

Reported by SisuAika · filed Sep 5, 2026Closed upstream on 2026-09-20 by bjarneo via an automated message, as a duplicate of #7355 (R-1694). 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

Cloned service plugins are invisible to firstPartyServiceFor() (breaks Stay Awake indicator after cloning omarchy.idle)revision 1 · captured 2026-10-04 12:10 UTC via poll

What happens

After cloning a service-kind shell plugin with omarchy plugin clone, every other
component that looks the service up by its built-in id via
shell.firstPartyServiceFor(...) gets null, and silently loses functionality.

Concrete case: omarchy plugin clone omarchy.idle (to customise the screensaver /
wake commands). Everything the clone itself does keeps working, but the Stay Awake
bar indicator goes dead — the icon still renders, but active is stuck false and
clicking it does nothing.

Steps to reproduce

  1. omarchy plugin clone omarchy.idle
  2. omarchy restart shell
  3. Hover the center of the bar and click the Stay Awake (☕ / 󰅶) indicator.

Expected: idle lock + screensaver get inhibited, indicator lights up.
Actual: nothing happens; stayAwake never changes.

The idle service itself is fine — driving it directly works:
omarchy-shell idle disable → stayAwake:true, omarchy-shell idle enable → stayAwake:false.

Root cause

firstPartyServiceFor() / serviceFor() are not clone-aware, unlike the rest of
the shell.

shell/shell.qml:

function serviceFor(pluginId) {
  return _services[String(pluginId)] || null
}

function firstPartyServiceFor(pluginId) {
  return serviceFor(pluginId)
}

_services is keyed by concrete manifest id (_syncServices() → ensureService(id)
iterating installedPlugins). After cloning, the running service is registered as
garrett.idle, so _services["omarchy.idle"] is undefined and the built-in is in
disabledPlugins, so it never loads either.

Everywhere else, calls that name a built-in id are routed through
PluginRegistry.resolveEnabledId(), which maps omarchy.idle → the enabled
clonedFrom: "omarchy.idle" manifest — shell.qml does this for summon(), panel
resolution, bar-widget lookup, etc. (5 call sites). serviceFor() is the one that
skips it.

This is contrary to the documented contract in bin/omarchy-plugin-clone:

# Keep built-in ids inside the plugin code as stable IPC targets. The shell
# uses clonedFrom to route those calls to this local manifest id.

Affected consumers in-tree

  • shell/plugins/bar/indicators/StayAwake.qml:7 — firstPartyServiceFor("omarchy.idle")
  • shell/plugins/bar/indicators/NightLight.qml:7 — firstPartyServiceFor("omarchy.nightlight")
  • shell/plugins/bar/indicators/Dnd.qml:8 — firstPartyServiceFor("omarchy.notifications")
  • shell/plugins/panels/audio/Panel.qml:20 and shell/plugins/services/media/BarWidget.qml:10 — firstPartyServiceFor("omarchy.media")

i.e. cloning omarchy.nightlight, omarchy.notifications or omarchy.media should
break their indicators/panels the same way.

Suggested fix

Route serviceFor() through resolveEnabledId() like the other lookups:

function serviceFor(pluginId) {
  var id = shell.pluginRegistry
    ? shell.pluginRegistry.resolveEnabledId(pluginId)
    : String(pluginId)
  return _services[String(id)] || _services[String(pluginId)] || null
}

Workaround

Also clone omarchy.indicators (it ships clonePaths for the indicator dir) and
point the cloned indicators/StayAwake.qml at the cloned service id, with a fallback:

readonly property var idleService: bar?.shell?.firstPartyServiceFor("garrett.idle")
  || bar?.shell?.firstPartyServiceFor("omarchy.idle")
  || null

System

  • Omarchy 4.0.0-1
  • Hyprland 0.56.2, Quickshell shell
  • Kernel 7.1.8-arch1-3, AMD Ryzen 5 5600 / Radeon RX 5700 XT (amdgpu)

Full omarchy debug log available on request.

View raw text
## What happens

After cloning a **service**-kind shell plugin with `omarchy plugin clone`, every other
component that looks the service up by its built-in id via
`shell.firstPartyServiceFor(...)` gets `null`, and silently loses functionality.

Concrete case: `omarchy plugin clone omarchy.idle` (to customise the screensaver /
wake commands). Everything the clone itself does keeps working, but the **Stay Awake**
bar indicator goes dead — the icon still renders, but `active` is stuck `false` and
clicking it does nothing.

## Steps to reproduce

1. `omarchy plugin clone omarchy.idle`
2. `omarchy restart shell`
3. Hover the center of the bar and click the Stay Awake (☕ / `󰅶`) indicator.

Expected: idle lock + screensaver get inhibited, indicator lights up.
Actual: nothing happens; `stayAwake` never changes.

The idle service itself is fine — driving it directly works:
`omarchy-shell idle disable` → `stayAwake:true`, `omarchy-shell idle enable` → `stayAwake:false`.

## Root cause

`firstPartyServiceFor()` / `serviceFor()` are **not clone-aware**, unlike the rest of
the shell.

`shell/shell.qml`:

```qml
function serviceFor(pluginId) {
  return _services[String(pluginId)] || null
}

function firstPartyServiceFor(pluginId) {
  return serviceFor(pluginId)
}
```

`_services` is keyed by concrete manifest id (`_syncServices()` → `ensureService(id)`
iterating `installedPlugins`). After cloning, the running service is registered as
`garrett.idle`, so `_services["omarchy.idle"]` is `undefined` and the built-in is in
`disabledPlugins`, so it never loads either.

Everywhere else, calls that name a built-in id are routed through
`PluginRegistry.resolveEnabledId()`, which maps `omarchy.idle` → the enabled
`clonedFrom: "omarchy.idle"` manifest — `shell.qml` does this for `summon()`, panel
resolution, bar-widget lookup, etc. (5 call sites). `serviceFor()` is the one that
skips it.

This is contrary to the documented contract in `bin/omarchy-plugin-clone`:

```
# Keep built-in ids inside the plugin code as stable IPC targets. The shell
# uses clonedFrom to route those calls to this local manifest id.
```

## Affected consumers in-tree

- `shell/plugins/bar/indicators/StayAwake.qml:7` — `firstPartyServiceFor("omarchy.idle")`
- `shell/plugins/bar/indicators/NightLight.qml:7` — `firstPartyServiceFor("omarchy.nightlight")`
- `shell/plugins/bar/indicators/Dnd.qml:8` — `firstPartyServiceFor("omarchy.notifications")`
- `shell/plugins/panels/audio/Panel.qml:20` and `shell/plugins/services/media/BarWidget.qml:10` — `firstPartyServiceFor("omarchy.media")`

i.e. cloning `omarchy.nightlight`, `omarchy.notifications` or `omarchy.media` should
break their indicators/panels the same way.

## Suggested fix

Route `serviceFor()` through `resolveEnabledId()` like the other lookups:

```qml
function serviceFor(pluginId) {
  var id = shell.pluginRegistry
    ? shell.pluginRegistry.resolveEnabledId(pluginId)
    : String(pluginId)
  return _services[String(id)] || _services[String(pluginId)] || null
}
```

## Workaround

Also clone `omarchy.indicators` (it ships `clonePaths` for the indicator dir) and
point the cloned `indicators/StayAwake.qml` at the cloned service id, with a fallback:

```qml
readonly property var idleService: bar?.shell?.firstPartyServiceFor("garrett.idle")
  || bar?.shell?.firstPartyServiceFor("omarchy.idle")
  || null
```

## System

- Omarchy 4.0.0-1
- Hyprland 0.56.2, Quickshell shell
- Kernel 7.1.8-arch1-3, AMD Ryzen 5 5600 / Radeon RX 5700 XT (amdgpu)

Full `omarchy debug` log available on request.

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.

No decision has been recorded yet.