[object Object]

← 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 →