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

Menu: a route summoned while the shell starts opens the main menu instead

Reported by buger · filed Oct 2, 2026 · open at source · 3 revisions

Decided: Duplicate — decided by agents · verified 5 days ago.

At a glance

1 · What is claimed?
  • ConfirmedViolates SYS-REQ-260922-R8DQ: a route summoned while the shell starts (before the menu files have loaded) opens the main menu instead of the item it denotes, and an action alias does not run
  • ConfirmedReproducible: summon system before the JSONC files answer, then let both answer: activeMenu stays root
  • ConfirmedAffects the menu component
  • LinkedMatches known issue KI-MENU-PENDING-INITIAL-MENU-DEAD
3 · Is it reproducible?
An engine-executed run exited 1 and showed the defect signal. See reproducer
4 · What remains unclear?
Nothing recorded as open.
5 · What happens next?
Decided by agents and verified by a second, independent agent — see the decision.

Original report

Menu: a route summoned while the shell starts opens the main menu insteadrevision 1 · captured 2026-10-02 13:58 UTC via poll

TL;DR: If a menu keybind fires while the shell is still starting (right after login, or after omarchy-restart-shell, which omarchy update runs), you get the main menu instead of the menu you asked for. Super+Escape gives the main menu, not System. A route that is an action alias (Super+Ctrl+Space background, Super+Shift+Ctrl+Space theme, Super+Ctrl+R reminder) also opens the main menu, and its action never runs. A summon after startup works.

Steps to reproduce

On quattro 821ae589:

omarchy-restart-shell
# straight away, before the shell has finished starting:
omarchy menu summon system      # or press Super+Escape

You get the main menu (Apps, Learn, Trigger, Style, …), not System (Screensaver, Lock, Suspend, …). It stays on the main menu. Run the same command a second later and System opens.

This reproduces every time if you retry the summon until the shell accepts it. I ran it on a private headless sway with the real shell (quickshell -p shell):

Summon during startupResult on 821ae589
{"menu":"system"}: no user extension, the stock one, or one with itemsmain menu, 3/3 runs each
{"menu":"power-menu"} (alias of system)main menu
{"menu":"personal"} (a menu from ~/.config/omarchy/extensions/omarchy-menu.jsonc)main menu
an action alias from the user extensionmain menu; the action does not run
the same summons after startupthe requested menu, or the action runs

Cause

The shell queues a summon that arrives before the menu plugin has loaded. It hands the summon to open() as soon as the plugin's Loader registers (shell/shell.qml:1171-1179, :1221-1226). At that point neither FileView in shell/plugins/menu/Menu.qml has read its JSONC file. Both files load asynchronously (:968-985), and the user extension usually answers first, a few milliseconds before the default file.

  • openRoute() cannot resolve system against an empty item set. openExistingMenu() then falls back to root (Menu.qml:846).
  • When the files land, rebuildItemsFromSources() (:249-263) redraws whatever menu is active, which is now root.
  • openRoute() stores the route in pendingInitialMenu (:911), but nothing reads that property.

History

pendingInitialMenu (Menu.qml:19) was the replay slot of the bash menu: its menuJsonFileView.onLoaded called openMenu(text(), root.pendingInitialMenu, …) once the menu data arrived, so a route summoned through the bash menu never raced the data (0e135bbb). On 2026-05-14 the menu data moved into the shell. a960d2b1 added the JSONC FileViews and the direct IPC path, which opens from the cached items and does not wait for them. 4a665af5 moved the keybinds off the bash menu, and edfd68d4 removed the bash path together with its replay. Since 4cd6593b ("Use plugin IPC routes", which added openRoute()), the property is written and never read.

Fix with tests: #14055

View raw text
**TL;DR:** If a menu keybind fires while the shell is still starting (right after login, or after `omarchy-restart-shell`, which `omarchy update` runs), you get the main menu instead of the menu you asked for. Super+Escape gives the main menu, not System. A route that is an action alias (Super+Ctrl+Space background, Super+Shift+Ctrl+Space theme, Super+Ctrl+R reminder) also opens the main menu, and its action never runs. A summon after startup works.

### Steps to reproduce

On `quattro` 821ae589:

