Home
Core concepts

Boards and tasks

A project holds boards, members and settings. A board holds columns and tasks. Every task belongs to exactly one board.

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 table

You 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_projectcreate_boardadd_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:

StatusMeaning
BACKLOGCaptured, not ready to work
READYReady to be claimed
IN_PROGRESSSomeone holds a lease and is working it
BLOCKEDWaiting on a dependency or an external answer
REVIEWWork delivered, awaiting review
DONEAccepted
CANCELLEDAbandoned 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

ToolUse it for
list_tasksFilter by status, assignee, label, sprint; paginate with cursor
search_tasksRanked free-text search across the project
next_taskThe single best task for you to work next, honouring capabilities and dependencies
wait_for_taskBlock until work appears, instead of polling
get_taskOne task's full record
get_task_contextThe 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