Skip to content

Terminate MCP child process trees on codex session close#56

Merged
ojowwalker77 merged 1 commit into
mainfrom
teacode/triage-github-issue-ojowwalker77/teacode-21-terminate-mcp-child
Jul 24, 2026
Merged

Terminate MCP child process trees on codex session close#56
ojowwalker77 merged 1 commit into
mainfrom
teacode/triage-github-issue-ojowwalker77/teacode-21-terminate-mcp-child

Conversation

@ojowwalker77

Copy link
Copy Markdown
Owner

Closes #21 (partial — core teardown; see Deferred).

Problem

On POSIX, closing/cancelling/replacing a codex session sent a bare SIGTERM to 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. killChildTree was Windows-only for tree teardown; POSIX fell through to child.kill().

Fix

  • childProcessTreeTerminator.ts (new): captures a child's descendant tree before signaling, sends graceful SIGTERM to the process group + tree + handle, then force-SIGKILLs survivors after a bounded grace window. Command-verifies captured PIDs before SIGKILL to avoid killing a reused PID, and skips the root's pid/group once it has exited. Reuses the tested terminal/processTreeKiller primitive instead of duplicating it; emits structured lifecycle logs (threadId, kind, pid/pgid, descendants, signal, graceMs).
  • spawnCodexAppServer: now spawns detached: true on POSIX so the app-server leads its own process group — teardown can signal codex + its MCP children as a unit in one call. Never unref'd; lifecycle stays owned by the manager. Windows keeps taskkill /T /F.
  • Codex teardown (stopSession / stopDiscoverySession) routes through the shared terminator with session-scoped logs.

Graceful app shutdown is already covered: NodeRuntime.runMain runs the stopAll finalizer 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

  • New childProcessTreeTerminator.test.ts: graceful group/tree/handle signaling, SIGTERMSIGKILL escalation, post-exit captured-descendant-only reaping (PID-reuse safety), escalation cancellation, no-pid skip, Windows taskkill path, and a real detached child-tree integration test (spawns sh + sleep grandchild, verifies the whole tree exits).
  • Existing 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):

  • Startup orphan reaping (requires a persisted PID registry).
  • Reference-counted shared/global MCP services.
  • macOS packaged-app verification + 5× open/close leak assertion.

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
@github-actions github-actions Bot added size:L vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. labels Jul 24, 2026
@ojowwalker77
ojowwalker77 merged commit 162bb4f into main Jul 24, 2026
14 checks passed
@ojowwalker77
ojowwalker77 deleted the teacode/triage-github-issue-ojowwalker77/teacode-21-terminate-mcp-child branch July 24, 2026 21:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Terminate MCP child processes when agent sessions close

1 participant