πŸ› Watchdog zombies + stale bundle β€” three coupled bugs

Diagnosis and fix for the recurring "[Agent Watchdog] CRITICAL: Agent X running for 5000+min" spam visible in every session. Three distinct issues, one PR.

🩺 Bugs found

BUG 1 Stale plugin bundle

src/hooks/dist/subagent.mjs had the 24h zombie reaper (rebuilt today). plugins/ork/hooks/dist/subagent.mjs was 8 days old β€” the cap-less version. Claude Code loads from plugins/, so the cap never ran.

Fix: the new pre-rsync hooks-build step (Bug 3 fix) refreshes plugins/ as a side effect.

BUG 2 No session_id filter

Even with the 24h cap in place, any zombie spawn from another session that died mid-flight (terminal closed, OOM, /clear) still fires CRITICAL when it falls in the 10min–24h window. Source comment said this was "follow-up (schema migration)" β€” but the session_id field has been written by subagent-validator.ts all along.

Fix: filter on process.env.CLAUDE_SESSION_ID in watchdog.

+ const currentSessionId = process.env.CLAUDE_SESSION_ID;
   for (const spawn of spawns) {
     if (spawn.agent_id === completedAgentId) continue;
+    if (currentSessionId && spawn.session_id && spawn.session_id !== currentSessionId) continue;
     if (!spawn.timestamp) continue;

BUG 3 build-plugins.sh trusts stale dist

Top-level npm run build ran scripts/build-plugins.sh, which rsynced whatever was in src/hooks/dist/ into plugins/. It never ran cd src/hooks && npm run build first. If a hook author edited TS source but forgot the hooks workspace's build, plugins/ shipped the previous bundle silently. Exactly how Bug 1 happened.

Fix: add a Phase 1.5 step that runs the hooks build before cleaning/rebuilding plugins. Gracefully skips when node_modules isn't installed.

🎯 State change

FileBeforeAfter
src/hooks/src/subagent-stop/watchdog.ts no session filter filters on CLAUDE_SESSION_ID
scripts/build-plugins.sh rsync only esbuild β†’ rsync
plugins/ork/hooks/dist/subagent.mjs 2026-05-14 (stale) 2026-05-22 (fresh, has cap + filter)
src/hooks/src/__tests__/subagent-stop/watchdog.test.ts 11 tests, all passing 13 tests (added 2 session-filter cases), all passing

πŸ§ͺ Test plan