gsd-opencode 1.3.33 → 1.4.2

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.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/command/gsd/add-phase.md +3 -3
  3. package/command/gsd/add-todo.md +182 -0
  4. package/command/gsd/check-todos.md +217 -0
  5. package/command/gsd/complete-milestone.md +4 -3
  6. package/command/gsd/consider-issues.md +5 -5
  7. package/command/gsd/create-roadmap.md +4 -4
  8. package/command/gsd/debug.md +58 -0
  9. package/command/gsd/discuss-phase.md +3 -4
  10. package/command/gsd/execute-phase.md +137 -0
  11. package/command/gsd/execute-plan.md +70 -95
  12. package/command/gsd/help.md +83 -6
  13. package/command/gsd/insert-phase.md +16 -16
  14. package/command/gsd/list-phase-assumptions.md +8 -8
  15. package/command/gsd/map-codebase.md +11 -11
  16. package/command/gsd/new-milestone.md +1 -1
  17. package/command/gsd/new-project.md +26 -7
  18. package/command/gsd/pause-work.md +4 -3
  19. package/command/gsd/plan-fix.md +8 -8
  20. package/command/gsd/plan-phase.md +9 -9
  21. package/command/gsd/progress.md +20 -11
  22. package/command/gsd/remove-phase.md +15 -15
  23. package/command/gsd/research-phase.md +10 -10
  24. package/command/gsd/resume-work.md +4 -5
  25. package/command/gsd/status.md +127 -0
  26. package/command/gsd/verify-work.md +8 -8
  27. package/get-shit-done/references/continuation-format.md +8 -8
  28. package/get-shit-done/references/debugging/debugging-mindset.md +253 -0
  29. package/get-shit-done/references/debugging/hypothesis-testing.md +373 -0
  30. package/get-shit-done/references/debugging/investigation-techniques.md +337 -0
  31. package/get-shit-done/references/debugging/verification-patterns.md +425 -0
  32. package/get-shit-done/references/debugging/when-to-research.md +361 -0
  33. package/get-shit-done/references/plan-format.md +68 -21
  34. package/get-shit-done/references/questioning.md +12 -12
  35. package/get-shit-done/references/research-pitfalls.md +2 -2
  36. package/get-shit-done/references/scope-estimation.md +95 -11
  37. package/get-shit-done/templates/DEBUG.md +159 -0
  38. package/get-shit-done/templates/agent-history.md +263 -0
  39. package/get-shit-done/templates/checkpoint-return.md +204 -0
  40. package/get-shit-done/templates/codebase/architecture.md +4 -4
  41. package/get-shit-done/templates/codebase/concerns.md +1 -1
  42. package/get-shit-done/templates/codebase/structure.md +11 -11
  43. package/get-shit-done/templates/config.json +8 -0
  44. package/get-shit-done/templates/context.md +0 -21
  45. package/get-shit-done/templates/continuation-prompt.md +235 -0
  46. package/get-shit-done/templates/milestone-archive.md +1 -1
  47. package/get-shit-done/templates/phase-prompt.md +289 -129
  48. package/get-shit-done/templates/roadmap.md +1 -1
  49. package/get-shit-done/templates/state.md +11 -0
  50. package/get-shit-done/templates/subagent-task-prompt.md +95 -0
  51. package/get-shit-done/templates/summary.md +2 -2
  52. package/get-shit-done/workflows/_archive/execute-phase.md +899 -0
  53. package/get-shit-done/workflows/complete-milestone.md +1 -1
  54. package/get-shit-done/workflows/create-milestone.md +1 -1
  55. package/get-shit-done/workflows/create-roadmap.md +2 -2
  56. package/get-shit-done/workflows/debug.md +426 -0
  57. package/get-shit-done/workflows/discovery-phase.md +1 -1
  58. package/get-shit-done/workflows/discuss-milestone.md +6 -6
  59. package/get-shit-done/workflows/discuss-phase.md +12 -22
  60. package/get-shit-done/workflows/execute-phase.md +272 -1504
  61. package/get-shit-done/workflows/execute-plan.md +1813 -0
  62. package/get-shit-done/workflows/map-codebase.md +9 -9
  63. package/get-shit-done/workflows/plan-phase.md +262 -49
  64. package/get-shit-done/workflows/resume-project.md +28 -2
  65. package/get-shit-done/workflows/transition.md +4 -4
  66. package/get-shit-done/workflows/verify-work.md +4 -4
  67. package/package.json +1 -1
