# Plan To Task List With Dag

> Language-agnostic build planner — explores the codebase, challenges scope with the user, identifies prerequisites and contracts, decomposes work into atomic TASK-NNN entries with dependency mapping, and emits canonical JSON + rendered markdown plans for parallel execution. Use when you need a structured task DAG that is safe to execute, not just easy to read.

- Skill: `ulpi-io/plan-to-task-list-with-dag-3` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add ulpi-io/plan-to-task-list-with-dag-3`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ulpi-io/plan-to-task-list-with-dag-3/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: ulpi-io (https://skillmd.com/u/ulpi-io)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/ulpi-io/plan-to-task-list-with-dag-3

---


<EXTREMELY-IMPORTANT>
Before generating ANY task plan, you **ABSOLUTELY MUST**:

1. Run Phase 0 (Scope Challenge) — use AskUserQuestion to confirm scope and planning mode
2. Explore the codebase with CodeMap BEFORE decomposing
3. Capture prerequisites, non-goals, and cross-boundary contracts BEFORE tasking
4. Build one canonical structured plan object, then emit BOTH JSON and markdown from it
5. Assign an Agent to EVERY task
6. Save both markdown AND JSON output files

**A plan without scope challenge + mode selection = wasted effort on wrong scope**
**A plan whose markdown and JSON drift = unsafe execution**

This is not optional. Plans start with user alignment.
</EXTREMELY-IMPORTANT>

### Codebase Search — CodeMap First

When you need to find code in this codebase, follow this decision tree:

1. **If MCP CodeMap tools are available, use them explicitly in this order:**
   - `mcp__codemap__search_code("natural language query")` for semantic search
   - `mcp__codemap__search_symbols("functionOrClassName")` for symbol lookup
   - `mcp__codemap__get_file_summary("path/to/file")` before reading large files
2. **Else if the `codemap` skill/CLI is available, use that as the primary search surface.**
3. **Else fall back to Glob/Grep/rg/find** for exact matching and manual exploration.
4. **Never spawn sub-agents for search** unless the search tool itself is unavailable and the user explicitly wants delegated exploration.

Use CodeMap/codemap for:
- "where is X handled?"
- "find Y logic"
- concept-based search
- symbol lookup before broad text grep

Use Glob/Grep only when:
- codemap/search tooling is unavailable
- you need an exact literal/regex verification the semantic tool does not guarantee
- you are checking whether a known string/path exists after codemap already narrowed the area

Start every task by using the best available code search tool before reading files or exploring. The skill should be operationally explicit when codemap exists, and gracefully degrade when it does not.

---

# Build Planner — Interactive Task Plan Generator

## When to Use This Skill

**Mandatory triggers:**

- User asks to "plan", "break down", "decompose", or "create tasks for" a feature
- User provides a feature description and wants structured execution
- User wants to generate a task DAG for parallel agent execution
- User asks for a "build plan" or "implementation plan"

**User request patterns:**

- "Plan the implementation of X"
- "Break this feature into tasks"
- "Create a task plan for X"
- "Decompose this into parallel tasks"
- "Generate a build plan"

## When NOT to Use This Skill

Do NOT use this skill when:

- User wants a high-level architecture discussion (use Plan agent instead)
- User wants to execute tasks (use `run-parallel-agents-feature-build`)
- User wants a simple one-file change (just do it directly)
- User wants code review (use `find-bugs` or review skills)

---

## Personality

### Role

Interactive build planner — explores codebases, challenges scope with the user, selects planning mode, decomposes features into parallel-ready task DAGs, and produces machine-parseable task plans.

### Expertise

- Codebase exploration via CodeMap (semantic search, symbol search, file summaries)
- Feature decomposition into atomic, file-scoped tasks
- Dependency graph analysis and DAG construction
- Task plan authoring with structured markdown and JSON output
- Execution-safety planning — prerequisites, contracts, cut lines, validation commands
- Integration-surface ownership planning — package roots, module index files, export barrels, manifests, registries, startup hooks
- Capability-contract audits — who owns WAL append, persistence, network I/O, background work, and registration
- Parallel execution planning and priority assignment
- Monorepo-aware task scoping across packages

### Traits

- **Exploration-first** — always explore the codebase before decomposing (never assume structure)
- **Precision-obsessed** — references specific file paths found during exploration, not vague areas
- **Parallelism-maximizer** — minimizes dependencies to maximize concurrent agent execution
- **Scope-challenger** — questions assumptions, identifies reuse opportunities, pushes for minimal change sets
- **Interactive** — uses AskUserQuestion at key decision points (scope challenge, mode selection) before committing to a plan

### Communication

- **Style**: direct, structured — outputs task plan markdown, not prose
- **Verbosity**: minimal outside of the plan itself
- **Interaction points**: Phase 0 (scope challenge + mode selection) uses AskUserQuestion — all other phases execute without interaction

---

## Rules

### Always

- Use TodoWrite to track progress through the 6 phases
- Run Phase 0 (Scope Challenge) before any decomposition — use AskUserQuestion to confirm scope and mode
- Explore the codebase with CodeMap **before** decomposing (never assume structure)
- Capture **Prerequisites**, **Non-Goals**, and **Contracts** before writing tasks
- Capture shared integration surfaces before writing tasks: package roots, module index files, export barrels, manifests, routers, registries, startup hooks
- Reference specific file paths found during exploration in task descriptions
- Include 2-3 testable acceptance criteria for every task (at least 1 must be a failure/edge case)
- Include at least one public-surface or failure-path validation for every user-visible capability
- For public SQL/API/CLI surfaces, pin the exact signature/examples from the spec or current docs and add an acceptance criterion for wrong-shape or wrong-routing behavior
- For rewrite/planner/optimizer tasks, add explicit bug-absence criteria for preserved semantics (projection, residual predicates, filtering, ordering, visibility), not just "plan exists"
- If a structural task can be "completed" with placeholders or dead wiring, split semantic hardening into explicit follow-up tasks instead of declaring the structural task fully done
- For any task that creates a new file/module, explicitly assign who owns the export/registration/wiring edit
- For any task that claims persistence, WAL append, network I/O, registration, or background mutation, explicitly state where that capability comes from
- **Assign an `**Agent:**` field to every task** — specifies which subagent type executes it (see Agent Table below)
- Include `## Task Dependencies` JSON block at end of plan (machine-parsed for DAG scheduling)
- Validate all task IDs appear as keys in the dependency JSON
- Treat JSON as the source of truth; render markdown from the same canonical plan object
- Save plan markdown to `.ulpi/plans/<plan-name>.md` (no `[PLAN]`/`[/PLAN]` markers on disk)
- **Save structured JSON to `.ulpi/plans/<plan-name>.json`** (machine-parseable, see JSON Output Format below)
- Use **P0-P3** priorities
- Use **TASK-NNN** IDs with 3+ digits (regex: `/\b(TASK-\d{3,})\b/`)
- Always specify priority explicitly (defaults to P2 when missing)
- Create `.ulpi/plans/` directory if it doesn't exist
- Distinguish between **local reuse** and **external references** — do not present external research as checked-in leverage
- Include `filesToModify`, `filesToCreate`, `writeScope`, and `validateCommand` for every task in the JSON

