Skip to main content
OrchestKit v6.7.1 — 67 skills, 38 agents, 77 hooks with Opus 4.6 support
OrchestKit
Skills

Task Dependency Patterns

CC 2.1.16 Task Management patterns with TaskCreate, TaskUpdate, TaskGet, TaskList tools. Decompose complex work into trackable tasks with dependency chains. Use when managing multi-step implementations, coordinating parallel work, or tracking completion status.

Reference medium

Primary Agent: workflow-architect

Task Dependency Patterns

Overview

Claude Code 2.1.16 introduces a native Task Management System with four tools:

  • TaskCreate: Create new tasks with subject, description, and activeForm
  • TaskUpdate: Update status (pending → in_progress → completed), set dependencies
  • TaskGet: Retrieve full task details including blockers
  • TaskList: View all tasks with status and dependency summary

Tasks enable structured work tracking, parallel coordination, and clear progress visibility.

When to Use

  • Breaking down complex multi-step implementations
  • Coordinating parallel work across multiple files
  • Tracking progress on large features
  • Managing dependencies between related changes
  • Providing visibility into work status

Key Patterns

1. Task Decomposition

Break complex work into atomic, trackable units:

Feature: Add user authentication

Tasks:
#1. [pending] Create User model
#2. [pending] Add auth endpoints (blockedBy: #1)
#3. [pending] Implement JWT tokens (blockedBy: #2)
#4. [pending] Add auth middleware (blockedBy: #3)
#5. [pending] Write integration tests (blockedBy: #4)

2. Dependency Chains

Use addBlockedBy to create execution order:

// Task #3 cannot start until #1 and #2 complete
{"taskId": "3", "addBlockedBy": ["1", "2"]}

3. Status Workflow

pending → in_progress → completed
   ↓           ↓
(unblocked)  (active)

pending/in_progress → deleted (CC 2.1.20)
  • pending: Task created but not started
  • in_progress: Actively being worked on
  • completed: Work finished and verified
  • deleted: Task removed (CC 2.1.20) - permanently removes the task

Task Deletion (CC 2.1.20)

CC 2.1.20 adds status: "deleted" to permanently remove tasks:

// Delete a task
{"taskId": "3", "status": "deleted"}

When to delete:

  • Orphaned tasks whose blockers have all failed
  • Tasks superseded by a different approach
  • Duplicate tasks created in error
  • Tasks from a cancelled pipeline

When NOT to delete:

  • Tasks that might be retried later (keep as pending)
  • Tasks with useful history (mark completed instead)
  • Tasks blocked by in_progress work (wait for resolution)

4. activeForm Pattern

Provide present-continuous form for spinner display:

subject (imperative)activeForm (continuous)
Run testsRunning tests
Update schemaUpdating schema
Fix authenticationFixing authentication

Agent Teams (CC 2.1.33+)

CC 2.1.33 introduces Agent Teams for multi-agent coordination with shared task lists and peer-to-peer messaging.

Team Workflow

1. TeamCreate("my-feature")           → Creates team + shared task list
2. TaskCreate(subject, description)    → Add tasks to shared list
3. Task(prompt, team_name, name)       → Spawn teammates
4. TaskUpdate(owner: "teammate-name")  → Assign tasks
5. SendMessage(type: "message")        → Direct teammate communication
6. SendMessage(type: "shutdown_request") → Graceful shutdown

When to Use Teams vs Task Tool

CriteriaTask Tool (subagents)Agent Teams
Independent tasksYesOverkill
Cross-cutting changesLimitedYes
Agents need to talkNo (star topology)Yes (mesh)
Cost sensitivityLower (~1x)Higher (~2.5x)
Complexity < 3.0YesNo
Complexity > 3.5PossibleRecommended

Team Task Patterns

# Spawn teammate into shared task list
Task(
  prompt="You are the backend architect...",
  team_name="my-feature",
  name="backend-architect",
  subagent_type="backend-system-architect"
)

# Teammate claims and works tasks
TaskList → find unblocked, unowned tasks
TaskUpdate(taskId, owner: "backend-architect", status: "in_progress")
# ... do work ...
TaskUpdate(taskId, status: "completed")
TaskList → find next task

Peer Messaging

