Foreground Bash/TaskStop don't kill subprocesses; harness tracks ghost shells
Summary
In a single 40-minute session, three different harness paths left processes running after they should have been dead, and the UI kept reporting activity for work that had long finished. The result was ~35 minutes of wasted wall time plus orphan processes holding container / DB resources.
Repros
1. task test -- --filter=X hangs silently for 30+ min with zero feedback
The task wrapper (our project's taskfile) eventually invokes php artisan test which passes --no-output to Pest. With coverage-mode Xdebug enabled, Pest can stall at ~0% CPU while the UI shows a running Bash call producing zero output. No way to tell from the UI whether the call is working, hung, or deadlocked.
Expected: either periodic heartbeat output from the harness, or a timeout warning when a Bash call goes quiet for N minutes.
2. TaskStop removes the task from the harness but leaves the OS process alive
I called TaskStop on a task test:parallel shell. Harness reported \"Successfully stopped task\". \ps\ showed the PHP / pest processes still running 28 minutes later at 0% CPU — they weren't sent SIGTERM/SIGKILL.
Expected: TaskStop should propagate the signal to the process group (setpgrp + killpg), or at least warn \"process still alive after stop signal\".
3. Rejecting a Bash tool call doesn't kill the subprocess it already started
I hit \"reject\" on a foreground \docker exec … pest …\ call about 10 seconds after it started. Four minutes later the pest invocation was still running inside the container. I had to manually \kill -9\ the host-side \sh\ wrapper.
Expected: user-side rejection should trigger SIGKILL of the spawned subprocess tree, not just disconnect the harness's read handle.
4. UI \"N shell still running\" banner is stale
After (1) / (2) / (3) were manually reaped via \kill -9\, the UI kept displaying \"1 shell still running\" for the remainder of the session. No way to clear it without starting fresh tool work.
Impact
- ~35 minutes of wasted wall time in one session.
- Resource leak: orphan PHP / docker processes holding DB connections + container memory.
- Status indicators can't be trusted — had to shell out to \
ps\/ \docker exec\repeatedly to know the real state, which defeats the purpose of an agentic harness.
Environment
- Claude Code CLI
- Model: Opus 4.7 (1M context)
- OS: Fedora 43, Linux 6.19.12
- Tools involved: Bash (foreground), TaskStop, Monitor
Suggested fixes
- Spawn subprocesses in their own process group; on rejection / TaskStop / session end, \
killpg(-PID, SIGKILL)\. - Emit a \"no output for Nm\" notification so silent hangs are visible without polling \
ps\. - Reconcile the \"shells running\" counter against real PIDs at each tool call; auto-clear ghosts.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