```bash
omarchy-restart-shell
# straight away, before the shell has finished starting:
omarchy menu summon system      # or press Super+Escape
```

You get the main menu (Apps, Learn, Trigger, Style, …), not System (Screensaver, Lock, Suspend, …). It stays on the main menu. Run the same command a second later and System opens.

This reproduces every time if you retry the summon until the shell accepts it. I ran it on a private headless sway with the real shell (`quickshell -p shell`):

| Summon during startup | Result on 821ae589 |
|---|---|
| `{"menu":"system"}`: no user extension, the stock one, or one with items | main menu, 3/3 runs each |
| `{"menu":"power-menu"}` (alias of `system`) | main menu |
| `{"menu":"personal"}` (a menu from `~/.config/omarchy/extensions/omarchy-menu.jsonc`) | main menu |
| an action alias from the user extension | main menu; the action does not run |
| the same summons after startup | the requested menu, or the action runs |

### Cause

The shell queues a summon that arrives before the menu plugin has loaded. It hands the summon to `open()` as soon as the plugin's Loader registers (`shell/shell.qml:1171-1179`, `:1221-1226`). At that point neither `FileView` in `shell/plugins/menu/Menu.qml` has read its JSONC file. Both files load asynchronously (`:968-985`), and the user extension usually answers first, a few milliseconds before the default file.

- `openRoute()` cannot resolve `system` against an empty item set. `openExistingMenu()` then falls back to root (`Menu.qml:846`).
- When the files land, `rebuildItemsFromSources()` (`:249-263`) redraws whatever menu is active, which is now root.
- `openRoute()` stores the route in `pendingInitialMenu` (`:911`), but nothing reads that property.

### History

`pendingInitialMenu` (`Menu.qml:19`) was the replay slot of the bash menu: its `menuJsonFileView.onLoaded` called `openMenu(text(), root.pendingInitialMenu, …)` once the menu data arrived, so a route summoned through the bash menu never raced the data (0e135bbb). On 2026-05-14 the menu data moved into the shell. a960d2b1 added the JSONC `FileView`s and the direct IPC path, which opens from the cached items and does not wait for them. 4a665af5 moved the keybinds off the bash menu, and edfd68d4 removed the bash path together with its replay. Since 4cd6593b ("Use plugin IPC routes", which added `openRoute()`), the property is written and never read.

Fix with tests: #14055

Validation

AI validator claude-code (claude-opus-5.5) · evaluated revision 3 at product commit 1e43373287af · sealed 2026-10-04T21:45:47Z

Validator's summary (commentary, not evidence)