# Direct message between teammates
SendMessage(type: "message", recipient: "frontend-dev",
  content: "API contract ready: GET /users/:id returns {...}",
  summary: "API contract shared")

# Broadcast to all (use sparingly)
SendMessage(type: "broadcast",
  content: "Breaking change: auth header format changed",
  summary: "Breaking auth change")

Anti-Patterns

  • Creating tasks for trivial single-step work
  • Circular dependencies (A blocks B, B blocks A)
  • Leaving tasks in_progress when blocked
  • Not marking tasks completed after finishing
  • Using broadcast for messages that only concern one teammate
  • Spawning teams for simple sequential work (use Task tool instead)
  • ork:implement - Implementation workflow with task tracking and progress updates
  • ork:verify - Verification tasks and completion checklists
  • ork:fix-issue - Issue resolution with hypothesis-based RCA tracking
  • ork:brainstorming - Design exploration with parallel agent tasks

References


Rules (3)

Coordinate agent task ownership to prevent duplicated work and orphaned tasks — HIGH

Tasks: Agent Coordination

In multi-agent workflows, every in-progress task must have a clear owner, and agents must coordinate through the task list and messaging tools. Without ownership, two agents may silently work on the same task, causing merge conflicts and wasted effort.

Incorrect:

// Two agents both start the same task without claiming ownership
// Agent-A:
TaskUpdate(taskId: "5", status: "in_progress")  // No owner set
// Agent-B (simultaneously):
TaskUpdate(taskId: "5", status: "in_progress")  // No owner set
// Both agents now work on #5 — duplicate effort, likely merge conflict

Correct:

// Agent-A claims the task atomically with owner field
TaskList  // Review available tasks
// Found #5: pending, no owner, blockedBy: []
TaskUpdate(taskId: "5", status: "in_progress", owner: "agent-a")

// Agent-B sees #5 is owned
TaskList  // #5 shows owner: "agent-a", in_progress
// Agent-B picks a different unblocked, unowned task instead
TaskUpdate(taskId: "6", status: "in_progress", owner: "agent-b")

Incorrect:

// Agent completes work silently — no one knows the output or context
TaskUpdate(taskId: "5", status: "completed")
// Downstream agent starts #7 (blocked by #5) with no context about what was done

Correct:

// Agent communicates completion context to dependent agent
TaskUpdate(taskId: "5", status: "completed")
SendMessage(
  type: "message",
  recipient: "frontend-dev",
  content: "Task #5 done: API returns { users: User[], total: number }. Schema in src/types/user.ts.",
  summary: "API contract ready for frontend"
)
// Downstream agent has full context to start dependent work

Key rules:

  • Always set owner when transitioning a task to in_progress — this prevents duplicate work
  • Use TaskList to find unblocked, unowned tasks before claiming one
  • Design tasks to be completable by a single agent — avoid tasks that require two agents to collaborate mid-execution
  • Use SendMessage to share completion context (output formats, file locations, decisions made) with agents who own dependent tasks
  • Mark tasks completed promptly after finishing — delayed completion blocks dependent agents unnecessarily
  • Release ownership (owner: "") if you cannot finish a task, reverting it to pending so another agent can pick it up

Reference: Multi-Agent Coordination — Best Practices (lines 110-116), Agent Workflow (lines 47-70)

Verify task completion criteria before marking done to prevent cascading dependency failures — HIGH

Tasks: Completion Criteria

A task must only be marked completed when all implementation is done, tests pass, and nothing blocks dependent tasks from proceeding safely. Premature completion cascades errors: downstream agents start work assuming a solid foundation that does not exist.

Incorrect:

// Marking complete when tests are failing
// Agent implements feature but 2 of 8 tests fail
TaskUpdate(taskId: "3", status: "completed")  // BAD: tests not passing
// Dependent task #4 starts, builds on broken code — compounds the failure

Correct:

// Verify all criteria before marking complete
// 1. Implementation done — all code changes committed
// 2. Tests passing — ran test suite, all green
// 3. No blockers for dependents — output matches expected interface
// 4. Documentation updated (if applicable)
TaskUpdate(taskId: "3", status: "completed")  // GOOD: fully verified
TaskList  // Check if #4 is now unblocked and ready

Incorrect:

