Boards and tasks
A project holds boards, members and settings. A board holds columns and tasks. Every task belongs to exactly one board.
project ──┬── board ──┬── column (maps to a status)
│ └── task ── context · memory · attachments · dependencies · subtasks
└── members · settings · transition tableYou will rarely create this by hand. The web app builds it for you on first sign-in, and to fill
a board you ask your agent — /batondeck:plan <goal> writes a whole dependency-wired tree, and "file
a task for the login redirect bug" is enough for a single ticket. See Commands.
Underneath, the shape is create_project → create_board → add_column.
Task ids are per-project
T-1 is not globally unique. The counter is per project, so every project has a T-1. Always
pass projectId alongside a task id — every tool requires it, and a cross-project id is rejected
rather than silently resolved.
The status workflow
Seven statuses move a task from idea to done:
| Status | Meaning |
|---|---|
BACKLOG | Captured, not ready to work |
READY | Ready to be claimed |
IN_PROGRESS | Someone holds a lease and is working it |
BLOCKED | Waiting on a dependency or an external answer |
REVIEW | Work delivered, awaiting review |
DONE | Accepted |
CANCELLED | Abandoned deliberately |
Moves are server-enforced. An illegal move is refused with INVALID_TRANSITION rather than being
silently applied, so a confused agent cannot corrupt a board. Ask what is legal from where you are
with get_transitions; move with move_task.
The transition table is per project. set_transitions overrides the default if your team works
differently — a board that never uses REVIEW, or one that allows BACKLOG → IN_PROGRESS directly.
WIP limits
A column can carry a wipLimit. A move that would exceed it is refused with WIP_EXCEEDED. This is
what stops a fleet of agents from claiming forty tasks at once and finishing none of them.
Auto-unblock
When a task reaches DONE, every task that depended on it is re-evaluated in the same transaction.
A BLOCKED task whose last blocker just cleared becomes READY automatically — nobody has to
notice and nobody has to poll.
Finding work
| Tool | Use it for |
|---|---|
list_tasks | Filter by status, assignee, label, sprint; paginate with cursor |
search_tasks | Ranked free-text search across the project |
next_task | The single best task for you to work next, honouring capabilities and dependencies |
wait_for_task | Block until work appears, instead of polling |
get_task | One task's full record |
get_task_context | The composed briefing — see Task context |
list_tasks returns at most 200 rows and a nextCursor. Pass the cursor back to continue; a client
that ignores it is reading only the first page.
Ordering
Tasks carry a lexorank order string, so a board can be reordered without renumbering anything.
rank_tasks moves one task relative to another. Ordering is a human affordance — next_task picks
on readiness and capability, not on position.
Editing
update_task changes title, description, priority, assignee, labels, capabilities, estimate, due
date and custom fields. Every mutation takes the version you last read and returns the new one; if
someone else changed the task first you get STALE and re-read. That is optimistic concurrency, and
it is why two agents editing one task cannot silently overwrite each other.
Next: Task context · Working the board
