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.
- package/LICENSE +21 -0
- package/command/gsd/add-phase.md +3 -3
- package/command/gsd/add-todo.md +182 -0
- package/command/gsd/check-todos.md +217 -0
- package/command/gsd/complete-milestone.md +4 -3
- package/command/gsd/consider-issues.md +5 -5
- package/command/gsd/create-roadmap.md +4 -4
- package/command/gsd/debug.md +58 -0
- package/command/gsd/discuss-phase.md +3 -4
- package/command/gsd/execute-phase.md +137 -0
- package/command/gsd/execute-plan.md +70 -95
- package/command/gsd/help.md +83 -6
- package/command/gsd/insert-phase.md +16 -16
- package/command/gsd/list-phase-assumptions.md +8 -8
- package/command/gsd/map-codebase.md +11 -11
- package/command/gsd/new-milestone.md +1 -1
- package/command/gsd/new-project.md +26 -7
- package/command/gsd/pause-work.md +4 -3
- package/command/gsd/plan-fix.md +8 -8
- package/command/gsd/plan-phase.md +9 -9
- package/command/gsd/progress.md +20 -11
- package/command/gsd/remove-phase.md +15 -15
- package/command/gsd/research-phase.md +10 -10
- package/command/gsd/resume-work.md +4 -5
- package/command/gsd/status.md +127 -0
- package/command/gsd/verify-work.md +8 -8
- package/get-shit-done/references/continuation-format.md +8 -8
- package/get-shit-done/references/debugging/debugging-mindset.md +253 -0
- package/get-shit-done/references/debugging/hypothesis-testing.md +373 -0
- package/get-shit-done/references/debugging/investigation-techniques.md +337 -0
- package/get-shit-done/references/debugging/verification-patterns.md +425 -0
- package/get-shit-done/references/debugging/when-to-research.md +361 -0
- package/get-shit-done/references/plan-format.md +68 -21
- package/get-shit-done/references/questioning.md +12 -12
- package/get-shit-done/references/research-pitfalls.md +2 -2
- package/get-shit-done/references/scope-estimation.md +95 -11
- package/get-shit-done/templates/DEBUG.md +159 -0
- package/get-shit-done/templates/agent-history.md +263 -0
- package/get-shit-done/templates/checkpoint-return.md +204 -0
- package/get-shit-done/templates/codebase/architecture.md +4 -4
- package/get-shit-done/templates/codebase/concerns.md +1 -1
- package/get-shit-done/templates/codebase/structure.md +11 -11
- package/get-shit-done/templates/config.json +8 -0
- package/get-shit-done/templates/context.md +0 -21
- package/get-shit-done/templates/continuation-prompt.md +235 -0
- package/get-shit-done/templates/milestone-archive.md +1 -1
- package/get-shit-done/templates/phase-prompt.md +289 -129
- package/get-shit-done/templates/roadmap.md +1 -1
- package/get-shit-done/templates/state.md +11 -0
- package/get-shit-done/templates/subagent-task-prompt.md +95 -0
- package/get-shit-done/templates/summary.md +2 -2
- package/get-shit-done/workflows/_archive/execute-phase.md +899 -0
- package/get-shit-done/workflows/complete-milestone.md +1 -1
- package/get-shit-done/workflows/create-milestone.md +1 -1
- package/get-shit-done/workflows/create-roadmap.md +2 -2
- package/get-shit-done/workflows/debug.md +426 -0
- package/get-shit-done/workflows/discovery-phase.md +1 -1
- package/get-shit-done/workflows/discuss-milestone.md +6 -6
- package/get-shit-done/workflows/discuss-phase.md +12 -22
- package/get-shit-done/workflows/execute-phase.md +272 -1504
- package/get-shit-done/workflows/execute-plan.md +1813 -0
- package/get-shit-done/workflows/map-codebase.md +9 -9
- package/get-shit-done/workflows/plan-phase.md +262 -49
- package/get-shit-done/workflows/resume-project.md +28 -2
- package/get-shit-done/workflows/transition.md +4 -4
- package/get-shit-done/workflows/verify-work.md +4 -4
- 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>
|