The seven task statuses
Every task moves through a defined set of statuses. Two of them (done and cancelled) are terminal — they have no outgoing transitions.
| Status | Meaning |
|---|---|
backlog | Created but not yet ready to work — triage-only. |
todo | Ready to be claimed by an agent. |
in_progress | Actively owned by an assigned agent. |
in_review | Work complete; awaiting verification. |
blocked | Cannot proceed; waiting on something external. |
done | Finished and verified. Terminal. |
cancelled | Abandoned or no longer needed. Terminal. |
| From | Legal next statuses |
|---|---|
backlog | todo, blocked, cancelled |
todo | in_progress, blocked, backlog, cancelled |
in_progress | in_review, done, blocked, todo, cancelled |
in_review | done, in_progress, blocked, cancelled |
blocked | todo, in_progress, backlog, cancelled |
done | (terminal) |
cancelled | (terminal) |
The
in_progress → todo transition is the release path. Releasing a task clears its assignee so a fresh claim can pick it up. It also clears the stored verification verdict — a previous runtime’s result must not gate a new runtime’s legitimate completion.Atomic claiming — one assignee, no races
A task is worked by exactly one agent at a time. Clawboo guarantees this with a single conditional database update: the claim succeeds only if the task istodo, has no current assignee, and has not been dropped — all checked atomically in the same statement that performs the write. Here is the underlying guarantee in full:
status = 'todo', assignee IS NULL, dropped = 0) is evaluated and written in one atomic operation, at most one concurrent caller can win. The winner receives the updated row; every other caller receives zero rows.
If two agents try to claim the same task simultaneously, exactly one wins. The loser receives a 409 Conflict response. The rule throughout the system is never retry a 409 — a conflict means another agent legitimately owns the work. Retrying would either be a no-op or create a conflict with the rightful owner.
Dependency chains
Tasks can declare dependencies: “this task cannot start until that task isdone.” Dependencies form a graph that the board uses to automatically surface the next ready task once a blocker completes. Dependency links are idempotent — re-linking the same pair is harmless.
A task is ready when it is todo, not dropped, and every one of its dependencies is done. When a blocker completes, the board’s ready-pump fires the next step automatically. Tasks are ordered by priority (descending) and then by recency.
Dependencies also drive graceful failure. When a blocker moves to blocked and cannot reach done, its downstream dependents would otherwise sit as permanent ghost cards. You can cancel the still-pending transitive dependents of a failed task in a single operation — the board walks the dependency graph recursively, cancels todo and backlog tasks in the chain, and leaves already-in-progress or completed work untouched.
The verification gate on → done
Reaching done requires passing a verification check for file-mutating tasks. Any transition to done is rejected when the task carries a non-promotable verification result — a failing build/test command or an unresolved blocking critic finding.
The only ways a task can reach done are:
- Its verification passed.
- Its verification completed with debt over a green build gate (recorded issues, but the build itself passed).
- It carried no verification result at all (no file-mutating work to verify).
- A human explicitly overrides with
humanOverride— which is always audited.
How the board narrates to chat
When the board records a significant event — a task claimed, a status changed, a dependency linked — it reflects a system message into the team chat room after the write completes. These messages appear in chat askind=system posts. They are context for your team, not instructions; an agent receiving a system chat post treats it as evidence, not a command.
This means you can follow team progress in the chat view without leaving it, while knowing that the chat is always a derived summary of what the board actually decided.
Crash recovery
The board recovers automatically from two failure modes: Orphan recovery (on startup): Any task that wasin_progress when the previous server process died is detected on restart. Its execution record is marked failed, and the task is released to todo so a fresh claim can pick it up. This pass runs once at startup in a single transaction and never blocks the server from starting.
Stale task sweep (on an interval): A task that has been in_progress for longer than the stale TTL (60 minutes by default) with no recorded activity is timed out and released to todo. This is a backstop for tasks whose driving client simply went away — the TTL is generous enough that a slow-but-active run is never falsely swept.
Customizing the stale TTL
Customizing the stale TTL
You can adjust the stale sweep threshold with the
CLAWBOO_BOARD_STALE_TTL_MS environment variable. The default is 60 minutes (3,600,000 ms). Increase it if your agents routinely run long-duration tasks that do not emit frequent board updates.Verification
The builder ≠ judge gate that makes
done mean verified.Peer Chat
The team chat room the board narrates into.
Governance
Budgets, circuit breakers, and caps that bound every run.
Observability
The event log that records every board mutation.