---
name: subagent-driven-development
description: "Execute plans via delegate_task subagents (2-stage review)."
version: 1.3.0
author: Hermes Agent (adapted from obra/superpowers — added research timeout trap)
license: MIT
platforms: [linux, macos, windows]
metadata:
  hermes:
    tags: [delegation, subagent, implementation, workflow, parallel]
    related_skills: [writing-plans, requesting-code-review, test-driven-development]
---

# Subagent-Driven Development

## Overview

Execute implementation plans by dispatching fresh subagents per task with systematic two-stage review.

**Core principle:** Fresh subagent per task + two-stage review (spec then quality) = high quality, fast iteration.

## When to Use

Use this skill when ALL of these hold:

- **You have an implementation plan** (from writing-plans skill or user requirements)
- **Tasks are file-disjoint** — each task touches files that no other task in the plan needs to read or modify. If tasks share even one file (e.g. Task 1 creates `interfaces.py`, Task 2 modifies it), the subagent dispatch cost stacks up fast because each subagent must re-acquire context about the shared file's state.
- **Tasks are semantically independent** — the output of Task N is not needed as input to Task N+1. If the plan is a pipeline (cache policy → port → adapter → integration), direct execution is faster because there's no handoff overhead between stages.
- **Quality and spec compliance are important** and the cost of occasional do-overs is acceptable
- **You want automated review between tasks** and the extra round-trips are worth the confidence gain

**vs. manual execution:**
- Fresh context per task (no confusion from accumulated state)
- Automated review process catches issues early
- Consistent quality checks across all tasks
- Subagents can ask questions before starting work

## When NOT to Use

Skip this skill and execute directly when ANY of these apply:

- **Tasks form a dependency chain** — Task 2 modifies Task 1's file, Task 3 builds on Task 2's result. The subagent handoff overhead (re-acquiring file state, re-reading modified modules) compounds across each link in the chain and quickly exceeds the time saved by parallelization.
- **Tasks share files** — even if logically independent, two tasks that both modify `routers.py` or `interfaces.py` cannot execute in parallel and will create merge conflicts when run sequentially through different subagents.
- **The plan has more than ~6 tasks** — at 3 subagent invocations per task (implement + spec review + quality review), a 7-task plan generates ~21 subagent calls. The token and latency cost approaches or exceeds the direct approach, with no remaining confidence advantage.
- **The user expects fast iteration** — subagent dispatch adds minutes of overhead per task. If the user is waiting interactively, direct execution is usually the right choice.
- **You are already deep in a session** with significant accumulated state about the codebase. Fresh subagents lose that context and need to re-read files to catch up. If you've been working in the project for 30+ minutes, the cost of re-establishing context per subagent is real.
- **Tasks are well-defined and have low ambiguity** — if there's little risk of spec drift or quality regression, the review stages add overhead without proportional value.
- **UI overhaul across tightly-coupled component files** — when the task is a visual/UI overhaul touching 10-30 files that all share the same component library (Jetpack Compose, tv-material3, Coil), subagents will each independently guess at API signatures. The resulting API drift (different subagents using different constructor shapes, parameter names, or import paths for the same library) creates systematic compilation errors across files. The fix cost (identifying the pattern, regex-replacing across all files, rebuilding in 3-4 passes) exceeds the time saved by parallel dispatch. **Direct execution with targeted `patch()` calls is faster and safer** for this class of task. The skill's own "Pitfalls: Parallel Subagent API Drift" section documents this in detail — when that section applies, skip delegation entirely.
- **Bulk file copy or mass find-replace** — copying 50+ files between directories or doing a regex replace across 100+ files with zero reasoning needed per file. Subagents copy files one-at-a-time (each is an API call); a 85-file batch can time out a 600s subagent at 9 calls completed. **Use execute_code with Python shutil or file I/O instead** — it runs in under 1 second.

## The Process

### 1. Read and Parse Plan

Read the plan file. Extract ALL tasks with their full text and context upfront. Create a todo list:

```python
# Read the plan
read_file("docs/plans/feature-plan.md")

# Create todo list with all tasks
todo([
    {"id": "task-1", "content": "Create User model with email field", "status": "pending"},
    {"id": "task-2", "content": "Add password hashing utility", "status": "pending"},
    {"id": "task-3", "content": "Create login endpoint", "status": "pending"},
])
```

