Terminate MCP child process trees on codex session close#56
Merged
ojowwalker77 merged 1 commit intoJul 24, 2026
Conversation
Closing/cancelling/replacing a codex session (or graceful app shutdown) previously sent a bare SIGTERM to only the codex app-server process on POSIX — no tree/group kill, no forced escalation. Any MCP server the agent CLI spawned could orphan and accumulate, degrading low-RAM Macs. - Add childProcessTreeTerminator: capture the descendant tree, graceful SIGTERM to the process group + tree + handle, then force-SIGKILL survivors after a bounded grace window (command-verified against PID reuse). Reuses the tested terminal/processTreeKiller primitive; emits structured lifecycle logs. - Spawn codex app-server detached on POSIX so it leads its own process group and teardown can signal codex + MCP children as a unit. - Route codex session/discovery teardown through the shared terminator with session-scoped lifecycle logs. Deferred (need cross-restart infra): startup orphan reaping, ref-counted shared MCP services, packaged-app verification. Refs #21
Merged
ojowwalker77
deleted the
teacode/triage-github-issue-ojowwalker77/teacode-21-terminate-mcp-child
branch
July 24, 2026 21:52
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #21 (partial — core teardown; see Deferred).
Problem
On POSIX, closing/cancelling/replacing a codex session sent a bare
SIGTERMto only the codex app-server process — no tree/group kill, no forced escalation. Any MCP server the agent CLI spawned as a grandchild could orphan and accumulate across sessions, degrading low-RAM (8 GB) Macs.killChildTreewas Windows-only for tree teardown; POSIX fell through tochild.kill().Fix
childProcessTreeTerminator.ts(new): captures a child's descendant tree before signaling, sends gracefulSIGTERMto the process group + tree + handle, then force-SIGKILLs survivors after a bounded grace window. Command-verifies captured PIDs beforeSIGKILLto avoid killing a reused PID, and skips the root's pid/group once it has exited. Reuses the testedterminal/processTreeKillerprimitive instead of duplicating it; emits structured lifecycle logs (threadId, kind, pid/pgid, descendants, signal, graceMs).spawnCodexAppServer: now spawnsdetached: trueon POSIX so the app-server leads its own process group — teardown can signal codex + its MCP children as a unit in one call. Neverunref'd; lifecycle stays owned by the manager. Windows keepstaskkill /T /F.stopSession/stopDiscoverySession) routes through the shared terminator with session-scoped logs.Graceful app shutdown is already covered:
NodeRuntime.runMainruns thestopAllfinalizer on SIGINT/SIGTERM, which now performs a real tree kill.Behavioral note
Codex app-server is now spawned detached on POSIX (its own process group). Functionally transparent for a server (no controlling TTY), called out for review visibility.
Tests
childProcessTreeTerminator.test.ts: graceful group/tree/handle signaling,SIGTERM→SIGKILLescalation, post-exit captured-descendant-only reaping (PID-reuse safety), escalation cancellation, no-pid skip, Windowstaskkillpath, and a real detached child-tree integration test (spawnssh+sleepgrandchild, verifies the whole tree exits).codexAppServerManager.test.ts(71) still pass.oxfmt,oxlint(0 warnings in new files),turbo run typecheck(8/8) green.Deferred (need cross-restart infrastructure)
Out of scope for this PR; the teardown fix eliminates the leak on every normal path (the reaper only matters after a hard crash/SIGKILL of the server):