---
title: "Task Dependency Patterns"
description: "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."
canonical: "https://orchestkit.dev/docs/reference/skills/task-dependency-patterns"
---

# Task Dependency Patterns

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.

<span className="badge badge-gray">Reference</span> <span className="badge badge-yellow">medium</span>

> **Not directly invocable**, no slash command and no model auto-selection. An agent loads it explicitly via `Read()`.

<ContextualSkillSidebar slug="task-dependency-patterns" />

> **Task Dependency Patterns** 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.


# Task Dependency Patterns

## Overview

Claude Code 2.1.16 introduces a native Task Management System with four tools:
> **CC 2.1.268 caveat:** TaskCreate, TaskGet, TaskUpdate, TaskList, and TodoWrite are offered only on Claude 3.x, Opus 4.0 to 4.7, Sonnet 4.0 to 4.6, and Haiku 4.5. On models outside this allowlist, these tools are absent unless the operator sets `CLAUDE_CODE_ENABLE_TODO_TOOLS=1`. CC honours the flag only from user or managed settings (or the shell). ork cannot ship it (CC reads only `permissions` from plugin settings), so treat every Task-tool call in this skill as conditional on the operator's environment.

- **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:

```json
// 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
```

- **pending**: Task created but not started
- **in_progress**: Actively being worked on
- **completed**: Work finished and verified
- **deleted**: Task removed, permanently removes the task

### Task Deletion

Use `status: "deleted"` to permanently remove tasks:

```json
// 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 tests | Running tests |
| Update schema | Updating schema |
| Fix authentication | Fixing authentication |

## Agent Teams

Agent Teams provides multi-agent coordination with shared task lists and peer-to-peer messaging.

> **CC 2.1.161, independent parallel-tool failure:** A failed tool call in a parallel batch no longer cancels siblings; each returns its own result. Teammates must check task status independently and handle failures explicitly rather than assuming a batch-wide abort.

### Team Workflow

```
1. (implicit team — CC 2.1.178+)       → one team per session; no TeamCreate
2. TaskCreate(subject, description)    → Add tasks to shared list
3. Agent(name, team_name, prompt)      → Spawn teammates into the implicit team
4. TaskUpdate(owner: "teammate-name")  → Assign tasks
5. SendMessage(to, message, summary)   → Direct teammate communication
6. (turn / background ends)            → teammates wind down; Ctrl+F x2 for bg
```

> **Cross-session replies land in the parent (CC 2.1.248):** when a subagent sends `SendMessage` to another session, the reply is delivered to the parent session's conversation, never to the subagent; a subagent sends and moves on, the parent reads the answer. Cross-session `SendMessage` / `ListAgents` also work on Bedrock, Vertex and Foundry and with telemetry disabled (CC 2.1.248).

### When to Use Teams vs Agent Tool

| Criteria | Agent Tool (subagents) | Agent Teams |
|----------|----------------------|-------------|
| Independent tasks | Yes | Overkill |
| Cross-cutting changes | Limited | Yes |
| Agents need to talk | No (star topology) | Yes (mesh) |
| Cost sensitivity | Lower (~1x) | Higher (~2.5x) |
| Complexity &lt; 3.0 | Yes | No |
| Complexity > 3.5 | Possible | Recommended |

### Team Task Patterns

```
# Spawn teammate into shared task list. A teammate that writes files works in
# a manual worktree the lead creates first (#4557); the lead merges its branch
# before dependent tasks start. No isolation on the call: a call with name and
# isolation launches a plain subagent, not a teammate (Claude Code docs).
Bash("git worktree add .worktrees/backend -b feat/my-feature-backend feat/my-feature")
Agent(
  prompt="You are the backend architect... Work only in .worktrees/backend/ "
         "(cd there, check pwd and branch first). Commit your work there and "
         "message the lead your branch name and commit sha.",
  team_name="my-feature",
  name="backend-architect",
  subagent_type="ork: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 (params: to, message, summary)
SendMessage(to: "frontend-dev",
  message: "API contract ready: GET /users/:id returns {...}",
  summary: "API contract shared")

# No broadcast primitive — send to each teammate, or post to the shared
# task list (TaskCreate/TaskUpdate) so every teammate sees it
SendMessage(to: "backend-dev",
  message: "Breaking change: auth header format changed",
  summary: "Breaking auth change")
```

## Context Exhaustion Handling

When using Agent Teams, if context limit is reached mid-workflow:
- Collect partial results from completed teammates via `TaskList`
- Synthesize available outputs, prefer partial results over silent failure
- Log skipped tasks with `TaskUpdate(taskId: task_id, status: "completed", metadata: {"skipped": "context limit"})`

## 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 Agent tool instead)

## Related Skills

- `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:brainstorm` - Design exploration with parallel agent tasks

## References

Load on demand with `Read("references/<file>")`:

| File | Content |
|------|---------|
| `dependency-tracking.md` | Dependency tracking patterns |
| `status-workflow.md` | Status workflow details |
| `multi-agent-coordination.md` | Multi-agent coordination |


---

## 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:**
```json
// 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:**
```json
// 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:**
```json
// 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:**
```json
// Agent communicates completion context to dependent agent
TaskUpdate(taskId: "5", status: "completed")
SendMessage(
  to: "frontend-dev",
  message: "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](../references/multi-agent-coordination.md), 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:**
```json
// 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:**
```json
// 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:**
```json
// 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:**
```json
// 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:**
```json
// 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:**
```json
// 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](../references/status-workflow.md), 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:**
```json
// 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:**
```json
// 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:**
```json
// Creating circular dependencies
TaskUpdate(taskId: "2", addBlockedBy: ["3"])
TaskUpdate(taskId: "3", addBlockedBy: ["2"])
// Deadlock: neither task can ever start
```

**Correct:**
```json
// 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](../references/dependency-tracking.md), 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

| Field | Description |
|-------|-------------|
| `blocks` | Tasks that cannot start until this task completes |
| `blockedBy` | Tasks that must complete before this task can start |

## Creating Dependencies

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

## Dependency Patterns

### Sequential Chain

```
#1 → #2 → #3 → #4
```

```json
// 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 ──┘
```

```json
{"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

```bash
# 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:

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

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

### Finding Available Work

```python
# 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

```json
// Agent startup: list all tasks
TaskList
```

### 2. Claim Task

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

### 3. Complete Work

```json
// 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: `pending` → `in_progress` → `completed`.

## 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

| From | To | When |
|------|-----|------|
| pending | in_progress | Starting work, no blockers |
| in_progress | completed | Work verified complete |
| in_progress | pending | Discovered blocker, need to wait |
| pending | deleted | Orphaned, superseded, or duplicate (CC 2.1.20) |
| in_progress | deleted | Cancelled or superseded (CC 2.1.20) |

## Status Update Examples

```json
// 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

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

### Abandoned in_progress

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

### Skipping States

```json
// 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
```

### activeForm (recommended)

- [ ] Uses present continuous tense
- [ ] Matches the subject semantically
- [ ] Reads naturally as spinner text

| Subject | activeForm |
|---------|-----------|
| Add user validation | Adding user validation |
| Fix broken tests | Fixing broken tests |
| Update API schema | Updating 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
