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.
mise tool wrappers reset argv[0], so multi-call binaries lose their alternate mode (Claude Code's built-in grep silently finds nothing)
Reported by manozzo · filed Aug 24, 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?
- 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
System details
Intel Core Ultra 7 258V, Intel Arc 140V, Omarchy 4.0.0.alpha, mise 2026.8.6, Hyprland 0.56.2, bash 5.3.15, kernel 7.1.8-arch1-3
What's wrong?
Sibling of #7426 — same wrapper, different failure. That one is the wrapper adding a line to stdout; this is the wrapper changing the name the program is invoked under. Fixing the banner does not fix this.
omarchy-mise-install writes:
exec mise x "$package" -- "$bin" "$@"This re-execs the real binary by name, discarding the incoming argv[0]. Any caller that deliberately invokes a tool under a different name — the busybox / vim-vs-vi multi-call pattern — silently loses the behaviour it asked for.
Claude Code does exactly that: it ships a built-in grep reached by calling its own binary as ugrep, via a shell function it installs:
( exec -a ugrep "$_cc_bin" -G --ignore-files --hidden -I ... "$@" )Through the wrapper, mise x claude -- claude restores claude into argv[0], so the binary starts in normal CLI mode, meets -G and exits with error: unknown option '-G'. The function has no command grep fallback, so every `grep` in that shell returns nothing with exit 1 — indistinguishable from a legitimate "no matches". I lost an hour to empty greps before noticing, including concluding that alias cx existed nowhere on the system when it sits in /usr/share/omarchy/default/bash/aliases:48.
Claude Code guards against this with CLAUDE_CODE_EXECPATH, but the guard goes stale exactly when the wrapper does its job: the session records its binary path at launch, then any later mise use -g claude (another terminal starting claude) upgrades and deletes that directory, so the [[ -x ]] test fails and the fallback is the wrapper.
Reproduce
# real binary invoked as ugrep → works
(exec -a ugrep "$(mise which claude)" -G --ignore-files -I "alias cx" /usr/share/omarchy/default/bash/aliases)
# alias cx='printf "\033[2J\033[3J\033[H" && claude --permission-mode bypassPermissions'
# wrapper invoked as ugrep → banner + parse error, no results
(exec -a ugrep "$HOME/.local/bin/claude" -G --ignore-files -I "alias cx" /usr/share/omarchy/default/bash/aliases)
# mise ~/.config/mise/config.toml tools: [email protected]
# error: unknown option '-G'Suggested fix
A shell wrapper cannot fix this from the inside — worth stating, because the obvious patch looks right and isn't:
exec -a "$0" "$(mise which "$bin")" "$@" # does NOT workWhen a script is exec'd with a forged argv[0], the kernel runs the shebang interpreter with the script path, and bash sets $0 to that path; the forged name is gone before line 1 (printf '#!/bin/bash\necho $0\n' > /tmp/t.sh; (exec -a ugrep /tmp/t.sh) prints /tmp/t.sh).
So the entry in ~/.local/bin has to be the binary, or a symlink to it. mise keeps a stable path it repoints on upgrade (installs/<pkg>/latest -> ./2.1.241):
ln -sf "$HOME/.local/share/mise/installs/$package/latest/$bin" "$HOME/.local/bin/$command"Verified here in both modes: as ugrep it greps, as claude it prints 2.1.241 (Claude Code).
That drops the per-invocation mise use -g. Moving it into omarchy-update would keep tools current and also stop every gh call from rewriting ~/.config/mise/config.toml (the "worth a second look" note in #7426). Alternatively, keep wrappers for tools never invoked under another name and symlink the rest.
mise's own shim (shims/claude -> /usr/bin/mise) is not a substitute: it dispatches on argv[0], so calling it as ugrep would make mise look for a tool named ugrep.
Workaround
ln -sf ~/.local/share/mise/installs/claude/latest/claude ~/.local/bin/claudeUndone by omarchy update, which rewrites these filenames (#7101).
View raw text
### System details Intel Core Ultra 7 258V, Intel Arc 140V, Omarchy 4.0.0.alpha, mise 2026.8.6, Hyprland 0.56.2, bash 5.3.15, kernel 7.1.8-arch1-3 ### What's wrong? Sibling of #7426 — same wrapper, different failure. That one is the wrapper *adding* a line to stdout; this is the wrapper *changing the name the program is invoked under*. Fixing the banner does not fix this. `omarchy-mise-install` writes: ```bash exec mise x "$package" -- "$bin" "$@" ``` This re-execs the real binary **by name**, discarding the incoming `argv[0]`. Any caller that deliberately invokes a tool under a different name — the busybox / `vim`-vs-`vi` multi-call pattern — silently loses the behaviour it asked for. Claude Code does exactly that: it ships a built-in grep reached by calling its own binary as `ugrep`, via a shell function it installs: ```bash ( exec -a ugrep "$_cc_bin" -G --ignore-files --hidden -I ... "$@" ) ``` Through the wrapper, `mise x claude -- claude` restores `claude` into `argv[0]`, so the binary starts in normal CLI mode, meets `-G` and exits with `error: unknown option '-G'`. The function has no `command grep` fallback, so **every `grep` in that shell returns nothing with exit 1** — indistinguishable from a legitimate "no matches". I lost an hour to empty greps before noticing, including concluding that `alias cx` existed nowhere on the system when it sits in `/usr/share/omarchy/default/bash/aliases:48`. Claude Code guards against this with `CLAUDE_CODE_EXECPATH`, but the guard goes stale exactly when the wrapper does its job: the session records its binary path at launch, then any later `mise use -g claude` (another terminal starting `claude`) upgrades and deletes that directory, so the `[[ -x ]]` test fails and the fallback is the wrapper. **Reproduce** ```bash # real binary invoked as ugrep → works (exec -a ugrep "$(mise which claude)" -G --ignore-files -I "alias cx" /usr/share/omarchy/default/bash/aliases) # alias cx='printf "\033[2J\033[3J\033[H" && claude --permission-mode bypassPermissions' # wrapper invoked as ugrep → banner + parse error, no results (exec -a ugrep "$HOME/.local/bin/claude" -G --ignore-files -I "alias cx" /usr/share/omarchy/default/bash/aliases) # mise ~/.config/mise/config.toml tools: [email protected] # error: unknown option '-G' ``` **Suggested fix** A shell wrapper cannot fix this from the inside — worth stating, because the obvious patch looks right and isn't: ```bash exec -a "$0" "$(mise which "$bin")" "$@" # does NOT work ``` When a script is exec'd with a forged `argv[0]`, the kernel runs the shebang interpreter with the script *path*, and bash sets `$0` to that path; the forged name is gone before line 1 (`printf '#!/bin/bash\necho $0\n' > /tmp/t.sh; (exec -a ugrep /tmp/t.sh)` prints `/tmp/t.sh`). So the entry in `~/.local/bin` has to be the binary, or a symlink to it. mise keeps a stable path it repoints on upgrade (`installs/<pkg>/latest -> ./2.1.241`): ```bash ln -sf "$HOME/.local/share/mise/installs/$package/latest/$bin" "$HOME/.local/bin/$command" ``` Verified here in both modes: as `ugrep` it greps, as `claude` it prints `2.1.241 (Claude Code)`. That drops the per-invocation `mise use -g`. Moving it into `omarchy-update` would keep tools current and also stop every `gh` call from rewriting `~/.config/mise/config.toml` (the "worth a second look" note in #7426). Alternatively, keep wrappers for tools never invoked under another name and symlink the rest. mise's own shim (`shims/claude -> /usr/bin/mise`) is not a substitute: it dispatches *on* `argv[0]`, so calling it as `ugrep` would make mise look for a tool named `ugrep`. **Workaround** ```bash ln -sf ~/.local/share/mise/installs/claude/latest/claude ~/.local/bin/claude ``` Undone by `omarchy update`, which rewrites these filenames (#7101).
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 08:40 UTC