---
name: subagent-driven-development
description: "Execute plans via delegate_task subagents (2-stage review)."
version: 1.1.0
author: Hermes Agent (adapted from obra/superpowers)
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:
- You have an implementation plan (from writing-plans skill or user requirements)
- Tasks are mostly independent
- Quality and spec compliance are important
- You want automated review between tasks

**Parallel fan-out preference:** When the user explicitly asks to delegate or the task involves building multiple independent pages/components (scaffolding, page builds, rewrites), use **parallel fan-out** (`delegate_task` with `tasks` array, up to 3 concurrent). Dispatch all independent pieces at once — no need for sequential 2-stage review on every single task. Follow up manually on anything the subagents didn't complete. The user prefers speed to perfect review discipline for bulk codegen.

**When NOT to use subagents — direct execution is better when:**
  • The plan contains **exact, copy-pasteable code** for every file (mechanical extraction / file-creation tasks). A subagent that receives fully specified code and just has to write it adds delegation overhead with zero decision-making value.
  • The task is a **pure refactor** that moves existing code between files without changing behavior. Writing the files yourself is faster, you keep awareness of structural interdependencies, and there's nothing for a reviewer to evaluate (spec = "move verbatim").
  • You have already read all the files and know the exact state. Spinning up a subagent means re-explaining context they'd need to re-read anyway.

**Decision rule:** When the plan's task description includes the full file contents (`write_file`, `patch` snippets), execute directly. Reserve subagents for tasks where the plan gives a *spec* and expects the implementer to *design and write* code — that's where the review cycle adds value.

**vs. manual execution when subagents ARE the right tool:**
- 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

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

## 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)
- Never skip scene-setting context (subagent needs to understand where the task fits)
- IGNORE subagent questions (answer before letting them proceed)
- Wait for ALL subagents in a parallel batch before testing/reviewing — React pages often share imports; a missing page import in App.tsx breaks the build
- After parallel fan-out completes: check for React context providers. Subagents may use hooks like `useToast()` that require a provider wrapper. If any page crashes (blank screen), check if `<ToastProvider>` wraps the routes. **Before dispatching**, scan the task specs for hooks that need providers (useToast, useAuth, useTheme) and include a reminder in each subagent's context to either use them safely or note the required wrapper
- After parallel fan-out where one subagent creates a library module (like `ai.ts`) and another consumes it (like `QuoteGenerator.tsx`), verify that function signatures match between the two. Subagents don't share context, so their exported/imported interfaces can drift. Check the actual call sites against the actual function signatures before building
- When the project uses `React.lazy()` for code splitting, import errors in lazy-loaded chunks surface as blank screens with empty console errors. Use eager imports first to isolate the failing module, then switch back to lazy once verified
- 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
- **Trust subagent generated UI buttons have wired handlers** — always verify interactive elements (buttons, links, forms) have onClick/onSubmit handlers after subagent work. Subagents frequently generate `<button>` elements with no action attached.

## Common Subagent Output Defects to Catch

Subagents produce code that compiles cleanly (TypeScript passes, bundler accepts it) but is functionally broken. After parallel fan-outs, scan for these common defects:

### Missing interactive handlers
Buttons, links, and form elements rendered in the DOM but with no `onClick`/`onSubmit` handler attached. The element appears on screen but clicking does nothing. **Check:** grep each new page file for `<button` and verify every interactive button has an `onClick` or `type="submit"`.

### Hardcoded mock/fallback responses
Subagents sometimes build "smart fallbacks" (simulated responses, canned data, mock delays) instead of calling the real API endpoint. **Check:** grep for keywords like `setTimeout`, `Math.random`, `fallback`, `simulate`, or hardcoded response objects. If the task spec says "call API X", the implementation must call API X — not simulate it.

### Function signature drift between modules
When subagent A creates a library and subagent B consumes it, the exported function signatures often don't match the call sites. `aiWriteExplanation(name, reason)` vs `aiWriteExplanation({serviceName, recommendation})`. **Check:** for each imported function in consumer files, verify the actual call argument shapes match the exported parameter types.

### Dependency stealth
Subagents add imports to `package.json` (`tesseract.js`, chart libraries, etc.) and use them in code without the package actually being installed. TypeScript may not catch this if the module isn't directly imported at compile time (e.g., dynamic `import()`). **Check:** compare new imports against `package.json` dependencies.

### React nested-component re‑mount (input focus loss)
Subagents define child components as nested functions inside parent components. When the parent re‑renders (e.g., due to a zustand store update from typing in an input), React destroys and recreates the nested component because its function identity changed — causing inputs to lose focus on every keystroke. **Symptom:** typing one character dismisses focus; the user must click the field again for each keypress. **Fix:** extract the nested component to a file‑level `const Component = memo(function Component({...}) {...})` with stable props. Pass callbacks as individual props rather than capturing parent closure variables.

**Variant: duplicate definitions (shadowing).** When a subagent adds a new feature to an existing file, it may create BOTH:
1. A **standalone** (prop-based) component **outside** the parent component function, AND
2. An **inline** (closure-based) component **inside** the parent component function

The inline definition **shadows** the proper standalone one because JavaScript scope resolution finds the inner binding first. The inner component is recreated every render (destroying focus), while the outer one is never used. **Diagnosis:** Search for `function ComponentName(` — if two definitions exist (one inside the parent component, one outside), delete the inline one. **Prevention:** when adding a feature to a file that already has standalone components, check whether the parent component ALSO contains an inline version that shadows the outer one.

### tsc clean ≠ build clean
TypeScript `--noEmit` passing does not guarantee the bundler (Vite/Rolldown, webpack) will succeed. Bundlers enforce module resolution, circular imports, and chunk splitting that tsc ignores. After type-checking, always run the actual build command.

### JSX fragment conversion during component extraction
When extracting JSX that uses fragment shorthand (`<>...</>`) into a named component and converting to `<Fragment key={...}>`, the brace/paren structure around the return expression often changes because the fragment shorthand doesn't carry a `key` prop but a moved `<Fragment>` needs one. **Common failure:** leaving the original closing pattern (`));` or `);`) unchanged when the Fragment's structural role changed.

**Root cause:** The original `<>...</>` sits directly inside `return ( ... )` and the closing `)` is obvious. After converting to `<Fragment key={expr}>`, the Fragment's open tag may introduce an extra nesting level or change how the return expression relates to the arrow function body. The old closing `);` may need to become just `);` (one paren fewer/more) depending on whether the fragment is the single child or wraps multiple elements.

**Prevention:** After extracting any JSX block that involved `<>...</>`, trace the return path: `return ( <Fragment> ... </Fragment> )` should close with `);` then `})}` for a block-arrow `.map()`. Count parens explicitly. The `;` ends the return statement, the `}` closes the arrow body, the `)` closes `.map()`, and the `}` closes the JSX expression.

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

## 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/pocketbase-proxy-pitfalls.md`** — PocketBase SDK path construction trap (double `/api`), Python http.server query string behavior, and admin auth endpoint differences across versions. Load when debugging PocketBase proxy 404 errors or setting up a local SPA dev server that proxies to PocketBase.
- **`references/spa-proxy-server.md`** — Template and pitfalls for a Python HTTP proxy server that serves a SPA's static dist/ while proxying API paths to a backend on a different port. Load when you need to serve a local build for browser testing and the SPA's relative API paths need to reach a backend like PocketBase.
- **`references/pocketbase-sequencing-pitfalls.md`** — PB migrations must be applied before frontend code that queries new collections can work. Load when dispatching subagents that write both PB migrations and frontend UI in the same batch — apply migrations first, then dispatch frontend subagents.

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