Files
nixos-config/profiles/opencode/skill/overseer/references/hierarchies.md
Christoph Schmatzler ff8650bedf oc
Signed-off-by: Christoph Schmatzler <christoph@schmatzler.com>
2026-02-04 20:04:32 +00:00

4.8 KiB

Task Hierarchies

Guidance for organizing work into milestones, tasks, and subtasks.

Three Levels

Level Name Purpose Example
0 Milestone Large initiative (5+ tasks) "Add user authentication system"
1 Task Significant work item "Implement JWT middleware"
2 Subtask Atomic implementation step "Add token verification function"

Maximum depth is 3 levels. Attempting to create a child of a subtask will fail.

When to Use Each Level

Single Task (No Hierarchy)

  • Small feature (1-2 files, ~1 session)
  • Work is atomic, no natural breakdown

Task with Subtasks

  • Medium feature (3-5 files, 3-7 steps)
  • Work naturally decomposes into discrete steps
  • Subtasks could be worked on independently

Milestone with Tasks

  • Large initiative (multiple areas, many sessions)
  • Work spans 5+ distinct tasks
  • You want high-level progress tracking

Creating Hierarchies

// Create the milestone
const milestone = await tasks.create({
  description: "Add user authentication system",
  context: "Full auth system with JWT tokens, password reset...",
  priority: 2
});

// Create tasks under it
const jwtTask = await tasks.create({
  description: "Implement JWT token generation",
  context: "Create token service with signing and verification...",
  parentId: milestone.id
});

const resetTask = await tasks.create({
  description: "Add password reset flow",
  context: "Email-based password reset with secure tokens...",
  parentId: milestone.id
});

// For complex tasks, add subtasks
const verifySubtask = await tasks.create({
  description: "Add token verification function",
  context: "Verify JWT signature and expiration...",
  parentId: jwtTask.id
});

Subtask Best Practices

Each subtask should be:

  • Independently understandable: Clear on its own
  • Linked to parent: Reference parent, explain how this piece fits
  • Specific scope: What this subtask does vs what parent/siblings do
  • Clear completion: Define "done" for this piece specifically

Example subtask context:

Part of JWT middleware (parent task). This subtask: token verification.

What it does:
- Verify JWT signature and expiration
- Extract user ID from payload
- Return 401 for invalid/expired tokens

Done when:
- Function complete and tested
- Unit tests cover valid/invalid/expired cases

Decomposition Strategy

When faced with large tasks:

  1. Assess scope: Is this milestone-level (5+ tasks) or task-level (3-7 subtasks)?
  2. Create parent task/milestone with overall goal and context
  3. Analyze and identify 3-7 logical children
  4. Create children with specific contexts and boundaries
  5. Work through systematically, completing with results
  6. Complete parent with summary of overall implementation

Don't Over-Decompose

  • 3-7 children per parent is usually right
  • If you'd only have 1-2 subtasks, just make separate tasks
  • If you need depth 3+, restructure your breakdown

Viewing Hierarchies

// List all tasks under a milestone
const children = await tasks.list({ parentId: milestoneId });

// Get task with context breadcrumb
const task = await tasks.get(taskId);
// task.context.parent - parent's context
// task.context.milestone - root milestone's context

// Check progress
const pending = await tasks.list({ parentId: milestoneId, completed: false });
const done = await tasks.list({ parentId: milestoneId, completed: true });
console.log(`Progress: ${done.length}/${done.length + pending.length}`);

Completion Rules

  1. Cannot complete with pending children

    // This will fail if task has incomplete subtasks
    await tasks.complete(taskId, "Done");
    // Error: "pending children"
    
  2. Complete children first

    • Work through subtasks systematically
    • Complete each with meaningful results
  3. Parent result summarizes overall implementation

    await tasks.complete(milestoneId, `User authentication system complete:
    
    Implemented:
    - JWT token generation and verification
    - Login/logout endpoints
    - Password reset flow
    - Rate limiting
    
    5 tasks completed, all tests passing.`);
    

Blocking Dependencies

Use blockedBy for cross-task dependencies:

// Create task that depends on another
const deployTask = await tasks.create({
  description: "Deploy to production",
  context: "...",
  blockedBy: [testTaskId, reviewTaskId]
});

// Add blocker to existing task
await tasks.block(deployTaskId, testTaskId);

// Remove blocker
await tasks.unblock(deployTaskId, testTaskId);

Use blockers when:

  • Task B cannot start until Task A completes
  • Multiple tasks depend on a shared prerequisite

Don't use blockers when:

  • Tasks can be worked on in parallel
  • The dependency is just logical grouping (use subtasks instead)