**Key:** Read the plan ONCE. Extract everything. Don't make subagents read the plan file — provide the full task text directly in context.

### 2. Per-Task Workflow

For EACH task in the plan:

#### Step 1: Dispatch Implementer Subagent

Use `delegate_task` with complete context:

```python
delegate_task(
    goal="Implement Task 1: Create User model with email and password_hash fields",
    context="""
    TASK FROM PLAN:
    - Create: src/models/user.py
    - Add User class with email (str) and password_hash (str) fields
    - Use bcrypt for password hashing
    - Include __repr__ for debugging

    FOLLOW TDD:
    1. Write failing test in tests/models/test_user.py
    2. Run: pytest tests/models/test_user.py -v (verify FAIL)
    3. Write minimal implementation
    4. Run: pytest tests/models/test_user.py -v (verify PASS)
    5. Run: pytest tests/ -q (verify no regressions)
    6. Commit: git add -A && git commit -m "feat: add User model with password hashing"

    PROJECT CONTEXT:
    - Python 3.11, Flask app in src/app.py
    - Existing models in src/models/
    - Tests use pytest, run from project root
    - bcrypt already in requirements.txt
    """,
    toolsets=['terminal', 'file']
)
```

#### Step 2: Dispatch Spec Compliance Reviewer

After the implementer completes, verify against the original spec:

```python
delegate_task(
    goal="Review if implementation matches the spec from the plan",
    context="""
    ORIGINAL TASK SPEC:
    - Create src/models/user.py with User class
    - Fields: email (str), password_hash (str)
    - Use bcrypt for password hashing
    - Include __repr__

    CHECK:
    - [ ] All requirements from spec implemented?
    - [ ] File paths match spec?
    - [ ] Function signatures match spec?
    - [ ] Behavior matches expected?
    - [ ] Nothing extra added (no scope creep)?

    OUTPUT: PASS or list of specific spec gaps to fix.
    """,
    toolsets=['file']
)
```

**If spec issues found:** Fix gaps, then re-run spec review. Continue only when spec-compliant.

#### Step 3: Dispatch Code Quality Reviewer

After spec compliance passes:

```python
delegate_task(
    goal="Review code quality for Task 1 implementation",
    context="""
    FILES TO REVIEW:
    - src/models/user.py
    - tests/models/test_user.py

    CHECK:
    - [ ] Follows project conventions and style?
    - [ ] Proper error handling?
    - [ ] Clear variable/function names?
    - [ ] Adequate test coverage?
    - [ ] No obvious bugs or missed edge cases?
    - [ ] No security issues?

    OUTPUT FORMAT:
    - Critical Issues: [must fix before proceeding]
    - Important Issues: [should fix]
    - Minor Issues: [optional]
    - Verdict: APPROVED or REQUEST_CHANGES
    """,
    toolsets=['file']
)
```

**If quality issues found:** Fix issues, re-review. Continue only when approved.

#### Step 4: Mark Complete

```python
todo([{"id": "task-1", "content": "Create User model with email field", "status": "completed"}], merge=True)
```

### 3. Final Review

After ALL tasks are complete, dispatch a final integration reviewer:

```python
delegate_task(
    goal="Review the entire implementation for consistency and integration issues",
    context="""
    All tasks from the plan are complete. Review the full implementation:
    - Do all components work together?
    - Any inconsistencies between tasks?
    - All tests passing?
    - Ready for merge?
    """,
    toolsets=['terminal', 'file']
)
```

### 4. Verify and Commit

```bash
# Run full test suite
pytest tests/ -q

# Review all changes
git diff --stat

# Final commit if needed
git add -A && git commit -m "feat: complete [feature name] implementation"
```

## Task Granularity

**Each task = 2-5 minutes of focused work.**

**Too big:**
- "Implement user authentication system"

**Right size:**
- "Create User model with email and password fields"
- "Add password hashing function"
- "Create login endpoint"
- "Add JWT token generation"
- "Create registration endpoint"

## Background Delegation Pattern (Long-Running Tasks)

**WHEN a task will take 30s+ and you need to keep working in the parent session:**

Use `delegate_task(background=True)` instead of the standard synchronous dispatch. The subagent runs independently, and its full result re-enters the conversation as a new message when finished.