// Leaving a task in_progress when blocked by a discovered issue
// Agent hits unexpected blocker mid-work
// Task sits as in_progress indefinitely — no one else can pick it up
// Other agents wait for dependent tasks that will never unblock

Correct:

// Revert to pending and create a blocker task for the discovered issue
TaskUpdate(taskId: "3", status: "pending")  // Revert — not abandonable as in_progress
TaskCreate(
  subject: "Fix database connection pooling",
  description: "Discovered during #3: pool exhaustion under load. Must fix before #3 can proceed.",
  activeForm: "Fixing connection pooling"
)
// New task #7 created
TaskUpdate(taskId: "3", addBlockedBy: ["7"])  // #3 now properly blocked

Incorrect:

// Skipping in_progress — going directly from pending to completed
TaskUpdate(taskId: "1", status: "completed")  // BAD: skipped in_progress
// No visibility that work was happening; no activeForm spinner shown

Correct:

// Always transition through in_progress for visibility
TaskUpdate(taskId: "1", status: "in_progress", activeForm: "Creating user model")
// ... do work, verify results ...
TaskUpdate(taskId: "1", status: "completed")

Key rules:

  • Verify all four completion criteria before marking done: implementation complete, tests passing, no blockers for dependents, documentation updated if applicable
  • Never skip in_progress — always transition pending to in_progress to completed for proper visibility
  • If blocked mid-work, revert to pending and create a new blocker task with addBlockedBy linking
  • When partial work is done but scope remains, create follow-up tasks for the remaining items rather than leaving one large task incomplete
  • After completing a task, run TaskList to identify newly unblocked dependents

Reference: Status Workflow — Completion Criteria (lines 71-78), Anti-Patterns (lines 80-105)

Validate task dependencies before starting to avoid wasted work on blocked tasks — HIGH

Tasks: Dependency Validation

Always validate that a task's dependencies are fully resolved before transitioning it to in_progress. Skipping validation leads to wasted effort, incorrect assumptions about system state, and potential circular dependency deadlocks.

Incorrect:

// Starting a task without checking if blockers are resolved
TaskList  // shows #3 has blockedBy: ["1", "2"]
// Task #1 is completed but #2 is still in_progress
TaskUpdate(taskId: "3", status: "in_progress")  // BAD: #2 not done yet
// Agent now works against incomplete prerequisite state

Correct:

// Always verify blockedBy is empty before starting work
TaskGet(taskId: "3")
// Returns: blockedBy: ["1", "2"], status: "pending"
// Check: #1 = completed, #2 = completed? No — #2 still in_progress
// Result: Do NOT start #3. Pick a different unblocked task instead.

// Later, when #2 completes:
TaskGet(taskId: "3")
// Returns: blockedBy: [] (all resolved), status: "pending"
TaskUpdate(taskId: "3", status: "in_progress", owner: "my-agent")  // GOOD

Incorrect:

// Creating circular dependencies
TaskUpdate(taskId: "2", addBlockedBy: ["3"])
TaskUpdate(taskId: "3", addBlockedBy: ["2"])
// Deadlock: neither task can ever start

Correct:

// Keep dependency chains acyclic — review the full chain before adding
// If #2 depends on #3 output, restructure:
TaskCreate(subject: "Extract shared interface", ...)  // New task #6
TaskUpdate(taskId: "2", addBlockedBy: ["6"])
TaskUpdate(taskId: "3", addBlockedBy: ["6"])
// Both #2 and #3 depend on #6, no cycle

Key rules:

  • Call TaskGet and verify blockedBy is empty before setting any task to in_progress
  • Never add a dependency that creates a cycle (A blocks B blocks A); restructure with a shared prerequisite task instead
  • Keep dependency chains shallow (3-4 levels max) to avoid long critical paths
  • When completing a task, call TaskList to check if dependent tasks are now unblocked
  • Document why each dependency exists in the task description so future agents understand the ordering

Reference: Dependency Tracking — Validation Rules (lines 72-77), Best Practices (lines 89-94)


References (3)

Dependency Tracking

Dependency Tracking

Overview

Task dependencies ensure correct execution order through blocks and blockedBy relationships.

Dependency Fields

FieldDescription
blocksTasks that cannot start until this task completes
blockedByTasks that must complete before this task can start

Creating Dependencies

