stella daemon
Find, watch, and stop runs that outlived the terminal they were started from.
A long-running verb started from a terminal — run, goal, monitor, fleet — is handed to a supervisor. The work becomes a detached process that survives the window closing, an ssh disconnect, and a logout; the terminal you started it in stays only to stream its output. stella daemon is how you find that process again afterwards.
Synopsis
stella daemon list
stella daemon attach [id]
stella daemon logs [id] [-n LINES]
stella daemon stop <id>Why runs are supervised
Closing a terminal sends SIGHUP to its foreground process group. Before this existed, that killed the run mid-turn: no answer, no record of why it stopped, and no way back to it. A supervised run is in its own session before it starts work, so the hangup never reaches it.
You do not start a supervised run — every terminal run already is one. The first two lines it prints say so:
▸ supervised ses-1785956826121-25167 — survives this terminal closing
reattach with stella daemon attach ses-1785956826121-25167Close that terminal, open another, and the run is still there:
$ stella daemon list
ID STATUS WHAT
ses-1785956826121-25167 Running stella: migrate the config loader to serde
$ stella daemon attach ses-1785956826121What supervision does and does not survive
It survives the terminal: a closed window, a dropped ssh session, a logout. It does not survive the process: a supervised run that is killed, or a machine that loses power, loses the turn it was in — only the fact of the run is recorded. Durable resume across a killed process is a different mechanism, and for interactive sessions stella resume is the one that exists today.
Which invocations are supervised
Only ones with a controlling terminal to lose. A terminal is exactly what can close, so a run that has none is already immune, and supervising it would add a process and a copy of every byte of output for nothing. Concretely:
| Invocation | Supervised |
|---|---|
stella run "…" typed in a terminal | yes |
stella run "…" --foreground | no — runs in this process, as older releases did |
cat spec.md | stella run with output redirected | no — no controlling terminal |
a CI step, a container, a cron job | no |
stella chat / stella resume | no — the deck is the terminal |
--foreground (or STELLA_FOREGROUND=1) opts any invocation out.
A supervised run is headless: its stdin is a file and its console is a log, so there is nobody to answer a scope-review prompt. A plan that expands scope stops with a named error instead of asking. The banner says so when it applies. Use --foreground to keep the interactive prompt, or set headless_scope_bypass = "on" in settings for a workspace where the tree is disposable.
list
Every supervised run on this machine, newest first. Local reads only — no API key, and no provider needs to resolve, so a run whose model configuration has since broken is still findable and stoppable.
STATUS is answered by a lock the run holds for its whole life rather than by its pid, because the kernel releases that lock when the process dies — crash, kill and power loss included. A run whose process is gone without recording an outcome reads as Crashed.
attach
Streams the run's output into this terminal, from the beginning, and stays until the run ends. A run that has already finished prints in full and exits. The id can be any unique prefix; omit it for the most recently started run.
Detaching again — Ctrl-C — leaves the run alone. stella daemon stop is what stops it.
logs
The tail of a finished or running console, without following it. -n sets how many lines back to start (default 40).
stdout and stderr are kept in two files and replayed onto the two streams they were written from, so stella run --output-format json stays parseable through a supervisor. One consequence is visible here: logs prints the stdout tail and then the stderr tail as separate blocks rather than interleaving them chronologically. attach on a live run interleaves naturally, because it follows both as they are written.
stop
Asks the run to stop the way Ctrl-C would: the signal reaches the whole process group — the run and every tool process it spawned — and the engine finishes the tool it is running and aborts at the next safe boundary, never mid-tool.
A run that has not stopped after 8 seconds is killed. Either way the stop is recorded as cancelled, deliberately: a run stopped by hand that recorded nothing would age into the registry indistinguishable from one that crashed.
Where the state lives
Beside the session registry, under the user-level stella home (~/.stella/sessions/<id>/, STELLA_DATA_DIR overrides): stdout.log and stderr.log are the console, stdin is the prompt the supervisor staged for the run, and supervisor.lock is the liveness lock. All owner-only. The prompt travels as a file rather than as an argument so it is not visible to every user on the machine in ps.