### Rules

1. **Set `background=True`** — This is the key parameter. Without it, `delegate_task` blocks the parent session until the child completes.
2. **Only for truly independent work** — Background tasks cannot ask questions (no `clarify`), cannot use memory, and their results arrive later. If the parent needs an answer before continuing, use synchronous dispatch.
3. **Accept the delay** — Background subagents take just as long as synchronous ones. The advantage is you can keep working, not that they're faster.
4. **Don't poll or wait** — The system delivers the result when it's done. Calling `process(action='poll')` or otherwise checking is unnecessary and wastes turns.

### Good Use Cases

- **Skill compaction** — Compacting 5 large skills while continuing config/memory/prompt work
- **Long test suites** — Running a full test suite while editing docs
- **Bulk file operations** — Large grep-and-replace operations across many files
- **Model downloads** — Downloading GGUF files while working on other config

### Bad Use Cases

- **Pipelined work** — Task B needs the results of background Task A. Use synchronous dispatch or chain them.
- **Interactive decisions** — Any task that might need to ask you a question
- **Rapid iteration** — If the parent makes changes that affect what the background task is working on, you'll get conflicting results

### Real-World Example (this session)

```python
# Background: compact 5 large skills (~6 minutes)
delegate_task(
    background=True,
    goal="Compact 5 large skills to <3KB each...",
    context="...detailed instructions...",
    toolsets=['file', 'terminal']
)

# Meanwhile, continue working:
# - Apply config changes
# - Compact USER.md
# - Update SOUL.md
# - Create profiles

# ~6 minutes later, the result re-enters the conversation automatically
```

### Pitfalls

- **The subagent ONLY returns when DONE.** If the subagent hits max_turns, gets interrupted, or fails, the result will report `status: 'interrupted'` with no partial output. There is no way to check on progress mid-flight.
- **Cannot re-dispatch with corrections.** If the background subagent went off-track, you can only dispatch a new synchronous cleaning subagent with corrected instructions — you cannot talk to the background one.
- **Result is a self-report, not verified fact.** The background subagent may claim "5 skills compacted successfully" when only 1 was done. Always verify results independently (check file sizes, test the output).
- **Background tasks use the current config at dispatch time.** If you change config (model, provider, delegation) after dispatching, the background task still uses the old config.

---

## Batch Splitting Under Parallelism Limits

When you have more independent tasks than `delegation.max_concurrent_children` (default: 3 for this config), you need to split them into sequential batches.

**The rule:** N tasks → first batch of min(N, max_children), subsequent batches of min(remaining, max_children).

| Total Tasks | max_children=3 | Batches |
|-------------|---------------|---------|
| 2 | 3 | 1 batch |
| 3 | 3 | 1 batch |
| 5 | 3 | 2 batches (3+2) |
| 7 | 3 | 3 batches (3+2+2) |

**Practical example (this session):** 5 UI file-edit tasks, max_children=3 → Batch 1: 3 tasks (shimmer, empty icons, back button), Batch 2: 2 tasks (settings shadow, entrance animation). Wait for all in Batch 1 to return, process results, then dispatch Batch 2.

**Don't outsmart the limit.** Trying to lump more work into each subagent to avoid batching backfires — larger subagent context means more tokens and longer run time. Clean split at the limit is cheaper.

**Build after each batch** when the tasks modify files in the same project. A mid-batch build catches API drift and import errors before they compound across all batches.

**No gap between batches.** As soon as Batch N returns, dispatch Batch N+1 immediately — don't pause to review intermediate output unless a subagent reported a failure.

## Avoid Systemic API-Mismatch Fix Passes

When subagents write code against third-party libraries (Android SDK, Compose for TV, ExoPlayer, Hilt, Coil, Retrofit), **they will guess at exact API signatures** and often get them wrong — especially for less-common overloads, Kotlin DSL builders, or recently-renamed symbols (`ImmutableBorder` → `Border`, `crossfade()` parameter locations, `DiskCache.Builder().directory()` API changes).

**This is the single biggest cost driver** of subagent-generated code for library-heavy projects. Plan for it:

