Repository navigation
Releases
v0.8.4
0.8.4: a stopped step stops everything it started
Fixed
- Runner: a step that is stopped (its timeout ran out, the run was
canceled, or the runner is shutting down) now stops everything it
started, not only the shell that wraps its command. Before, the runner
killed that one shell and whatever ran under it carried on with nobody
watching: on 2026-11-11 the org-rootdataset-scoutseed step hit its
240 minute timeout and itsclaudeprocess kept working against the
server for another 40 minutes. Each step now runs in its own session
and process group. On a stop the runner notes every process under the
step (one that moved to a session of its own is still found, by
parentage), sends them SIGTERM so a program that manages children of
its own can stop them, and kills whatever is still running 5 seconds
later (TERMINATE_GRACE_SECONDS). Windows is unchanged: the direct
child is terminated as before.
Changed
- Runner: because a step has its own session, Ctrl-C in the terminal the
runner was started from reaches the runner alone. The runner then stops
its running steps itself, through the path above.
v0.8.3
0.8.3: a dropped websocket no longer cancels running steps
Fixed
- Runner: a dropped websocket no longer cancels the steps the runner is
running. Before, any transport failure (no close frame received or sent,keepalive ping timeout, a rolling API deploy) tore down every
running step before reconnecting, so a four-second blip killed hours of
work (the org-rootdataset-scoutseed step, 2026-11-09, three drops in
eighteen minutes). Now only the connection's own tasks (monitoring, the
stop-signal and command listeners) are rebuilt on reconnect. A step that
finishes while the runner is disconnected holds its result (its last log
lines and the completion) until the connection is back and retries the
report for up to 10 minutes; after that it logs the loss and drops the
result. A completion the server no longer accepts (the step was failed,
canceled or timed out there while the runner was offline) is logged and
absorbed, never a crash. A real shutdown (Ctrl-C, SIGTERM) still cancels
running steps as before. - Runner: finished step tasks are removed from the daemon's task list, so
the shutdown path and its "Exiting N active step(s)" line count the
steps really in flight (the list only ever grew before: 71, 74, 77 across
three reconnects on the same day). - Runner: a claim that fails because the connection just dropped is logged
and the step is left for the next connection to pick up (the server
offers unclaimed steps again on connect), instead of dying silently. - Runner: a step whose final log upload fails is still reported as
finished; the lines go out with the completion.
Changed
- Runner: a step's log lines stream to the server every 3 seconds while
the step runs (before, one batch was sent 10 seconds in and the rest
only at the end), so the run page and a chat turn's live view show
them as they are printed. A batch that fails to send is kept and goes
out with the next one. - Runner:
datatorch.runner.serve_forever(client, transport)is the
connect-serve-reconnect loopstart()runs, with oneRunnerDaemon
across connections (daemon.serve(session)per connection). The
one-shotRunnerDaemon.run(session)still works for outside callers.
v0.8.2
0.8.2: leave ${{ }} text the runner does not own exactly as written
The runner renders only its own namespaces in step inputs (runner/agent,
directory, machine, python, step, action, run, input/variable). Any other
${{ ... }} expression (steps., inputs., jobs., secrets., unknown
names, text that does not parse) passes through untouched: never
rendered, never emptied, never an error. The server resolves its
namespaces before dispatch, so such text still in an input is data. A
message input that quoted an older error such as
${{ steps.fetch.output.body }} used to fail the step with "'steps' is
undefined". Objects and arrays were never rendered and still pass through.
Also in this release: datatorch import coco runs the import on the
server by default (--dataset picks the dataset, --client-side keeps the
old pycocotools path).
v0.8.1
0.8.1: hand each step its place in the record
Every action a runner executes receives DATATORCH_PROJECT_ID,
DATATORCH_RUN_ID, DATATORCH_PIPELINE_ID and DATATORCH_STEP_ID, set by the
runner from the dispatch and never inherited from the outer process. The
same facts are available to an action's own templates as run.*. An
action that works for the project it runs in no longer needs a project
input, which is what lets a pipeline fork into another project unchanged.