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

File manager (cwd) opens $HOME when the terminal runs tmux or herdr

Reported by vaknin · filed Sep 17, 2026 · open at source

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

File manager (cwd) opens $HOME when the terminal runs tmux or herdrrevision 1 · captured 2026-09-28 21:23 UTC via poll

System details

  • Omarchy 4.0.4-1, Hyprland 0.56.2, Linux 7.2.5-3-omarchy
  • tmux 3.7c, Alacritty (default terminal)
  • bin/omarchy-cmd-terminal-cwd on quattro is byte-identical to the installed 4.0.4 copy,

so this is current.

(No diagnostic log attached: omarchy debug is listed in omarchy --help on 4.0.4-1 but does
not route there — Unknown Omarchy command: omarchy debug, and /usr/share/omarchy/bin has no
omarchy-debug*. It does exist on quattro, so this looks like a packaging gap in 4.0.4-1 rather
than anything to do with this bug; say the word and I will file it separately.)

What's wrong?

SUPER + ALT + SHIFT + F ("File manager (cwd)") opens Files on $HOME instead of the
directory shown in the focused terminal, whenever that terminal is running a multiplexer.
Both multiplexers Omarchy ships hit it — tmux and herdr are each in
install/omarchy-base.packages, each have a stock launcher and a stock binding — so no
third-party software is involved in either reproduction.

There is no error and no log entry: a Files window does open, just on the wrong directory,
so it reads as "the binding worked" rather than "the binding resolved the wrong path".

Steps to reproduce

With tmux:

  1. SUPER + ALT + RETURN to start the stock tmux session (omarchy-launch-terminal-tmux).
  2. In the tmux pane, cd anywhere that is not $HOME, e.g. cd /etc.
  3. Press SUPER + ALT + SHIFT + F.

With herdr, the same three steps starting from SUPER + CTRL + RETURN
(omarchy-launch-terminal-herdr).

Expected: Files opens on /etc.
Actual: Files opens on $HOME, in both.

Reproduced directly against the resolver, with a real tmux server and client, stubbing only
hyprctl activewindow so the check needs no window focus:

window = terminal, client attached with `tmux -L … attach`, pane cwd = <tmpdir>/pane

stock omarchy-cmd-terminal-cwd : /home/<user>          <- $HOME fallback
expected                       : <tmpdir>/pane

Why

bin/omarchy-cmd-terminal-cwd takes the terminal's last direct child, reads
/proc/<pid>/cwd, and discards it unless that child's exe is listed in /etc/shells:

shell_pid=$(pgrep -P "$terminal_pid" | tail -n1)

if [[ -n $shell_pid ]]; then
  cwd=$(readlink -f "/proc/$shell_pid/cwd" 2>/dev/null)
  shell=$(readlink -f "/proc/$shell_pid/exe" 2>/dev/null)
  grep -Fqsx "$shell" /etc/shells || cwd=""
fi

Three separate assumptions in there do not hold:

  1. The shell is not always in the window's process tree. A multiplexer runs its panes

under a server process; where that server is detached and reparented to systemd --user
(plain tmux), there is no path from the terminal window to the pane's shell, so
walking children can never find it. The multiplexer has to be asked.
2. The client is not always a direct child. omarchy-launch-terminal-tmux runs
bash -c "tmux attach || tmux new -s Work", so the terminal's last direct child is that
bash — which is in /etc/shells, so its launch directory is returned confidently and
wrongly. omarchy-launch-terminal-herdr runs herdr directly, so there the last direct
child is the client itself, whose exe fails the /etc/shells test and whose readable cwd
is discarded.
3. `/etc/shells` is not the set of shells people use. fish, nushell and xonsh are
frequently not registered there, and their perfectly good cwd is thrown away.

pgrep -P … | tail -n1 also picks the highest-PID direct child, which is ordering luck
rather than a choice.

Two smaller symptoms of the same code: with no focused window, pgrep -P "" writes its
usage text to stderr, and when a multiplexer client is readable the /etc/shells check
throws away a directory that was already in hand.

Also affected

  • Any shell not listed in /etc/shells (fish, nushell, xonsh), in a plain terminal.
  • Other client/server multiplexers with the same shape: zellij and screen look like the same

class, though I have not tested them.
- Every caller of the resolver, though today omarchy-launch-nautilus-cwd is the only one.

Fix

PR follows: resolve in layers — kitty over its socket, then a multiplexer client anywhere
among the window's descendants (asking tmux for #{pane_current_path} of the client with the
matching pid, on the client's own -L/-S socket), then the deepest descendant attached to
the terminal whether or not its shell is listed, then $HOME.

View raw text
### System details

