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.
Theme changes don't reach TUIs under a daemon-owned multiplexer: omarchy-theme-set-foot only walks foot's direct children
Reported by marvreichmann · filed Sep 12, 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
After a theme change, TUIs running inside a terminal multiplexer whose PTYs are owned by a detached server process keep rendering the previous theme's palette. The terminal window itself retints correctly, so the bug looks like an application problem rather than a theming one.
Reproduced on omarchy 4.0.3, Arch, foot 1.28.0, with herdr as the multiplexer and opencode 1.18.29 ("theme": "system", i.e. terminal-adaptive) in a pane. The same shape should apply to tmux and zellij in server mode, and to any TUI that resolves colors by querying the terminal.
Mechanism
omarchy-theme-set-foot retints by writing OSC sequences into the ttys of foot's direct children:
for foot_pid in $(pgrep -x foot); do
for child_pid in $(pgrep -P "$foot_pid"); do
tty=$(readlink "/proc/$child_pid/fd/1")
[[ $tty == /dev/pts/* ]] && printf '%b' "$foot_osc" >"$tty"With a client/server multiplexer the process tree splits:
foot 843251 ──> herdr (client) 843277 /dev/pts/0
herdr server 45465 (detached, tty=/dev/null, PPid=1599)
└─ bash 249510 ──> opencode 253283 /dev/pts/2The write lands on /dev/pts/0, reaches foot's master, and the window repaints correctly — that part works. But the pane PTYs (/dev/pts/2) are owned by the server, which is not a descendant of foot, so the loop never visits them.
That alone would be cosmetic, except the multiplexer also answers OSC 10/11 palette queries on behalf of its panes, from a palette it cached when the client attached. Nothing in the theme path tells it to re-query, so a TUI that asks its terminal what color the background is gets the previous theme's answer and renders accordingly.
Why it presents as "one theme behind"
post_theme_commands runs under run_parallel, so omarchy-restart-opencode (killall -SIGUSR2 opencode) races the retint with no ordering between them. The signalled application re-queries, gets the stale cached palette, and settles on the previous theme. The next theme change repeats this one step later, which reads to the user as a consistent one-change lag rather than a race.
Impact
Any OSC-querying TUI under a daemon-owned multiplexer. It is not specific to opencode — opencode is just a common case because its default system theme is terminal-adaptive by design.
Suggested direction
There is already precedent for multiplexers needing an explicit entry: omarchy-theme-set-tmux pushes theme environment into running tmux sessions. There is no equivalent for other multiplexers, and no generic way for one to learn that the palette changed.
Two options, not mutually exclusive:
- Add a per-multiplexer hook, mirroring
omarchy-theme-set-tmux. For herdr this is a one-liner —herdr server reload-configmakes the server re-read its config and, withtheme.name = "terminal", re-query the host palette. - Prefer generated theme files over palette queries for applications that support them, which sidesteps the cached palette entirely. PR #8684 does exactly this for opencode and fixes that case; the underlying traversal gap remains for everything else.
Happy to send a patch for (1) if that direction seems right.
View raw text
## Summary
After a theme change, TUIs running inside a terminal multiplexer whose PTYs are owned by a **detached server process** keep rendering the previous theme's palette. The terminal window itself retints correctly, so the bug looks like an application problem rather than a theming one.
Reproduced on omarchy 4.0.3, Arch, foot 1.28.0, with [herdr](https://herdr.dev) as the multiplexer and opencode 1.18.29 (`"theme": "system"`, i.e. terminal-adaptive) in a pane. The same shape should apply to tmux and zellij in server mode, and to any TUI that resolves colors by querying the terminal.
## Mechanism
`omarchy-theme-set-foot` retints by writing OSC sequences into the ttys of foot's **direct children**:
```bash
for foot_pid in $(pgrep -x foot); do
for child_pid in $(pgrep -P "$foot_pid"); do
tty=$(readlink "/proc/$child_pid/fd/1")
[[ $tty == /dev/pts/* ]] && printf '%b' "$foot_osc" >"$tty"
```
With a client/server multiplexer the process tree splits:
```
foot 843251 ──> herdr (client) 843277 /dev/pts/0
herdr server 45465 (detached, tty=/dev/null, PPid=1599)
└─ bash 249510 ──> opencode 253283 /dev/pts/2
```
The write lands on `/dev/pts/0`, reaches foot's master, and the window repaints correctly — that part works. But the pane PTYs (`/dev/pts/2`) are owned by the **server**, which is not a descendant of foot, so the loop never visits them.
That alone would be cosmetic, except the multiplexer also answers `OSC 10/11` palette queries on behalf of its panes, from a palette it cached when the client attached. Nothing in the theme path tells it to re-query, so a TUI that asks its terminal what color the background is gets the previous theme's answer and renders accordingly.
## Why it presents as "one theme behind"
`post_theme_commands` runs under `run_parallel`, so `omarchy-restart-opencode` (`killall -SIGUSR2 opencode`) races the retint with no ordering between them. The signalled application re-queries, gets the stale cached palette, and settles on the previous theme. The next theme change repeats this one step later, which reads to the user as a consistent one-change lag rather than a race.
## Impact
Any OSC-querying TUI under a daemon-owned multiplexer. It is not specific to opencode — opencode is just a common case because its default `system` theme is terminal-adaptive by design.
## Suggested direction
There is already precedent for multiplexers needing an explicit entry: `omarchy-theme-set-tmux` pushes theme environment into running tmux sessions. There is no equivalent for other multiplexers, and no generic way for one to learn that the palette changed.
Two options, not mutually exclusive:
1. **Add a per-multiplexer hook**, mirroring `omarchy-theme-set-tmux`. For herdr this is a one-liner — `herdr server reload-config` makes the server re-read its config and, with `theme.name = "terminal"`, re-query the host palette.
2. **Prefer generated theme files over palette queries** for applications that support them, which sidesteps the cached palette entirely. PR #8684 does exactly this for opencode and fixes that case; the underlying traversal gap remains for everything else.
Happy to send a patch for (1) if that direction seems right.
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 12:14 UTC