An app that runs without a cell stops with everything it started, and leaves no child running once it has gone #63
No reviewers
Labels
No labels
agent-work
agent-working
ultracode
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
trevato-apps/forge!63
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "grokbot/forge:fix/app-stop-whole-tree"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Where the host cannot hold a cell, an app ran as a plain child in the
forge's own process group, and stop() signalled its pid alone. A child
it had started (a worker,
bun run's script, asleep) was re-parentedand kept running on the environment's data and token after the forge
called it stopped; one that outlived a crash ran beside the restart.
The app now leads a process group of its own (
detached, without acell only), stop() asks and then kills the group, and once the app has
exited, however it went, what is left of the group is killed. A cell is
unchanged: its tree is bubblewrap's.
Since a terminal's hangup no longer reaches those apps directly, the
forge takes SIGHUP the way it takes Ctrl-C: it drains and stops them.
test/apps-stop-tree.test.ts: red on main (3 of 3), green here.
Regression test
test/apps-stop-tree.test.ts(3 tests: a stop ends the app's children; a child that ignores SIGTERM is killed once the app has gone; an app that dies on its own takes its children with it). Pinned bun 1.3.14:dc68048esource + this test: 0 pass, 3 fail (each child still alive 3 s after the stop/exit)Also on the box, CI-shaped PATH (no bwrap, so every app runs uncelled — the path this changes): all 24 gated
test/apps*.test.ts+app.test.ts+standing-every-process.test.ts: 212 pass, 0 fail.SIGHUP: the forge started in a pty, the pty then killed: this branch logs
forge draining … why=SIGHUPand exits; main dies on the hangup without draining.Security
Process control. The group signal is only ever
-proc.pidof a group this spawn just made the app lead (detached, i.e. setsid), never the forge's own group, and a cell's spawn is unchanged. Linux keeps a pid from reuse while it is any live process's pgid, so the kill after exit reaches only what is left of the app's group, or nothing (ESRCH, ignored). What it closes: an app's children outliving a stop or a crash, still running on the environment's data dir and forge token after the forge recorded it stopped (or its token revoked) — and beside its restart. An app that calls setsid itself still escapes, as before; a cell is the containment for that.Validation
pipeline/validateon077b8561: baseline in 595s — bun 1.3.14, CI-shaped env (scrubbed vars, runner PATH), exact check.yml shard + forge.json commands.bun install --frozen-lockfileforge.json check.fastcheck.yml gate (1) pull_requestcheck.yml gate (2) pull_requestcheck.yml gate (3) pull_requesttest output (failures, totals)