### In the Plan (prevention)
- For each third-party dep, include a `// KNOWN API` comment block in the plan that names the exact class and constructor signature the subagent must use. Subagents don't auto-know library internals — they pattern-match from training data which is often wrong for the version you're on.
- Specify the **exact version** in the plan context (e.g., `Coil 3.0.4`, `tv-material 1.0.0-rc01`). The version constrains the API surface the subagent should target.

### After the Build (recovery)
When compile errors show a repeated API-mismatch pattern across files:

1. **Identify the pattern** — grep for the wrong symbol across the project. Don't fix files one at a time.
2. **Fix the import** — update import paths in bulk via sed/python across all affected files.
3. **Fix the constructor** — if the constructor signature changed (e.g., `ImmutableBorder(width, color, shape)` → `Border(border = BorderStroke(width, color))`), write a regex replacement script.
4. **Sync and rebuild** — scp/rsync the fixed files to the target machine, recompile, check for the next layer of errors.
5. **Expect 3-4 passes** — resource errors → Kotlin API errors → library API errors → KSP annotation errors. Each pass fixes a layer.

**Accept this cost up front.** It is cheaper than (a) having the controller write all code directly, or (b) dispatching individual fix subagents per file (the subagent dispatch overhead per file far exceeds the regex-replace cost).

## Pitfalls: Parallel Subagent API Drift

When dispatching multiple subagents that all target the same third-party library, each subagent may assume different API signatures, leading to systematic compilation errors.

**Symptoms:**
- 10 files broken by the same wrong API name (e.g., `ImmutableBorder` instead of `Border`)
- Some subagents used `focused =`, others used `focusedBorder =`
- Identical patterns fail in some files but not others

**Prevention:**
1. **Pin exact API shapes in the task context.** Don't just say "use tv-material3 Border" — show the exact constructor:
   ```kotlin
   // Include this in EVERY subagent's context:
   // Correct: Border(BorderStroke(2.dp, color))
   // Wrong: ImmutableBorder(width=, color=, shape=)
   // Correct: ClickableSurfaceDefaults.border(focusedBorder = Border(...))
   // Wrong: ClickableSurfaceDefaults.border(focused = Border(...))
   ```