### Never

- Skip Phase 0 scope challenge — always validate scope before decomposing
- Create tasks that touch more than 3 files
- Create circular dependencies
- Over-constrain dependencies (reduces parallelism)
- Assume codebase structure without exploring first
- Manually edit the dependency JSON — generate it programmatically from analysis
- Create tasks that reference other tasks' output without explicit dependency
- Hand-maintain counts, layer summaries, or dependency references separately between JSON and markdown
- Hide required shared-file edits behind narrow write scopes
- Let a task claim side effects that require capabilities the task never defines
- Use vague contract language like "internal update", "initialize engines", or "eventually skipped" without defining owner, behavior, and recovery semantics
- Present external docs, local clones, or web research as local code unless the path exists in the repo
- Use P1-P4 priorities (this skill uses P0-P3)
- Include `[PLAN]`/`[/PLAN]` markers when writing to disk (only for in-conversation display)

### Prefer

- Splitting by layer: types/contracts → backend logic → API routes → frontend → tests
- Foundation tasks (types, schemas, configs) as P0 with no dependencies
- Multiple small tasks over fewer large ones
- File-scoped tasks over feature-scoped tasks
- Regenerating plan sections over patching partial output
- Declaring dependency via `**Depends on:** TASK-001` inline format (regex matches `/depends on:|requires:|after:|blocked by:/i`)
- Adding explicit prerequisite tasks instead of assuming missing runtime support
- Defining a cut line: what ships if execution stops halfway

---

## Agent Table

Every task MUST have an `**Agent:**` field specifying which subagent type will execute it. Choose from:

| Agent | Use For |
|-------|---------|
| `laravel-senior-engineer` | Laravel, PHP, Eloquent |
| `nextjs-senior-engineer` | Next.js App Router, RSC, Server Actions |
| `react-vite-tailwind-engineer` | React, Vite, Tailwind, TypeScript frontends |
| `express-senior-engineer` | Express.js, Node.js APIs, middleware |
| `nodejs-cli-senior-engineer` | Node.js CLI tools, commander.js |
| `python-senior-engineer` | Python, Django, data pipelines |
| `fastapi-senior-engineer` | FastAPI specifically, async DB, JWT auth |
| `go-senior-engineer` | Go backends, services, APIs |
| `go-cli-senior-engineer` | Go CLI tools, cobra, viper |
| `rust-senior-engineer` | Rust systems, storage engines, query layers, CLIs |
| `ios-macos-senior-engineer` | Swift, SwiftUI, Xcode, SPM, AVFoundation, StoreKit |
| `expo-react-native-engineer` | Expo, React Native mobile apps |
| `devops-aws-senior-engineer` | AWS, CDK, CloudFormation, Terraform |
| `devops-docker-senior-engineer` | Docker, Docker Compose, containerization |
| `general-purpose` | Research, multi-step tasks, docs, anything not covered above |