// During task update
{
  "taskId": "3",
  "addBlockedBy": ["1", "2"],
  "addBlocks": ["4", "5"]
}

Dependency Patterns

Sequential Chain

#1 → #2 → #3 → #4
// Task #2 blocked by #1
{"taskId": "2", "addBlockedBy": ["1"]}
// Task #3 blocked by #2
{"taskId": "3", "addBlockedBy": ["2"]}

Fan-Out Pattern

     ┌→ #2
#1 ──┼→ #3
     └→ #4

All depend on #1, but can run in parallel after #1 completes.

Fan-In Pattern

#1 ──┐
#2 ──┼→ #4
#3 ──┘
{"taskId": "4", "addBlockedBy": ["1", "2", "3"]}

Diamond Pattern

     #1
    ↙  ↘
  #2    #3
    ↘  ↙
     #4

Validation Rules

  1. No circular dependencies: A → B → A is invalid
  2. Blocked tasks cannot start: Check blockedBy before setting in_progress
  3. Completing unblocks dependents: When #1 completes, #2 becomes available

Querying Dependencies

# List tasks to see blockedBy summary
TaskList

# Get full dependency details
TaskGet taskId="3"
# Returns: blockedBy: ["1", "2"], blocks: ["4"]

Best Practices

  • Keep dependency chains shallow (3-4 levels max)
  • Use fan-out for parallelizable work
  • Document why dependencies exist in task description
  • Review blocked tasks when completing work

Multi Agent Coordination

Multi-Agent Task Coordination

Overview

When multiple Claude Code instances or agents work on a shared codebase, the Task system provides coordination primitives.

Coordination Patterns

Task Assignment

Use owner field to track which agent owns a task:

// Claim a task
{"taskId": "3", "owner": "backend-agent"}

// Release task
{"taskId": "3", "owner": ""}

Finding Available Work

# Pseudo-code for agent task selection
tasks = TaskList()
available = [t for t in tasks
             if t.status == "pending"
             and not t.owner
             and not t.blockedBy]
next_task = available[0] if available else None

Work Distribution

┌─────────────────────────────────────────┐
│           Task Board                     │
├──────────────┬──────────────┬───────────┤
│   pending    │ in_progress  │ completed │
├──────────────┼──────────────┼───────────┤
│ #4 (blocked) │ #2 (agent-A) │ #1        │
│ #5 (ready)   │ #3 (agent-B) │           │
│ #6 (ready)   │              │           │
└──────────────┴──────────────┴───────────┘

Agent Workflow

1. Check for Work

// Agent startup: list all tasks
TaskList

2. Claim Task

// Found unblocked, unowned task
{"taskId": "5", "status": "in_progress", "owner": "my-agent"}

3. Complete Work

// After finishing work
{"taskId": "5", "status": "completed"}
// Check for newly unblocked tasks
TaskList

Handoff Patterns

Sequential Handoff

Agent-A completes #1 → Agent-B unblocked for #2

Parallel Fork

Agent-A completes #1
├→ Agent-B can start #2
├→ Agent-C can start #3
└→ Agent-D can start #4

Merge Point

Agent-A completes #2 ─┐
Agent-B completes #3 ─┼→ Any agent can start #5
Agent-C completes #4 ─┘

Best Practices

  1. Atomic task design: Tasks should be completable by single agent
  2. Clear ownership: Always set owner when starting work
  3. Timely completion: Mark completed as soon as work is done
  4. Dependency awareness: Check blockedBy before starting
  5. Communication via tasks: Use description for context handoff

Integration with OrchestKit

The task system integrates with:

  • context-compression: Task context in compressed summaries
  • agent handoff hooks: Auto-document in decision log

Status Workflow

Status Workflow

Overview

Tasks progress through a defined state machine: pendingin_progresscompleted.

Status States

pending

  • Task created but not started
  • May be blocked by other tasks
  • Available for claiming if no blockers

in_progress

  • Actively being worked on
  • Only one task should typically be in_progress per worker
  • Mark immediately when starting work

completed

  • Work finished and verified
  • Unblocks dependent tasks
  • Cannot be modified further

deleted (CC 2.1.20)

  • Task permanently removed
  • Use for orphaned, superseded, or duplicate tasks
  • Cannot be recovered after deletion

