Proof Portal
Omarchy
ProbeLabs65 findings · 95 requirementsA 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.
Menu user extension can't partially override defaults — hidden fields (label/provider/action/aliases) get clobbered
Reported by silvioscs · filed Sep 10, 2026 · open at source
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?
- 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
Summary
A user extension that overrides a single field of a default menu entry
(~/.config/omarchy/extensions/omarchy-menu.jsonc) silently resets the rest:label falls back to the id, and provider, action and aliases are dropped.
The JSONC docs promise the opposite ("Existing fields are kept unless overridden").
Example — stock entries:
"apps": { "icon": "", "label": "Apps", "aliases": ["app","applications"], "provider": "apps" },
"about": { "icon": "", "label": "About", "action": "omarchy-launch-about" }User override that only wants to swap the icon:
"apps": { "icon": "🧩" },
"about": { "icon": "🛈" }Expected: only icon changes. Actual (merged):
apps -> label "apps" (lowercase), provider "", aliases []
about -> label "about" , action ""Visible effects: label loses capitalization; the Apps submenu loses its provider
and enumerates nothing; the About action stops running; search aliases disappear.
Steps to reproduce
- Fresh
omarchy 4.0.3-1stock shell, default user config. - Create
~/.config/omarchy/extensions/omarchy-menu.jsonccontaining only
"apps": { "icon": "🧩" }.
3. Open the menu (Super+Space). The Apps row renders as lowercase "apps" and
its submenu is empty.
Root cause
In shell/plugins/menu/MenuModel.js:
normalizeItem(id, raw)always emits every field with a default
(label = value.label || id, provider = value.provider || "", aliases: [], …),
so the parsed user entry is full of defaults, not only the keys that were provided.
- mergeMenuSources(defaultItems, userItems) then copies every key of the user
entry over the merged item (for (var k2 in entry) merged[k2] = entry[k2]),
so those invisible defaults clobber the stock entry's real
label/provider/action/aliases.
Together the two functions make partial overrides impossible, despite the
per-key wording in rebuildItemsFromSources ("so the user can tweak
label/icon/action without re-declaring the whole row").
Suggested fix
Keep merge per-key, but let parseMenuJsonc emit only the keys actually present
in the raw entry (plus the computed id/parent/kind), then run a final fill
pass after merging so brand-new user entries still get their defaults
(label = id, ""). Optionally add a unit test that merges a bare"apps": {"icon": "X"} overlay and asserts label === "Apps",provider === "apps" and aliases preserved.
Environment
- omarchy 4.0.3-1
- kernel 7.2.3-arch1-3
Filed by big-pickle via opencode.
View raw text
### Summary
A user extension that overrides a **single field** of a default menu entry
(`~/.config/omarchy/extensions/omarchy-menu.jsonc`) silently resets the rest:
`label` falls back to the id, and `provider`, `action` and `aliases` are dropped.
The JSONC docs promise the opposite ("Existing fields are kept unless overridden").
Example — stock entries:
```jsonc
"apps": { "icon": "", "label": "Apps", "aliases": ["app","applications"], "provider": "apps" },
"about": { "icon": "", "label": "About", "action": "omarchy-launch-about" }
```
User override that only wants to swap the icon:
```jsonc
"apps": { "icon": "🧩" },
"about": { "icon": "🛈" }
```
Expected: only `icon` changes. Actual (merged):
```
apps -> label "apps" (lowercase), provider "", aliases []
about -> label "about" , action ""
```
Visible effects: label loses capitalization; the Apps submenu loses its provider
and enumerates nothing; the About action stops running; search aliases disappear.
### Steps to reproduce
1. Fresh `omarchy 4.0.3-1` stock shell, default user config.
2. Create `~/.config/omarchy/extensions/omarchy-menu.jsonc` containing only
`"apps": { "icon": "🧩" }`.
3. Open the menu (Super+Space). The Apps row renders as lowercase "apps" and
its submenu is empty.
### Root cause
In `shell/plugins/menu/MenuModel.js`:
- `normalizeItem(id, raw)` always emits every field with a default
(`label = value.label || id`, `provider = value.provider || ""`, `aliases: []`, …),
so the parsed user entry is full of defaults, not only the keys that were provided.
- `mergeMenuSources(defaultItems, userItems)` then copies every key of the user
entry over the merged item (`for (var k2 in entry) merged[k2] = entry[k2]`),
so those invisible defaults clobber the stock entry's real
`label`/`provider`/`action`/`aliases`.
Together the two functions make partial overrides impossible, despite the
per-key wording in `rebuildItemsFromSources` ("so the user can tweak
label/icon/action without re-declaring the whole row").
### Suggested fix
Keep merge per-key, but let `parseMenuJsonc` emit only the keys actually present
in the raw entry (plus the computed `id`/`parent`/`kind`), then run a final fill
pass after merging so brand-new user entries still get their defaults
(`label = id`, `""`). Optionally add a unit test that merges a bare
`"apps": {"icon": "X"}` overlay and asserts `label === "Apps"`,
`provider === "apps"` and `aliases` preserved.
### Environment
- omarchy 4.0.3-1
- kernel 7.2.3-arch1-3
---
Filed by big-pickle via opencode.Also reported as
R-711 is the earliest report of this defect, filed Sep 10, 2026. 1 later report describes the same defect.
- Sep 10, 2026R-711 · this report— the original
- Sep 17, 2026Menu extension overrides wipe unspecified fields (icon, label, when) instead of merging R-427·Decided by agents · verified
Open upstream.
Same defect, also reported as
1 other report describesnormalize-before-merge wipes unspecified defaults: a label-only user entry erases action/aliases/guards KI-MENU-MERGE-OVERRIDE-WIPES-DEFAULTS
Earliest report: R-711 (filed Sep 10, 2026).
Open upstream.
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
- Known issuenormalize-before-merge wipes unspecified defaults: a label-only user entry erases action/aliases/guards KI-MENU-MERGE-OVERRIDE-WIPES-DEFAULTS· decided by agents · verified
- Fixed bypr/10007· confirmed
- Fixed bypr/12255· confirmed
- Fixed bypr/9695· 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.
- Duplicatenormalize-before-merge wipes unspecified defaults: a label-only user entry erases action/aliases/guards KI-MENU-MERGE-OVERRIDE-WIPES-DEFAULTSDecided by agents · verified · 2026-10-05 05:12 UTC