Public: anyone can read this; nobody can change it.
An app's terminal that runs without a cell ends with everything it started, on a hangup or its own exit #66
Check · Review · Land done · Live — Landed; nothing deploys from this branch, so this is the end of its path.
Where the host cannot hold a cell (CI, a pod without bwrap), an app's terminal (`ssh <slug>@forge`, or `t` in the forge's terminal UI) ran as a plain `/bin/sh -c` child in the forge's own process group, and a hangup sent SIGHUP to the program's pid alone. What the program had started (a server it left running, a job sent to the background) was re-parented and kept running in the deployed checkout,…
shipped merged
Sign in to join this conversation.
Where the host cannot hold a cell (CI, a pod without bwrap), an app's terminal (
ssh <slug>@forge, ortin the forge's terminal UI) ran as a plain/bin/sh -cchild in the forge's own process group, and a hangup sent SIGHUP to the program's pid alone. What the program had started (a server it left running, a job sent to the background) was re-parented and kept running in the deployed checkout, with the environment's data dir, forge token and secrets, after the terminal had closed; nothing ever stopped it.The terminal now leads a process group of its own (
detached, without a cell only), a hangup signals the group, and once the program has exited, what is left of the group is killed: the pattern #63 and #64 gave apps and steps. The spawn moves intostartTerminal, so it is tested without a deploy. A cell is unchanged: its tree dies with bubblewrap.signalGroupis exported fromapps/process.tsfor it.<!-- pipeline:validation -->
Validation
pipeline/validateona97b8e6b: baseline in 594s — 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)