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-25167

Close 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-1785956826121

What 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:

InvocationSupervised
stella run "…" typed in a terminalyes
stella run "…" --foregroundno — runs in this process, as older releases did
cat spec.md | stella run with output redirectedno — no controlling terminal
a CI step, a container, a cron jobno
stella chat / stella resumeno — 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.