mirror of
https://github.com/hanzoai/forge.git
synced 2026-10-30 15:00:39 +00:00
A runner stopped between accepting a task and starting its first step cancels that task and reports it failed. act_runner's graceful shutdown covers a job that is executing, not one still being set up, so a pod rolling or a node going away ended the job red with nothing built and nothing to tell it apart from a job whose steps ran and failed. The steps are what tell them apart. A step carries a Started stamp from the moment it begins, so a task whose every step is unstamped executed no user code: nothing it could have done has been done, and another runner may take the job without repeating anything. One stamp vetoes. RequeueDroppedTask applies that rule from the two places a task is failed without its own steps having decided it: the runner's final report, and the zombie sweep for a runner that stops reporting at all. A new Drops count on the job bounds it at three, so a job nothing can get through fails rather than circulating, and a cancel is never re-queued. UpdateTaskByState now persists the reported step states before settling the job, because a step that starts and fails inside one report interval is only ever seen in the report that ends the task. StopTask's job writes are conditioned on the job still pointing at that task, so stopping a task cannot settle a job that has already been handed back. Assisted-by: blue:claude-opus-5