State Transitions

┌─────────┐     start     ┌─────────────┐    finish    ┌───────────┐
│ pending │ ────────────→ │ in_progress │ ───────────→ │ completed │
└─────────┘               └─────────────┘              └───────────┘
     ↑  │                       │  │
     │  └───────────────────────│──│──→ ┌─────────┐
     └───── revert ─────────────┘  └──→ │ deleted │ (CC 2.1.20)
           (if blocked)                  └─────────┘

Valid Transitions

FromToWhen
pendingin_progressStarting work, no blockers
in_progresscompletedWork verified complete
in_progresspendingDiscovered blocker, need to wait
pendingdeletedOrphaned, superseded, or duplicate (CC 2.1.20)
in_progressdeletedCancelled or superseded (CC 2.1.20)

Status Update Examples

// Start work
{"taskId": "1", "status": "in_progress"}

// Mark complete
{"taskId": "1", "status": "completed"}

// Revert if blocked
{"taskId": "1", "status": "pending"}

// Delete orphaned task (CC 2.1.20)
{"taskId": "1", "status": "deleted"}

Completion Criteria

Before marking completed, verify:

  1. Implementation done: All code changes complete
  2. Tests passing: Related tests succeed
  3. No blockers: Nothing prevents dependent tasks
  4. Documentation updated: If applicable

Anti-Patterns

Premature Completion

// DON'T: Mark complete with failing tests
{"taskId": "1", "status": "completed"}

Abandoned in_progress

// DON'T: Leave task in_progress when blocked
// DO: Revert to pending, create blocker task
{"taskId": "1", "status": "pending"}

Skipping States

// DON'T: Go directly from pending to completed
// DO: Always transition through in_progress
{"taskId": "1", "status": "in_progress"}
// ... do work ...
{"taskId": "1", "status": "completed"}

activeForm Display

The activeForm field displays during in_progress status:

