---
name: wt-single-process-husk-cleanup
description: Windows Terminal is single-process multi-window — killing the WT pid to clear husk windows takes down every agent session it hosts; close husks by HWND with a title filter + session-title refusal guard.
metadata: 
  node_type: memory
  type: project
  originSessionId: a6044c46-9fd0-4ab0-831a-cea2fc0b2b7d
  modified: 2026-08-03T04:42:30.844Z
---

2026-08-02 (hertz near-miss): 21 dead launch-failure husk windows (`ping  -n 120 127.0.0.1`, error `0x800700e8` ERROR_PIPE_NOT_CONNECTED) were all owned by ONE WindowsTerminal pid — which ALSO owned the hertz and todlando live-agent session windows. Killing the process to clear husks would have killed two agent sessions. Residue came from running the teardown test 80× for the IR-15 A/B.

**Why:** WT is single-process multi-window; window ≠ process. A launch-failure window is held open by the terminal regardless of `closeOnExit`, with no process behind it — process-table sweeps see nothing to reap. Confirm husk-not-survivor first with a live-process count (`Get-CimInstance Win32_Process -Filter "Name='PING.EXE'"` → 0).

**How to apply:** any window-cleanup on a box hosting live-agent terminals goes by HWND + title guard, never by terminal-process kill. Enumerate visible top-level windows via `EnumWindows` (owner pid + title), filter targets by title, `PostMessage(hwnd, WM_CLOSE=0x0010, 0, 0)` each. Include a guard that **throws** if any target title matches a session pattern; dry-run first; assert after — husks → 0, session windows still present, zero live processes behind them.

**Root cause class:** spawn helpers missing `CREATE_NO_WINDOW` — every spawned-console husk traces to a spawn flag, not to the terminal. Here: `detached_no_inherit_env` (spt-daemon/src/daemon.rs) spawns with `CREATE_BREAKAWAY_FROM_JOB | CREATE_SUSPENDED` and an access-denied fallback of bare `CREATE_SUSPENDED`, neither setting `CREATE_NO_WINDOW`/`DETACHED_PROCESS`, while every sibling spawn path does. Board **#131**. The name lies — "detached" there means breakaway-from-job, not `DETACHED_PROCESS`, which is how it escaped notice. Its product caller is `servicehost.rs`'s supervised `[service]` spawn, so shipped services popped terminal windows too; the fix must ride `resident_service_e2e`, never be assumed inert.

Related: [[live-agents-lock-target-debug-spt-exe]], [[rig-ownership-reap-only-your-own]], [[worktree-pin-holder-triage]].
