Issue #1030
Most task systems give Claude a flat list and hope for the best. Beads is different. It tracks dependencies between tasks and only surfaces work that is actually ready — no blockers, no wasted effort.
Let’s use beads via its CLI called bd.
What a task looks like
Every task in the Beads database has a hash-based ID like bd-a3f8. The status field tells the full story:
| Status | Meaning |
|---|---|
open |
Not started, no blockers |
blocked |
Open but waiting on another task |
in_progress |
Claimed by someone (or an agent) |
closed |
Done |
Priority runs from 0 (critical) to 4 (backlog). Type is one of bug, feature, task, epic, or chore.
A task also carries a full audit trail — every status change, every update, timestamped. Run bd show bd-a3f8 to see the history of a single task.
The ready queue is Claude’s entry point
The core idea is simple: Claude should never guess what to work on. It asks Beads.
bd ready
This returns only tasks with status open and no unresolved dependencies. Blocked tasks are invisible here. Claude picks from this list, nothing else.
To see why something is not ready:
bd ready --explain --json
Beads explains the full dependency graph — what is blocked, what is blocking it, and what needs to close first.
How Claude works through tasks
Tell Claude how to behave in your CLAUDE.md:
Use 'bd' for all task tracking.
1. Run 'bd ready' to find available work.
2. Run 'bd update <id> --claim' before starting any task.
3. Run 'bd close <id> --reason "..."' when done.
Never use 'bd edit' — it opens an interactive editor and blocks.
That is the entire workflow. Claude polls the ready queue, claims a task atomically (sets assignee + in_progress in one step), does the work, then closes it. The next bd ready call reflects the updated state, potentially unblocking tasks that were waiting.
When Claude discovers a new bug or subtask during work, it creates it with a link back to the parent:
bd create "Found null crash in session handler" -p 0 -t bug --deps discovered-from:bd-a3f8 --json
The --json flag returns the new task’s ID so Claude can reference it programmatically without parsing text.
Dependencies keep agents honest
If writing tests depends on the feature being built first, record that:
bd dep add bd-b2c3 bd-a3f8 # bd-b2c3 is blocked by bd-a3f8
Now bd-b2c3 does not appear in bd ready until bd-a3f8 is closed. Claude cannot accidentally start the tests before the feature exists.
For larger features, group work under an epic:
bd create "Auth System" -t epic -p 1 # → bd-9f2a
bd create "Design login UI" --parent bd-9f2a # → bd-9f2a.1
bd create "Backend auth" --parent bd-9f2a # → bd-9f2a.2
The epic cannot close until all children are closed. Claude always knows the shape of the work.
What the database looks like mid-session
After a few sessions with Claude, your task database might look like this:
bd-a3f8 closed p1 feature Add login page
bd-9f2a open p1 epic Auth System
bd-9f2a.1 in_progress p1 task Design login UI ← Claude is here
bd-9f2a.2 blocked p1 task Backend auth ← waiting on bd-9f2a.1
bd-c12e open p2 task Write auth tests
bd-f7b1 open p0 bug Fix null crash
bd ready right now would return only bd-9f2a.1, bd-c12e, and bd-f7b1. The epic itself and the blocked subtask stay off the list. Claude sees a clean, actionable queue.
Beads remembers what Claude did
Beads stores the audit trail in a Dolt database — version-controlled SQL. Every bd update, bd claim, and bd close is committed to Dolt’s history. This means you can see exactly what Claude worked on, in what order, and what decisions were made.
After 30 days, old closed tasks are semantically compressed to save context. The original content is recoverable from Dolt’s git-like history if you need it.
The combination of dependency tracking, a clean ready queue, and a durable audit trail gives Claude Code exactly what it needs: a clear answer to “what should I do next?” at every step.
Start the conversation