# Command: create-plans Generate execution plans via action-planning-agent. Produces IMPL_PLAN.md, .task/IMPL-*.json, and TODO_LIST.md — the same artifact format as workflow-plan skill. ## Purpose Transform phase context into structured task JSONs and implementation plan. Delegates to action-planning-agent for document generation. Produces artifacts compatible with workflow-plan's output format, enabling reuse of executor and verifier logic. ## When to Use - Phase 3 of planner execution (after research, before self-validation) - Called once per PLAN-* task ## Strategy Delegate to action-planning-agent with phase context (context.md + roadmap phase section). The agent produces task JSONs with convergence criteria (replacing the old must_haves concept), dependency graph (replacing wave numbering), and implementation steps. ## Parameters | Parameter | Source | Description | |-----------|--------|-------------| | `sessionFolder` | From PLAN-* task description | Session artifact directory | | `phaseNumber` | From PLAN-* task description | Phase number (1-based) | ## Output Artifact Mapping (vs old plan-NN.md) | Old (plan-NN.md) | New (IMPL-*.json) | Notes | |-------------------|--------------------|-------| | `plan: NN` | `id: "IMPL-N"` | Task identifier | | `wave: N` | `depends_on: [...]` | Dependency graph replaces explicit waves | | `files_modified: [...]` | `files: [{path, action, change}]` | Structured file list | | `requirements: [REQ-IDs]` | `description` + `scope` | Requirements embedded in description | | `must_haves.truths` | `convergence.criteria` | Observable behaviors → measurable criteria | | `must_haves.artifacts` | `files` + `convergence.verification` | File checks in verification command | | `must_haves.key_links` | `convergence.verification` | Import wiring in verification command | | Plan body (implementation steps) | `implementation: [...]` | Step-by-step actions | ## Execution Steps ### Step 1: Load Phase Context ```javascript const context = Read(`${sessionFolder}/phase-${phaseNumber}/context.md`) const roadmap = Read(`${sessionFolder}/roadmap.md`) const config = JSON.parse(Read(`${sessionFolder}/config.json`)) // Extract phase section from roadmap const phaseGoal = extractPhaseGoal(roadmap, phaseNumber) const requirements = extractRequirements(roadmap, phaseNumber) const successCriteria = extractSuccessCriteria(roadmap, phaseNumber) // Check for gap closure context const isGapClosure = context.includes("Gap Closure Context") // Load prior phase summaries for cross-phase context const priorSummaries = [] for (let p = 1; p < phaseNumber; p++) { try { const summaryFiles = Glob(`${sessionFolder}/phase-${p}/summary-*.md`) for (const sf of summaryFiles) { priorSummaries.push(Read(sf)) } } catch {} } ``` ### Step 2: Prepare Output Directories ```javascript Bash(`mkdir -p "${sessionFolder}/phase-${phaseNumber}/.task"`) ``` ### Step 3: Delegate to action-planning-agent ```javascript const taskDir = `${sessionFolder}/phase-${phaseNumber}/.task` const implPlanPath = `${sessionFolder}/phase-${phaseNumber}/IMPL_PLAN.md` const todoListPath = `${sessionFolder}/phase-${phaseNumber}/TODO_LIST.md` Task({ subagent_type: "action-planning-agent", run_in_background: false, description: `Generate phase ${phaseNumber} planning documents`, prompt: ` ## TASK OBJECTIVE Generate implementation planning documents (IMPL_PLAN.md, task JSONs, TODO_LIST.md) for roadmap-dev session phase ${phaseNumber}. IMPORTANT: This is PLANNING ONLY - generate planning documents, NOT implementing code. ## PHASE CONTEXT ${context} ## ROADMAP PHASE ${phaseNumber} Goal: ${phaseGoal} Requirements: ${requirements.map(r => `- ${r.id}: ${r.desc}`).join('\n')} Success Criteria: ${successCriteria.map(c => `- ${c}`).join('\n')} ${isGapClosure ? `## GAP CLOSURE This is a gap closure iteration. Only address gaps listed in context — do NOT re-plan completed work. Existing task JSONs in ${taskDir} represent prior work. Create gap-specific tasks starting from next available ID.` : ''} ${priorSummaries.length > 0 ? `## PRIOR PHASE CONTEXT ${priorSummaries.join('\n\n---\n\n')}` : ''} ## SESSION PATHS Output: - Task Dir: ${taskDir} - IMPL_PLAN: ${implPlanPath} - TODO_LIST: ${todoListPath} ## CONTEXT METADATA Session: ${sessionFolder} Phase: ${phaseNumber} Depth: ${config.depth || 'standard'} ## USER CONFIGURATION Execution Method: agent Preferred CLI Tool: gemini ## EXPECTED DELIVERABLES 1. Task JSON Files (${taskDir}/IMPL-*.json) - Unified flat schema (task-schema.json) - Quantified requirements with explicit counts - focus_paths from context.md relevant files - convergence criteria derived from success criteria (goal-backward) 2. Implementation Plan (${implPlanPath}) - Phase goal and context - Task breakdown and execution strategy - Dependency graph 3. TODO List (${todoListPath}) - Flat structure with [ ] for pending - Links to task JSONs ## TASK ID FORMAT Use: IMPL-{phaseNumber}{seq} (e.g., IMPL-101, IMPL-102 for phase 1) ## CONVERGENCE CRITERIA RULES (replacing old must_haves) Each task MUST include convergence: - criteria: Measurable conditions derived from success criteria (goal-backward, not task-forward) - Include file existence checks - Include export/symbol presence checks - Include test passage checks where applicable - verification: Executable command to verify criteria - definition_of_done: Business-language completion definition ## CLI EXECUTION ID FORMAT Each task: cli_execution.id = "RD-${sessionFolder.split('/').pop()}-{task_id}" ## QUALITY STANDARDS - Task count <= 10 per phase (hard limit) - All requirements quantified - Acceptance criteria measurable - Dependencies form a valid DAG (no cycles) ` }) ``` ### Step 4: Validate Generated Artifacts ```javascript // 4a. Verify task JSONs were created const taskFiles = Glob(`${taskDir}/IMPL-*.json`) if (!taskFiles || taskFiles.length === 0) { mcp__ccw-tools__team_msg({ operation: "log", team: "roadmap-dev", from: "planner", to: "coordinator", type: "error", summary: `[planner] action-planning-agent produced no task JSONs for phase ${phaseNumber}` }) return } // 4b. Validate each task JSON for (const taskFile of taskFiles) { const taskJson = JSON.parse(Read(taskFile)) // Required fields check const requiredFields = ['id', 'title', 'description', 'files', 'implementation', 'convergence'] for (const field of requiredFields) { if (!taskJson[field]) { mcp__ccw-tools__team_msg({ operation: "log", team: "roadmap-dev", from: "planner", to: "coordinator", type: "plan_progress", summary: `[planner] Warning: ${taskFile} missing field: ${field}` }) } } // Convergence criteria check if (!taskJson.convergence?.criteria || taskJson.convergence.criteria.length === 0) { mcp__ccw-tools__team_msg({ operation: "log", team: "roadmap-dev", from: "planner", to: "coordinator", type: "plan_progress", summary: `[planner] Warning: ${taskFile} has no convergence criteria` }) } // Dependency cycle check (simple: task cannot depend on itself) if (taskJson.depends_on?.includes(taskJson.id)) { mcp__ccw-tools__team_msg({ operation: "log", team: "roadmap-dev", from: "planner", to: "coordinator", type: "error", summary: `[planner] Self-dependency detected in ${taskJson.id}` }) } } // 4c. Validate dependency DAG (no cycles) const allTasks = taskFiles.map(f => JSON.parse(Read(f))) const taskIds = new Set(allTasks.map(t => t.id)) // Check all depends_on references are valid for (const task of allTasks) { for (const dep of (task.depends_on || [])) { if (!taskIds.has(dep)) { mcp__ccw-tools__team_msg({ operation: "log", team: "roadmap-dev", from: "planner", to: "coordinator", type: "plan_progress", summary: `[planner] Warning: ${task.id} depends on unknown task ${dep}` }) } } } // 4d. Verify IMPL_PLAN.md exists const implPlanExists = Bash(`test -f "${implPlanPath}" && echo "EXISTS" || echo "NOT_FOUND"`).trim() if (implPlanExists === "NOT_FOUND") { mcp__ccw-tools__team_msg({ operation: "log", team: "roadmap-dev", from: "planner", to: "coordinator", type: "plan_progress", summary: `[planner] Warning: IMPL_PLAN.md not generated, creating minimal version` }) // Create minimal IMPL_PLAN.md from task JSONs generateMinimalImplPlan(allTasks, implPlanPath, phaseGoal, phaseNumber) } ``` ### Step 5: Compute Wave Structure (for reporting) ```javascript // Derive wave structure from dependency graph (for reporting only — executor uses depends_on directly) function computeWaves(tasks) { const waves = {} const assigned = new Set() let currentWave = 1 while (assigned.size < tasks.length) { const waveMembers = tasks.filter(t => !assigned.has(t.id) && (t.depends_on || []).every(d => assigned.has(d)) ) if (waveMembers.length === 0 && assigned.size < tasks.length) { const unassigned = tasks.find(t => !assigned.has(t.id)) waveMembers.push(unassigned) } for (const task of waveMembers) { waves[task.id] = currentWave assigned.add(task.id) } currentWave++ } return { waves, totalWaves: currentWave - 1 } } const { waves, totalWaves } = computeWaves(allTasks) ``` ### Step 6: Report Plan Structure ```javascript const taskCount = allTasks.length mcp__ccw-tools__team_msg({ operation: "log", team: "roadmap-dev", from: "planner", to: "coordinator", type: "plan_progress", summary: `[planner] Created ${taskCount} tasks across ${totalWaves} waves for phase ${phaseNumber}`, ref: `${sessionFolder}/phase-${phaseNumber}/` }) return { taskCount, totalWaves, waves, taskFiles, implPlanPath, todoListPath } ``` ## Gap Closure Plans When creating plans for gap closure (re-planning after verification found gaps): ```javascript if (isGapClosure) { // 1. Existing IMPL-*.json files represent completed work // 2. action-planning-agent receives gap context and creates gap-specific tasks // 3. New task IDs start from next available (e.g., IMPL-103 if 101,102 exist) // 4. convergence criteria should directly address gap descriptions from verification.md // 5. Gap tasks may depend on existing completed tasks } ``` ## Helper: Minimal IMPL_PLAN.md Generation ```javascript function generateMinimalImplPlan(tasks, outputPath, phaseGoal, phaseNumber) { const content = `# Implementation Plan: Phase ${phaseNumber} ## Goal ${phaseGoal} ## Tasks ${tasks.map(t => `### ${t.id}: ${t.title} ${t.description} **Files**: ${(t.files || []).map(f => f.path).join(', ')} **Depends on**: ${(t.depends_on || []).join(', ') || 'None'} **Convergence Criteria**: ${(t.convergence?.criteria || []).map(c => `- ${c}`).join('\n')} `).join('\n---\n\n')} ## Dependency Graph ${'```'} ${tasks.map(t => `${t.id} → [${(t.depends_on || []).join(', ')}]`).join('\n')} ${'```'} ` Write(outputPath, content) } ``` ## Error Handling | Scenario | Resolution | |----------|------------| | context.md not found | Error — research phase was skipped or failed | | action-planning-agent fails | Retry once. If still fails, error to coordinator | | No task JSONs generated | Error to coordinator — agent may have misunderstood input | | Dependency cycle detected | Log warning, break cycle at lowest-numbered task | | Too many tasks (>10) | Log warning — agent should self-limit but validate | | Missing convergence criteria | Log warning — every task should have at least one criterion | | IMPL_PLAN.md not generated | Create minimal version from task JSONs |