handleAttach 4 paths (new/alive/exited-L1/not-found); reapIdle uses now-max(detachedAt,lastOutputAt)>idleTtl (M3); shutdown kills all; injected onExit removes from table when attached, keeps for L1 replay when detached (L2); createSession errors propagate (M4). 21 tests; full suite 181 green.