- Omarchy 4.0.4-1, Hyprland 0.56.2, Linux 7.2.5-3-omarchy
- tmux 3.7c, Alacritty (default terminal)
- `bin/omarchy-cmd-terminal-cwd` on `quattro` is byte-identical to the installed 4.0.4 copy,
  so this is current.

(No diagnostic log attached: `omarchy debug` is listed in `omarchy --help` on 4.0.4-1 but does
not route there — `Unknown Omarchy command: omarchy debug`, and `/usr/share/omarchy/bin` has no
`omarchy-debug*`. It does exist on `quattro`, so this looks like a packaging gap in 4.0.4-1 rather
than anything to do with this bug; say the word and I will file it separately.)

### What's wrong?

`SUPER + ALT + SHIFT + F` ("File manager (cwd)") opens Files on `$HOME` instead of the
directory shown in the focused terminal, whenever that terminal is running a multiplexer.
Both multiplexers Omarchy ships hit it — tmux and herdr are each in
`install/omarchy-base.packages`, each have a stock launcher and a stock binding — so no
third-party software is involved in either reproduction.

There is no error and no log entry: a Files window does open, just on the wrong directory,
so it reads as "the binding worked" rather than "the binding resolved the wrong path".

### Steps to reproduce

With tmux:

1. `SUPER + ALT + RETURN` to start the stock tmux session (`omarchy-launch-terminal-tmux`).
2. In the tmux pane, `cd` anywhere that is not `$HOME`, e.g. `cd /etc`.
3. Press `SUPER + ALT + SHIFT + F`.

With herdr, the same three steps starting from `SUPER + CTRL + RETURN`
(`omarchy-launch-terminal-herdr`).

**Expected:** Files opens on `/etc`.
**Actual:** Files opens on `$HOME`, in both.

Reproduced directly against the resolver, with a real tmux server and client, stubbing only
`hyprctl activewindow` so the check needs no window focus:

```
window = terminal, client attached with `tmux -L … attach`, pane cwd = <tmpdir>/pane

stock omarchy-cmd-terminal-cwd : /home/<user>          <- $HOME fallback
expected                       : <tmpdir>/pane
```

### Why

`bin/omarchy-cmd-terminal-cwd` takes the terminal's **last direct child**, reads
`/proc/<pid>/cwd`, and discards it unless that child's exe is listed in `/etc/shells`:

```bash
shell_pid=$(pgrep -P "$terminal_pid" | tail -n1)

if [[ -n $shell_pid ]]; then
  cwd=$(readlink -f "/proc/$shell_pid/cwd" 2>/dev/null)
  shell=$(readlink -f "/proc/$shell_pid/exe" 2>/dev/null)
  grep -Fqsx "$shell" /etc/shells || cwd=""
fi
```

Three separate assumptions in there do not hold:

1. **The shell is not always in the window's process tree.** A multiplexer runs its panes
   under a server process; where that server is detached and reparented to `systemd --user`
   (plain `tmux`), there is *no* path from the terminal window to the pane's shell, so
   walking children can never find it. The multiplexer has to be asked.
2. **The client is not always a direct child.** `omarchy-launch-terminal-tmux` runs
   `bash -c "tmux attach || tmux new -s Work"`, so the terminal's last direct child is that
   `bash` — which *is* in `/etc/shells`, so its launch directory is returned confidently and
   wrongly. `omarchy-launch-terminal-herdr` runs `herdr` directly, so there the last direct
   child is the client itself, whose exe fails the `/etc/shells` test and whose readable cwd
   is discarded.
3. **`/etc/shells` is not the set of shells people use.** fish, nushell and xonsh are
   frequently not registered there, and their perfectly good cwd is thrown away.

`pgrep -P … | tail -n1` also picks the highest-PID direct child, which is ordering luck
rather than a choice.

Two smaller symptoms of the same code: with no focused window, `pgrep -P ""` writes its
usage text to stderr, and when a multiplexer client *is* readable the `/etc/shells` check
throws away a directory that was already in hand.

### Also affected

- Any shell not listed in `/etc/shells` (fish, nushell, xonsh), in a plain terminal.
- Other client/server multiplexers with the same shape: zellij and screen look like the same
  class, though I have not tested them.
- Every caller of the resolver, though today `omarchy-launch-nautilus-cwd` is the only one.

### Fix

PR follows: resolve in layers — kitty over its socket, then a multiplexer client anywhere
among the window's descendants (asking tmux for `#{pane_current_path}` of the client with the
matching pid, on the client's own `-L`/`-S` socket), then the deepest descendant attached to
the terminal whether or not its shell is listed, then `$HOME`.

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 14:52 UTC