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

App library rescans hidden entries on every save of any file in $HOME (no debounce, ~105 processes per scan)

Reported by benedikt-personal · filed Oct 10, 2026 · open at source

Decided: Out of scope — decided by agents · verified 2 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

App library rescans hidden entries on every save of any file in $HOME (no debounce, ~105 processes per scan)revision 1 · captured 2026-10-10 15:54 UTC via poll

Version: omarchy 4.0.4-1, quickshell 0.3.1-1.

Problem
shell/services/AppLibrary.qml starts hiddenEntryScan (shell/services/hidden-entries.sh) on every DesktopEntries.applications onValuesChanged, with no debounce. iconIndexScan already uses a 750 ms Timer (iconIndexDebounce) for the same signal; hiddenEntryScan does not.

Quickshell's desktop-entry watcher holds inotify watches on $HOME, ~/.local, ~/.local/share and the applications folders (verified in /proc/<quickshell pid>/fdinfo). A normal atomic save of any file in $HOME (for example ~/.claude.json written by Claude Code: lock dir, tmp file, rename) therefore fires the signal. In a 90 s trace one save produced 3 scans within 0.4 s. In a later 60 s window with normal use: 1 save, 2 scans.

Cost per scan (99 .desktop files): about 105-135 forks, 0.34 s wall, 0.36 s CPU. The forks come from id=$(desktop_id_for_file ...), one command-substitution subshell per file. On a machine where agents save the file often, reaped quickshell children averaged 19.8 percent of one core over 26.3 h (CORCO-2013 measurement).

Suggested fix (two parts)
1. In AppLibrary.qml add a debounce Timer for hiddenEntryScan, same as iconIndexDebounce (interval 750), and call hiddenEntryDebounce.restart() instead of hiddenEntryScan.running = true in onValuesChanged. Keep the immediate scan in Component.onCompleted.
2. Remove the per-file subshell in hidden-entries.sh. Tested: output identical (29 ids), forks about 125 -> about 25-45, wall 345 ms -> 175 ms.

@@ -30,7 +30,7 @@
   local rel=${file#"$dir"/}
 
   rel=${rel%.desktop}
-  printf '%s\n' "${rel//\//-}"
+  desktop_id=${rel//\//-}
 }
 
 is_hidden_desktop_file() {
@@ -82,7 +82,8 @@
   [[ -d $dir ]] || return
 
   while IFS= read -r -d '' file; do
-    id=$(desktop_id_for_file "$dir" "$file")
+    desktop_id_for_file "$dir" "$file"
+    id=$desktop_id
     [[ -n ${seen_ids[$id]+set} ]] && continue
     seen_ids[$id]=1
 

Optional, quickshell side (https://git.outfoxxed.me/quickshell/quickshell): DesktopEntryMonitor could ignore events on parent directories whose name is not the next path component of a watched applications folder, or only emit when a *.desktop file or an applications folder changed.

Workaround found: none. AppLibrary is instantiated directly in shell.qml (not a plugin), the script path is fixed to $OMARCHY_PATH/shell/services, and no quickshell environment variable controls the DesktopEntries watcher.

View raw text
Version: omarchy 4.0.4-1, quickshell 0.3.1-1.

Problem
shell/services/AppLibrary.qml starts hiddenEntryScan (shell/services/hidden-entries.sh) on every DesktopEntries.applications onValuesChanged, with no debounce. iconIndexScan already uses a 750 ms Timer (iconIndexDebounce) for the same signal; hiddenEntryScan does not.

Quickshell's desktop-entry watcher holds inotify watches on $HOME, ~/.local, ~/.local/share and the applications folders (verified in /proc/<quickshell pid>/fdinfo). A normal atomic save of any file in $HOME (for example ~/.claude.json written by Claude Code: lock dir, tmp file, rename) therefore fires the signal. In a 90 s trace one save produced 3 scans within 0.4 s. In a later 60 s window with normal use: 1 save, 2 scans.

Cost per scan (99 .desktop files): about 105-135 forks, 0.34 s wall, 0.36 s CPU. The forks come from `id=$(desktop_id_for_file ...)`, one command-substitution subshell per file. On a machine where agents save the file often, reaped quickshell children averaged 19.8 percent of one core over 26.3 h (CORCO-2013 measurement).

Suggested fix (two parts)
1. In AppLibrary.qml add a debounce Timer for hiddenEntryScan, same as iconIndexDebounce (interval 750), and call hiddenEntryDebounce.restart() instead of hiddenEntryScan.running = true in onValuesChanged. Keep the immediate scan in Component.onCompleted.
2. Remove the per-file subshell in hidden-entries.sh. Tested: output identical (29 ids), forks about 125 -> about 25-45, wall 345 ms -> 175 ms.

```diff
@@ -30,7 +30,7 @@
   local rel=${file#"$dir"/}
 
   rel=${rel%.desktop}
-  printf '%s\n' "${rel//\//-}"
+  desktop_id=${rel//\//-}
 }
 
 is_hidden_desktop_file() {
@@ -82,7 +82,8 @@
   [[ -d $dir ]] || return
 
   while IFS= read -r -d '' file; do
-    id=$(desktop_id_for_file "$dir" "$file")
+    desktop_id_for_file "$dir" "$file"
+    id=$desktop_id
     [[ -n ${seen_ids[$id]+set} ]] && continue
     seen_ids[$id]=1
 
```

Optional, quickshell side (https://git.outfoxxed.me/quickshell/quickshell): DesktopEntryMonitor could ignore events on parent directories whose name is not the next path component of a watched applications folder, or only emit when a *.desktop file or an applications folder changed.

Workaround found: none. AppLibrary is instantiated directly in shell.qml (not a plugin), the script path is fixed to $OMARCHY_PATH/shell/services, and no quickshell environment variable controls the DesktopEntries watcher.

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

  • Fixed bypr/14992· 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.

  • Out of scopeDecided by agents · verified · 2026-10-10 17:10 UTC