← back to Terminal Status
set-variant: --tty targeting + don't require caller ancestry (2026-09-11)
1bc426cdea9873999a7b239619ccb472196bfa38 · 2026-09-11 11:16:33 -0700 · Steve Abrams
Lets an EXTERNAL supervisor mark another session. Two fixes, both found by forcing a
launchd run rather than trusting its exit code:
1. --tty was registered on the shared subcommand loop but NOT on set-variant, and its
dispatch resolved the caller's own tty — so it could never target another session.
2. caller = current_owner(rows) ran UNCONDITIONALLY, before --tty was read. It walks the
caller's process ancestry for a terminal; launchd has none, so every scheduled run
died on 'No owning Claude/Codex terminal in this process ancestry' while launchctl
reported
wtmp begins Mon May 25 23:28:20 PDT 2026, , and an empty stderr. A textbook false
green: loaded, exited clean, accomplished nothing. Caller resolution is now optional
when --tty names an explicit target; assert_owner() still validates that target
against the live process table, so a dead or reassigned tty is refused as before.
Verified under launchd after the fix: 4 failures -> 0, verdict WARN -> PASS.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Files touched
Diff
commit 1bc426cdea9873999a7b239619ccb472196bfa38
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Fri Sep 11 11:16:33 2026 -0700
set-variant: --tty targeting + don't require caller ancestry (2026-09-11)
Lets an EXTERNAL supervisor mark another session. Two fixes, both found by forcing a
launchd run rather than trusting its exit code:
1. --tty was registered on the shared subcommand loop but NOT on set-variant, and its
dispatch resolved the caller's own tty — so it could never target another session.
2. caller = current_owner(rows) ran UNCONDITIONALLY, before --tty was read. It walks the
caller's process ancestry for a terminal; launchd has none, so every scheduled run
died on 'No owning Claude/Codex terminal in this process ancestry' while launchctl
reported
wtmp begins Mon May 25 23:28:20 PDT 2026, , and an empty stderr. A textbook false
green: loaded, exited clean, accomplished nothing. Caller resolution is now optional
when --tty names an explicit target; assert_owner() still validates that target
against the live process table, so a dead or reassigned tty is refused as before.
Verified under launchd after the fix: 4 failures -> 0, verdict WARN -> PASS.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---
terminal_status.py | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/terminal_status.py b/terminal_status.py
index 8b9e6cc..3346de7 100644
--- a/terminal_status.py
+++ b/terminal_status.py
@@ -707,7 +707,19 @@ def main(argv=None):
if failures:
raise StatusError("; ".join(failures))
return 0
- caller = current_owner(rows)
+ # An EXTERNAL supervisor (the launchd greendot-agent) has no terminal ancestry of its
+ # own, so current_owner() raises "No owning Claude/Codex terminal in this process
+ # ancestry". When such a caller addresses a session EXPLICITLY with --tty it never needs
+ # a caller at all, so resolving one must not be a precondition. Before this, every
+ # scheduled run failed on that raise while launchctl still reported `last exit code = 0`
+ # — a textbook false green: loaded, exit 0, runs=1, accomplishing nothing. (2026-09-11)
+ if getattr(args, "tty", ""):
+ try:
+ caller = current_owner(rows)
+ except StatusError:
+ caller = None
+ else:
+ caller = current_owner(rows)
if args.command == "set-variant":
# Use the already-resolved caller + the real store instance (the branch shipped calling
# a nonexistent Owner.detect()/STORE, so set-variant crashed in EVERY session — the
← 1f88b72 terminal_status.py: set-variant --if-blocked (only 🔵-mark n
·
back to Terminal Status
·
terminal-status: fix paint hang — raise per-process PROC_TTL 9696608 →