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-update -y hangs forever at orphan-pkgs: gum confirm ignores OMARCHY_UPDATE_UNATTENDED
Reported by nanstey · filed Sep 26, 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
omarchy-update -y hangs indefinitely at the orphan-package step whenever stdin/stdout are TTYs. omarchy-update-orphan-pkgs decides interactivity purely from -t 0/-t 1 and never consults -y or OMARCHY_UPDATE_UNATTENDED, so it calls gum confirm in a run that promised not to ask anything.
Current behaviour
# /usr/share/omarchy/bin/omarchy-update-orphan-pkgs
if [[ ! -t 0 || ! -t 1 ]]; then
echo "${#orphans[@]} orphaned package(s) found. Re-run omarchy-update-orphan-pkgs in a terminal to review/remove them."
echo
exit 0
fi
if ! gum confirm --default=false "Remove ${#orphans[@]} orphaned package(s)?"; thenThe TTY check is a reasonable proxy for "nobody is watching", but it is the wrong signal here. omarchy-update itself documents the contract:
# -y is a promise not to ask anything. Steps that would need an answer report
# and move on instead of waiting on a prompt nobody is here to give.
[[ ${1:-} != "-y" ]] || export OMARCHY_UPDATE_UNATTENDED=1omarchy-update-orphan-pkgs is the one step that ignores it. Note also that omarchy-update re-execs itself under script -qefc, which allocates a PTY — so stdin/stdout are TTYs even in contexts where no human is present.
Reproduction
- Have at least one orphan (
pacman -Qtdqnon-empty). Mine wereasarandvulkan-headers, pulled in as build deps byquickshell-git. - Run
omarchy-update -yattached to a PTY but with no human answering (automation, supervised process, CI, agent-driven session). - Output stops after the orphan list and never advances.
Orphan system packages
asar
vulkan-headers
<hangs here>I left it 27 minutes. gum never rendered its TUI over that PTY; keystrokes sent to the process were echoed back as raw text rather than consumed, so the prompt could not be answered from outside either. I had to SIGTERM it.
Consequence
Everything after the orphan step is skipped:
omarchy-update-orphan-pkgs # blocks here
omarchy-update-analyze-logs
omarchy-update-status
omarchy-update-restartThe update's own log analysis, status report, and reboot offer never run, and the caller sees a hang rather than a failure. The package transaction itself had already completed successfully, so the system is in a fine state — but an automated caller cannot tell.
Suggested fix
Honour the existing contract:
if [[ ${OMARCHY_UPDATE_UNATTENDED:-0} == 1 || ! -t 0 || ! -t 1 ]]; then
echo "${#orphans[@]} orphaned package(s) found. Re-run omarchy-update-orphan-pkgs in a terminal to review/remove them."
echo
exit 0
fiThat keeps interactive behaviour unchanged and makes -y mean what the parent script says it means. Any other step calling gum should get the same treatment.
Environment
Omarchy 4.0.4
invoked omarchy-update -y (as root, PTY attached)
orphans asar, vulkan-headersView raw text
### Summary
`omarchy-update -y` hangs indefinitely at the orphan-package step whenever stdin/stdout are TTYs. `omarchy-update-orphan-pkgs` decides interactivity purely from `-t 0`/`-t 1` and never consults `-y` or `OMARCHY_UPDATE_UNATTENDED`, so it calls `gum confirm` in a run that promised not to ask anything.
### Current behaviour
```bash
# /usr/share/omarchy/bin/omarchy-update-orphan-pkgs
if [[ ! -t 0 || ! -t 1 ]]; then
echo "${#orphans[@]} orphaned package(s) found. Re-run omarchy-update-orphan-pkgs in a terminal to review/remove them."
echo
exit 0
fi
if ! gum confirm --default=false "Remove ${#orphans[@]} orphaned package(s)?"; then
```
The TTY check is a reasonable proxy for "nobody is watching", but it is the wrong signal here. `omarchy-update` itself documents the contract:
```bash
# -y is a promise not to ask anything. Steps that would need an answer report
# and move on instead of waiting on a prompt nobody is here to give.
[[ ${1:-} != "-y" ]] || export OMARCHY_UPDATE_UNATTENDED=1
```
`omarchy-update-orphan-pkgs` is the one step that ignores it. Note also that `omarchy-update` re-execs itself under `script -qefc`, which allocates a PTY — so stdin/stdout are TTYs even in contexts where no human is present.
### Reproduction
1. Have at least one orphan (`pacman -Qtdq` non-empty). Mine were `asar` and `vulkan-headers`, pulled in as build deps by `quickshell-git`.
2. Run `omarchy-update -y` attached to a PTY but with no human answering (automation, supervised process, CI, agent-driven session).
3. Output stops after the orphan list and never advances.
```
Orphan system packages
asar
vulkan-headers
<hangs here>
```
I left it 27 minutes. `gum` never rendered its TUI over that PTY; keystrokes sent to the process were echoed back as raw text rather than consumed, so the prompt could not be answered from outside either. I had to `SIGTERM` it.
### Consequence
Everything after the orphan step is skipped:
```bash
omarchy-update-orphan-pkgs # blocks here
omarchy-update-analyze-logs
omarchy-update-status
omarchy-update-restart
```
The update's own log analysis, status report, and reboot offer never run, and the caller sees a hang rather than a failure. The package transaction itself had already completed successfully, so the system is in a fine state — but an automated caller cannot tell.
### Suggested fix
Honour the existing contract:
```bash
if [[ ${OMARCHY_UPDATE_UNATTENDED:-0} == 1 || ! -t 0 || ! -t 1 ]]; then
echo "${#orphans[@]} orphaned package(s) found. Re-run omarchy-update-orphan-pkgs in a terminal to review/remove them."
echo
exit 0
fi
```
That keeps interactive behaviour unchanged and makes `-y` mean what the parent script says it means. Any other step calling `gum` should get the same treatment.
### Environment
```
Omarchy 4.0.4
invoked omarchy-update -y (as root, PTY attached)
orphans asar, vulkan-headers
```
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
- Fixed bypr/12419· confirmed
- Fixed bypr/9511· confirmed
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 18:47 UTC