[#1 in_progress] Running tests... ⣾

Provide meaningful present-continuous descriptions:

  • "Creating database schema"
  • "Updating API endpoints"
  • "Writing integration tests"

Checklists (2)

Dependency Checklist

Dependency Validation Checklist

Before Adding Dependencies

  • Is there a true execution order requirement?
  • Would parallel execution cause conflicts?
  • Is the dependency on task completion (not just start)?

Dependency Types

Code Dependencies

  • Task B modifies files created by Task A
  • Task B imports modules defined in Task A
  • Task B extends patterns established in Task A

Schema Dependencies

  • Task B uses database schema from Task A
  • Task B consumes API contracts from Task A
  • Task B references types defined in Task A

Test Dependencies

  • Task B tests functionality from Task A
  • Task B requires fixtures from Task A
  • Task B extends test suites from Task A

Dependency Anti-Patterns

Circular Dependencies

Task A blockedBy [B]
Task B blockedBy [A]

Fix: Identify shared prerequisite, extract to Task C

Over-Specification

Task D blockedBy [A, B, C]
# But really only needs C

Fix: Remove unnecessary dependencies, rely on transitive blocking

Under-Specification

Task B has no blockedBy
# But actually needs Task A's output

Fix: Add explicit dependency to prevent race conditions

Validation Steps

1. Trace Dependency Chain

For each task with blockedBy:
  - Can the blocking task(s) actually complete?
  - Is there a path from START to this task?
  - Is there a path from this task to END?

2. Check for Cycles

For each task T:
  visited = {}
  queue = [T.blockedBy]
  while queue:
    current = queue.pop()
    if current == T: ERROR: Cycle detected
    if current in visited: continue
    visited.add(current)
    queue.extend(current.blockedBy)

3. Verify Parallelism

Tasks without mutual dependencies CAN run in parallel.
Verify: No shared file writes, no ordering requirement.

Updating Dependencies

When modifying existing dependencies:

  • Reviewed impact on blocked tasks
  • No orphaned tasks (tasks that can never unblock)
  • Critical path still reasonable
  • Notified other agents/workers if relevant

Documentation

For complex dependency chains:

  • Diagram in task description or PR
  • Rationale for non-obvious dependencies
  • Expected execution order documented

Task Design Checklist

Task Design Checklist

Before Creating Tasks

  • Is this work complex enough to need task tracking? (3+ steps)
  • Have you identified the natural work boundaries?
  • Can each task be completed independently once unblocked?

Task Structure

Subject (required)

  • Uses imperative form ("Add", "Fix", "Update", not "Adding", "Fixed")
  • Describes the outcome, not the process
  • Concise but descriptive (5-10 words max)

Good examples:

  • "Create User model with validation"
  • "Add JWT authentication endpoint"
  • "Fix pagination in search results"

Bad examples:

  • "Work on the feature" (too vague)
  • "Adding stuff to the database" (wrong tense, vague)
  • "Implement the new user authentication system with JWT tokens and refresh token rotation including rate limiting" (too long)

Description (required)

  • Explains what needs to be done
  • Includes acceptance criteria
  • Notes any constraints or considerations
  • References relevant files or patterns

Template:

Implement [specific thing] that:
- [Requirement 1]
- [Requirement 2]

Acceptance criteria:
- [ ] Tests pass
- [ ] Documentation updated
- [ ] No type errors
  • Uses present continuous tense
  • Matches the subject semantically
  • Reads naturally as spinner text
SubjectactiveForm
Add user validationAdding user validation
Fix broken testsFixing broken tests
Update API schemaUpdating API schema

Dependency Design

  • Dependencies represent real execution order requirements
  • No circular dependency chains
  • Parallel work identified and unblocked appropriately
  • Critical path minimized

Task Granularity

Too Large

Signs your task is too large:

  • Description exceeds 200 words
  • Estimated to touch 5+ files
  • Multiple distinct outcomes combined

Split strategy:

  1. Identify sub-outcomes
  2. Create task per outcome
  3. Link with dependencies

Too Small

Signs your task is too small:

  • Single line change
  • Pure refactoring without behavior change
  • Part of another task's natural work

Merge strategy:

  1. Combine with related task
  2. Add to description as sub-item

Review Before Submitting

  • Each task has clear completion criteria
  • Dependencies are minimal but sufficient
  • Task can be understood without external context
  • activeForm provides useful progress feedback
Edit on GitHub

Last updated on

On this page

Task Dependency PatternsOverviewWhen to UseKey Patterns1. Task Decomposition2. Dependency Chains3. Status WorkflowTask Deletion (CC 2.1.20)4. activeForm PatternAgent Teams (CC 2.1.33+)Team WorkflowWhen to Use Teams vs Task ToolTeam Task PatternsPeer MessagingAnti-PatternsRelated SkillsReferencesRules (3)Coordinate agent task ownership to prevent duplicated work and orphaned tasks — HIGHTasks: Agent CoordinationVerify task completion criteria before marking done to prevent cascading dependency failures — HIGHTasks: Completion CriteriaValidate task dependencies before starting to avoid wasted work on blocked tasks — HIGHTasks: Dependency ValidationReferences (3)Dependency TrackingDependency TrackingOverviewDependency FieldsCreating DependenciesDependency PatternsSequential ChainFan-Out PatternFan-In PatternDiamond PatternValidation RulesQuerying DependenciesBest PracticesMulti Agent CoordinationMulti-Agent Task CoordinationOverviewCoordination PatternsTask AssignmentFinding Available WorkWork DistributionAgent Workflow1. Check for Work2. Claim Task3. Complete WorkHandoff PatternsSequential HandoffParallel ForkMerge PointBest PracticesIntegration with OrchestKitStatus WorkflowStatus WorkflowOverviewStatus Statespendingin_progresscompleteddeleted (CC 2.1.20)State TransitionsValid TransitionsStatus Update ExamplesCompletion CriteriaAnti-PatternsPremature CompletionAbandoned in_progressSkipping StatesactiveForm DisplayChecklists (2)Dependency ChecklistDependency Validation ChecklistBefore Adding DependenciesDependency TypesCode DependenciesSchema DependenciesTest DependenciesDependency Anti-PatternsCircular DependenciesOver-SpecificationUnder-SpecificationValidation Steps1. Trace Dependency Chain2. Check for Cycles3. Verify ParallelismUpdating DependenciesDocumentationTask Design ChecklistTask Design ChecklistBefore Creating TasksTask StructureSubject (required)Description (required)activeForm (recommended)Dependency DesignTask GranularityToo LargeToo SmallReview Before Submitting