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)

Closed
#1,697 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.