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

Cloned bar plugins: silent failure on denied service lookups, and nested QML files not hot-reloaded

Reported by piotrsynowiec · filed Sep 29, 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

Cloned bar plugins: silent failure on denied service lookups, and nested QML files not hot-reloadedrevision 1 · captured 2026-09-29 23:01 UTC via poll

System details

Intel i7-9750H, Intel UHD 630 + AMD Radeon Pro 5500M (MacBook Pro T2), Omarchy 4.0.4-1

What's wrong?

Two related problems with cloned bar plugins (found with a clone of omarchy.indicators made via omarchy plugin clone):

1. Cloned indicators break silently after the scoped plugin shell API change

My clone (piotr.indicators, made before 4.0.4) had the StayAwake indicator looking up the idle service the old way:

readonly property string idleServiceId: bar?.shell?.pluginRegistry
  ? bar.shell.pluginRegistry.resolveEnabledId("omarchy.idle")
  : "omarchy.idle"
readonly property var idleService: bar?.shell?.serviceFor(idleServiceId)

With the scoped PluginShellApi / PluginRegistryApi, resolveEnabledId() returns "" for anything but the plugin's own id and serviceFor() only returns the plugin's own service, so idleService is always null. The icon still renders, but clicking it does nothing and it never shows as active. No warning is logged. The stock indicator already uses bar.shell.firstPartyServiceFor("omarchy.idle"), and switching the clone to that fixes it.

Expected: when a plugin asks for a service or id it's not allowed to access, the shell logs a warning (e.g. plugin piotr.indicators denied access to service omarchy.idle, use firstPartyServiceFor()), so broken clones are diagnosable after an update.

2. Hot reload doesn't pick up changes to nested QML files in a local plugin

Steps:
1. omarchy plugin clone omarchy.indicators
2. Edit ~/.config/omarchy/plugins/<user>.indicators/indicators/StayAwake.qml (e.g. add a console.warn in Component.onCompleted)
3. The log shows DEBUG qml: Local plugin changed, reloading: <user>.indicators, but the old StayAwake.qml keeps running (no new output, behaviour unchanged).
4. Only omarchy restart shell loads the edited file.

It looks like the QML component cache keeps the files loaded through Loader { source: Qt.resolvedUrl("indicators/" + id + ".qml") } in Indicators.qml, and the plugin reload only re-creates the entry point (engine.clearComponentCache(), or a cache-busting query on the source URL, would probably fix it).

View raw text
### System details

Intel i7-9750H, Intel UHD 630 + AMD Radeon Pro 5500M (MacBook Pro T2), Omarchy 4.0.4-1

### What's wrong?

Two related problems with cloned bar plugins (found with a clone of `omarchy.indicators` made via `omarchy plugin clone`):

**1. Cloned indicators break silently after the scoped plugin shell API change**

My clone (`piotr.indicators`, made before 4.0.4) had the `StayAwake` indicator looking up the idle service the old way:

```qml
readonly property string idleServiceId: bar?.shell?.pluginRegistry
  ? bar.shell.pluginRegistry.resolveEnabledId("omarchy.idle")
  : "omarchy.idle"
readonly property var idleService: bar?.shell?.serviceFor(idleServiceId)
```

With the scoped `PluginShellApi` / `PluginRegistryApi`, `resolveEnabledId()` returns `""` for anything but the plugin's own id and `serviceFor()` only returns the plugin's own service, so `idleService` is always `null`. The icon still renders, but clicking it does nothing and it never shows as active. **No warning is logged.** The stock indicator already uses `bar.shell.firstPartyServiceFor("omarchy.idle")`, and switching the clone to that fixes it.

Expected: when a plugin asks for a service or id it's not allowed to access, the shell logs a warning (e.g. `plugin piotr.indicators denied access to service omarchy.idle, use firstPartyServiceFor()`), so broken clones are diagnosable after an update.

**2. Hot reload doesn't pick up changes to nested QML files in a local plugin**

Steps:
1. `omarchy plugin clone omarchy.indicators`
2. Edit `~/.config/omarchy/plugins/<user>.indicators/indicators/StayAwake.qml` (e.g. add a `console.warn` in `Component.onCompleted`)
3. The log shows `DEBUG qml: Local plugin changed, reloading: <user>.indicators`, but the old `StayAwake.qml` keeps running (no new output, behaviour unchanged).
4. Only `omarchy restart shell` loads the edited file.

It looks like the QML component cache keeps the files loaded through `Loader { source: Qt.resolvedUrl("indicators/" + id + ".qml") }` in `Indicators.qml`, and the plugin reload only re-creates the entry point (`engine.clearComponentCache()`, or a cache-busting query on the source URL, would probably fix it).

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 20:15 UTC