--- name: omp-extension-stale-module-audit description: "Diagnose recurring omp extension handler timeouts/silence when the on-disk fix is already deployed: harness has no extension hot-reload, so running sessions freeze the module at session start (zombie modules)." --- Use when a fix for an omp extension is merged/deployed yet the SAME errors persist ("handler timed out after 30000ms", silence, wrong behavior) in running sessions. **Core fact:** the harness loads extension `.ts` modules at session start and never reloads them (no `/reload` for extensions; bundle `reload` hits are LSP/MCP/browser only). A session older than the fix keeps executing stale code regardless of the file on disk. **Procedure:** 1. Census the errors from logs, not guesses — timeout lines carry the culprit pids: `grep -h "handler timed out" ~/.omp/logs/omp.*.log | python3 -c 'import sys,json; rows=[json.loads(l) for l in sys.stdin]; rows.sort(key=lambda r:r["timestamp"]); [print(r["timestamp"], r["event"], r["pid"]) for r in rows]'` (`~/.omp/logs/omp...log` — the pid in the filename is the session.) 2. Session start times vs deployed file versions: `ps -eo pid,lstart,args | grep '[o]mp'` `git log --format='%h %ad %s' --date=format:'%m-%d %H:%M' -- ` `git reflog --format='%gd %ad %gs' --date=format:'%m-%d %H:%M' | grep merge` (live-sync pull times = when the file content changed). Any session whose start time precedes the fix's arrival has the stale module. 3. Confirm the stale revision actually contains the bad pattern — read what that session loaded, not HEAD: `git show : | grep -n 'await speak\|async (event'` (e.g. an `async agent_end` awaiting a >30 s chain is exactly what the harness's per-handler `Kzc` 30 s race logs; fire-and-forget `void` is fine — detached promises are NOT tracked by the dispatch window.) 4. Optional empirical proof when static analysis says "impossible": probe extensions through the real harness: `omp -p --no-extensions -e /tmp/probe.ts "Reply OK"` with a probe that logs handler start/return and `void`s a 40 s detached promise + spawns a long child. Fast exit + no timeout log ⇒ detachment is untracked ⇒ blame stale modules, not the harness. 5. Remediation: restart the affected sessions (kill the listed pids or their terminals — the operator session itself may be one of the zombies; say so explicitly). There is no other fix. **Gotchas:** - Per-handler attribution in the log is accurate per dispatch; don't blame other extensions before checking the pid's start time. - Endpoints healthy + silence persisting usually means TWO stacked bugs (e.g. stale awaiting module in old sessions AND a mute bug in current code) — diagnose each pid cohort separately. - Extension chain code must use self-owned `AbortSignal.timeout(...)`, never a ctx-scoped signal: harness dispatch signals die when the dispatch window closes.