code-yeongyu / code-yeongyu/senpi
bug(codemode): eval cell child processes are abandoned at cell end (clear without kill, no process-group kill, Bun.$ untracked)
- Dominant language
- TypeScript
- Stars
- 429
- Forks
- 98
- Avg merge
- 5h 3m
- Merged PRs (30d)
- 526
Description
## Summary
packages/senpi-codemode/src/kernels/js/worker-runtime.js:
- Line 45: the cell finally block runs #children.clear() WITHOUT killing anything. Any child process still running at cell end (a dev server, a watcher, a build) loses its only owner and is reparented to launchd.
- interrupt() kills each tracked child directly but never the process group, so grandchildren survive.
- Bun.$ subprocesses are never tracked (worker-shell-capture.js), and on hard timeout worker.terminate() drops every reference — the most likely source of the orphaned vite / dev-runner / vp trees (up to 3.1 GB each, fully compressed = dead weight) found on the profiled host.
Related lifecycle gaps in the same run:
- pty session kill (packages/pty session.ts:185-203): after the first SIGTERM, kill() is a no-op — no SIGKILL escalation; registry grace expiry only marks 'stopping' then deletes the entry (registry.ts:120-134, 200-213), abandoning the process.
- coding-agent tools/bash.ts:170-181: on shell exit the pid is untracked immediately while descendants in its process group survive.
## Context
Root-caused during a profiling investigation of a long-lived macOS host (M4 Pro, 64 GB) running ~28 concurrent senpi/omo sessions for several days. Symptoms: load average ~150 with ~50% CPU utilization (threads blocked on swap I/O), 20 GB swap in use, 61 ppid=1 orphan processes (~2.1 GB, including vite dev servers up to 3.1 GB compressed, dev-runner and vp trees), and 12-14 zombies whose parents are live TUI main processes. All file:line references are against main (b19491745). Raw profiling evidence held locally.
## Expected (ideal state)
At cell end (settle, timeout, or interrupt), tracked children are terminated — process-group TERM then KILL after a grace — or explicitly handed off to a background registry by user intent (detached shell). Bun.$ children are tracked. PTY and bash tool sessions escalate SIGTERM to SIGKILL and keep group ownership until the last descendant exits.
## Acceptance criteria
- Tests: a cell spawning a sleeper (direct and via Bun.$) leaves zero live descendants after settle/timeout/interrupt; pty kill escalates to SIGKILL when TERM is ignored; no ppid=1 survivors in the test tree.
- Zombie reaping verified: no defunct children accumulate under the session process.
## Related
- #1507 (shared RPC host ps-child zombies — same zombie theme, different owner)
Contributor guide
Research direction
Start by tracing child cleanup in packages/senpi-codemode/src/kernels/js/worker-runtime.js and Bun.$ handling in worker-shell-capture.js, then inspect the PTY and bash lifecycle paths named in the issue. Add or run tests covering sleeper descendants during settle, timeout, and interrupt, PTY SIGKILL escalation, process-group ownership, and zombie reaping; done means no live descendants, ppid=1 survivors, or accumulating defunct children.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- bun, typescript
- Domain
- cli, devtools, operating-systems
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100