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.
Search ranks `Remove › Development › Rust` above the RustDesk app — Enter runs the removal
Reported by RodriMora · filed Aug 20, 2026 · open at source
At a glance
- 1 · What is claimed?
- ConfirmedReproducible: searching 'rust' with ~/.rustup present and RustDesk installed makes Remove > Development > Rust row 1, the Enter target
- Not confirmedAffects the menu component
- 2 · What does it affect?
- 3 · Is it reproducible?
- An engine-executed run exited 1 and showed the defect signal. See reproducer
- 4 · What remains unclear?
- Open question for maintainers: Open decision: may a search result that runs a destructive action (remove, uninstall) be the default Enter target? Options: (A) keep the current ranking (SW-REQ-260922-SJ7P); (B) rank destructive rows below other matches unless the query names the action (PR #7661); (C) keep install/remove rows out of global search (#6376's ask); (D) ask for confirmation before a destructive row runs from search, as SW-REQ-260922-8CQ4 does for uninstalling an app.
- Open question for maintainers: The decision is the Omarchy maintainers'; a draft requirement listing these options sits on this report's branch (report/cmulrfoje01ui18w4w89862tn), and approving one option = merging that draft into the baseline with the chosen text.
- Affects the menu component — no requirement of the menu component is confirmed as violated
- 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. So far: in the audited area (menu) — decided by agents · verified; not a duplicate of another report — decided by agents · verified; intended behaviour — a design question, not a defect — decided by agents · verified. The outcome (valid, duplicate, not a bug, …) is not decided yet. See the decision.
Open question — draft spec awaiting a decision
May a search result that runs a destructive action (remove, uninstall) be the default Enter target?
(upstream quattro 035ce29f) searchScore (MenuModel.js:341-363) puts an exact label match in the best tier, so with ~/.rustup present and RustDesk installed, 'rust' ranks Remove > Development > Rust first; the menu selects row 0 on a query change (Menu.qml:722-726) and Enter activates it (Menu.qml:1153-1157), which runs omarchy-remove-dev-env rust (default/omarchy/omarchy-menu.jsonc:343) and rustup self uninstall -y with no confirmation (bin/omarchy-remove-dev-env:111-114).
- AKeep the current ranking (SW-REQ-260922-SJ7P)
- BA destructive row shall rank below the other matches unless the query names the action
- CInstall/remove rows shall not appear in global search
- DA destructive row activated from search shall ask for confirmation, as SW-REQ-260922-8CQ4 does for uninstalling an app
Approving this draft means choosing one option; its text then replaces this description.
Why this is an open question
Raised by omacom/omarchy#7630 (proof inbox R-1616). The validation (report/cmulrfoje01ui18w4w89862tn, rval-6102a632d0b497ca1436a3f8476bcf72) reproduced the order with MenuModel.js on the shipped menu. The order conforms to SW-REQ-260922-SJ7P; SYS-REQ-260922-V7W6's rationale says ranking decides which row Enter activates; no requirement says whether a destructive action may be that row. Open upstream PR #7661 implements option B; #6376 asked for option C.
Proposed on this report's branch @ 135fe5b6af · specs/software/requirements/SW-REQ-261005-ZEQ3.req.yaml · not part of the audited spec until approved and merged
Written after the validation was sealed at 923b93ce72: the seal covers the reproducer and the observed behaviour, not this proposed text.
Original report
Summary
Typing rust in the Omarchy menu (Super+Alt+Space) surfaces Remove › Development › Rust as the top result, above the RustDesk app. Since Enter runs whatever is highlighted and it's easy to press Enter before reading the row, the toolchain gets wiped instead of launching RustDesk.
Related: #6376 (same class of problem, marked fixed). This is a case that fix doesn't cover.
Reproduction
Omarchy 4.0 (Quattro), stock menu. Conditions:
- ~/.rustup exists → remove.development.rust is visible and matches rust exactly
- RustDesk is an installed app (label "RustDesk")
- Open the menu, type
rust - First result is
Rust(pathRemove › Development), not RustDesk - Enter executes
omarchy-remove-dev-env rust
Root cause
searchScore in shell/plugins/menu/MenuModel.js ties the top tier to exact label matches regardless of subtree:
remove.development.rust→ labelRust== query → tier 0 (action row)- RustDesk app row →
rustdeskonly prefix-matches → tier 10, then −5 for being an app → 5000 - Result: the removal ranks ~4700 points first.
It only didn't bite in the #6376 "steam" case because the Steam app also exact-matches and its −5 app bonus edges out the Remove row. Any app whose name merely starts with the query loses to a same-named install/remove entry ("rust", "go", "zen" while installed, etc.).
Expected behavior / solution options
- Don't let destructive rows trump apps —
remove.*/install.*rows should not outrank the app the user is actually after unless the query is verb-specific ("remove rust"). - #6376's original ask — keep
install.*/remove.*out of global search entirely; only searchable inside their own submenu. - Removal/install rows must be unmistakable — show the parent path (
Remove › Development) as the primary title, not a subtitle, and/or require a second keypress (Enter → confirm) for destructive rows. - Remember what I actually pick (frecency) — record successful searches locally and use them to boost ranking on later runs:
- When a row is activated from a search, save
{query, itemId/menuId, timestamp}to a local state file (e.g.~/.local/state/omarchy/menu-search-history.json), hooked intoactivateIndex/runActioninshell/plugins/menu/Menu.qml. - In
searchScore/sorting, add a recency+frequency boost for rows previously opened from the same query: first timerust→ RustDesk, from then on RustDesk leads and the muscle-memory Enter is safe. - Local-only, cheap to store, resettable (delete the file), and helps generally — not just for this bug.
- Gives the best long-term behavior for a keyboard-first workflow: the menu learns instead of hardcoding which subtree wins.
Notes
Any of 1–3 alone fixes the immediate hazard; 4 in combination makes the menu safe by default and predictable over time. Suggested combined ask: 1 or 2 for the safety floor, plus 4 for personal ranking.
View raw text
### Summary
Typing `rust` in the Omarchy menu (Super+Alt+Space) surfaces `Remove › Development › Rust` as the top result, above the RustDesk app. Since Enter runs whatever is highlighted and it's easy to press Enter before reading the row, the toolchain gets wiped instead of launching RustDesk.
Related: #6376 (same class of problem, marked fixed). This is a case that fix doesn't cover.
### Reproduction
Omarchy 4.0 (Quattro), stock menu. Conditions:
- `~/.rustup` exists → `remove.development.rust` is visible and matches `rust` exactly
- RustDesk is an installed app (label "RustDesk")
1. Open the menu, type `rust`
2. First result is `Rust` (path `Remove › Development`), not RustDesk
3. Enter executes `omarchy-remove-dev-env rust`
### Root cause
`searchScore` in `shell/plugins/menu/MenuModel.js` ties the top tier to exact label matches regardless of subtree:
- `remove.development.rust` → label `Rust` == query → tier **0** (action row)
- RustDesk app row → `rustdesk` only prefix-matches → tier 10, then −5 for being an app → **5000**
- Result: the removal ranks ~4700 points first.
It only didn't bite in the #6376 "steam" case because the Steam app also exact-matches and its −5 app bonus edges out the Remove row. Any app whose name merely starts with the query loses to a same-named install/remove entry ("rust", "go", "zen" while installed, etc.).
### Expected behavior / solution options
1. **Don't let destructive rows trump apps** — `remove.*`/`install.*` rows should not outrank the app the user is actually after unless the query is verb-specific ("remove rust").
2. **#6376's original ask** — keep `install.*`/`remove.*` out of global search entirely; only searchable inside their own submenu.
3. **Removal/install rows must be unmistakable** — show the parent path (`Remove › Development`) as the primary title, not a subtitle, and/or require a second keypress (Enter → confirm) for destructive rows.
4. **Remember what I actually pick (frecency)** — record successful searches locally and use them to boost ranking on later runs:
- When a row is activated from a search, save `{query, itemId/menuId, timestamp}` to a local state file (e.g. `~/.local/state/omarchy/menu-search-history.json`), hooked into `activateIndex`/`runAction` in `shell/plugins/menu/Menu.qml`.
- In `searchScore`/sorting, add a recency+frequency boost for rows previously opened from the same query: first time `rust` → RustDesk, from then on RustDesk leads and the muscle-memory Enter is safe.
- Local-only, cheap to store, resettable (delete the file), and helps generally — not just for this bug.
- Gives the best long-term behavior for a keyboard-first workflow: the menu learns instead of hardcoding which subtree wins.
### Notes
Any of 1–3 alone fixes the immediate hazard; 4 in combination makes the menu safe by default *and* predictable over time. Suggested combined ask: 1 or 2 for the safety floor, plus 4 for personal ranking.
Validation
AI validator claude-code (claude-opus-5.5) · evaluated revision 1 at product commit 1e43373287af · sealed 2026-10-05T14:29:56Z
Validation of omacom/omarchy#7630 on quattro-proof 1e433732 (upstream quattro 035ce29f product code plus the proof layer). The reported ranking reproduces with the shipped menu and MenuModel.js: on a system with ~/.rustup present and RustDesk installed, searching 'rust' from the root menu ranks Remove > Development > Rust first (exact label, best tier; searchScore, MenuModel.js:341-363 upstream) and the RustDesk app second (label prefix, minus the app shift). Install > Development > Rust is disabled by its ~/.rustup guard and search skips disabled rows. The menu selects row 0 when the query changes (Menu.qml:722-726) and Enter activates the selected row (Menu.qml:1153-1157), so Enter runs omarchy-remove-dev-env rust (default/omarchy/omarchy-menu.jsonc:343), which calls rustup self uninstall -y with no confirmation (bin/omarchy-remove-dev-env:111-114). This order conforms to SW-REQ-260922-SJ7P (score tiers); SYS-REQ-260922-V7W6's rationale says ranking decides which row Enter activates, and SW-REQ-260922-8CQ4 asks for a confirmation only when an app is uninstalled with Delete. No requirement says whether a destructive action may be the default Enter target, so this is an open specification question for the maintainers. KI-MENU-SEARCH-SCORE-RANKING (root exact labels vs nested twins, cross-field terms) was examined: a different ranking defect. Open upstream PR #7661 proposes one of the options; #6376 is the earlier, related report.
- ConfirmedReproducible
Reproducible: searching 'rust' with ~/.rustup present and RustDesk installed makes Remove > Development > Rust row 1, the Enter target
Engine: engine-executed run exited 1 and showed the defect signal
Evidence: file test/reports/report-cmulrfoje01ui18w4w89862tn.sh
Validator's rationale (commentary): Observed with MenuModel.js on the shipped menu: Remove > Development > Rust score 356, RustDesk score 5372. The order follows SW-REQ-260922-SJ7P; whether a destructive row may be the Enter target is the open question below.
Affects the menu component
Engine: no requirement of the menu component is confirmed as violated
Engine reference checks at 923b93ce72af (11/11 ok)
- okcommit923b93ce72af9b445616721fabde7eb822a21635
- okbase commit1e43373287afbd6dca4674ad463d5b5db7812358
- okbase ancestry1e43373287afbd6dca4674ad463d5b5db7812358
- okproduct code untouchedthis report's reproducer branch
- okbranchthis report's reproducer branch
- okfiletest/reports/report-cmulrfoje01ui18w4w89862tn.sh
- okrequirementSW-REQ-260922-8CQ4
- okrequirementSW-REQ-260922-SJ7P
- okrequirementSYS-REQ-260922-V7W6
- okcomponentmenu
- okknown issueKI-MENU-SEARCH-SCORE-RANKING
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.
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
sh test/reports/report-cmulrfoje01ui18w4w89862tn.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 AS-REPORTED:
AS-REPORTED: row 1 (the Enter target) is the destructive row [action] Remove › Development › Rust (omarchy-launch-floating-terminal-with-presentation 'omarchy-remove-dev-env rust'); the RustDesk app is row 2
search 'rust' from the root menu, top rows (row 1 is the Enter target): 1. [action] Remove › Development › Rust (score 356) -> omarchy-launch-floating-terminal-with-presentation 'omarchy-remove-dev-env rust' 2. [app] Apps › RustDesk (score 5372) AS-REPORTED: row 1 (the Enter target) is the destructive row [action] Remove › Development › Rust (omarchy-launch-floating-terminal-with-presentation 'omarchy-remove-dev-env rust'); the RustDesk app is row 2
Needs: linux · node >= 18 on PATH (the script exits 2 with SETUP: otherwise); nothing to build: MenuModel.js is plain JavaScript loaded straight from the worktree · ran on linux/amd64
Linked
- Fixed bypr/7661· confirmed
- Related PRpr/10457· confirmed
- Fixed bypr/12223· 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.
- Decided by agents · verified: in the audited area (menu)
- Decided by agents · verified: not a duplicate of another report
- Decided by agents · verified: intended behaviour — a design question, not a defect
The outcome (valid, duplicate, not a bug, …) is not decided yet.