Skip to content

fix(sshx): tear down the carrier's process tree on interruption - #1055

Open
loning wants to merge 1 commit into
ChronoAIProject:devfrom
loning:fix/runner-teardown-process-tree
Open

loning wants to merge 1 commit into
ChronoAIProject:devfrom
loning:fix/runner-teardown-process-tree

Conversation

@loning

@loning loning commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Skill: consensus-rnd:sshx — implemented by one codex-cli seat (flight runner-teardown-0912) on a clone of this repository; orchestrator (claude main loop, trureturing project) reviewed the diff summary and test list and opens this PR from a fork (no push access). Zero review seats at open time.

Defect (observed 2026-09-12 in a downstream project)

run-codex-worker.sh runs the carrier synchronously and its interrupt() trap only records INTERRUPTED; when the host signals the runner (four host memory-pressure kills in one session), the carrier's descendants — make → lake → lean, dotnet test hosts, profiler runs — are not signalled. Five orphaned lean -Dprofiler processes of ~15 GB each survived 56 minutes after their runners died, which in turn caused further memory-pressure kills. CODEX_WORKER_SPEC.md documented this as host-owned teardown ("The runner therefore does not propagate signals"), citing two TaskStop experiments; the memory-pressure kill path signals only the runner and leaves the tree.

Change

  • Runner: the carrier is launched as the runner's own recorded background job and waited on; on INT/TERM the runner snapshots the carrier's descendants (pgrep -P, recursive; portable macOS/Linux, no setsid), sends TERM individually, allows ~5 s grace, KILLs survivors, reaps the carrier, then publishes INTERRUPTED as before. Repeated signals and the Bash 3.2 launch window are handled. Nothing outside the carrier's descendant set is signalled. Status JSON gains an interruption-only teardown record (descendants_signalled excludes the carrier; killed_after_grace includes it); all existing fields, carrier.exit semantics, success-path artifacts and envelope/sentinel validation are unchanged.
  • Spec/SKILL/formal: catchable carrier-tree teardown is now runner-owned; the host keeps ownership of signalling the runner itself, time limits and uncatchable termination. Contract pins and the Lean ownership clause are aligned.
  • Tests (behaviour, fake carriers): test_sigterm_tears_down_carrier_process_tree, test_sigterm_kills_term_ignoring_carrier_tree_after_grace, test_success_does_not_teardown_carrier_descendants, test_signal_at_carrier_launch_boundaries; existing trap/status/batch tests updated to the new wiring. Verified on macOS Bash 3.2; Linux and real host cancellation not exercised (marked ASSUMED-UNVERIFIED in the seat report). No version bump (maintainer's call).

🤖 Generated with Claude Code

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