Toggle CLAUDE_SESSION_ID state to see how the old filter silently bypassed cross-session zombies — and how the new filter catches them.
Filter outcome — OLD vs NEW logic
OLD filter
NEW filter
The 1-line fix
- if (currentSessionId && spawn.session_id && spawn.session_id !== currentSessionId) continue;+ if (spawn.session_id && (!currentSessionId || spawn.session_id !== currentSessionId)) continue;
Why this matters
Aspect
Detail
Bug
OLD filter required currentSessionId truthy. When hook env lacked CLAUDE_SESSION_ID, the entire filter short-circuited to a no-op.
Result
24h cap was the only guard. Overnight gap between sessions (17-18h) fits under 24h. Yesterday's spawn entries fired CRITICAL noise.
Fix
Always drop tagged-as-different-session spawns. Untagged ones still fall through to the 24h cap.
Tests added
+2 cases in watchdog.test.ts: (a) unset session_id + cross-session spawn drops, (b) unset session_id + legacy untagged spawn still fires.
Session arc — the bug we papered over and now fixed
PR
What it did
Status
#1882
Added 24h zombie cap to silence days-old spawn noise
Right idea, wrong width (24h > 17-18h overnight gap)
#1952
Added session-id filter (this PR's bug location)
Right filter, silent bypass when env unset
#1966
Rotated subagent-spawns.jsonl at 500KB
Independent — about file size, not staleness
#1967
Cross-reference CC 2.1.145 background_tasks[]
Workaround. Hid the user-visible noise but didn't fix the bypass
THIS
Tighten the session-id filter
Actual root-cause fix
Root cause found by ork:debug-investigator agent (~5 min, read-only) after the user asked "lets assess all throughly and properly" and then "use sub agents and skills". The agent ruled out timestamp parse failure, clock skew, and NaN comparison; identified the actual structural issue in 281s.