Skip to content

fix(executor): terminate abandoned execution trees - #1009

Open
stgmt wants to merge 2 commits into
mksglu:mainfrom
stgmt:fix/executor-abort-cleanup
Open

fix(executor): terminate abandoned execution trees#1009
stgmt wants to merge 2 commits into
mksglu:mainfrom
stgmt:fix/executor-abort-cleanup

Conversation

@stgmt

@stgmt stgmt commented Jul 28, 2026

Copy link
Copy Markdown

Summary

  • propagate MCP request cancellation into ctx_execute and ctx_execute_file
  • terminate the exact spawned process tree and settle aborted executions deterministically
  • clean .ctx-mode-* sandboxes and add metadata-only ownership manifests for safe recovery
  • cover pre-abort, child/grandchild termination, manifest secrecy, active request isolation, timeout behavior, and file execution

Regression

A disconnected/abandoned ctx_execute request could leave bash -c .../.ctx-mode-*/script and its Python descendants running indefinitely. One observed tree consumed CPU continuously for five days.

Verification

  • tests/executor.test.ts: 127 passed, 25 platform-specific skipped
  • tsc --noEmit: passed
  • independent adversarial review: CLEAN

🤖 Generated with Claude Code

stgmt and others added 2 commits July 29, 2026 01:36
Co-Authored-By: Claude <noreply@anthropic.com>
…hrough MCP handlers

Commit 83aefee added AbortSignal plumbing and an ownership sidecar, but the
signal never reached the executor on the public MCP path: wrapToolHandler
dropped the SDK's (args, extra) second argument, so every handler saw
extra === {} and no host cancellation could arrive; ctx_execute_file never
forwarded a signal at all. Also fixed two abort hangs: pre-aborted signals
now short-circuit before spawn, and a post-kill grace timer settles the
execution instead of waiting indefinitely for `close` (inherited stdio
handles on Windows can delay it far past the kill).

- server.ts: wrapToolHandler forwards extra (request-scoped AbortSignal);
  ctx_execute_file forwards signal to executeFile
- executor.ts: pre-abort fast path; ABORT_SETTLE_GRACE_MS deterministic
  settle with listener/stream cleanup; abortSettleTimer cleared on
  close/error
- tests/executor.test.ts: regression suite - shell tree (child+grandchild)
  killed on abort with <5s settlement and .ctx-mode-* temp cleanup;
  ownership.json is metadata-only (canary: no command/code/secrets) and
  removed; pre-abort never spawns; abort is request-scoped (concurrent and
  fresh executions unaffected); timeout path green with inert signal;
  executeFile forwards signal
- README.md: document host-driven cancellation and the sidecar contract

Tests: 127 passed | 25 platform-skipped (vitest tests/executor.test.ts);
tsc --noEmit green.

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant