[object Object]

← back to Desktop Dotbar

dotbar: document claimed-vs-unclaimed bg-spare liveness + negative test (TK-12236 contrarian follow-up)

426230af88d76bc5ffe3ac0c55d9d59c53fb78ff · 2026-09-25 10:26:34 -0700 · Steve Abrams

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RyJoXLrB22bwqavSf2ex1S

Files touched

Diff

commit 426230af88d76bc5ffe3ac0c55d9d59c53fb78ff
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Fri Sep 25 10:26:34 2026 -0700

    dotbar: document claimed-vs-unclaimed bg-spare liveness + negative test (TK-12236 contrarian follow-up)
    
    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01RyJoXLrB22bwqavSf2ex1S
---
 live-filter.js           | 5 ++++-
 test/live-filter.test.js | 9 +++++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/live-filter.js b/live-filter.js
index a6fb616..10d2f81 100644
--- a/live-filter.js
+++ b/live-filter.js
@@ -10,7 +10,10 @@ const CLOSED = new Set(['done', 'closed', 'cancelled', 'canceled']);
 const ttyBase = (t) => String(t || '').split('/').pop();
 const tkKey = (id) => { const m = /^(TK-\d+)/i.exec(String(id || '')); return m ? m[1].toUpperCase() : ''; };
 
-// `comm` can carry a renamed title ("claude bg-spare") or a full path.
+// `comm` can carry a renamed title ("claude bg-spare") or a full path. A "claude bg-spare"
+// ON A REAL TTY is a CLAIMED daemon spare, i.e. the interactive session itself (cc-daemon
+// keeps the spare's argv after the claim; verified 2026-09-25: pid 90349 on ttys004, S+
+// foreground, 8m CPU). UNCLAIMED spares sit on tty "??" and never count (see parsePs).
 function isClaudeComm(comm) { return /(^|\/)claude(\s|$)/.test(String(comm || '').trim()); }
 
 // Parse `ps -axo pid=,tty=,comm=`. Returns null when the probe produced nothing usable
diff --git a/test/live-filter.test.js b/test/live-filter.test.js
index f77b586..5276fca 100644
--- a/test/live-filter.test.js
+++ b/test/live-filter.test.js
@@ -93,3 +93,12 @@ test('parked chip count == panel row count (payload + UI read the same array)',
   assert.match(html, /<span class="cnt">\$\{pItems\.length\}<\/span>/, 'chip count must be the panel item array length');
   assert.match(html, /const items = \(data\.parked && data\.parked\.items\) \|\| \[\];/, 'panel renders data.parked.items');
 });
+
+test('NEGATIVE: an UNCLAIMED daemon spare (tty ??) never makes a tty or pid row live', () => {
+  const p = lf.parsePs(['  700 ??  claude bg-spare --bg-spare /tmp/x.claim.sock',
+                        '  701 ??  claude bg-pty-host --bg-pty-host /tmp/x.pty.sock',
+                        '  702 ttys099  /bin/zsh'].join('\n'));
+  assert.ok(!p.claudeTtys.has('??'), 'unclaimed spares do not populate claudeTtys');
+  const out = lf.buildParked([tab('ttys099'), tab('ttys098', 700)], { procs: p, tickets });
+  assert.deepEqual(ids(out), [], 'no-pid row on a spare-less tty and a pid that is an unclaimed spare elsewhere are both hidden');
+});

← 9c338a8 dotbar: carry pid on live parked tab rows so folder/realm cw  ·  back to Desktop Dotbar  ·  dotbar: start-bar comment now says Jev paid is ARMED (Steve 7010761 →