2. **Use a shared reference file.** Write a small `API_SNIPPETS.md` in the project root with the exact, verified API usage for each third-party class. Point all subagents to it.
3. **Reduce parallelism for tightly-coupled UI code.** If 20 UI files all use the same `Surface` API, running them through 5 sequential subagents (each seeing the previous agent's output) is faster than fixing 20 diverging files after parallel dispatch.

**Fix strategy when drift has already occurred:**
- **Do NOT use regex bulk fixes across 20+ files.** Every file has slightly different indentation, variable naming, and context. The regex will mangle some and save others.
- Instead, open the project in the IDE and fix each `focusedBorder`/`Border(BorderStroke)` issue individually. It's faster (Alt+Enter per squiggle) and safer.
- Layer the fixes: resources → syntax → API names → third-party libs — so each build shows only remaining issues, not cascading errors.
- **Subagents can damage the codebase.** In the 2026-05-18 NEXSTREAM session, a delegate_task subagent removed 27,604 lines (deleted file contents) across 20+ files while attempting bulk fixes. **Always git checkout back to a clean state before fixing yourself** if a subagent's work looks suspicious. The cleanup cost of subagent damage exceeds any time saved by delegation.

- **Timeout-recovery pattern (2026-06-03).** When multiple subagents time out during the same session, they leave the same class of error across many files (e.g., `FocusRequester?` → `FocusRequester` type mismatches in `focusProperties` blocks). Recovery: `git checkout -- <all-touched-files>` → rebuild clean → redo sequentially in-process. Do NOT try to fix one file at a time — the errors are systematic, the git revert is O(1), and manual per-file fixes create cascading new issues.

## Pitfall: Web Research Subagents

When delegating web research tasks, subagents often fail if told to "find document X" — they
spend their turns doing filesystem searches for a local copy instead of using the context you
provided. Two fixes:

1. **Inline all reference material.** Don't say "read Part B of the user's document." Copy the
   relevant section directly into the task `context` field. The subagent has no access to your
   conversation history or the user's uploaded files.
2. **Be explicit about the toolset.** Set `toolsets: ['web']` — don't include `file` or `terminal`
   unless those are genuinely needed. A subagent with file tools will default to searching the
   local filesystem.

**Good:**
```
delegate_task(
    goal="Research Android Room DB best practices...",
    context="""USER'S SPEC (inline):
    ## B5. Required Index Review
    Add composite indexes on watch_progress (profileId+mediaId, profileId+updatedAt)...
    
    Compare the above against Android official docs and NowInAndroid patterns.
    Return: what aligns, what's missing, what's different.""",
    toolsets=['web']
)
```

**Bad:**
```
delegate_task(
    goal="Research Android Room DB best practices...",
    context="Find the user's Part B document and compare against best practices.",
    toolsets=['web', 'file']  # subagent will search filesystem for the document
)
```

**Parallel research pattern (proven):** Delegate_task is effective for independent research
tasks despite the web tool's call count. The key is independence and upfront context:

- **Tasks MUST be truly independent.** Each subtask researches a different dimension
  of the same problem (e.g., Project A, Project B, Build System C — all different repos/sites).
  If two tasks would visit the same sites, they should be one task.
- **Set high timeouts.** Use `child_timeout_seconds: 600` in config.yaml (or rely on the default
  600s). A web/browser research subagent making 40+ API calls needs the full window.
  The default max_iterations=50 is tight but achievable with focused browsing.
- **Provide starting URLs.** Don't say "research live CD projects" — say "visit github.com/...,
  then project-site.org, then check releases." This prevents aimless searching.
- **Use `toolsets=['browser']`** (not `['web']`). The browser tool (browser_navigate, browser_snapshot,
  browser_console) is more capable for site research than the web tool alone. Browser handles
  JS-rendered pages, navigation, and element inspection.
- **Limit scope explicitly.** "Find: GitHub stars, last release date, license, base distro,
  UEFI support, active/inactive. Return a table." Constrained scope keeps subagent focused.
- **Expect 30-50 tool calls per subagent.** This is normal for deep research and does NOT
  mean the subagent is looping. The browser navigation + snapshot + scroll pattern is
  inherently call-heavy. The 50-call max_iterations default is tight — increase it to 60-80
  or break the research into smaller tasks.
- **Accept partial results.** A subagent that hits max_iterations at 48 calls with 6/15 projects
  studied still produced valuable data. The partial output is better than nothing and can be
  extended with a follow-up subagent.

**2026-06-06 session example:** Three research subagents ran in parallel:
- Subagent A: 50 calls, 237s — researched 15 rescue CD projects across official sites and GitHub
- Subagent B: 50 calls, 220s — researched 45+ tools across Arch/Debian package databases  
- Subagent C: 32 calls, 206s — researched 7 build systems (archiso, live-build, mkosi, buildroot, etc.)

All three completed within their timeouts. The key was providing specific starting URLs (not
search queries), limiting each subagent to one dimension of the problem, and accepting
that 30-50 calls were normal for deep research.

**Compare with the old view (now revised):** Earlier versions of this skill advised against
delegating research at all, citing the 40+ call timeout trap. **This was wrong.** The call
count is a function of the research depth, not a bug. If the subagent times out at 600s
with 48 calls, expand the timeout or scope, don't ban the pattern.

## Red Flags — Never Do These

- Start implementation without a plan
- Skip reviews (spec compliance OR code quality)
- Proceed with unfixed critical/important issues
- Dispatch multiple implementation subagents for tasks that touch the same files
- Make subagent read the plan file (provide full text in context instead)
- Skip scene-setting context (subagent needs to understand where the task fits)
- Ignore subagent questions (answer before letting them proceed)
- Accept "close enough" on spec compliance
- Skip review loops (reviewer found issues → implementer fixes → review again)
- Let implementer self-review replace actual review (both are needed)
- **Start code quality review before spec compliance is PASS** (wrong order)
- Move to next task while either review has open issues
- **Use subagents for tightly-coupled sequential work** — if tasks are a dependency chain (Task 2 needs Task 1's output), direct execution is faster and produces fewer merge conflicts. The subagent overhead of re-establishing file state per task compounds quickly.

## Handling Issues

### If Subagent Asks Questions

- Answer clearly and completely
- Provide additional context if needed
- Don't rush them into implementation

### If Reviewer Finds Issues

- Implementer subagent (or a new one) fixes them
- Reviewer reviews again
- Repeat until approved
- Don't skip the re-review

### If Subagent Fails a Task

- Dispatch a new fix subagent with specific instructions about what went wrong
- Don't try to fix manually in the controller session (context pollution)

## Efficiency Notes

**Why fresh subagent per task:**
- Prevents context pollution from accumulated state
- Each subagent gets clean, focused context
- No confusion from prior tasks' code or reasoning

**Why two-stage review:**
- Spec review catches under/over-building early
- Quality review ensures the implementation is well-built
- Catches issues before they compound across tasks

**Cost trade-off:**
- More subagent invocations (implementer + 2 reviewers per task)
- But catches issues early (cheaper than debugging compounded problems later)

## Integration with Other Skills

### With writing-plans

This skill EXECUTES plans created by the writing-plans skill:
1. User requirements → writing-plans → implementation plan
2. Implementation plan → subagent-driven-development → working code

### With test-driven-development

Implementer subagents should follow TDD:
1. Write failing test first
2. Implement minimal code
3. Verify test passes
4. Commit

Include TDD instructions in every implementer context.

### With requesting-code-review

The two-stage review process IS the code review. For final integration review, use the requesting-code-review skill's review dimensions.

### With systematic-debugging

If a subagent encounters bugs during implementation:
1. Follow systematic-debugging process
2. Find root cause before fixing
3. Write regression test
4. Resume implementation

## Example Workflow

```
[Read plan: docs/plans/auth-feature.md]
[Create todo list with 5 tasks]

--- Task 1: Create User model ---
[Dispatch implementer subagent]
  Implementer: "Should email be unique?"
  You: "Yes, email must be unique"
  Implementer: Implemented, 3/3 tests passing, committed.

[Dispatch spec reviewer]
  Spec reviewer: ✅ PASS — all requirements met

[Dispatch quality reviewer]
  Quality reviewer: ✅ APPROVED — clean code, good tests

[Mark Task 1 complete]

--- Task 2: Password hashing ---
[Dispatch implementer subagent]
  Implementer: No questions, implemented, 5/5 tests passing.

[Dispatch spec reviewer]
  Spec reviewer: ❌ Missing: password strength validation (spec says "min 8 chars")

[Implementer fixes]
  Implementer: Added validation, 7/7 tests passing.

[Dispatch spec reviewer again]
  Spec reviewer: ✅ PASS

[Dispatch quality reviewer]
  Quality reviewer: Important: Magic number 8, extract to constant
  Implementer: Extracted MIN_PASSWORD_LENGTH constant
  Quality reviewer: ✅ APPROVED

[Mark Task 2 complete]

... (continue for all tasks)

[After all tasks: dispatch final integration reviewer]
[Run full test suite: all passing]
[Done!]
```

## Remember

```
Fresh subagent per task
Two-stage review every time
Spec compliance FIRST
Code quality SECOND
Never skip reviews
Catch issues early
```

**Quality is not an accident. It's the result of systematic process.**

## Multi-Layer Audit Variant

For comprehensive codebase audits, use the parallel read-only inspection pattern documented in `references/parallel-audit.md`. Unlike the implementation workflow, audit sub-agents are inspectors (read-only), dispatched in parallel across independent layers, and findings are synthesized in the parent session. Load this reference when the user asks for a codebase audit or security review.

## Further reading (load when relevant)

When the orchestration involves significant context usage, long review loops, or complex validation checkpoints, load these references for the specific discipline:

- **`references/context-budget-discipline.md`** — Four-tier context degradation model (PEAK / GOOD / DEGRADING / POOR), read-depth rules that scale with context window size, and early warning signs of silent degradation. Load when a run will clearly consume significant context (multi-phase plans, many subagents, large artifacts).
- **`references/gates-taxonomy.md`** — The four canonical gate types (Pre-flight, Revision, Escalation, Abort) with behavior, recovery, and examples. Load when designing or reviewing any workflow that has validation checkpoints — use the vocabulary explicitly so each gate has defined entry, failure behavior, and resumption rules.
- **`references/parallel-porting-pattern.md`** — Batch strategy for porting 80+ similar Kotlin extractors to Go using parallel subagent dispatch. Load when the task involves mass porting of many small implementations (extractors, providers, converters) that share a common interface and follow a predictable pattern.

Both references adapted from gsd-build/get-shit-done (MIT © 2025 Lex Christopherson).
