cyberine
UsageRun recipes

Stopping a run or worker

s (stop run) / x (stop worker) work cross-process: the TUI and the engine run in separate processes and share only the filesystem, so stop is a control file the engine polls.

  • The TUI writes .local/runs/<runId>/control.json atomically (tmp+rename).
  • The engine polls it every 500ms, aborts the targeted worker(s) — the loop adapter aborts its in-flight HTTP stream, the CLI adapter SIGTERMs its subprocess (then SIGKILL after a 2s grace) — and renames the file to control.json.done so it's processed exactly once.
  • A run-level stop also skips the remaining steps and the (unaborted) judge phase, so the run exits within ~1s rather than waiting on a slow worker's timeout.
  • Stopped runs/workers settle to a new cancelled state, rendered as ⊘ (yellow). Partial streamed output is preserved.

A run-level stop transitions the run to cancelled, but individual steps reflect what actually happened:

  • A step that had at least one worker finish (success or partial) is recorded as done — its output is preserved and counts toward the "N/M step(s) done" summary in the run detail. The step detail reads Done (stopped; K/N worker(s) finished) to make the partial nature visible.
  • A step with no completed worker (all cancelled or errored before producing output) is recorded as cancelled.

The judge phase is always skipped on stop (it would otherwise make extra unaborted LLM calls), and a stopped-but-done step's winnerOutput still flows into any dependent steps.