Skip to content

Task states

A task’s status field holds one of two things: one of the six ordinary statuses, or a state belonging to its task type. Both are enforced the same way, by refusing a move that is not in the table.

StatusMeans
backlogWritten down, but not now. Where a new task can start, and where live work is parked
openReady to be picked up. What a new task starts at
in_progressBeing worked, usually by a run
blockedCannot proceed until something else changes
doneFinished. For work in a repository, reached when the branch merges, not when the run is accepted
cancelledDeliberately not doing it
FromMay move to
backlogopen, cancelled
openin_progress, blocked, backlog, done, cancelled
in_progressblocked, backlog, done, cancelled
blockedopen, in_progress, backlog, cancelled
donenothing (reopen only)
cancellednothing (reopen only)

Anything not in that table is refused with a validation error naming both states. Three consequences follow from it:

  • backlog is a park, not a starting line. Every live status has a way into it, for work that is real but not now. The ways back out are open when it is time, or cancelled when it never will be.
  • done and cancelled are terminal. They change only through reopen, which is a separate action rather than an ordinary move, and always lands on open.
  • in_progress cannot go back to open. Send it to backlog if it is simply not happening now, or to blocked if something else has to change first.

A task also carries a priority, which affects ordering rather than transitions: low, normal, high, urgent.

A task with a taskType replaces the six statuses entirely. Each type has its own initial state, its own terminal states, and its own transition table.

The content lifecycle, from a captured idea to a measured result. killed is reachable from every non-terminal state.

FromMay move to
captured (initial)ideating, killed
ideatingdrafting, killed
draftingverifying, killed
verifyinghuman_review, drafting, blocked, killed
human_reviewscheduling, drafting, blocked, killed
schedulingmeasuring, blocked, killed
measuringdone, blocked, killed
blockeddrafting, verifying, human_review, scheduling, measuring, killed

Terminal: done, killed. The two backward edges are the ones that matter in practice: verification and human review both send a draft back to drafting rather than failing it.

blocked is where a piece is parked when the platform cannot take the next step on its own: there was nothing to publish, the publish failed, the approval reached nobody, or the stage’s child task could not be created. It is not terminal, and it is not a stage anything works on. Whoever unblocks it chooses which stage to retry, which is why every re-enterable stage is reachable from it. done is not, because a piece is never declared finished from a state that records it never shipped.

FromMay move to
pending (initial)scoring, passed, failed, needs_revision
scoringpassed, failed, needs_revision

Terminal: passed, failed, needs_revision. A verdict is submitted from whichever non-terminal state the task is sitting in, so Pass, Fail and Needs revision all work straight from pending. scoring is optional: it records that someone has picked the review up, and nothing moves a task into it for you. See verification tasks.

FromMay move to
pending (initial)approved, rejected, expired

Terminal: approved, rejected, expired. See approval and feedback tasks.

FromMay move to
awaiting_window (initial)collecting
collectingcollected, awaiting_window, failed
collectedlearned

Terminal: learned, failed. The edge back to awaiting_window is what lets one feedback task cover several measurement windows. failed is where a window ends up once its metric sources have spent their retry budget: those numbers can never be collected, so the task stops rather than cycling between awaiting_window and collecting forever and pinning the content task it measures in measuring.

FromMay move to
waiting (initial)fired, cancelled

Terminal: fired, cancelled. See scheduled triggers.

The blocker a task carries when it needs information from you before work can start.

FromMay move to
pending (initial)collecting, cancelled
collectingcomplete, cancelled

Terminal: complete, cancelled.

What an agent raises mid-run when it hits a blocker it cannot clear itself. It records what it already tried, what it needs from you, and what answering unblocks. A run creates one; nobody writes one by hand.

FromMay move to
pending (initial)answered, cancelled

Terminal: answered, cancelled. Answering releases the task that was waiting on it and the work resumes on the branch the run already pushed; cancelling it cancels that task too. See assist tasks.

The huddle’s own final check, one per huddle, created by the merge and by nothing else. waiting_siblings is where it sits until every task on the branch has landed, so it runs against the finished working copy rather than a half-built one. It cannot be started by hand and it is never dispatched before ready.

FromMay move to
waiting_siblings (initial)ready, blocked, cancelled
readyin_progress, done, blocked, cancelled
in_progressdone, blocked, cancelled
blockedready, cancelled

Terminal: done, cancelled. ready moves straight to done because the base merge finishes every task on the branch, and blocked is reachable from everywhere a merge conflict can reach. See coding delivery.

The type a task has when it has no type. It accepts any state and any transition, which is why an ordinary task is validated against the six statuses above rather than against a graph.

Work bound to a repository, stamped when a huddle’s software draft is merged into a project that has one. It is a budget class rather than a lifecycle: it runs on the ordinary statuses above, accepts any state and any transition exactly as generic does, and changes only the budget a run of it resolves.