@@ -0,0 +1,899 @@
1
+ <purpose>
2
+ Execute all plans in a phase with intelligent parallelization.
3
+ Analyzes plan dependencies to identify independent plans that can run in parallel.
4
+
5
+ **Critical constraint:** One subagent per plan, always. This is for context isolation, not parallelization. Even strictly sequential plans spawn separate subagents so each starts with fresh 200k context at 0%. Quality degrades above 50% context - executing multiple plans in one subagent defeats the entire segmentation model.
6
+ </purpose>
7
+
8
+ <when_to_use>
9
+ Use /gsd:execute-phase when:
10
+ - Phase has multiple unexecuted plans (2+)
11
+ - Want "walk away, come back to completed work" execution
12
+ - Plans have clear dependency boundaries
13
+
14
+ Use /gsd:execute-plan when:
15
+ - Executing a single specific plan
16
+ - Want sequential, interactive execution
17
+ - Need checkpoint interactions
18
+ </when_to_use>
19
+
20
+ <required_reading>
21
+ Read STATE.md before any operation to load project context.
22
+ </required_reading>
23
+
24
+ <process>
25
+
26
+ <step name="load_project_state" priority="first">
27
+ Before any operation, read project state:
28
+
29
+ ```bash
30
+ cat .planning/STATE.md 2>/dev/null
31
+ ```
32
+
33
+ **If file exists:** Parse and internalize:
34
+
35
+ - Current position (phase, plan, status)
36
+ - Accumulated decisions (constraints on this execution)
37
+ - Deferred issues (context for deviations)
38
+ - Blockers/concerns (things to watch for)
39
+
40
+ **If file missing but .planning/ exists:**
41
+
42
+ ```
43
+ STATE.md missing but planning artifacts exist.
44
+ Options:
45
+ 1. Reconstruct from existing artifacts
46
+ 2. Continue without project state (may lose accumulated context)
47
+ ```
48
+
49
+ **If .planning/ doesn't exist:** Error - project not initialized.
50
+ </step>
51
+
52
+ <step name="identify_phase">
53
+ **Identify the phase to execute from argument or roadmap.**
54
+
55
+ **1. Parse phase argument:**
56
+ ```bash
57
+ # From command argument: /gsd:execute-phase 10
58
+ # Or: /gsd:execute-phase .planning/phases/10-parallel-execution/
59
+ PHASE_ARG="$1"
60
+ ```
61
+
62
+ **2. Find phase directory:**
63
+ ```bash
64
+ # If numeric: find matching directory
65
+ if [[ "$PHASE_ARG" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
66
+ PHASE_DIR=$(ls -d .planning/phases/${PHASE_ARG}-* 2>/dev/null | head -1)
67
+ else
68
+ PHASE_DIR="$PHASE_ARG"
69
+ fi
70
+
71
+ # Verify exists
72
+ if [ ! -d "$PHASE_DIR" ]; then
73
+ echo "Error: Phase directory not found: $PHASE_DIR"
74
+ exit 1
75
+ fi
76
+ ```
77
+
78
+ **3. List all PLAN.md files:**
79
+ ```bash
80
+ PLANS=($(ls "$PHASE_DIR"/*-PLAN.md 2>/dev/null | sort))
81
+ echo "Found ${#PLANS[@]} plans in phase"
82
+ ```
83
+
84
+ **4. Identify unexecuted plans:**
85
+ ```bash
86
+ UNEXECUTED=()
87
+ for plan in "${PLANS[@]}"; do
88
+ summary="${plan//-PLAN.md/-SUMMARY.md}"
89
+ if [ ! -f "$summary" ]; then
90
+ UNEXECUTED+=("$plan")
91
+ fi
92
+ done
93
+ echo "Unexecuted: ${#UNEXECUTED[@]} plans"
94
+ ```
95
+
96
+ **5. Check if parallelization is appropriate:**
97
+
98
+ | Condition | Action |
99
+ |-----------|--------|
100
+ | 0 unexecuted plans | "All plans complete. Nothing to execute." |
101
+ | 1 unexecuted plan | "Single plan - use /gsd:execute-plan instead" |
102
+ | 2+ unexecuted plans | Proceed to dependency analysis |
103
+
104
+ </step>
105
+
106
+ <step name="analyze_plan_dependencies">
107
+ **Analyze plan dependencies to determine parallelization.**
108
+
109
+ **1. Find all unexecuted plans:**
110
+
111
+ ```bash
112
+ UNEXECUTED=()
113
+ for plan in .planning/phases/${PHASE}-*/*-PLAN.md; do
114
+ summary="${plan//-PLAN.md/-SUMMARY.md}"
115
+ [ ! -f "$summary" ] && UNEXECUTED+=("$plan")
116
+ done
117
+ echo "Found ${#UNEXECUTED[@]} unexecuted plans"
118
+ ```
119
+
120
+ **2. For each plan, extract dependency info:**
121
+
122
+ ```bash
123
+ # Initialize associative arrays for tracking
124
+ declare -A PLAN_REQUIRES # plan -> required plans (from depends_on or inferred)
125
+ declare -A PLAN_FILES # plan -> files modified
126
+ declare -A PLAN_CHECKPOINTS # plan -> has checkpoints
127
+
128
+ for plan in "${UNEXECUTED[@]}"; do
129
+ plan_id=$(basename "$plan" -PLAN.md)
130
+
131
+ # Check for depends_on frontmatter
132
+ DEPENDS_ON=$(awk '/^---$/,/^---$/' "$plan" | grep "^depends_on:" | sed 's/depends_on: \[//' | sed 's/\]//' | tr -d ' "')
133
+
134
+ # Check for files_modified frontmatter
135
+ FILES_MODIFIED=$(awk '/^---$/,/^---$/' "$plan" | grep "^files_modified:" | sed 's/files_modified: \[//' | sed 's/\]//' | tr -d ' "')
136
+
137
+ # Use frontmatter if present
138
+ if [ -n "$DEPENDS_ON" ]; then
139
+ PLAN_REQUIRES["$plan_id"]="$DEPENDS_ON"
140
+ else
141
+ # Fall back to inference from old frontmatter format
142
+ REQUIRES=$(awk '/^---$/,/^---$/' "$plan" | grep -E "^\s*-\s*phase:" | grep -oP '\d+' | tr '\n' ',')
143
+ PLAN_REQUIRES["$plan_id"]="${REQUIRES%,}"
144
+
145
+ # Check for SUMMARY references in @context (implies dependency)
146
+ SUMMARY_REFS=$(grep -oP '@[^@]*\d+-\d+-SUMMARY\.md' "$plan" | grep -oP '\d+-\d+' | tr '\n' ',')
147
+ if [ -n "$SUMMARY_REFS" ]; then
148
+ PLAN_REQUIRES["$plan_id"]="${PLAN_REQUIRES[$plan_id]},${SUMMARY_REFS%,}"
149
+ fi
150
+ fi
151
+
152
+ # Use files_modified frontmatter if present, else extract from <files> elements
153
+ if [ -n "$FILES_MODIFIED" ]; then
154
+ PLAN_FILES["$plan_id"]="$FILES_MODIFIED"
155
+ else
156
+ FILES=$(grep -oP '(?<=<files>)[^<]+(?=</files>)' "$plan" | tr '\n' ',' | tr -d ' ')
157
+ PLAN_FILES["$plan_id"]="${FILES%,}"
158
+ fi
159
+
160
+ # Check for checkpoint tasks
161
+ if grep -q 'type="checkpoint' "$plan"; then
162
+ PLAN_CHECKPOINTS["$plan_id"]="true"
163
+ else
164
+ PLAN_CHECKPOINTS["$plan_id"]="false"
165
+ fi
166
+ done
167
+ ```
168
+
169
+ **Dependency detection:**
170
+
171
+ 1. **If `depends_on` frontmatter exists:** Use it directly
172
+ 2. **If no frontmatter:** Fall back to inference:
173
+ - Parse `requires` from old frontmatter format
174
+ - Check for SUMMARY references in @context
175
+ 3. **File conflicts:** Detected separately in step 4
176
+
177
+ **3. Build dependency graph:**
178
+
179
+ For each plan, determine:
180
+ - `requires`: Prior phases/plans this depends on
181
+ - `files_modified`: Files from `<files>` elements
182
+ - `has_checkpoints`: Contains checkpoint tasks
183
+
184
+ ```
185
+ Example dependency graph:
186
+ ┌─────────┬───────────────────────┬─────────────────────────────┬──────────────┐
187
+ │ Plan │ Requires │ Files Modified │ Checkpoints │
188
+ ├─────────┼───────────────────────┼─────────────────────────────┼──────────────┤
189
+ │ 10-01 │ [] │ [workflows/execute-plan.md] │ false │
190
+ │ 10-02 │ [10-01] │ [workflows/execute-phase.md]│ false │
191
+ │ 10-03 │ [10-02] │ [commands/execute-phase.md] │ false │
192
+ │ 10-04 │ [] │ [templates/agent-history.md]│ false │
193
+ └─────────┴───────────────────────┴─────────────────────────────┴──────────────┘
194
+ ```
195
+
196
+ **4. Detect file conflicts:**
197
+
198
+ ```bash
199
+ # Build file-to-plan mapping
200
+ declare -A FILE_TO_PLANS
201
+
202
+ for plan_id in "${!PLAN_FILES[@]}"; do
203
+ IFS=',' read -ra files <<< "${PLAN_FILES[$plan_id]}"
204
+ for file in "${files[@]}"; do
205
+ [ -n "$file" ] && FILE_TO_PLANS["$file"]="${FILE_TO_PLANS[$file]},$plan_id"
206
+ done
207
+ done
208
+
209
+ # Detect conflicts (same file modified by multiple plans)
210
+ declare -A CONFLICTS
211
+ for file in "${!FILE_TO_PLANS[@]}"; do
212
+ plans="${FILE_TO_PLANS[$file]}"
213
+ plan_count=$(echo "$plans" | tr ',' '\n' | grep -c .)
214
+ if [ "$plan_count" -gt 1 ]; then
215
+ CONFLICTS["$file"]="${plans#,}"
216
+ fi
217
+ done
218
+
219
+ # Add conflict dependencies (later plan depends on earlier)
220
+ for file in "${!CONFLICTS[@]}"; do
221
+ IFS=',' read -ra conflict_plans <<< "${CONFLICTS[$file]}"
222
+ for ((i=1; i<${#conflict_plans[@]}; i++)); do
223
+ # Each plan depends on previous one in conflict set
224
+ prev="${conflict_plans[$((i-1))]}"
225
+ curr="${conflict_plans[$i]}"
226
+ PLAN_REQUIRES["$curr"]="${PLAN_REQUIRES[$curr]},${prev}"
227
+ done
228
+ done
229
+ ```
230
+
231
+ **File conflict rules:**
232
+ - If Plan A and Plan B both modify same file → B depends on A (ordered by plan number)
233
+ - If Plan B reads file created by Plan A → B depends on A
234
+ - If Plan B references Plan A's SUMMARY in @context → B depends on A
235
+
236
+ **5. Categorize plans:**
237
+
238
+ | Category | Criteria | Action |
239
+ |----------|----------|--------|
240
+ | independent | Empty `depends_on` AND no file conflicts | Can run in parallel (Wave 1) |
241
+ | dependent | Has `depends_on` OR file conflicts with earlier plan | Wait for dependency |
242
+ | has_checkpoints | Contains checkpoint tasks | Foreground or skip checkpoints |
243
+
244
+ **6. Build execution waves (topological sort):**
245
+
246
+ ```bash
247
+ # Calculate wave for each plan
248
+ declare -A PLAN_WAVE
249
+
250
+ calculate_wave() {
251
+ local plan="$1"
252
+ [ -n "${PLAN_WAVE[$plan]}" ] && echo "${PLAN_WAVE[$plan]}" && return
253
+
254
+ local max_dep_wave=0
255
+
256
+ # Check depends_on (from frontmatter or inferred)
257
+ if [ -n "${PLAN_REQUIRES[$plan]}" ]; then
258
+ IFS=',' read -ra dep_array <<< "${PLAN_REQUIRES[$plan]}"
259
+ for dep in "${dep_array[@]}"; do
260
+ [ -z "$dep" ] && continue
261
+ # Only consider deps in current phase (unexecuted)
262
+ if [[ " ${!PLAN_FILES[*]} " =~ " $dep " ]]; then
263
+ dep_wave=$(calculate_wave "$dep")
264
+ [ "$dep_wave" -gt "$max_dep_wave" ] && max_dep_wave="$dep_wave"
265
+ fi
266
+ done
267
+ fi
268
+
269
+ PLAN_WAVE[$plan]=$((max_dep_wave + 1))
270
+ echo "${PLAN_WAVE[$plan]}"
271
+ }
272
+
273
+ # Calculate waves for all plans
274
+ for plan_id in "${!PLAN_FILES[@]}"; do
275
+ calculate_wave "$plan_id" > /dev/null
276
+ done
277
+
278
+ # Group by wave
279
+ declare -A WAVES
280
+ for plan_id in "${!PLAN_WAVE[@]}"; do
281
+ wave="${PLAN_WAVE[$plan_id]}"
282
+ WAVES[$wave]="${WAVES[$wave]} $plan_id"
283
+ done
284
+
285
+ # Output wave structure
286
+ echo "Execution waves:"
287
+ for wave in $(echo "${!WAVES[@]}" | tr ' ' '\n' | sort -n); do
288
+ plans="${WAVES[$wave]}"
289
+ checkpoint_note=""
290
+ frontmatter_note=""
291
+ for p in $plans; do
292
+ [ "${PLAN_CHECKPOINTS[$p]}" = "true" ] && checkpoint_note=" (has checkpoints)"
293
+ [ "${PLAN_HAS_FRONTMATTER[$p]}" = "true" ] && frontmatter_note=" [frontmatter]"
294
+ done
295
+ echo " Wave $wave:$plans$checkpoint_note$frontmatter_note"
296
+ done
297
+ ```
298
+
299
+ **Example output:**
300
+ ```
301
+ Execution waves:
302
+ Wave 1: 10-01 10-04
303
+ Wave 2: 10-02
304
+ Wave 3: 10-03
305
+ ```
306
+
307
+ **7. Handle checkpoints in parallel context:**
308
+
309
+ Plans with checkpoints require special handling:
310
+ - `checkpoint_handling: "foreground"` → Run in main context (not parallel)
311
+ - `checkpoint_handling: "skip"` → Skip checkpoints during parallel (not recommended)
312
+
313
+ ```bash
314
+ # Separate checkpoint plans
315
+ PARALLEL_PLANS=()
316
+ FOREGROUND_PLANS=()
317
+
318
+ for plan_id in "${!PLAN_CHECKPOINTS[@]}"; do
319
+ if [ "${PLAN_CHECKPOINTS[$plan_id]}" = "true" ]; then
320
+ FOREGROUND_PLANS+=("$plan_id")
321
+ else
322
+ PARALLEL_PLANS+=("$plan_id")
323
+ fi
324
+ done
325
+
326
+ if [ ${#FOREGROUND_PLANS[@]} -gt 0 ]; then
327
+ echo "Plans requiring foreground execution: ${FOREGROUND_PLANS[*]}"
328
+ fi
329
+ ```
330
+
331
+ **8. Safety rule:**
332
+ If dependency detection is uncertain (e.g., complex file patterns, unclear requires), default to sequential execution within that wave.
333
+ </step>
334
+
335
+ <step name="parallelization_config">
336
+ **Read parallelization configuration.**
337
+
338
+ ```bash
339
+ cat .planning/config.json 2>/dev/null
340
+ ```
341
+
342
+ **Config schema (parallelization section):**
343
+
344
+ ```json
345
+ {
346
+ "parallelization": {
347
+ "enabled": true,
348
+ "max_concurrent_agents": 3,
349
+ "checkpoint_handling": "foreground",
350
+ "commit_strategy": "orchestrator"
351
+ }
352
+ }
353
+ ```
354
+
355
+ **Config options:**
356
+
357
+ | Option | Values | Default | Description |
358
+ |--------|--------|---------|-------------|
359
+ | enabled | true/false | true | Enable parallel execution |
360
+ | max_concurrent_agents | 1-5 | 3 | Max simultaneous background agents |
361
+ | checkpoint_handling | "foreground"/"skip" | "foreground" | How to handle plans with checkpoints |
362
+ | commit_strategy | "orchestrator"/"agent" | "orchestrator" | Who commits changes |
363
+
364
+ **If parallelization.enabled is false:**
365
+ - Fall back to sequential execution
366
+ - Use /gsd:execute-plan for each plan in order
367
+
368
+ **Checkpoint handling modes:**
369
+ - `foreground`: Plans with checkpoints run in foreground (not parallel)
370
+ - `skip`: Skip checkpoints during parallel execution (not recommended)
371
+
372
+ **Commit strategy:**
373
+ - `orchestrator`: Agents don't commit. Orchestrator collects all changes and commits.
374
+ - `agent`: Each agent commits its own changes (may cause conflicts)
375
+ </step>
376
+
377
+ <step name="spawn_parallel_agents">
378
+ **Spawn independent plans as parallel background agents.**
379
+
380
+ **1. Record pre-spawn git state:**
381
+ ```bash
382
+ PRE_SPAWN_COMMIT=$(git rev-parse HEAD)
383
+ echo "All agents start from commit: $PRE_SPAWN_COMMIT"
384
+ ```
385
+
386
+ **2. Generate parallel group ID:**
387
+ ```bash
388
+ PARALLEL_GROUP="pg-$(date +%Y%m%d%H%M%S)-$(openssl rand -hex 4)"
389
+ ```
390
+
391
+ **3. Initialize tracking:**
392
+ ```bash
393
+ # Ensure agent-history.json exists
394
+ if [ ! -f .planning/agent-history.json ]; then
395
+ echo '{"version":"1.2","max_entries":50,"entries":[]}' > .planning/agent-history.json
396
+ fi
397
+
398
+ # Initialize tracking arrays
399
+ declare -a RUNNING_AGENTS=()
400
+ declare -a QUEUED_PLANS=()
401
+ declare -A AGENT_TO_PLAN=()
402
+ ```
403
+
404
+ **4. Spawn Wave 1 plans (no dependencies):**
405
+
406
+ ```
407
+ For each plan in Wave 1:
408
+ # Check concurrent agent limit
409
+ if len(RUNNING_AGENTS) >= max_concurrent_agents:
410
+ QUEUED_PLANS.append(plan)
411
+ continue
412
+
413
+ # Use Task tool to spawn background agent
414
+ Task(
415
+ description="Execute {plan_id} (parallel)",
416
+ prompt="[Agent prompt below]",
417
+ subagent_type="general",
418
+ run_in_background=true
419
+ )
420
+
421
+ # After Task returns, capture agent_id
422
+ RUNNING_AGENTS.append(agent_id)
423
+ AGENT_TO_PLAN[agent_id] = plan_id
424
+
425
+ # Record to agent-history.json
426
+ add_entry_to_history(...)
427
+ ```
428
+
429
+ **Agent spawn prompt (for plans WITHOUT checkpoints):**
430
+
431
+ ```xml
432
+ <parallel_agent_instructions>
433
+ You are executing plan: {plan_path} as part of a PARALLEL phase execution.
434
+
435
+ <critical_rules>
436
+ 1. Execute ALL tasks in the plan following deviation rules from execute-plan.md
437
+ 2. Commit each task atomically (standard task_commit protocol)
438
+ 3. Create SUMMARY.md in the phase directory when complete
439
+ 4. Report files modified and commit hashes when done
440
+ </critical_rules>
441
+
442
+ <plan_context>
443
+ @{plan_path}
444
+ Read the plan for full context, tasks, and deviation rules.
445
+ </plan_context>
446
+
447
+ <execution_protocol>
448
+ 1. Read plan file and context files
449
+ 2. Execute each task in order
450
+ 3. For each task:
451
+ - Implement the action
452
+ - Run verification
453
+ - Track files modified
454
+ - Track any deviations
455
+ 4. After all tasks: create SUMMARY.md
456
+ </execution_protocol>
457
+
458
+ <report_format>
459
+ When complete, output this exact format:
460
+
461
+ PARALLEL_AGENT_COMPLETE
462
+ plan_id: {phase}-{plan}
463
+ tasks_completed: [count]/[total]
464
+ task_commits:
465
+ - task_1: abc123f
466
+ - task_2: def456g
467
+ files_modified:
468
+ - path/to/file1.ts
469
+ - path/to/file2.md
470
+ deviations:
471
+ - [Rule X] description
472
+ summary_path: .planning/phases/{phase-dir}/{phase}-{plan}-SUMMARY.md
473
+ issues: [none or list]
474
+ END_REPORT
475
+ </report_format>
476
+
477
+ <forbidden_actions>
478
+ - git push (orchestrator may push after all complete)
479
+ - Modifying files outside plan scope
480
+ - Running long-blocking network operations
481
+ </forbidden_actions>
482
+ </parallel_agent_instructions>
483
+ ```
484
+
485
+ **5. Record spawn in agent-history.json:**
486
+
487
+ ```bash
488
+ # Read current entries
489
+ ENTRIES=$(jq '.entries' .planning/agent-history.json)
490
+
491
+ # Create new entry
492
+ NEW_ENTRY=$(cat <<EOF
493
+ {
494
+ "agent_id": "$AGENT_ID",
495
+ "task_description": "Parallel: Execute ${PHASE}-${PLAN}-PLAN.md",
496
+ "phase": "$PHASE",
497
+ "plan": "$PLAN",
498
+ "parallel_group": "$PARALLEL_GROUP",
499
+ "granularity": "plan",
500
+ "wave": $WAVE_NUM,
501
+ "depends_on": $(echo "${PLAN_REQUIRES[$PLAN]}" | jq -R 'split(",") | map(select(. != ""))'),
502
+ "timestamp": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
503
+ "status": "spawned",
504
+ "files_modified": [],
505
+ "completion_timestamp": null,
506
+ "deviations": []
507
+ }
508
+ EOF
509
+ )
510
+
511
+ # Append and write back
512
+ echo "$ENTRIES" | jq ". += [$NEW_ENTRY]" > /tmp/entries.json
513
+ jq --argjson entries "$(cat /tmp/entries.json)" '.entries = $entries' .planning/agent-history.json > /tmp/history.json
514
+ mv /tmp/history.json .planning/agent-history.json
515
+ ```
516
+
517
+ **6. Queue remaining plans:**
518
+
519
+ ```bash
520
+ # Queue Wave 2+ plans
521
+ for wave in $(seq 2 $MAX_WAVE); do
522
+ for plan in ${WAVES[$wave]}; do
523
+ QUEUED_PLANS+=("$plan:$wave")
524
+ done
525
+ done
526
+
527
+ echo "Spawned: ${#RUNNING_AGENTS[@]} agents"
528
+ echo "Queued: ${#QUEUED_PLANS[@]} plans"
529
+ ```
530
+ </step>
531
+
532
+ <step name="monitor_parallel_completion">
533
+ **Poll for agent completion and spawn dependents.**
534
+
535
+ **1. Polling loop implementation:**
536
+
537
+ ```
538
+ declare -A COMPLETED_AGENTS=()
539
+ declare -A FAILED_AGENTS=()
540
+
541
+ while [ ${#RUNNING_AGENTS[@]} -gt 0 ] || [ ${#QUEUED_PLANS[@]} -gt 0 ]; do
542
+
543
+ # Check each running agent
544
+ for agent_id in "${RUNNING_AGENTS[@]}"; do
545
+
546
+ # Use TaskOutput to check status (non-blocking)
547
+ TaskOutput(
548
+ task_id=agent_id,
549
+ block=false,
550
+ timeout=5000
551
+ )
552
+
553
+ if result.status == "completed":
554
+ # Parse agent's completion report
555
+ files_modified = parse_report_files(result.output)
556
+ deviations = parse_report_deviations(result.output)
557
+ plan_id = AGENT_TO_PLAN[agent_id]
558
+
559
+ # Update agent-history.json
560
+ update_history_entry(
561
+ agent_id,
562
+ status="completed",
563
+ files_modified=files_modified,
564
+ deviations=deviations,
565
+ completion_timestamp=now()
566
+ )
567
+
568
+ # Track completion
569
+ COMPLETED_AGENTS[agent_id] = plan_id
570
+ RUNNING_AGENTS.remove(agent_id)
571
+
572
+ echo "✓ Agent $agent_id completed plan $plan_id"
573
+ echo " Files: ${#files_modified[@]}"
574
+ echo " Deviations: ${#deviations[@]}"
575
+
576
+ # Check if dependents can now spawn
577
+ check_and_spawn_dependents()
578
+
579
+ elif result.status == "failed":
580
+ plan_id = AGENT_TO_PLAN[agent_id]
581
+
582
+ # Log failure
583
+ update_history_entry(
584
+ agent_id,
585
+ status="failed",
586
+ error=result.error,
587
+ completion_timestamp=now()
588
+ )
589
+
590
+ FAILED_AGENTS[agent_id] = plan_id
591
+ RUNNING_AGENTS.remove(agent_id)
592
+
593
+ echo "✗ Agent $agent_id FAILED on plan $plan_id"
594
+ echo " Error: ${result.error}"
595
+
596
+ # Continue monitoring - don't abort batch
597
+
598
+ # else: still running, check next agent
599
+ done
600
+
601
+ # Brief pause between polls
602
+ sleep 10
603
+
604
+ done
605
+ ```
606
+
607
+ **2. Parse agent completion report:**
608
+
609
+ ```bash
610
+ parse_report_files() {
611
+ local output="$1"
612
+ # Extract files from PARALLEL_AGENT_COMPLETE block
613
+ echo "$output" | \
614
+ sed -n '/^files_modified:/,/^[a-z_]*:/p' | \
615
+ grep '^\s*-' | \
616
+ sed 's/^\s*-\s*//'
617
+ }
618
+
619
+ parse_report_deviations() {
620
+ local output="$1"
621
+ echo "$output" | \
622
+ sed -n '/^deviations:/,/^[a-z_]*:/p' | \
623
+ grep '^\s*-' | \
624
+ sed 's/^\s*-\s*//'
625
+ }
626
+ ```
627
+
628
+ **3. Spawn ready dependents:**
629
+
630
+ ```bash
631
+ check_and_spawn_dependents() {
632
+ # Get completed plan IDs
633
+ local completed_plans=$(printf '%s\n' "${COMPLETED_AGENTS[@]}")
634
+
635
+ for i in "${!QUEUED_PLANS[@]}"; do
636
+ local queued="${QUEUED_PLANS[$i]}"
637
+ local plan_id="${queued%%:*}"
638
+ local wave="${queued##*:}"
639
+
640
+ # Get this plan's dependencies
641
+ local deps="${PLAN_REQUIRES[$plan_id]}"
642
+
643
+ # Check if all dependencies are in completed list
644
+ local all_deps_met=true
645
+ IFS=',' read -ra dep_array <<< "$deps"
646
+ for dep in "${dep_array[@]}"; do
647
+ [ -z "$dep" ] && continue
648
+ if ! echo "$completed_plans" | grep -q "^$dep$"; then
649
+ all_deps_met=false
650
+ break
651
+ fi
652
+ done
653
+
654
+ if [ "$all_deps_met" = true ]; then
655
+ # Check concurrent limit
656
+ if [ ${#RUNNING_AGENTS[@]} -lt $MAX_CONCURRENT ]; then
657
+ # Remove from queue
658
+ unset 'QUEUED_PLANS[$i]'
659
+
660
+ # Spawn agent
661
+ spawn_plan_agent "$plan_id" "$wave"
662
+
663
+ echo "→ Spawned dependent: $plan_id (wave $wave)"
664
+ fi
665
+ fi
666
+ done
667
+
668
+ # Rebuild array to remove gaps
669
+ QUEUED_PLANS=("${QUEUED_PLANS[@]}")
670
+ }
671
+ ```
672
+
673
+ **4. Handle failures:**
674
+
675
+ | Failure Type | Action |
676
+ |--------------|--------|
677
+ | Agent crash | Log status="failed", continue batch |
678
+ | Plan error | Same as crash - logged, batch continues |
679
+ | All dependents | Plans depending on failed agent also fail |
680
+
681
+ ```bash
682
+ # When agent fails, mark its dependents as blocked
683
+ mark_dependents_blocked() {
684
+ local failed_plan="$1"
685
+
686
+ for i in "${!QUEUED_PLANS[@]}"; do
687
+ local queued="${QUEUED_PLANS[$i]}"
688
+ local plan_id="${queued%%:*}"
689
+ local deps="${PLAN_REQUIRES[$plan_id]}"
690
+
691
+ if echo "$deps" | grep -q "$failed_plan"; then
692
+ echo "⚠ Plan $plan_id blocked (depends on failed $failed_plan)"
693
+ # Mark in history as blocked
694
+ update_history_entry("queued-$plan_id", status="blocked", blocked_by="$failed_plan")
695
+ fi
696
+ done
697
+ }
698
+ ```
699
+
700
+ **5. Completion conditions:**
701
+
702
+ ```
703
+ while true:
704
+ if RUNNING_AGENTS is empty AND QUEUED_PLANS is empty:
705
+ break # All done
706
+
707
+ if RUNNING_AGENTS is empty AND QUEUED_PLANS is not empty:
708
+ # All queued plans are blocked by failed dependencies
709
+ echo "All remaining plans blocked by failures"
710
+ break
711
+
712
+ poll_and_check()
713
+ ```
714
+
715
+ **6. Progress display:**
716
+
717
+ ```
718
+ During execution, show:
719
+
720
+ ═══════════════════════════════════════════════════
721
+ Parallel Execution Status
722
+ ═══════════════════════════════════════════════════
723
+ Running: [agent-1: 10-01] [agent-2: 10-04]
724
+ Queued: 10-02, 10-03
725
+ Complete: 0
726
+ Failed: 0
727
+ ═══════════════════════════════════════════════════
728
+
729
+ [Update periodically as agents complete]
730
+ ```
731
+ </step>
732
+
733
+ <step name="orchestrator_commit">
734
+ **Commit metadata after all agents complete.**
735
+
736
+ Agents commit their own task code (per-task atomic commits). The orchestrator only commits metadata.
737
+
738
+ **1. Verify all agents committed successfully:**
739
+ ```bash
740
+ # Check git log for expected commits from each agent
741
+ for agent in $(jq -r ".entries[] | select(.parallel_group==\"$PARALLEL_GROUP\" and .status==\"completed\") | .agent_id" .planning/agent-history.json); do
742
+ PLAN=$(jq -r ".entries[] | select(.agent_id==\"$agent\") | .plan" .planning/agent-history.json)
743
+ # Verify commits exist for this plan
744
+ git log --oneline --grep="(${PHASE}-${PLAN}):" | head -5
745
+ done
746
+ ```
747
+
748
+ **2. Stage and commit metadata:**
749
+ ```bash
750
+ # Stage all SUMMARY.md files created by agents
751
+ git add .planning/phases/${PHASE_DIR}/*-SUMMARY.md
752
+
753
+ # Stage STATE.md and ROADMAP.md
754
+ git add .planning/STATE.md
755
+ git add .planning/ROADMAP.md
756
+
757
+ # Commit metadata
758
+ git commit -m "docs(${PHASE}): complete phase via parallel execution
759
+
760
+ Plans executed: ${#COMPLETED[@]}
761
+ Parallel group: $PARALLEL_GROUP
762
+
763
+ Agents:
764
+ $(for a in "${COMPLETED[@]}"; do echo "- $a"; done)"
765
+ ```
766
+
767
+ **3. Generate timing stats:**
768
+ ```bash
769
+ START_TIME=$(jq -r ".entries[] | select(.parallel_group==\"$PARALLEL_GROUP\") | .timestamp" .planning/agent-history.json | sort | head -1)
770
+ END_TIME=$(jq -r ".entries[] | select(.parallel_group==\"$PARALLEL_GROUP\") | .completion_timestamp" .planning/agent-history.json | sort -r | head -1)
771
+
772
+ echo "Parallel execution stats:"
773
+ echo "- Plans executed: ${#COMPLETED[@]}"
774
+ echo "- Wall clock time: $(time_diff $START_TIME $END_TIME)"
775
+ echo "- Sequential estimate: $(sum of individual plan durations)"
776
+ echo "- Time saved: ~X%"
777
+ ```
778
+
779
+ **Note on merge conflicts:**
780
+ Since agents commit independently, git will catch conflicts at commit time if they occur.
781
+ The dependency analysis step should prevent this, but if an agent fails to commit due to conflict:
782
+ - That agent's status will be "failed"
783
+ - Other agents continue normally
784
+ - User can resolve and retry the failed plan with /gsd:execute-plan
785
+ </step>
786
+
787
+ <step name="create_phase_summary">
788
+ **Aggregate results into phase-level summary.**
789
+
790
+ After all plans complete, create a phase summary that aggregates:
791
+
792
+ **1. Collect individual SUMMARY.md files:**
793
+ ```bash
794
+ SUMMARIES=($(ls "$PHASE_DIR"/*-SUMMARY.md | sort))
795
+ ```
796
+
797
+ **2. Update STATE.md:**
798
+ - Update Current Position
799
+ - Add any decisions from individual summaries
800
+ - Update session continuity
801
+
802
+ **3. Update ROADMAP.md:**
803
+ - Mark phase as complete
804
+ - Add completion date
805
+ - Update progress table
806
+
807
+ **4. Report completion:**
808
+ ```
809
+ ═══════════════════════════════════════════════════
810
+ Phase {X}: {Phase Name} Complete (Parallel Execution)
811
+ ═══════════════════════════════════════════════════
812
+
813
+ Plans executed: {N}
814
+ - {phase}-01: [name] - {duration}
815
+ - {phase}-02: [name] - {duration}
816
+ - {phase}-03: [name] - {duration}
817
+
818
+ Execution mode: Parallel ({max_concurrent} agents)
819
+ Wall clock time: {total_duration}
820
+ Estimated sequential time: {sum_of_durations}
821
+ Time saved: ~{percent}%
822
+
823
+ Files modified: {total_count}
824
+ Commits created: {commit_count}
825
+ ```
826
+ </step>
827
+
828
+ <step name="offer_next">
829
+ **Present next steps after phase completion.**
830
+
831
+ Read ROADMAP.md to determine milestone status.
832
+
833
+ **If more phases remain in milestone:**
834
+ ```
835
+ ## ✓ Phase {X}: {Phase Name} Complete
836
+
837
+ All {N} plans finished via parallel execution.
838
+
839
+ ---
840
+
841
+ ## ▶ Next Up
842
+
843
+ **Phase {X+1}: {Next Phase Name}** — {Goal from ROADMAP.md}
844
+
845
+ `/gsd:plan-phase {X+1}`
846
+
847
+ *`/clear` first → fresh context window*
848
+
849
+ ---
850
+
851
+ **Also available:**
852
+ - `/gsd:verify-work {X}` — manual acceptance testing
853
+ - `/gsd:discuss-phase {X+1}` — gather context first
854
+ ```
855
+
856
+ **If milestone complete:**
857
+ ```
858
+ 🎉 MILESTONE COMPLETE!
859
+
860
+ All {N} phases finished.
861
+
862
+ `/gsd:complete-milestone`
863
+ ```
864
+ </step>
865
+
866
+ </process>
867
+
868
+ <error_handling>
869
+
870
+ **Agent failure during parallel execution:**
871
+ - Log failure but continue with other agents
872
+ - Failed plans can be retried individually with /gsd:execute-plan
873
+ - Do not automatically retry (may cause cascade failures)
874
+
875
+ **Merge conflict detected:**
876
+ - Stop orchestrator_commit
877
+ - Present conflicting files to user
878
+ - Options:
879
+ 1. Manual resolution
880
+ 2. Re-run sequential with /gsd:execute-plan
881
+
882
+ **Max concurrent limit reached:**
883
+ - Queue excess plans
884
+ - Spawn as agents complete
885
+ - First-in-first-out ordering within each wave
886
+
887
+ **Config.json missing:**
888
+ - Use defaults: enabled=true, max_concurrent=3, orchestrator commits
889
+
890
+ </error_handling>
891
+
892
+ <success_criteria>
893
+ - All plans in phase executed
894
+ - All agents completed (no failures)
895
+ - Commits created for all plans
896
+ - STATE.md updated
897
+ - ROADMAP.md updated
898
+ - No merge conflicts
899
+ </success_criteria>