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.
omarchy-cmd-terminal-cwd returns $HOME on kitty >= 0.47 — Super+Enter no longer opens in current directory
Reported by gusevdigital · filed Jul 17, 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
Summary
Since kitty 0.47.0, omarchy-cmd-terminal-cwd always falls back to $HOME, so Super+Enter opens a new terminal in the home directory instead of the active terminal's cwd. Super+Alt+Enter (tmux) and Super+Alt+Shift+F (Nautilus in cwd) are affected too, since they call the same command.
Cause
The script picks the shell by taking the terminal's highest-numbered child PID:
shell_pid=$(pgrep -P "$terminal_pid" | tail -n1)kitty 0.47.0 added auto config reloading (auto_reload_config, enabled by default), which spawns a long-lived helper from boss.py:
if opts.auto_reload_config >= 0 and not hasattr(self, 'config_reload_watcher_process') and opts.all_config_paths:
self.config_reload_watcher_process = subprocess.Popen(
[kitten_exe(), '__watch_conf__', str(os.getpid()), ...])It's spawned after the shell, so it has a higher PID and tail -n1 selects it:
192573 kitten __atexit__
192575 bash <- actual shell
192581 kitten __watch_conf__ <- tail -n1 picks this/usr/bin/kitten isn't in /etc/shells, so the guard fails and the script echoes $HOME. On kitty <= 0.46 the shell happened to be the last child, so tail -n1 worked by coincidence.
Only reproduced on kitty. ghostty and alacritty likely don't spawn a config watcher and are probably unaffected.
Suggested fix
Scan every child and take the first one that is a real shell, rather than relying on PID ordering:
terminal_pid=$(hyprctl activewindow | awk '/pid:/ {print $2}')
if [[ -n $terminal_pid ]]; then
for pid in $(pgrep -P "$terminal_pid"); do
shell=$(readlink -f "/proc/$pid/exe" 2>/dev/null)
grep -qsxF "$shell" /etc/shells || continue
cwd=$(readlink -f "/proc/$pid/cwd" 2>/dev/null)
if [[ -d $cwd ]]; then
echo "$cwd"
exit 0
fi
done
fi
echo "$HOME"This also tightens the shell check: the current grep -qs "$shell" /etc/shells treats the path as a regex and matches substrings, so /bin/sh matches a /bin/shell-foo line. grep -qsxF matches the full line literally.
Environment
- Omarchy 3.8.3 (
bec26eea) - kitty 0.47.4-1
- Hyprland 0.55.4
- Arch Linux
View raw text
### Summary
Since kitty 0.47.0, `omarchy-cmd-terminal-cwd` always falls back to `$HOME`, so Super+Enter opens a new terminal in the home directory instead of the active terminal's cwd. Super+Alt+Enter (tmux) and Super+Alt+Shift+F (Nautilus in cwd) are affected too, since they call the same command.
### Cause
The script picks the shell by taking the terminal's highest-numbered child PID:
```bash
shell_pid=$(pgrep -P "$terminal_pid" | tail -n1)
```
kitty 0.47.0 added auto config reloading (`auto_reload_config`, enabled by default), which spawns a long-lived helper from `boss.py`:
```python
if opts.auto_reload_config >= 0 and not hasattr(self, 'config_reload_watcher_process') and opts.all_config_paths:
self.config_reload_watcher_process = subprocess.Popen(
[kitten_exe(), '__watch_conf__', str(os.getpid()), ...])
```
It's spawned after the shell, so it has a higher PID and `tail -n1` selects it:
```
192573 kitten __atexit__
192575 bash <- actual shell
192581 kitten __watch_conf__ <- tail -n1 picks this
```
`/usr/bin/kitten` isn't in `/etc/shells`, so the guard fails and the script echoes `$HOME`. On kitty <= 0.46 the shell happened to be the last child, so `tail -n1` worked by coincidence.
Only reproduced on kitty. ghostty and alacritty likely don't spawn a config watcher and are probably unaffected.
### Suggested fix
Scan every child and take the first one that is a real shell, rather than relying on PID ordering:
```bash
terminal_pid=$(hyprctl activewindow | awk '/pid:/ {print $2}')
if [[ -n $terminal_pid ]]; then
for pid in $(pgrep -P "$terminal_pid"); do
shell=$(readlink -f "/proc/$pid/exe" 2>/dev/null)
grep -qsxF "$shell" /etc/shells || continue
cwd=$(readlink -f "/proc/$pid/cwd" 2>/dev/null)
if [[ -d $cwd ]]; then
echo "$cwd"
exit 0
fi
done
fi
echo "$HOME"
```
This also tightens the shell check: the current `grep -qs "$shell" /etc/shells` treats the path as a regex and matches substrings, so `/bin/sh` matches a `/bin/shell-foo` line. `grep -qsxF` matches the full line literally.
### Environment
- Omarchy 3.8.3 (`bec26eea`)
- kitty 0.47.4-1
- Hyprland 0.55.4
- Arch Linux
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 03:57 UTC