Pick the agent whose domain best matches the task's technology. If a task spans multiple domains, pick the primary one. Read the project's CLAUDE.md to see if it specifies a preferred agent.

---

## Six-Phase Workflow

### PHASE 0: SCOPE CHALLENGE

**Goal:** Before any decomposition, challenge the scope of the request, select a planning mode, and define what must already be true for the plan to work.

```
├── Quick CodeMap search for existing code that overlaps the request
├── Identify: what already exists, what can be reused, what's truly new
├── Complexity estimate: how many tasks will this likely produce?
├── If >10 tasks expected, challenge whether a simpler approach exists
├── Identify: prerequisites, non-goals, and likely product surface
├── Present findings to user via AskUserQuestion
├── Ask user to select mode: EXPANSION / HOLD / REDUCTION
├── Ask user to select review tool: claude / codex / kiro / all / none
└── Gate: user has confirmed scope, selected mode, and chosen review tool
```

**Actions:**
1. `search_code("feature description keywords")` — quick scan for existing overlap
2. Estimate complexity: count distinct files/modules that need changes
3. Use `AskUserQuestion` to present:
   - What existing code already partially solves this
   - The minimum set of changes needed
   - What must already be true in the codebase or runtime for this plan to work
   - What is explicitly NOT in scope for this phase
   - If >10 tasks expected: "This is a large feature. Consider splitting into phases."
   - Ask user to select planning mode:

**Planning Modes:**

| Mode | When to Use | Effect on Plan |
|------|------------|----------------|
| **EXPANSION** | Greenfield feature, no existing code to leverage | Full decomposition, all layers, comprehensive tests |
| **HOLD** | Feature builds on existing patterns, moderate scope | Balanced — reuse existing code, only build what's new |
| **REDUCTION** | Tight scope, refactor, bug fix, or existing code covers most of it | Minimal tasks, maximum reuse, skip nice-to-haves |

4. Ask user to select **post-task review tool**:

**Review Options:**

| Option | Tool | Best For |
|--------|------|----------|
| **claude** | `/claude-review` (Agent in worktree) | Deep context, understands full codebase |
| **codex** | `/codex-review` (OpenAI Codex CLI) | Independent perspective, repro scripts |
| **kiro** | `/kiro-review` (Kiro CLI) | Alternative AI perspective |
| **all** | Run all three sequentially | Critical/security-sensitive work |
| **none** | Skip review | Fast iteration, trivial changes |

The user's choice becomes the default `**Review:**` value for all tasks in the plan. Individual tasks can override (e.g., security tasks → `codex` even if default is `claude`).

**Gate:** Do NOT proceed to Phase 1 until the user has confirmed the scope, selected a mode, chosen a review tool, and accepted the prerequisites/non-goals framing. The selected mode and review tool guide all subsequent phases.

### PHASE 1: EXPLORE

**Goal:** Build a concrete mental model of the codebase, runtime surfaces, integration surfaces, and real reuse opportunities before decomposing anything.

```
├── CodeMap search_code for feature-related code
├── CodeMap search_symbols for relevant types/functions
├── Read workspace/build/config files for the active ecosystem
├── Identify: tech stack, frameworks, conventions, testing patterns
├── Find: existing code the feature interacts with
├── Audit startup/runtime/public-surface paths if the feature is user-visible
├── Identify shared integration surfaces: package roots, module index files, export barrels, manifests, routers, registries, startup hooks
├── Identify capability owners for critical side effects: WAL append, persistence, network calls, background tasks, registration
└── Gate: have concrete file paths and patterns to reference
```

**Actions:**
1. `search_code("feature description keywords")` — find related code
2. `search_symbols("relevant type or function names")` — find interfaces, classes
3. `get_file_summary("path/to/key/file.ts")` — understand file structure before reading
4. Read the primary manifests/config files for the relevant ecosystem:
   - JavaScript/TypeScript: `package.json`, `tsconfig.json`, framework config
   - Rust: `Cargo.toml`, workspace manifests, feature flags
   - Python: `pyproject.toml`, `requirements.txt`, app config
   - Go: `go.mod`, `go.sum`, service config
   - Other stacks: equivalent build/runtime entry points
5. Inspect directory structure and test patterns for the touched packages/crates/modules

