clu
Getting Started

Status semantics

What each issue status means and how it propagates through the dep graph.

statusmeaningdownstream effect
opennot yet startednormal
in_progressclaimed; an agent is workingnormal
closeddone successfullyunblocks dependents
cancelledabandoneddependents stay blocked (or cascade-cancel)

The split between closed and cancelled is the whole reason both exist — clu cancel <id> marks the target and all transitive descendants as cancelled in a single CTE walk. If a chunk of work turns out to be unnecessary or unrecoverable, you don't have to manually close every dependent issue.

clu reopen <id> reverses either terminal state and puts the issue back to open. Issues also carry a started_at timestamp (set on claim, distinct from updated) so clu show, the web list, and doctor's stuck-check can tell how long something has actually been in progress.

Behavioral types

Two issue types add behavior on top of the status loop:

  • A checkpoint is a manual gate. It stays labelled checkpoint:pending until someone runs clu approve (or clu checkpoint pass); failing it (clu checkpoint fail) cascade-cancels the rest of the run.
  • A milestone auto-closes when all its dependencies close. It's the self-completing umbrella behind clu batch --group and the automatic phase boundaries in bulk graphs and workflows.

Why claim is atomic

clu claim is implemented as a single SQL statement:

UPDATE issues
SET status = 'in_progress', assignee = ?
WHERE id = (
  SELECT id FROM issues
  WHERE status = 'open'
    AND <lane filter>
  ORDER BY priority DESC, created_at
  LIMIT 1
)
RETURNING *;

Two agents calling clu claim at the same time will receive different rows or one will receive nothing. There is no read-modify-write window for them to step on each other.

On this page