Task Graph & Dependencies
Model complex work as a dependency graph with TaskCreate, TaskUpdate, TaskGet, and TaskList.
What You’ll Learn
Session 3 introduced structured Task tools. Here we add dependency edges so Claude can distinguish work that is ready, blocked, or safe to parallelize.
You will learn:
- How tasks form a directed acyclic graph (DAG)
- How
addBlockedByandaddBlocksexpress dependency edges - How to find the ready set with
TaskListand inspect details withTaskGet - Why a task graph enables parallel work but does not automatically launch agents
Why a Flat List Is Not Enough
Consider five tasks:
□ Create database migration
□ Add API routes
□ Add authorization middleware
□ Update the frontend
□ Run integration tests
A flat list hides three important facts: which tasks may start now, which can run together, and which must stop if an upstream task fails.
Model the Work as a DAG
┌───────────────┐
│ Inspect system │
└───────┬───────┘
│
┌───────┴────────┐
▼ ▼
┌────────────┐ ┌────────────┐
│ DB migration│ │ API design │
└──────┬─────┘ └──────┬─────┘
└───────┬─────────┘
▼
┌───────────────┐
│ Authorization │
└───────┬───────┘
┌───────┴────────┐
▼ ▼
┌────────────┐ ┌────────────┐
│ Frontend │ │ Integration│
│ integration │ │ tests │
└────────────┘ └────────────┘
A task is ready when its status is pending and every task in blockedBy is complete. Several ready tasks may be independent, but parallel execution still requires Claude to assign them to separate subagents or teammates. The Task tools store coordination state; they are not a scheduler by themselves.
Build Dependencies with Current Tools
Create tasks first and capture the IDs returned by TaskCreate:
{"tool": "TaskCreate", "subject": "Create DB migration", "description": "Add schema and rollback test"}
{"tool": "TaskCreate", "subject": "Design API contract", "description": "Define request, response, and errors"}
{"tool": "TaskCreate", "subject": "Add authorization", "description": "Implement policy and unit tests"}
Suppose the returned IDs are 1, 2, and 3. Make task 3 wait for both upstream tasks:
{
"tool": "TaskUpdate",
"taskId": "3",
"addBlockedBy": ["1", "2"]
}
The inverse relationship can also be added from an upstream task:
{
"tool": "TaskUpdate",
"taskId": "1",
"addBlocks": ["3"]
}
Use TaskList for a compact snapshot and TaskGet when you need a task’s description plus its blocks and blockedBy edges:
{"tool": "TaskList"}
{"tool": "TaskGet", "taskId": "3"}
These payloads document the tool contract for integrations. In a normal Claude Code conversation, describe the dependencies in plain language and let Claude call the tools.
Execute the Ready Set
At each scheduling point:
- Read the current task list.
- Exclude completed, deleted, and already in-progress tasks.
- Exclude tasks with incomplete
blockedByentries. - Choose one ready task, or deliberately assign independent ready tasks in parallel.
- Mark chosen work
in_progressbefore starting. - Mark it
completedonly after its verification succeeds. - Re-read the graph because the ready set may have changed.
ready(task) = pending(task)
AND every dependency in blockedBy(task) is completed
If an upstream task fails, keep dependents pending and update the failed task’s description with the blocker or revise the graph. Do not mark downstream work complete merely to make the list green.
Prompt Pattern
Implement this feature using the structured Task tools.
1. Create one task per independently verifiable outcome.
2. Add dependency edges with addBlockedBy or addBlocks.
3. Show me the initial TaskList before implementation.
4. Run independent ready tasks in parallel only when their files and side effects do not conflict.
5. Keep blocked tasks pending.
6. Complete a task only after its stated check passes.
7. At the end, show the final task graph and verification evidence.
Common Mistakes
- Using TodoWrite for dependency edges: current dependency fields belong to
TaskUpdate. - Inventing task IDs: IDs come from
TaskCreateresults. - Treating “ready” as “automatically running”: assignment and execution are separate decisions.
- Creating cycles: if A waits for B and B waits for A, neither can become ready.
- Encoding every tiny edit as a task: make tasks independently meaningful and verifiable.
Next Session
In Session 8, we’ll examine foreground and background execution. The same dependency graph can guide when background work is safe to start.
Official sources
Last verified: 2026-07-20.