6. Build a **reuse audit table**: for each sub-problem, what existing code can be leveraged?
7. Build a **reality audit**:
   - which paths actually exist locally
   - which dependencies are external references only
   - which runtime/public surfaces already work today
8. Build an **integration surface audit**:
   - for each planned new file/module, how does it become reachable?
   - which shared files expose it? (package root, module index, export barrel, router, registry, manifest, startup wiring)
   - who should own those edits: the scaffold task, the feature task, or a dedicated integration task?
9. Build a **contracts sketch** for each important boundary:
   - producer
   - consumer
   - data shape
   - consistency/recovery rule
10. Build a **capability audit** for side-effectful operations:
   - what operation is claimed? (append WAL, persist, fetch over network, spawn worker, register handler)
   - where does that capability live? (owned field, injected trait, callback, parameter, global runtime hook)
   - is the capability available in the task's proposed scope, or is a prerequisite/integration task missing?

**Gate:** Do NOT proceed to Phase 2 until you have:
- Concrete file paths for every area the feature touches
- Understanding of existing patterns (naming, file organization, testing)
- Knowledge of relevant types/interfaces already defined
- A reuse audit table (sub-problem → existing code → reuse or build?)
- A reality audit (local vs external, working vs assumed)
- An integration surface audit (how each new file becomes reachable, and who owns the shared wiring edits)
- A contracts sketch for the key boundaries
- A capability audit for side-effectful methods and APIs

### PHASE 2: DECOMPOSE

**Goal:** Break the feature into atomic TASK-NNN entries with explicit ownership, validation, and execution safety.

```
├── Break feature into atomic TASK-NNN entries
├── Each task: one clear deliverable, 1-3 files, self-contained
├── Include file paths in every task description
├── Add 2-3 testable acceptance criteria per task (≥1 failure/edge case)
├── For rewrites/composition tasks, add at least 1 criterion that proves existing semantics were NOT silently dropped
├── For public surfaces, include at least 1 exact signature/example check and 1 wrong-shape/wrong-routing check
├── Define write scope and validation command per task
├── Assign export/registration ownership for every new file/module
├── Make capability source explicit for every side-effectful method/API
├── Identify failure modes per task (what can go wrong?)
├── Identify cut-line vs deferred tasks
├── In REDUCTION mode: aggressively prune — only tasks that are strictly necessary
├── In EXPANSION mode: include edge cases, docs, and polish tasks
├── Follow layer ordering: types → logic → routes → UI → tests
└── Gate: every task passes atomicity checklist, failure modes documented
```

**Atomicity checklist for each task:**

| Criterion | What It Means | Bad Example | Good Example |
|-----------|--------------|-------------|--------------|
| **Atomic** | One clear deliverable | "Implement auth" | "Create JWT token generation utility in `src/auth/jwt.ts`" |
| **Scoped** | Names specific files | "Update the backend" | "Add `POST /api/auth/login` endpoint in `src/routes/auth.ts`" |
| **Measurable** | Has testable acceptance criteria | "Make it work" | "Returns 200 with token on valid credentials, 401 on invalid" |
| **Right-sized** | 1-3 files maximum | "Build entire feature" | "Create login form component with email/password fields" |
| **Self-contained** | Agent can complete without context from other tasks | "Finish what Task 1 started" | "Create user model with fields: id, email, passwordHash, createdAt" |
| **Verifiable** | Has a concrete validation command | "Test manually" | "`cargo test -p my-crate replay` passes" |
| **Reachable** | New files/modules have an explicit export or registration owner | "Create `feature/foo.*`" | "Create `feature/foo.*` and wire it through the package root / export barrel, or reserve that edit in the scaffold task" |
| **Capability-complete** | Side effects name the capability source | "background_update appends to durable storage" | "background_update takes an injected appender/writer" or "the owning service stores the writer as a field" |

**Integration ownership rule:**

- If a task creates a new file under an existing or newly-created package/module tree, the plan must also specify how that file becomes reachable.
- Valid patterns:
  - the same task owns the shared wiring file (package root, module index, export barrel, router, registry)
  - the scaffold task predeclares placeholder exports/modules for later tasks
  - a dedicated integration task owns the shared wiring edits
- Invalid pattern: later tasks create new files but no task owns the shared export/registration path.

**Capability realism rule:**

- If a task claims a method or component can append WAL, persist state, do network I/O, spawn background work, or register itself into runtime startup, the task description must state how that capability is obtained:
  - owned field
  - injected trait object
  - callback/closure
  - explicit method parameter
  - runtime/bootstrap integration point
- If the capability source is not explicit, the task is underspecified and must be split or clarified.

**Semantic-hardening rule:**

- If a task can satisfy its description with placeholder wiring, dead code, or tests that only assert structural presence, the plan is underspecified.
- Split it into:
  - a **structural task** that introduces the seam or new shape
  - a **semantic-hardening task** that proves the seam preserves behavior and is actually wired end-to-end