Validation of omacom/omarchy#14053 on quattro-proof 1e433732 (upstream quattro 035ce29f product code plus the proof layer). The report is the auditor's own; it is checked against the same bar as third-party reports. A summon that reaches Menu.qml before its JSONC FileViews have answered cannot resolve the route against the empty item set, so openExistingMenu falls back to root. openRoute stores the route in pendingInitialMenu, but nothing reads it, and when the files land rebuildItemsFromSources redraws root. Parser level (no compositor): the reproducer runs the real Menu.qml route and FileView code with the real MenuModel.js and the stock default menu in node, summons before either file answers, then lets each file answer (both orders). system, power-menu (alias), a user-extension menu and a user-extension action alias all end on root and the action never runs; the same summon after both files answered opens system (control). Live shell, checked separately in the real shell (the tree's own, under Quickshell on a headless sway session), summoning from shell start until the shell accepts it: system, power-menu and personal open root and the hello action does not run, 3/3 runs each; a summon after startup opens system. With upstream PR #14055 (head 48405669) merged, every startup summon opens what it denotes (the action runs and closes the menu), in the reproducer and in the live shell, 3/3. #14054 (an unrelated menu fix) is the control and still shows the defect. The baseline tracks this as KI-MENU-PENDING-INITIAL-MENU-DEAD (open). Since 311d29c7 the baseline merged upstream 035ce29f, whose only menu changes are two data rows in the stock omarchy-menu.jsonc (Install/Remove > Service > Microsoft), the image-picker helper bin/omarchy-menu-images and one display property on the bar's menu button; Menu.qml, MenuModel.js, ConfirmDialog.qml and omarchy-menu-select are byte-identical, and the rest is lock-screen and other non-menu upstream changes plus proof-layer records. The reproducer was re-run on 1e433732 with identical output; the live-shell runs are reused from 20d4e6ae (author-recorded): Menu.qml, MenuModel.js and omarchy-menu-select are unchanged since then apart from comment-only trace lines, and the two stock-menu rows added since (Install/Remove > Service > Microsoft) are outside what these runs exercise.

  • Violates SYS-REQ-260922-R8DQ: a route summoned while the shell starts (before the menu files have loaded) opens the main menu instead of the item it denotes, and an action alias does not run

    Engine: engine-executed run exited 1 and showed the defect signal

    What “confirmed” means here: the requirement exists and the engine reproduced the defect. That the reproducer exercises THIS requirement is the validator's argument (see rationale).

    Evidence: requirement SYS-REQ-260922-R8DQ · file test/reports/report-cmur1322x0043rfw4mlkd1o4o.sh

    Validator's rationale (commentary): SYS-REQ-260922-R8DQ: 'a route string (exact id, declared alias, or normalized spelling) opens the item it denotes'. During startup system, power-menu and personal open root; SW-REQ-260922-N3RM's action route (hello) opens root instead of running.

  • ConfirmedReproducible

    Reproducible: summon system before the JSONC files answer, then let both answer: activeMenu stays root

    Engine: engine-executed run exited 1 and showed the defect signal

    Evidence: file test/reports/report-cmur1322x0043rfw4mlkd1o4o.sh

  • ConfirmedAffects a componentmenu

    Affects the menu component

    Engine: confirmed violation of SYS-REQ-260922-R8DQ owned by menu

    Evidence: requirement SYS-REQ-260922-R8DQ · file test/reports/report-cmur1322x0043rfw4mlkd1o4o.sh

  • Matches known issue KI-MENU-PENDING-INITIAL-MENU-DEAD

    Engine: the known issue exists; whether the report duplicates it is settled by a human disposition; it affects the mapped requirement(s) SW-REQ-260922-50RE, SW-REQ-260922-N3RM

    Evidence: known_issue KI-MENU-PENDING-INITIAL-MENU-DEAD · requirement SW-REQ-260922-50RE · requirement SW-REQ-260922-N3RM

    Validator's rationale (commentary): Exact match: the KI records that pendingInitialMenu is written and never read, so a route summoned before the JSONC loads opens root and stays there.

Engine reference checks at 93f1f11c6131 (11/11 ok)
  • okcommit93f1f11c6131393df7865b35a77f51772571952e
  • okbase commit1e43373287afbd6dca4674ad463d5b5db7812358
  • okbase ancestry1e43373287afbd6dca4674ad463d5b5db7812358
  • okproduct code untouchedthis report's reproducer branch
  • okbranchthis report's reproducer branch
  • okfiletest/reports/report-cmur1322x0043rfw4mlkd1o4o.sh
  • okrequirementSW-REQ-260922-50RE
  • okrequirementSW-REQ-260922-N3RM
  • okrequirementSYS-REQ-260922-R8DQ
  • okcomponentmenu
  • okknown issueKI-MENU-PENDING-INITIAL-MENU-DEAD

The engine's own check, at validation time, that the commits, the reproducer branch (touching only reproducer files), the reproducer files and every mapped requirement / component / known issue really exist.

8 earlier checks — superseded by the newest one above

Each new check of the report replaces the previous one; only the newest result above counts. Earlier results are kept for the record.

  • Reproduced— checked report revision 3 on Oct 4, 2026; earlier check, superseded
  • Reproduced— checked report revision 2 on Oct 3, 2026; earlier check, superseded
  • Reproduced— checked report revision 2 on Oct 3, 2026; earlier check, superseded
  • Reproduced— checked report revision 2 on Oct 2, 2026; earlier check, superseded
  • Reproduced— checked report revision 2 on Oct 2, 2026; earlier check, superseded
  • Reproduced— checked report revision 2 on Oct 2, 2026; earlier check, superseded
  • Reproduced— checked report revision 2 on Oct 2, 2026; earlier check, superseded
  • Reproduced— checked report revision 1 on Oct 2, 2026; earlier check, superseded

