sdd-pipeline 1.2.4 → 1.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,17 +1,28 @@
1
1
  param(
2
2
  [string]$Url = "http://localhost:3000",
3
3
  [switch]$Strict,
4
+ [switch]$SkipUrlCheck, # Skip URL/dev server checks (for static files)
4
5
  [string]$ProjectDomain = "general",
5
6
  [string]$TaskDir = "",
7
+ [string]$TaskId = "",
6
8
  [string]$SpecFile = ""
7
9
  )
8
10
 
11
+ # Import shared functions (inline - file may not exist)
12
+ $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
13
+ $sharedPath = Join-Path $scriptDir "lib/shared-converge.ps1"
14
+ if (Test-Path $sharedPath) {
15
+ . $sharedPath
16
+ }
17
+
9
18
  $ErrorActionPreference = "Continue"
10
19
  $overallPass = $true
20
+ $script:issuesFound = @()
11
21
 
12
22
  # ============================================================
13
23
  # SDD Path Resolution
14
24
  # ============================================================
25
+ # Check config for output directory
15
26
  $SDD_OUTPUT_BASE = "sdd"
16
27
  $SDD_CONVERGE_DIR = "sdd/converge"
17
28
  $SDD_SPEC_FILE = "sdd/SPEC.md"
@@ -32,7 +43,7 @@ if (Test-Path ".sdd/config.json") {
32
43
  # Legacy file fallback
33
44
  if (-not $SpecFile) {
34
45
  if (Test-Path "SPEC.md") { $SpecFile = "SPEC.md" }
35
- elseif (Test-Path $SDD_SPEC_FILE) { $SpecFile = $SDD_SPEC_FILE }
46
+ elseif (Test-Path "$SDD_SPEC_FILE") { $SpecFile = $SDD_SPEC_FILE }
36
47
  else { $SpecFile = $SDD_SPEC_FILE }
37
48
  }
38
49
 
@@ -41,6 +52,7 @@ if (-not (Test-Path $SDD_CONVERGE_DIR)) {
41
52
  New-Item -ItemType Directory -Path $SDD_CONVERGE_DIR -Force | Out-Null
42
53
  }
43
54
 
55
+ # Helper Functions
44
56
  function Test-UrlSafe {
45
57
  param([string]$Url)
46
58
  $parsed = [System.Uri]::new($Url)
@@ -71,7 +83,7 @@ function Wait-ForDevServer {
71
83
  try {
72
84
  $response = Invoke-WebRequest -Uri $Url -Method Get -TimeoutSec 5 -UseBasicParsing
73
85
  if ($response.StatusCode -eq 200 -or $response.StatusCode -eq 301 -or $response.StatusCode -eq 302) {
74
- Write-Host "[OK] Dev server ready at $Url" -ForegroundColor Green
86
+ Write-Host "[PASS] Dev server ready at $Url" -ForegroundColor Green
75
87
  return $true
76
88
  }
77
89
  } catch {
@@ -79,49 +91,271 @@ function Wait-ForDevServer {
79
91
  }
80
92
  Start-Sleep -Seconds $RetryIntervalSeconds
81
93
  }
82
- Write-Host "[ERROR] Dev server failed to start within $TimeoutSeconds seconds" -ForegroundColor Red
94
+ Write-Host "[FAIL] Dev server failed to start within $TimeoutSeconds seconds" -ForegroundColor Red
83
95
  return $false
84
96
  }
85
97
 
86
98
  function Update-SddConfig {
87
99
  param([string]$Phase, [string]$Status)
88
100
  if (Test-Path ".sdd/config.json") {
89
- $config = Get-Content ".sdd/config.json" -Raw | ConvertFrom-Json
90
- $config.phases.($Phase).status = $Status
91
- if ($Status -eq "completed") {
92
- $config.phases.($Phase).completedAt = (Get-Date -Format "yyyy-MM-dd")
101
+ try {
102
+ $config = Get-Content ".sdd/config.json" -Raw | ConvertFrom-Json
103
+ if ($config.phases -and $config.phases.($Phase)) {
104
+ $config.phases.($Phase).status = $Status
105
+ if ($Status -eq "completed" -and $config.phases.($Phase).PSObject.Properties.Name -contains "completedAt") {
106
+ $config.phases.($Phase).completedAt = (Get-Date -Format "yyyy-MM-dd")
107
+ }
108
+ }
109
+ $config | ConvertTo-Json -Depth 10 | Set-Content ".sdd/config.json"
110
+ } catch {
111
+ Write-Host "[WARN] Could not update .sdd/config.json: $_" -ForegroundColor Yellow
93
112
  }
94
- $config | ConvertTo-Json -Depth 10 | Set-Content ".sdd/config.json"
95
113
  }
96
114
  }
97
115
 
98
- Write-Host "=== SDD Converge Validation ===" -ForegroundColor Cyan
99
- Write-Host "Output: $SDD_OUTPUT_BASE/" -ForegroundColor Gray
100
- Write-Host "Domain: $ProjectDomain"
116
+ # Get-SpecClauses - Extract clause IDs from SPEC.md
117
+ function Get-SpecClauses {
118
+ param([string]$File)
119
+ $clauses = @()
120
+ if (Test-Path $File) {
121
+ $content = Get-Content $File -Raw
122
+ # Match [SC-xxx], [AC-xxx], [FE-xxx] patterns
123
+ $pattern = '\[([A-Z]{2,3}-\d{3,4})\]'
124
+ $matches = [regex]::Matches($content, $pattern)
125
+ foreach ($m in $matches) {
126
+ $id = $m.Groups[1].Value
127
+ if ($clauses -notcontains $id) {
128
+ $clauses += $id
129
+ }
130
+ }
131
+ }
132
+ return $clauses
133
+ }
134
+
135
+ # Test-ClauseMatch - Check if clause is in implementation
136
+ function Test-ClauseMatch {
137
+ param([string]$ClauseId, [string]$ClauseText, [string]$ClauseType, [string[]]$Files)
138
+ foreach ($file in $Files) {
139
+ if (Test-Path $file) {
140
+ $content = Get-Content $file -Raw
141
+ if ($content -match [regex]::Escape($ClauseText)) {
142
+ return @{ Found = $true; Location = $file }
143
+ }
144
+ }
145
+ }
146
+ return @{ Found = $false; Location = "Not found" }
147
+ }
148
+
149
+ # Get-TaskFiles - Find files associated with a task
150
+ function Get-TaskFiles {
151
+ param([string]$TaskId, [string]$TaskDir)
152
+ $files = @()
153
+ $taskFile = Get-ChildItem -Path $TaskDir -Filter "${TaskId}-*.md" -ErrorAction SilentlyContinue | Where-Object { $_.Name -ne "MASTER-TASKS.md" }
154
+ if ($taskFile) {
155
+ $content = Get-Content $taskFile.FullName -Raw
156
+ # Extract file names from "## Files to Modify" section
157
+ if ($content -match '(?s)## Files to (?:Modify|Create)\s*\n((?:- .+\n?)+)') {
158
+ $filesBlock = $matches[1]
159
+ $fileMatches = [regex]::Matches($filesBlock, '-\s+`([^`]+)`')
160
+ foreach ($fm in $fileMatches) {
161
+ $files += $fm.Groups[1].Value
162
+ }
163
+ }
164
+ }
165
+ return $files
166
+ }
167
+
168
+ # Main Execution
169
+ Write-Host ""
170
+ Write-Host "========================================" -ForegroundColor Cyan
171
+ Write-Host " SDD Converge Validation" -ForegroundColor Cyan
172
+ Write-Host "========================================" -ForegroundColor Cyan
173
+ Write-Host ""
174
+ Write-Host " Domain: $ProjectDomain" -ForegroundColor Gray
175
+ if ($TaskId) {
176
+ Write-Host " Task: $TaskId" -ForegroundColor Gray
177
+ }
178
+ Write-Host ""
179
+
180
+ # Per-Task Mode
181
+ if ($TaskId) {
182
+ Write-Host "[INFO] Running per-task converge for $TaskId" -ForegroundColor Cyan
183
+
184
+ # Find task files
185
+ $implFiles = Get-TaskFiles -TaskId $TaskId -TaskDir $TaskDir
186
+ if ($implFiles.Count -eq 0) {
187
+ Write-Host "[WARN] Could not find implementation files for $TaskId" -ForegroundColor Yellow
188
+ } else {
189
+ Write-Host "[INFO] Implementation files: $($implFiles.Count)" -ForegroundColor Cyan
190
+ foreach ($f in $implFiles) {
191
+ Write-Host " -> $f" -ForegroundColor Gray
192
+ }
193
+ }
194
+
195
+ # Check SPEC
196
+ if (-not (Test-Path $SpecFile)) {
197
+ Write-Host "[FAIL] SPEC not found: $SpecFile" -ForegroundColor Red
198
+ $overallPass = $false
199
+ } else {
200
+ Write-Host "[PASS] SPEC file found: $SpecFile" -ForegroundColor Green
201
+
202
+ # Extract and verify clauses
203
+ $clauses = Get-SpecClauses -File $SpecFile
204
+ Write-Host "[INFO] Found $($clauses.Count) clause IDs in SPEC" -ForegroundColor Cyan
205
+
206
+ if ($clauses.Count -gt 0) {
207
+ Write-Host ""
208
+ Write-Host "--- Clause Validation ---" -ForegroundColor Magenta
209
+
210
+ $passCount = 0
211
+ $failCount = 0
212
+
213
+ foreach ($clause in $clauses) {
214
+ $result = Test-ClauseMatch -ClauseId $clause.Id -ClauseText $clause.Text -ClauseType $clause.Type -Files $implFiles
215
+
216
+ if ($result.Found) {
217
+ $passCount++
218
+ Write-Host "[PASS] $($clause.Id)" -ForegroundColor Green
219
+ } else {
220
+ $failCount++
221
+ Write-Host "[FAIL] $($clause.Id)" -ForegroundColor Red
222
+ $script:issuesFound += @{
223
+ Clause = $clause.Id
224
+ Issue = "Not found in implementation"
225
+ Location = $result.Location
226
+ }
227
+ }
228
+ }
229
+
230
+ Write-Host ""
231
+ Write-Host " Clauses Passed: $passCount" -ForegroundColor Green
232
+ Write-Host " Clauses Failed: $failCount" -ForegroundColor $(if ($failCount -gt 0) { "Red" } else { "Green" })
233
+
234
+ if ($failCount -gt 0) {
235
+ $overallPass = $false
236
+ }
237
+ }
238
+ }
239
+
240
+ # Generate task converge report in sdd/converge/
241
+ $reportDir = "$SDD_CONVERGE_DIR/task-$TaskId"
242
+ if (-not (Test-Path $reportDir)) {
243
+ New-Item -ItemType Directory -Path $reportDir -Force | Out-Null
244
+ }
245
+
246
+ $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
247
+ $passCount = $clauses.Count - $script:issuesFound.Count
248
+
249
+ $report = @"
250
+ # Converge Report: $TaskId
251
+
252
+ Generated: $timestamp by SDD Converge
253
+
254
+ ## Summary
255
+
256
+ | Metric | Value |
257
+ |--------|-------|
258
+ | Clauses Found | $($clauses.Count) |
259
+ | Clauses Passed | $passCount |
260
+ | Clauses Failed | $($script:issuesFound.Count) |
261
+ | Status | $(if ($script:issuesFound.Count -eq 0) { 'PASS' } else { 'FAIL' }) |
262
+
263
+ ## Clause Results
264
+
265
+ | Clause ID | Type | Status | Location |
266
+ |-----------|------|--------|----------|
267
+ "@
268
+
269
+ foreach ($clause in $clauses) {
270
+ $isFail = $clause.Id -in $script:issuesFound.Clause
271
+ $status = if ($isFail) { "FAIL" } else { "PASS" }
272
+ $location = if ($isFail) {
273
+ ($script:issuesFound | Where-Object { $_.Clause -eq $clause.Id }).Location
274
+ } else {
275
+ "Verified"
276
+ }
277
+ $report += "`n| $($clause.Id) | $($clause.Type) | $status | $location |"
278
+ }
279
+
280
+ $report += @"
281
+
282
+ ## Issues Found
283
+
284
+ | Clause | Issue | Location |
285
+ |--------|-------|----------|
286
+ "@
287
+
288
+ if ($script:issuesFound.Count -eq 0) {
289
+ $report += "`n| - | No issues found | - |"
290
+ } else {
291
+ foreach ($issue in $script:issuesFound) {
292
+ $report += "`n| $($issue.Clause) | $($issue.Issue) | $($issue.Location) |"
293
+ }
294
+ }
295
+
296
+ $report += @"
297
+
298
+ ## Next Steps
299
+
300
+ $(if ($script:issuesFound.Count -eq 0) {
301
+ "- [ ] **PROCEED:** All checks pass -> Move to next task"
302
+ } else {
303
+ "- [ ] **FIX:** Address issues above -> Re-run converge
304
+ - [ ] **IF SPEC ISSUE:** Update SPEC.md clause -> Re-generate task"
305
+ })
306
+
307
+ ---
308
+ Generated by SDD Per-Task Converge
309
+ "@
310
+
311
+ $reportFile = Join-Path $reportDir "report.md"
312
+ $report | Out-File -FilePath $reportFile -Encoding UTF8
313
+ Write-Host ""
314
+ Write-Host "[INFO] Report saved: $reportFile" -ForegroundColor Cyan
315
+
316
+ # Final decision
317
+ Write-Host ""
318
+ if ($overallPass) {
319
+ Write-Host "[PASS] CONVERGE PASSED" -ForegroundColor Green
320
+ Update-SddConfig -Phase "phase5" -Status "completed"
321
+ } else {
322
+ Write-Host "[FAIL] CONVERGE FAILED" -ForegroundColor Red
323
+ if ($Strict) {
324
+ Update-SddConfig -Phase "phase5" -Status "failed"
325
+ }
326
+ }
327
+
328
+ exit $(if ($overallPass -or -not $Strict) { 0 } else { 1 })
329
+ }
330
+
331
+ # Full Project Mode
332
+ Write-Host "[INFO] Running full project converge" -ForegroundColor Cyan
101
333
  Write-Host ""
102
334
 
103
335
  # Check SPEC file
104
336
  if (Test-Path $SpecFile) {
105
- Write-Host "[V] SPEC file found: $SpecFile" -ForegroundColor Green
337
+ Write-Host "[PASS] SPEC file found: $SpecFile" -ForegroundColor Green
106
338
  } else {
107
- Write-Host "[X] SPEC file MISSING: $SpecFile" -ForegroundColor Red
339
+ Write-Host "[FAIL] SPEC file MISSING: $SpecFile" -ForegroundColor Red
108
340
  $overallPass = $false
109
341
  }
110
342
 
111
343
  # Find task directory (check new path first, then legacy)
112
344
  if (-not $TaskDir) {
345
+ # Check new location
113
346
  if (Test-Path $SDD_TASKS_DIR) {
114
347
  $taskDirs = Get-ChildItem -Path $SDD_TASKS_DIR -Filter "task-*-*" -Directory -ErrorAction SilentlyContinue
115
348
  if ($taskDirs) {
116
349
  $TaskDir = Join-Path $SDD_TASKS_DIR ($taskDirs | Select-Object -First 1).Name
117
- Write-Host "[V] Task directory found: $TaskDir" -ForegroundColor Green
350
+ Write-Host "[PASS] Task directory found: $TaskDir" -ForegroundColor Green
118
351
  }
119
352
  }
353
+ # Fallback to legacy location
120
354
  if (-not $TaskDir) {
121
355
  $legacyTaskDirs = Get-ChildItem -Filter "task-*-*" -Directory -ErrorAction SilentlyContinue
122
356
  if ($legacyTaskDirs) {
123
- $TaskDir = ($legacyTaskDirs | Select-Object -First 1).FullName
124
- Write-Host "[V] Task directory found: $TaskDir (legacy)" -ForegroundColor Green
357
+ $TaskDir = ($legacyTaskDirs | Select-Object -First 1).Name
358
+ Write-Host "[PASS] Task directory found: $TaskDir (legacy location)" -ForegroundColor Green
125
359
  }
126
360
  }
127
361
  }
@@ -129,71 +363,83 @@ if (-not $TaskDir) {
129
363
  if ($TaskDir) {
130
364
  $masterTasks = Join-Path $TaskDir "MASTER-TASKS.md"
131
365
  if (Test-Path $masterTasks) {
132
- Write-Host "[V] MASTER-TASKS.md exists" -ForegroundColor Green
366
+ Write-Host "[PASS] $masterTasks exists" -ForegroundColor Green
133
367
  } else {
134
- Write-Host "[X] MASTER-TASKS.md MISSING" -ForegroundColor Red
368
+ Write-Host "[FAIL] $masterTasks MISSING" -ForegroundColor Red
135
369
  $overallPass = $false
136
370
  }
137
371
 
138
372
  Write-Host ""
139
- Write-Host "--- Task Validation ---" -ForegroundColor Cyan
373
+ Write-Host "--- Task Validation ---" -ForegroundColor Magenta
140
374
  $taskFiles = Get-ChildItem -Path $TaskDir -Filter "T-*.md" -ErrorAction SilentlyContinue
141
375
  $taskFiles = $taskFiles | Where-Object { $_.Name -ne "MASTER-TASKS.md" }
142
- Write-Host "Found $($taskFiles.Count) task files" -ForegroundColor Cyan
376
+ Write-Host "[INFO] Found $($taskFiles.Count) task files" -ForegroundColor Cyan
143
377
  foreach ($task in $taskFiles) {
144
- Write-Host "[V] $($task.Name)" -ForegroundColor Green
378
+ Write-Host "[PASS] $($task.Name)" -ForegroundColor Green
145
379
  }
146
380
  } else {
147
- Write-Host "[X] No task directory found" -ForegroundColor Red
148
- $overallPass = $false
381
+ Write-Host "[WARN] No task directory found" -ForegroundColor Yellow
149
382
  }
150
383
 
151
384
  if (-not $overallPass) {
152
385
  Write-Host ""
153
- Write-Host "Converge FAILED: Missing artifacts" -ForegroundColor Red
386
+ Write-Host "[FAIL] Converge FAILED: Missing artifacts" -ForegroundColor Red
154
387
  exit 1
155
388
  }
156
389
 
157
390
  Write-Host ""
158
- Write-Host "--- URL Validation ---" -ForegroundColor Cyan
159
- try {
160
- Test-UrlSafe -Url $Url
161
- Write-Host "[V] URL is safe: $Url" -ForegroundColor Green
162
- } catch {
163
- Write-Host "[X] URL validation failed: $_" -ForegroundColor Red
164
- $overallPass = $false
165
- }
391
+ Write-Host "--- URL Validation ---" -ForegroundColor Magenta
392
+ if ($SkipUrlCheck) {
393
+ Write-Host "[SKIP] URL check skipped (use for static files)" -ForegroundColor Yellow
394
+ } else {
395
+ try {
396
+ Test-UrlSafe -Url $Url
397
+ Write-Host "[PASS] URL is safe: $Url" -ForegroundColor Green
398
+ } catch {
399
+ Write-Host "[FAIL] URL validation failed: $_" -ForegroundColor Red
400
+ $overallPass = $false
401
+ }
166
402
 
167
- Write-Host ""
168
- Write-Host "--- Dev Server Health Check ---" -ForegroundColor Cyan
169
- $serverReady = Wait-ForDevServer -Url $Url -TimeoutSeconds 30
170
- if (-not $serverReady) {
171
- Write-Host "[WARN] Dev server not available -- skipping live checks" -ForegroundColor Yellow
403
+ Write-Host ""
404
+ Write-Host "--- Dev Server Health Check ---" -ForegroundColor Magenta
405
+ $serverReady = Wait-ForDevServer -Url $Url -TimeoutSeconds 30
406
+ if (-not $serverReady) {
407
+ Write-Host "[WARN] Dev server not available -- skipping live checks" -ForegroundColor Yellow
408
+ }
172
409
  }
173
410
 
174
411
  Write-Host ""
175
- Write-Host "--- SPEC.md Validation ---" -ForegroundColor Cyan
412
+ Write-Host "--- SPEC.md Validation ---" -ForegroundColor Magenta
176
413
  if (Test-Path $SpecFile) {
177
414
  $specContent = Get-Content $SpecFile -Raw
178
415
  $requiredSections = @("Overview", "User Stories", "Functional Requirements", "Success Criteria")
179
416
  foreach ($section in $requiredSections) {
180
417
  if ($specContent -match $section) {
181
- Write-Host "[V] SPEC.md has '$section' section" -ForegroundColor Green
418
+ Write-Host "[PASS] SPEC.md has '$section' section" -ForegroundColor Green
182
419
  } else {
183
- Write-Host "[X] SPEC.md missing '$section' section" -ForegroundColor Red
420
+ Write-Host "[FAIL] SPEC.md missing '$section' section" -ForegroundColor Red
184
421
  $overallPass = $false
185
422
  }
186
423
  }
424
+
425
+ # Check for clause IDs
426
+ $clauses = Get-SpecClauses -File $SpecFile
427
+ if ($clauses.Count -gt 0) {
428
+ Write-Host ""
429
+ Write-Host "[INFO] SPEC.md contains $($clauses.Count) clause IDs" -ForegroundColor Cyan
430
+ Write-Host " Run per-task converge for detailed validation" -ForegroundColor Gray
431
+ }
187
432
  }
188
433
 
189
434
  Write-Host ""
435
+ Write-Host "========================================" -ForegroundColor Cyan
190
436
  if ($overallPass) {
191
- Write-Host "=== CONVERGE PASSED ===" -ForegroundColor Green
437
+ Write-Host "[PASS] CONVERGE PASSED" -ForegroundColor Green
192
438
  Update-SddConfig -Phase "phase5" -Status "completed"
193
439
  Update-SddConfig -Phase "phase4" -Status "completed"
194
440
  exit 0
195
441
  } else {
196
- Write-Host "=== CONVERGE FAILED ===" -ForegroundColor Red
442
+ Write-Host "[FAIL] CONVERGE FAILED" -ForegroundColor Red
197
443
  if ($Strict) {
198
444
  Update-SddConfig -Phase "phase5" -Status "failed"
199
445
  exit 1
@@ -0,0 +1,259 @@
1
+ ---
2
+ name: sdd-tasks
3
+ description: "SDD Phase 3 task generation. Read SPEC.md, extract features and testing requirements, generate modular tasks (≤2 hours each) in sdd/tasks/."
4
+ user-invocable: true
5
+ when_to_use: "After /sdd-spec generates SPEC.md. Run /sdd-tasks to break SPEC into tasks."
6
+ category: sdd
7
+ keywords: [sdd, tasks, task-generation, phase3]
8
+ argument-hint: "[--spec SPEC.md] [--output sdd/tasks/]"
9
+ metadata:
10
+ author: xdm-kit
11
+ version: "1.0.0"
12
+ ---
13
+
14
+ # SDD Tasks — Phase 3 Task Generation
15
+
16
+ Generate modular, independently verifiable tasks from SPEC.md.
17
+
18
+ **Reads:** `sdd/SPEC.md`
19
+ **Outputs:** `sdd/tasks/task-{timestamp}-{project}/MASTER-TASKS.md` + `T-XXX-*.md`
20
+
21
+ ---
22
+
23
+ ## Process Flow
24
+
25
+ ```mermaid
26
+ flowchart TD
27
+ A[Read SPEC.md] --> B{SPEC valid?}
28
+ B -->|No| E[ERROR: SPEC not found]
29
+ B -->|Yes| C[Extract Features]
30
+ C --> D[Extract Testing Requirements]
31
+ D --> F[Generate Tasks]
32
+ F --> G[Create Task Directory]
33
+ G --> H[Write MASTER-TASKS.md]
34
+ H --> I[Write T-XXX-*.md files]
35
+ I --> J[Summary]
36
+ ```
37
+
38
+ ---
39
+
40
+ ## Step 1: Prerequisites Check
41
+
42
+ 1. **SPEC.md exists** at `sdd/SPEC.md`
43
+ 2. **SPEC.md has required sections:**
44
+ - Section 4.1 (Core Features)
45
+ - Section 9 (Testing Requirements) - if present
46
+
47
+ If SPEC not found:
48
+ ```
49
+ ERROR: SPEC.md not found.
50
+ Run /sdd-spec first.
51
+ ```
52
+
53
+ ---
54
+
55
+ ## Step 2: Extract Information
56
+
57
+ ### From SPEC.md Section 4.1 (Core Features)
58
+
59
+ Parse each feature block:
60
+ ```
61
+ #### [Feature Name]
62
+
63
+ - **Description:** [What it does]
64
+ - **States:** [List states]
65
+
66
+ **Acceptance criteria:**
67
+ - [AC-XXX] [Criterion]
68
+ ```
69
+
70
+ Extract:
71
+ - Feature name
72
+ - Implementation steps
73
+ - Acceptance criteria
74
+
75
+ ### From SPEC.md Section 9 (Testing Requirements)
76
+
77
+ Parse test categories and specifications:
78
+ ```
79
+ ### 9.1 Test Categories
80
+ | Category | Priority |
81
+ |----------|----------|
82
+ | Unit Tests | MUST |
83
+ | Integration Tests | MUST |
84
+ ```
85
+
86
+ Extract:
87
+ - Test categories (Unit, Integration, E2E, Accessibility)
88
+ - Test specifications from 9.2-9.4
89
+ - Test data from 9.5
90
+
91
+ ### From SPEC.md Section 2 (User Stories)
92
+
93
+ Parse user stories:
94
+ ```
95
+ - **As a** [user], **I want** [action], **so that** [benefit]
96
+ ```
97
+
98
+ Extract:
99
+ - User stories for context
100
+ - Priority (Must Have vs Nice to Have)
101
+
102
+ ---
103
+
104
+ ## Step 3: Generate Tasks
105
+
106
+ ### Task Structure
107
+
108
+ Each task:
109
+ - Takes ≤2 hours
110
+ - Independently verifiable
111
+ - Has frontmatter with dependencies
112
+
113
+ ### Task Categories
114
+
115
+ | Phase | Category | Description |
116
+ |-------|----------|-------------|
117
+ | 1 | Setup | Project initialization, configs |
118
+ | 2-4 | Feature | Core feature implementation |
119
+ | N-3 | Test | Unit, Integration, E2E, Accessibility |
120
+ | N-2 | Polish | Final styling, edge cases |
121
+ | N-1 | Converge | Validation and testing |
122
+ | N | Deploy | Deployment preparation |
123
+
124
+ ### Task File Template
125
+
126
+ ```markdown
127
+ ---
128
+ name: T-XXX-task-name
129
+ description: "[Brief description]"
130
+ phase: N
131
+ estimate: 1h
132
+ spec_sections: ["4.1", "9.1"]
133
+ depends_on: ["T-XXX"]
134
+ ---
135
+
136
+ # T-XXX: Task Name
137
+
138
+ ## Files to Modify/Create
139
+ - [file1]
140
+ - [file2]
141
+
142
+ ## Implementation Steps
143
+
144
+ 1. [Step 1]
145
+ 2. [Step 2]
146
+ 3. [Step 3]
147
+
148
+ ## Verification
149
+
150
+ - [ ] [Check 1]
151
+ - [ ] [Check 2]
152
+ - [ ] [Check 3]
153
+ ```
154
+
155
+ ---
156
+
157
+ ## Step 4: Generate MASTER-TASKS.md
158
+
159
+ ```markdown
160
+ # MASTER-TASKS — {Project Name}
161
+
162
+ ## Task Index
163
+
164
+ | ID | Name | Estimate | Status |
165
+ |----|------|----------|--------|
166
+ | T-001 | Setup | 1h | [ ] |
167
+ | T-002 | Feature A | 1h | [ ] |
168
+ | ... | ... | ... | ... |
169
+ | T-NNN | Final | 1h | [ ] |
170
+
171
+ ## Progress
172
+
173
+ - Completed: 0 / NNN
174
+ - In Progress: 0
175
+ - Pending: NNN
176
+
177
+ ## Dependencies
178
+
179
+ ```
180
+ T-001
181
+ T-002 ──┬── T-004
182
+ T-003 ──┴── T-005 ── T-006
183
+ ```
184
+
185
+ ## Notes
186
+
187
+ Generated from: SPEC.md
188
+ Test categories: {from Section 9.1}
189
+ ```
190
+
191
+ ---
192
+
193
+ ## Step 5: Output Summary
194
+
195
+ ```
196
+ === SDD Tasks Generated ===
197
+
198
+ Project: {name}
199
+ Tasks: NNN
200
+ Test categories: {list}
201
+
202
+ Task directory: sdd/tasks/task-{timestamp}-{project}/
203
+
204
+ Tasks:
205
+ T-001: Setup (1h)
206
+ T-002: Feature A (1h)
207
+ T-003: Feature B (1h)
208
+ T-004: Unit Tests (1h)
209
+ T-005: Integration Tests (1h)
210
+ T-006: Polish (1h)
211
+ T-007: Converge (1h)
212
+
213
+ Next: /sdd-cook --all
214
+ ```
215
+
216
+ ---
217
+
218
+ ## Error Handling
219
+
220
+ | Error | Message | Action |
221
+ |-------|---------|--------|
222
+ | SPEC.md not found | ERROR: SPEC.md not found | Exit 1 |
223
+ | Empty features | WARN: No features found | Generate setup only |
224
+ | Missing test section | INFO: No testing section | Skip test tasks |
225
+ | Directory exists | WARN: Overwriting existing | Confirm or skip |
226
+
227
+ ---
228
+
229
+ ## Testing Requirements Integration
230
+
231
+ Section 9 of SPEC.md defines testing requirements. Generate test tasks:
232
+
233
+ ### Unit Tests Task
234
+ - Parse Section 9.2 for test specifications
235
+ - Create test file templates
236
+ - Include coverage targets
237
+
238
+ ### Integration Tests Task
239
+ - Parse Section 9.3 for flow specifications
240
+ - Map user flows to test scenarios
241
+ - Create Given/When/Then templates
242
+
243
+ ### E2E Tests Task
244
+ - Parse Section 9.4 for scenario specifications
245
+ - Create complete user journey tests
246
+ - Include browser automation
247
+
248
+ ### Accessibility Tests Task
249
+ - Parse accessibility requirements
250
+ - Include WCAG compliance checks
251
+ - Create axe-core/Lighthouse tests
252
+
253
+ ---
254
+
255
+ ## References
256
+
257
+ - `references/task-template.md` - Task file template
258
+ - `references/test-task-template.md` - Test task template
259
+ - `references/task-master-template.md` - MASTER-TASKS template