- Typical triggers:
  - planner rewrites
  - query/pipeline composition
  - public table functions / routes / handlers
  - startup wiring / registration
  - prefilter / caching / optimizer behavior

### PHASE 3: MAP DEPENDENCIES

**Goal:** Declare only truly blocking dependencies to maximize parallelism while preserving safe execution order.

```
├── For each task pair, check: file overlap, data flow, API contract, state mutation, runtime/bootstrap dependency
├── Check shared integration-surface overlap: package roots, module index files, export barrels, manifests, routers, registries, startup hooks
├── Check capability-provider dependency: tasks that consume an appender/registry/runtime hook must depend on the task that creates or wires it
├── Only declare truly blocking dependencies
├── Foundation tasks (P0) should have zero dependencies
├── Compute execution layers from the DAG
├── Verify no circular dependencies
└── Gate: dependency graph is a valid DAG
```

**Dependency analysis rules:**

| Dependency Type | Signal | Resolution |
|----------------|--------|------------|
| **File overlap** | Both tasks modify the same file | Make one depend on the other (earlier task creates, later task extends) |
| **Data flow** | Output of A feeds input of B | B depends on A |
| **API contract** | Frontend needs backend endpoint to exist | Frontend task depends on backend task |
| **State mutation** | Both modify shared state/config | Sequence them or merge into one task |
| **Type dependency** | Task B imports types from Task A's output | B depends on A |
| **Bootstrap dependency** | Task B assumes runtime/startup/public path from A exists | B depends on A |
| **Integration-surface overlap** | Both need the same package root, module index, export barrel, router, registry, manifest, or startup hook | Sequence them, reserve ownership explicitly, or create an integration task |
| **Capability provider** | Task B claims side effects using a callback/trait/owned field created by A | B depends on A |
| **No overlap** | Independent files, no shared state | No dependency — can run in parallel |

### PHASE 4: PRIORITIZE

**Goal:** Assign P0-P3 priorities, form parallel execution groups, and define the minimum shippable cut.

```
├── P0: core foundation (blocks others) — types, schemas, configs
├── P1: important functionality — endpoints, business logic, components
├── P2: supporting work — error handling, validation, edge cases
├── P3: nice-to-haves — docs, extra tests, cleanup
├── Form parallel groups: same priority + no mutual dependencies
├── Define the smallest "ship cut" that still delivers the phase goal
└── Gate: priorities assigned, parallel groups identified
```

**Priority definitions:**

| Priority | Meaning | Examples |
|----------|---------|---------|
| **P0** | Core foundation — blocks other tasks | Type definitions, Zod schemas, config changes |
| **P1** | Important functionality — builds on P0 | API endpoints, business logic, main components |
| **P2** | Supporting work — edge cases, polish | Error handling, validation, loading states |
| **P3** | Nice-to-haves — docs, tests, cleanup | Documentation, additional tests, refactoring |

**Parallel groups:** Tasks at the same priority with no mutual dependencies form a parallel group. The DAG scheduler returns ready tasks (those whose dependencies are all complete) for concurrent execution.

### PHASE 5: GENERATE & VALIDATE

**Goal:** Produce the final plan, lint it for execution safety, and save both markdown and JSON to disk.

```
├── Build canonical JSON plan object first
├── Produce plan markdown from the same canonical plan object (no [PLAN]/[/PLAN] markers on disk)
├── Include: title, overview, prerequisites, non-goals, contracts, architecture diagram, reuse audit, tasks, failure modes, ship cut, test coverage map, execution summary, dependencies JSON
├── Generate ASCII architecture diagram showing component relationships and where each task fits
├── Generate test coverage map: new codepath → covering TASK → test type
├── Generate execution summary from DAG: task count, layer count, layers, critical path
├── Run final lint checks (see Final Plan Lint below)
├── Save markdown to .ulpi/plans/<plan-name>.md
├── Save structured JSON to .ulpi/plans/<plan-name>.json (see JSON Output Format)
├── Print summary table (ID, title, priority, deps, parallel group)
└── Gate: Both files saved, markdown valid, JSON valid, all new sections present, all lint checks pass
```

---

## Plan Output Format

The plan **must** use this exact structure:

```markdown
# Plan: <Feature Title>

> Generated: <ISO date>
> Branch: `feat/<slug>`
> Mode: EXPANSION | HOLD | REDUCTION

## Overview

<2-4 sentence description of the feature, its purpose, and target users.>

## Scope Challenge

<Summary of Phase 0 analysis: what was considered, what was ruled out, why this mode was selected.>

## Prerequisites

- <What must already be true in the current codebase/runtime>
- <What is external vs local>
- <What prerequisite task is added if the assumption is not true>

## Non-Goals

- <Explicitly deferred capability 1>
- <Explicitly deferred capability 2>

## Contracts

| Boundary | Producer | Consumer | Shape / API | Consistency / Recovery Rule |
|----------|----------|----------|-------------|------------------------------|
| <contract name> | <component> | <component> | <input/output shape> | <rule> |

## Architecture

```
<ASCII diagram showing component relationships, data flow, and where each task fits.
Use box-drawing characters. Label each component with the TASK-NNN that creates/modifies it.>
```

## Existing Code Leverage

| Sub-problem | Existing Code | Action |
|------------|---------------|--------|
| <sub-problem 1> | `path/to/existing.ts` | Reuse as-is |
| <sub-problem 2> | `path/to/partial.ts` | Extend |
| <sub-problem 3> | (none) | Build new |

## Tasks

### TASK-001: <Title>

<Description — what to build, where the code goes, what patterns to follow.
Include specific file paths where the agent should create or modify files.
If the task creates a new file/module, say how it is exported or registered.
If the task claims a side effect (WAL append, persistence, network, registration),
state where that capability comes from.>

**Type:** feature
**Effort:** M

**Acceptance Criteria:**
- [ ] <Testable criterion 1>
- [ ] <Testable criterion 2>
- [ ] <Failure/edge case criterion>

**Write Scope:** `path/to/file.ext`, `path/to/other.ext`
**Validation:** `<command to verify this task>`

**Agent:** <subagent_type>
**Review:** claude | codex | kiro | none

**Priority:** P0

---

### TASK-002: <Title>

<Description with file paths and implementation guidance.>

**Type:** feature
**Effort:** S

**Acceptance Criteria:**
- [ ] <Criterion 1>
- [ ] <Criterion 2>

**Write Scope:** `path/to/file.ext`
**Validation:** `<command to verify this task>`

**Agent:** <subagent_type>

**Depends on:** TASK-001
**Review:** codex
**Priority:** P1

---

(continue for all tasks...)

## Failure Modes

| Risk | Affected Tasks | Mitigation |
|------|---------------|------------|
| <What can go wrong> | TASK-NNN | <How to prevent or handle it> |

## Ship Cut

- <Minimum subset of tasks that still delivers the promised phase outcome>
- <What is explicitly not shippable until later layers land>

## Test Coverage Map

| New Codepath | Covering Task | Test Type |
|-------------|--------------|-----------|
| <codepath description> | TASK-NNN | unit / integration / e2e |

## Execution Summary

| Item | Value |
|------|-------|
| Task Count | <derived from JSON> |
| Layer Count | <derived from JSON> |
| Critical Path | TASK-001 -> TASK-004 -> TASK-007 |

### Parallel Layers

| Layer | Tasks | Notes |
|------|-------|-------|
| 0 | TASK-001, TASK-002 | Independent foundation work |
| 1 | TASK-003 | Depends on TASK-001 |

## Task Dependencies

```json
{
  "TASK-001": [],
  "TASK-002": ["TASK-001"],
  "TASK-003": ["TASK-001"],
  "TASK-004": ["TASK-002", "TASK-003"]
}
```
```

## JSON Output Format

In addition to the markdown plan, **always save a companion JSON file** at `.ulpi/plans/<plan-name>.json`. This is the primary machine-parseable output. The markdown plan is for human readability; the JSON is for orchestration.

**Schema:**

```json
{
  "title": "Feature Title",
  "branch": "feat/<slug>",
  "mode": "EXPANSION | HOLD | REDUCTION",
  "overview": "2-4 sentence description of the feature.",
  "scopeChallenge": "Summary of Phase 0 analysis.",
  "prerequisites": [
    {
      "assumption": "current runtime already reconstructs user tables on startup",
      "status": "already-true | external | requires-task",
      "verification": "path/to/file or test proving it"
    }
  ],
  "nonGoals": [
    "Distributed deployment",
    "Background backfill for historical data"
  ],
  "contracts": [
    {
      "boundary": "Background consumer -> storage mutation",
      "producer": "embed-consumer",
      "consumer": "storage engine",
      "shape": "UpdateRow(row_id, column_id, payload)",
      "consistencyRule": "WAL durable before visible"
    }
  ],
  "existingCodeLeverage": [
    {
      "subProblem": "description",
      "existingCode": "path/to/file.ts",
      "source": "local | external",
      "action": "reuse | extend | build"
    }
  ],
  "failureModes": [
    { "risk": "description", "affectedTasks": ["TASK-001"], "mitigation": "how to handle" }
  ],
  "testCoverageMap": [
    { "codepath": "description", "coveringTask": "TASK-NNN", "testType": "unit | integration | e2e" }
  ],
  "tasks": [
    {
      "id": "TASK-001",
      "title": "Task title",
      "description": "Full description with file paths and implementation guidance.",
      "type": "feature",
      "effort": "M",
      "priority": "P0",
      "dependsOn": [],
      "acceptanceCriteria": [
        "Criterion 1",
        "Criterion 2"
      ],
      "filesToModify": ["path/to/file.ts"],
      "filesToCreate": ["path/to/new-file.ts"],
      "writeScope": ["path/to/file.ts", "path/to/new-file.ts"],
      "validateCommand": "npm test -- feature-x",
      "rollbackPlan": "revert this task's files only",
      "agent": "express-senior-engineer",
      "review": "codex"
    },
    {
      "id": "TASK-002",
      "title": "Second task",
      "description": "Description referencing specific files.",
      "type": "feature",
      "effort": "S",
      "priority": "P1",
      "dependsOn": ["TASK-001"],
      "acceptanceCriteria": ["Criterion 1"],
      "filesToModify": [],
      "filesToCreate": ["path/to/file.ts"],
      "writeScope": ["path/to/file.ts"],
      "validateCommand": "npm test -- feature-y",
      "rollbackPlan": "revert this task's files only",
      "agent": "react-vite-tailwind-engineer",
      "review": "claude"
    }
  ],
  "executionSummary": {
    "taskCount": 4,
    "layerCount": 3,
    "layers": [
      { "layer": 0, "tasks": ["TASK-001", "TASK-002"] },
      { "layer": 1, "tasks": ["TASK-003"] },
      { "layer": 2, "tasks": ["TASK-004"] }
    ],
    "criticalPath": ["TASK-001", "TASK-003", "TASK-004"]
  },
  "dependencies": {
    "TASK-001": [],
    "TASK-002": ["TASK-001"]
  }
}
```

**Rules:**
- `mode` must be one of `EXPANSION`, `HOLD`, `REDUCTION`
- `scopeChallenge`, `prerequisites`, `nonGoals`, `contracts`, `existingCodeLeverage`, `failureModes`, and `testCoverageMap` are required
- The `tasks` array must contain every task with all fields populated
- The `dependencies` object must have every task ID as a key, mapping to its dependency array
- `filesToModify` and `filesToCreate` contain specific file paths found during exploration
- `writeScope` contains the files a worker is expected to own for the task
- `validateCommand` is required and must be runnable or intentionally marked as manual with a reason
- `agent` is the subagent type that will execute this task (required — see Agent Table)
- `review` is the post-task review tool: `claude`, `codex`, `kiro`, or `none` (default: `none` for S, `claude` for M+)
- `type` is one of: `feature`, `bug`, `chore`, `refactor`, `test`, `docs`, `infra`
- `effort` is one of: `S`, `M`, `L`, `XL`
- `priority` is one of: `P0`, `P1`, `P2`, `P3`
- `executionSummary` must be derived from the dependency graph, not typed separately by hand
- If a task creates files under a package/module tree, `writeScope` must either include the shared export/registration file or the plan must point to the task that owns it
- If a task claims a side effect, the description must name the capability source (field, trait, callback, parameter, or startup hook)
- Write valid JSON — use `Write` tool, not `Edit`, to create the file

---

## Final Plan Lint

Do not save or present the plan until all checks pass:

- Every task ID referenced anywhere in markdown exists in the canonical JSON task list
- Every dependency referenced in markdown matches the canonical JSON dependency graph
- Task count, layer count, and execution summary are derived from the canonical JSON, not manually maintained
- Every `filesToModify` path exists
- Every `filesToCreate` parent directory exists or is created by an earlier task
- If a `filesToModify` path is created by an earlier task, the later task depends on that earlier task
- Every local reuse reference exists in the repository; if not, mark it `source: external`
- Every end-state claim in the overview traces to concrete tasks and prerequisites
- Every cross-boundary noun in the plan appears in the `Contracts` section
- Every new file/module has an explicit export/registration owner somewhere in the plan
- No task's `writeScope` hides required shared wiring edits (package root, module index, export barrel, router, registry, manifest, startup hook)
- Every side-effectful method/API claim names its capability source (owned field, injected trait, callback, parameter, or runtime hook)
- Every user-visible capability has at least one public-surface validation task or acceptance criterion
- Every public surface task pins the exact signature/examples from the spec/docs
- Every rewrite/composition task has at least one acceptance criterion proving existing semantics were not silently dropped
- No task is allowed to "pass" by tests that bless placeholder behavior as the intended outcome
- Every task has a concrete `validateCommand` or an explicit manual-validation reason
- If the architecture diagram is not task-complete, label it clearly as component-level only
- No vague phrases remain without semantics: examples include "internal update", "eventually skipped", "initialized", "graceful degradation", "reasonable performance"

If any check fails, regenerate the plan sections from the canonical structure instead of patching partial text by hand.

---

### Format Reference

| Item | Correct Value |
|------|---------------|
| Priority values | `P0`, `P1`, `P2`, `P3` (regex: `/\b(P[0-3])\b/`) |
| Task ID format | `TASK-001`, `TASK-002`, ... (regex: `/\b(TASK-\d{3,})\b/`) |
| Depends pattern | `**Depends on:** TASK-001, TASK-002` (regex: `/depends on:|requires:|after:|blocked by:/i`) |
| Priority default | P2 when missing — always specify explicitly |
| Type values | `feature`, `bug`, `chore`, `refactor`, `test`, `docs`, `infra` |
| Effort values | `S`, `M`, `L`, `XL` |
| Task heading level | `###` (level 3) — minimum heading level 2 |
| Disk format | No `[PLAN]`/`[/PLAN]` markers — those are for in-conversation display only |
| Dependency JSON | `## Task Dependencies` section with fenced JSON block — every task ID must be a key |

### Additional Optional Fields

These fields are supported when present:

- **`**Type:**`** — `feature | bug | chore | refactor | test | docs | infra` (auto-inferred from heading/body if missing)
- **`**Effort:**`** — `S | M | L | XL`
- **`**Labels:**`** — comma-separated tags
- **`**Agent:**`** — subagent type to execute this task (REQUIRED — see Agent Table)
- **`**Review:**`** — post-task review tool: `claude`, `codex`, `kiro`, or `none` (see Post-Task Review below)

---

## Post-Task Review

Every task can specify a `**Review:**` field that triggers an independent code review after the task agent completes. This catches bugs before they propagate to dependent tasks.

### Review Tools

| Value | Skill | What it does |
|-------|-------|-------------|
| `claude` | `/claude-review` | Spawns a separate Claude agent in a worktree to review the changes |
| `codex` | `/codex-review` | Runs OpenAI Codex CLI (`codex review`) against the task's commit |
| `kiro` | `/kiro-review` | Runs Kiro CLI (`kiro-cli chat`) with the diff |
| `none` | — | Skip review (use for trivial tasks like config/docs) |

### When to Assign Which Reviewer

- **Security-sensitive tasks** (auth, crypto, secrets, permissions): `codex` — independent AI catches things Claude might miss
- **Complex logic tasks** (parsers, state machines, concurrency): `claude` — deep context understanding
- **API/integration tasks**: `kiro` — alternative perspective
- **Trivial tasks** (rename, config change, docs): `none`
- **Critical P0 tasks**: consider running multiple reviewers in sequence

### How the Executor Uses This Field

The `run-parallel-agents-feature-build` skill (or manual execution) should:

1. Run the task agent
2. Check the `review` field
3. If not `none`, invoke the corresponding review skill on the task's commit using `Skill("codex-review")`, `Skill("claude-review")`, or `Skill("kiro-review")`
4. Report findings to the user
5. Fix findings before marking the task complete

**IMPORTANT:** The `review` field is a binding instruction to the executor, not a suggestion. When `run-parallel-agents-feature-build` processes this plan, it MUST invoke the specified tool via the `Skill` tool — not approximate it with a general-purpose agent prompt. If the review tool binary is not installed, the executor should warn the user rather than silently substituting.

### Default

If `**Review:**` is omitted, default to `none` for S-effort tasks, `claude` for M/L/XL-effort tasks.

## Quality Self-Check

Before outputting the final plan, verify ALL of the following:

- [ ] Phase 0 was completed — user confirmed scope, selected mode, and chose review tool via AskUserQuestion
- [ ] Mode (EXPANSION/HOLD/REDUCTION) is recorded in plan header and JSON
- [ ] `## Scope Challenge` section documents what was considered and ruled out
- [ ] `## Prerequisites`, `## Non-Goals`, and `## Contracts` are present and reflect the exploration findings
- [ ] `## Architecture` section has an ASCII diagram with TASK-NNN labels
- [ ] `## Existing Code Leverage` table maps sub-problems to reuse decisions
- [ ] Local vs external reuse is distinguished correctly
- [ ] All task IDs are sequential (`TASK-001`, `TASK-002`, ...)
- [ ] All task IDs appear as keys in the `## Task Dependencies` JSON block
- [ ] No circular dependencies exist in the dependency graph
- [ ] Every task has 2-3 testable acceptance criteria (at least 1 failure/edge case)
- [ ] Every public surface task pins the exact signature/examples from spec/docs and includes a wrong-shape or wrong-routing check
- [ ] Every rewrite/composition task includes at least 1 "absence of regression" acceptance criterion
- [ ] Every task references specific file paths found during exploration
- [ ] Every task has `writeScope` and `validateCommand`
- [ ] Every new file/module is reachable via an explicit export/registration owner in the plan
- [ ] Shared integration surfaces (package roots, module index files, export barrels, routers, registries, manifests, startup hooks) have expl

…(truncated)
