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-941GitHub issuePublicDecided· Out of scope

omarchy-mise-install wrappers in ~/.local/bin are shadowed by `mise activate` after first run

Reported by YotamPeled · filed Sep 5, 2026 · open at source

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

omarchy-mise-install wrappers in ~/.local/bin are shadowed by `mise activate` after first runrevision 1 · captured 2026-09-28 21:23 UTC via poll

Description

omarchy-mise-install writes a self-updating wrapper to ~/.local/bin/<command>:

#!/bin/bash
export MISE_MINIMUM_RELEASE_AGE=0
mise use -g --quiet "claude" || exit 1
exec mise x "claude" -- "claude" "$@"

The wrapper's whole purpose (per its own comment) is to bypass mise's release cooldown so these fast-moving tools update on every launch.

It works exactly once. The first run's mise use -g adds the tool to ~/.config/mise/config.toml. From then on mise activate bash (sourced from default/bash/init) prepends that tool's install dir to PATH on every prompt and every cd — ahead of ~/.local/bin, which default/bash/env-bootstrap deliberately appends ("appended so system binaries keep precedence").

The wrapper is shadowed by a directory entry that the wrapper itself caused to exist. It is self-defeating by construction.

Steps to reproduce

omarchy-mise-install claude
command -v claude          # ~/.local/bin/claude          ✅ wrapper
claude --version           # runs once, adds claude to the global mise config
# new shell
command -v claude          # ~/.local/share/mise/installs/claude/latest/claude   ❌ raw binary

Expected

command -v claude keeps resolving to ~/.local/bin/claude, so the tool self-updates on launch.

Actual

It resolves to the mise install dir. The update step never runs. The tool sits on whatever version mise's cooldown last allowed, and Claude Code shows a permanent "Update available! Run: mise upgrade claude" banner — while mise upgrade claude correctly reports nothing to do, because the cooldown is still withholding the release. Two sources of truth disagreeing, with no way for the user to reconcile them short of mup.

On this machine, claude, codex and gh are affected (the wrappers that have been run). The other nine wrappers present in ~/.local/bin — copilot, crush, gemini, ghui, grok, hunk, omp, opencode, pi — still resolve correctly only because they have never been launched. They break on second use.

Root cause

Ordering conflict between two Omarchy-owned files:

FileEffect
default/bash/env-bootstrapappends ~/.local/bin (low precedence, by design)
default/bash/init → mise activate bashprepends each globally-active tool's install dir on every prompt/cd

Note on workarounds

A static PATH="$HOME/.local/bin:$PATH" in ~/.bashrc does not hold — mise's prompt/chpwd hook rebuilds PATH on the next cd and re-shadows the wrapper. Verified:

after prepend:        ~/.local/bin/claude
after cd + mise hook: ~/.local/share/mise/installs/claude/latest/claude

An alias (alias claude="$HOME/.local/bin/claude") does hold, since alias resolution precedes the PATH search — but that is a user-side patch, not a fix.

Possible fixes

  1. Have omarchy-mise-install emit a shell alias/function alongside the wrapper rather than relying on PATH precedence.
  2. Don't use mise use -g in the wrapper — keep these tools out of the global config so mise activate never puts them on PATH (e.g. mise x <tool>@latest directly).
  3. Re-prepend ~/.local/bin from a mise chpwd/prompt hook that runs after mise's own.

System details

  • Omarchy 4.0.2-1
  • mise 2026.8.15 linux-x64 (mise-bin from the omarchy repo)
  • bash, Arch, Hyprland
View raw text
## Description

`omarchy-mise-install` writes a self-updating wrapper to `~/.local/bin/<command>`:

```bash
#!/bin/bash
export MISE_MINIMUM_RELEASE_AGE=0
mise use -g --quiet "claude" || exit 1
exec mise x "claude" -- "claude" "$@"
```

The wrapper's whole purpose (per its own comment) is to bypass mise's release cooldown so these fast-moving tools update on every launch.

It works exactly once. The first run's `mise use -g` adds the tool to `~/.config/mise/config.toml`. From then on `mise activate bash` (sourced from `default/bash/init`) prepends that tool's install dir to `PATH` on every prompt and every `cd` — ahead of `~/.local/bin`, which `default/bash/env-bootstrap` deliberately *appends* ("appended so system binaries keep precedence").

The wrapper is shadowed by a directory entry that the wrapper itself caused to exist. It is self-defeating by construction.

## Steps to reproduce

```bash
omarchy-mise-install claude
command -v claude          # ~/.local/bin/claude          ✅ wrapper
claude --version           # runs once, adds claude to the global mise config
# new shell
command -v claude          # ~/.local/share/mise/installs/claude/latest/claude   ❌ raw binary
```

## Expected

`command -v claude` keeps resolving to `~/.local/bin/claude`, so the tool self-updates on launch.

## Actual

It resolves to the mise install dir. The update step never runs. The tool sits on whatever version mise's cooldown last allowed, and Claude Code shows a permanent "Update available! Run: `mise upgrade claude`" banner — while `mise upgrade claude` correctly reports nothing to do, because the cooldown is still withholding the release. Two sources of truth disagreeing, with no way for the user to reconcile them short of `mup`.

On this machine, `claude`, `codex` and `gh` are affected (the wrappers that have been run). The other nine wrappers present in `~/.local/bin` — `copilot`, `crush`, `gemini`, `ghui`, `grok`, `hunk`, `omp`, `opencode`, `pi` — still resolve correctly only because they have never been launched. They break on second use.

## Root cause

Ordering conflict between two Omarchy-owned files:

| File | Effect |
|---|---|
| `default/bash/env-bootstrap` | appends `~/.local/bin` (low precedence, by design) |
| `default/bash/init` → `mise activate bash` | prepends each globally-active tool's install dir on every prompt/`cd` |

## Note on workarounds

A static `PATH="$HOME/.local/bin:$PATH"` in `~/.bashrc` does **not** hold — mise's prompt/`chpwd` hook rebuilds `PATH` on the next `cd` and re-shadows the wrapper. Verified:

```
after prepend:        ~/.local/bin/claude
after cd + mise hook: ~/.local/share/mise/installs/claude/latest/claude
```

An alias (`alias claude="$HOME/.local/bin/claude"`) does hold, since alias resolution precedes the `PATH` search — but that is a user-side patch, not a fix.

## Possible fixes

1. Have `omarchy-mise-install` emit a shell alias/function alongside the wrapper rather than relying on `PATH` precedence.
2. Don't use `mise use -g` in the wrapper — keep these tools out of the global config so `mise activate` never puts them on `PATH` (e.g. `mise x <tool>@latest` directly).
3. Re-prepend `~/.local/bin` from a mise `chpwd`/prompt hook that runs after mise's own.

## System details

- Omarchy `4.0.2-1`
- mise `2026.8.15 linux-x64` (`mise-bin` from the omarchy repo)
- bash, Arch, Hyprland

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 10:50 UTC