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

Bar widgets under a replacement (cloned) bar cannot resolve their own service — panel dead-ends on "warming up"

Reported by Tiedeyez · filed Sep 9, 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

Bar widgets under a replacement (cloned) bar cannot resolve their own service — panel dead-ends on "warming up"revision 1 · captured 2026-09-28 21:23 UTC via poll

Environment

  • omarchy 4.0.3-1, Hyprland + quickshell
  • Reproduced with a bar plugin created via the plugin generator (manifest carries omarchy: { "clonedFrom": "omarchy.bar" })

What happened

After the 4.0.3 scoped-shell change, a third-party bar widget that pairs a service + bar-widget kind can no longer reach its own service when the bar is a replacement bar:

  • Stock Bar.qml injects bar for non-first-party widgets as a facade whose .shell is pluginShellForId(moduleName) — service-capable, trusted-bar only (Bar.qml:234-237).
  • A replacement bar receives a scoped shell with no pluginShellForId, and the generated clone's common widget pattern is target.bar = root (the bar root itself), so bar.shell.serviceFor("my.plugin") lands in createScopedPluginShell()._serviceLookup (shell.qml:608):
  return allowOwnService ? shell.pluginServiceFor(key, requestedId) : null

where key is the bar's id. pluginOwnsTarget(barId, pluginId) is false for the hosted widget, so the lookup returns null.

  • Result: the widget's service binding stays null forever; the panel renders its "loading/warming up" placeholder and never resolves. The identical plugin works perfectly under the trusted default bar.

Steps to reproduce

  1. Any service + bar-widget plugin whose BarWidget reads bar.shell.serviceFor(moduleName) (e.g. a tree widget backed by Service.qml).
  2. omarchy plugins bar new → clone of omarchy.bar; keep the generated target.bar = root in ModuleSlot injectProps.
  3. Select the clone as the active bar and add the widget — the panel never receives its service.

Expected

Widget-coupled services resolve identically regardless of which bar (stock, or a user-selected omarchy.bar clone) hosts the widget. Plugin service objects are already gated by resolveEnabledId + the plugin's own manifest — the hosting bar's identity shouldn't shadow the widget's own id.

Proposed fix (locally validated)

Widen _serviceLookup only for the active bar when its manifest is an omarchy.bar clone the user deliberately selected; arbitrary custom bars keep the service-less facade:

_serviceLookup: function(requestedId) {
  if (allowOwnService) {
    var own = shell.pluginServiceFor(key, requestedId)
    if (own) return own
  }
  if (key === shell.activeBarId && shell.activeBarManifest
      && String(shell.activeBarManifest.id || "") === key) {
    var meta = Util.isPlainObject(shell.activeBarManifest.omarchy)
      ? shell.activeBarManifest.omarchy : null
    if (meta && String(meta.clonedFrom || "") === "omarchy.bar")
      return shell.serviceFor(shell.pluginRegistry.resolveEnabledId(requestedId))
  }
  return null
},

This fixes the case without touching any plugin. Alternatives for discussion: an explicit "widgetServices": true flag in the bar clone's manifest, or having the generated bar clone stamp pluginShellForBarEntry-style facades the way stock does (currently blocked — pluginShellForId is trusted-bar-only by design).

Happy to open a PR in whichever shape you prefer.

View raw text
## Environment

- omarchy 4.0.3-1, Hyprland + quickshell
- Reproduced with a `bar` plugin created via the plugin generator (manifest carries `omarchy: { "clonedFrom": "omarchy.bar" }`)

## What happened

After the 4.0.3 scoped-shell change, a third-party bar widget that pairs a `service` + `bar-widget` kind can no longer reach **its own** service when the bar is a replacement bar:

- Stock `Bar.qml` injects `bar` for non-first-party widgets as a facade whose `.shell` is `pluginShellForId(moduleName)` — service-capable, trusted-bar only (`Bar.qml:234-237`).
- A replacement bar receives a scoped shell with no `pluginShellForId`, and the generated clone's common widget pattern is `target.bar = root` (the bar root itself), so `bar.shell.serviceFor("my.plugin")` lands in `createScopedPluginShell()._serviceLookup` (`shell.qml:608`):

  ```js
  return allowOwnService ? shell.pluginServiceFor(key, requestedId) : null
  ```

  where `key` is the **bar's** id. `pluginOwnsTarget(barId, pluginId)` is false for the hosted widget, so the lookup returns `null`.

- Result: the widget's service binding stays `null` forever; the panel renders its "loading/warming up" placeholder and never resolves. The identical plugin works perfectly under the trusted default bar.

## Steps to reproduce

1. Any `service` + `bar-widget` plugin whose BarWidget reads `bar.shell.serviceFor(moduleName)` (e.g. a tree widget backed by `Service.qml`).
2. `omarchy plugins bar new` → clone of `omarchy.bar`; keep the generated `target.bar = root` in ModuleSlot `injectProps`.
3. Select the clone as the active bar and add the widget — the panel never receives its service.

## Expected

Widget-coupled services resolve identically regardless of which bar (stock, or a user-selected `omarchy.bar` clone) hosts the widget. Plugin service objects are already gated by `resolveEnabledId` + the plugin's own manifest — the hosting bar's identity shouldn't shadow the widget's own id.

## Proposed fix (locally validated)

Widen `_serviceLookup` only for the **active** bar when its manifest is an `omarchy.bar` clone the user deliberately selected; arbitrary custom bars keep the service-less facade:

```js
_serviceLookup: function(requestedId) {
  if (allowOwnService) {
    var own = shell.pluginServiceFor(key, requestedId)
    if (own) return own
  }
  if (key === shell.activeBarId && shell.activeBarManifest
      && String(shell.activeBarManifest.id || "") === key) {
    var meta = Util.isPlainObject(shell.activeBarManifest.omarchy)
      ? shell.activeBarManifest.omarchy : null
    if (meta && String(meta.clonedFrom || "") === "omarchy.bar")
      return shell.serviceFor(shell.pluginRegistry.resolveEnabledId(requestedId))
  }
  return null
},
```

This fixes the case without touching any plugin. Alternatives for discussion: an explicit `"widgetServices": true` flag in the bar clone's manifest, or having the generated bar clone stamp `pluginShellForBarEntry`-style facades the way stock does (currently blocked — `pluginShellForId` is trusted-bar-only by design).

Happy to open a PR in whichever shape you prefer.

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 11:27 UTC