Skip to content

A Task Board is a durable, multi-agent-readable queue β€” the markdown or DB artifact where humans AND agents read/write the same state, and the Trigger and the Agent meet without a central coordinator.

Primitive

Task Board ​

What it looks like

Plain markdown. Grouped by worktree. ​

tasks.md

# ATL## Worktree: feature-auth[βœ… a1b2c3d4, adw001]Implement JWT middleware[🟑, adw002]Add OAuth2 provider[⏰]Add user profiles# blocked: prior not all βœ…[]Add session logging# eligible, not blocked## Worktree: bugfix-session[βœ… e5f6g7h8, adw003]Fix session timeout[❌, adw004]Add session logging // Failed: timeout[]Retry session logging{opus}

Humans and agents read and write the same artifact. No ORM, no admin UI, no separate mutation channel. You can cat the queue.

The state machine

Five states, four transitions. ​

[ ]

queued

⏰

blocked

🟑

in_progress

βœ…

done

❌

failed

[]β†’[🟑]

[⏰]β†’[🟑]iff all prior in worktree are [βœ…]

[🟑]β†’[βœ… <hash>] | [❌]

[βœ…] / [❌]β†’terminal β€” no further transitions

Modeled as a Pydantic enum in data_models.py. Invalid transitions fail at parse time, not at runtime β€” the file IS the state.

Tag vocabulary

Braces modify routing. Polymorphic executors, same queue. ​

{sonnet | opus}

Model choice β€” Cost-Quality Is a Knob. Haiku for simple, Opus for hard planning.

{adw_plan_implement_update}

Workflow selector β€” which ADW script handles this row. Different tags β†’ different executors.

{retry <n>}

Retry metadata β€” set by Correction Task pattern when re-enqueueing after failure.

How blocking works

Linear order instead of an explicit DAG. ​

[⏰] means "blocked by everything above me in this worktree."

Sequential dependencies are expressed by top-to-bottom ordering, not by explicit blockedBy arrays. Simple and inspectable; the downside is cross-worktree dependencies aren't expressible. All blocking is intra-worktree.

When markdown breaks

Graduate to a database when one of these is true. ​

graduation signals

Markdown is kernel-atomic on POSIX small writes β€” that's enough for one machine. Beyond that:

  • Multiple machines poll the same board β†’ NFS loses file-level atomicity
  • Task count exceeds ~100 active rows β†’ merge conflicts and slow reads
  • Claim expiry with sub-second TTL required β†’ file polling is second-grain
  • Cross-machine fanout needed β†’ distributing worktrees across nodes

Until then, markdown is simpler and easier to debug. Graduation is a one-way door. Don't do it speculatively.

The discipline ​

The board IS the coordinator.

No central process. No hidden state. Humans and agents write the same rows. When the Trigger sees a [], it transitions to [🟑] atomically β€” that's Work Claim. When the agent finishes, [βœ… &lt;hash&gt;]. When it crashes, Orphan Reaper recovers. The board is the whole coordination substrate for small- to medium-scale multi-agent work.