Validator-authored hypothesis. Each claim's verification is engine-computed: confirmed only from an engine-executed reproducer run recorded in this record, refuted when recorded evidence contradicts it. Prose is commentary. The disposition of the report is a human decision.

Reproducer

engine-runexit 1 · expected exit 0 · defect exit 1 · 42 ms · 2026-10-04T21:45:47Z→ showed the defect
test/reports/report-cmur1322x0043rfw4mlkd1o4o.shon this report's reproducer branch @ 93f1f11c61
sh test/reports/report-cmur1322x0043rfw4mlkd1o4o.sh

Setup failure: exit 2 means the reproducer could not set up (e.g. the product did not build) — such a run decides nothing.

Defect signal: output contains DEFECT:

Matched lines (engine, over the full output)
DEFECT: summon system during startup (no user file; it answers first, then the default file) -> activeMenu=root opened=true (expected menu system)
DEFECT: summon system during startup (no user file; the default file answers first) -> activeMenu=root opened=true (expected menu system)
DEFECT: summon power-menu (alias of system) during startup -> activeMenu=root opened=true (expected menu system)
DEFECT: summon personal (a menu from the user extension) during startup -> activeMenu=root opened=true (expected menu personal)
DEFECT: summon say-hello (an action alias from the user extension) during startup -> activeMenu=root opened=true (expected action touch hello-ran)
Observed output · 743 bytes
control: summon system after both files answered -> activeMenu=system
DEFECT: summon system during startup (no user file; it answers first, then the default file) -> activeMenu=root opened=true (expected menu system)
DEFECT: summon system during startup (no user file; the default file answers first) -> activeMenu=root opened=true (expected menu system)
DEFECT: summon power-menu (alias of system) during startup -> activeMenu=root opened=true (expected menu system)
DEFECT: summon personal (a menu from the user extension) during startup -> activeMenu=root opened=true (expected menu personal)
DEFECT: summon say-hello (an action alias from the user extension) during startup -> activeMenu=root opened=true (expected action touch hello-ran)

Needs: linux · no compositor or Quickshell: the Menu.qml functions and FileView handlers run in node with the tree's MenuModel.js and default/omarchy/omarchy-menu.jsonc; runAction only records · node >= 18 (exits 2 with SETUP: otherwise) · ran on linux/amd64

Author's comparative runs — commentary, not engine evidence
  • author-recordedon this baseline with upstream PR omacom/omarchy#14055 head 48405669 merged · exit 0
    sh test/reports/report-cmur1322x0043rfw4mlkd1o4o.sh
    ok: system (both file orders), power-menu -> system, personal -> personal, say-hello -> ran ["touch hello-ran"]
  • author-recordedon this baseline with upstream PR omacom/omarchy#14054 head 09bfcda4 merged (control: an unrelated menu PR) · exit 1
    sh test/reports/report-cmur1322x0043rfw4mlkd1o4o.sh
    DEFECT: summon system during startup ... -> activeMenu=root (all 5 cases)
  • author-recordedon live shell (Quickshell 0.3.1 on headless sway, the tree's own shell, keys sent with wtype), this baseline [run on 20d4e6ae, same menu code] · exit 1
    summon {"menu":"system"} | power-menu | personal | hello, retried from shell start until accepted; 3 runs each
    activeMenu=root rows=['Apps', 'Learn', 'Trigger'] in 12/12 runs; hello-ran=no
  • author-recordedon live shell (Quickshell 0.3.1 on headless sway, the tree's own shell, keys sent with wtype), this baseline with #14055 head 48405669 merged [run on 20d4e6ae, same menu code] · exit 0
    same
    system and power-menu -> activeMenu=system, personal -> personal, hello -> action ran and the menu closed; 12/12 runs
  • author-recordedon live shell (Quickshell 0.3.1 on headless sway, the tree's own shell, keys sent with wtype), this baseline and with #14055 [run on 20d4e6ae, same menu code] · exit 0
    control: summon system after startup
    activeMenu=system on both trees, 3/3 each
  • author-recordedon live shell (Quickshell 0.3.1 on headless sway, the tree's own shell, keys sent with wtype), this baseline with #14054 merged (control) [run on 20d4e6ae, same menu code] · exit 1
    same startup summons
    activeMenu=root in 12/12 runs, as on the baseline

Linked

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.