diff --git a/get-shit-done/workflows/execute-phase.md b/get-shit-done/workflows/execute-phase.md
index 12b127f28..61e4d670f 100644
--- a/get-shit-done/workflows/execute-phase.md
+++ b/get-shit-done/workflows/execute-phase.md
@@ -104,27 +104,52 @@ echo "Unexecuted: ${#UNEXECUTED[@]} plans"
**Analyze plan dependencies to determine parallelization.**
-**1. For each plan, extract dependency info:**
-
-Read each plan file and extract:
-- Frontmatter `requires:` field (explicit dependencies)
-- `` elements (files this plan modifies)
-- References to other plan SUMMARYs in context
+**1. Find all unexecuted plans:**
```bash
+UNEXECUTED=()
+for plan in .planning/phases/${PHASE}-*/*-PLAN.md; do
+ summary="${plan//-PLAN.md/-SUMMARY.md}"
+ [ ! -f "$summary" ] && UNEXECUTED+=("$plan")
+done
+echo "Found ${#UNEXECUTED[@]} unexecuted plans"
+```
+
+**2. For each plan, extract dependency info:**
+
+```bash
+# Initialize associative arrays for tracking
+declare -A PLAN_REQUIRES # plan -> required plans
+declare -A PLAN_FILES # plan -> files modified
+declare -A PLAN_CHECKPOINTS # plan -> has checkpoints
+
for plan in "${UNEXECUTED[@]}"; do
- # Extract frontmatter requires
- REQUIRES=$(grep -A10 "^---" "$plan" | grep "requires:" | cut -d: -f2-)
+ plan_id=$(basename "$plan" -PLAN.md)
- # Extract files from elements
- FILES=$(grep -oP '(?<=).*(?=)' "$plan")
+ # Extract frontmatter requires (handles YAML array syntax)
+ REQUIRES=$(awk '/^---$/,/^---$/' "$plan" | grep -E "^\s*-\s*phase:" | grep -oP '\d+' | tr '\n' ',')
+ PLAN_REQUIRES["$plan_id"]="${REQUIRES%,}"
- # Check for SUMMARY references in context
- SUMMARY_REFS=$(grep -oP '\d+-\d+-SUMMARY\.md' "$plan" || echo "")
+ # Extract files from elements (all occurrences)
+ FILES=$(grep -oP '(?<=)[^<]+(?=)' "$plan" | tr '\n' ',' | tr -d ' ')
+ PLAN_FILES["$plan_id"]="${FILES%,}"
+
+ # Check for SUMMARY references in @context
+ SUMMARY_REFS=$(grep -oP '@[^@]*\d+-\d+-SUMMARY\.md' "$plan" | grep -oP '\d+-\d+' | tr '\n' ',')
+ if [ -n "$SUMMARY_REFS" ]; then
+ PLAN_REQUIRES["$plan_id"]="${PLAN_REQUIRES[$plan_id]},${SUMMARY_REFS%,}"
+ fi
+
+ # Check for checkpoint tasks
+ if grep -q 'type="checkpoint' "$plan"; then
+ PLAN_CHECKPOINTS["$plan_id"]="true"
+ else
+ PLAN_CHECKPOINTS["$plan_id"]="false"
+ fi
done
```
-**2. Build dependency graph:**
+**3. Build dependency graph:**
For each plan, determine:
- `requires`: Prior phases/plans this depends on
@@ -132,23 +157,58 @@ For each plan, determine:
- `has_checkpoints`: Contains checkpoint tasks
```
-Plan dependencies:
-- 10-01: requires=[], files=[workflow/execute-plan.md], checkpoints=false
-- 10-02: requires=[10-01], files=[workflow/execute-phase.md], checkpoints=false
-- 10-03: requires=[10-02], files=[commands/execute-phase.md], checkpoints=false
-- 10-04: requires=[], files=[templates/agent-history.md], checkpoints=false
+Example dependency graph:
+┌─────────┬───────────────────────┬─────────────────────────────┬──────────────┐
+│ Plan │ Requires │ Files Modified │ Checkpoints │
+├─────────┼───────────────────────┼─────────────────────────────┼──────────────┤
+│ 10-01 │ [] │ [workflows/execute-plan.md] │ false │
+│ 10-02 │ [10-01] │ [workflows/execute-phase.md]│ false │
+│ 10-03 │ [10-02] │ [commands/execute-phase.md] │ false │
+│ 10-04 │ [] │ [templates/agent-history.md]│ false │
+└─────────┴───────────────────────┴─────────────────────────────┴──────────────┘
```
-**3. Detect conflicts:**
+**4. Detect file conflicts:**
+```bash
+# Build file-to-plan mapping
+declare -A FILE_TO_PLANS
+
+for plan_id in "${!PLAN_FILES[@]}"; do
+ IFS=',' read -ra files <<< "${PLAN_FILES[$plan_id]}"
+ for file in "${files[@]}"; do
+ [ -n "$file" ] && FILE_TO_PLANS["$file"]="${FILE_TO_PLANS[$file]},$plan_id"
+ done
+done
+
+# Detect conflicts (same file modified by multiple plans)
+declare -A CONFLICTS
+for file in "${!FILE_TO_PLANS[@]}"; do
+ plans="${FILE_TO_PLANS[$file]}"
+ plan_count=$(echo "$plans" | tr ',' '\n' | grep -c .)
+ if [ "$plan_count" -gt 1 ]; then
+ CONFLICTS["$file"]="${plans#,}"
+ fi
+done
+
+# Add conflict dependencies (later plan depends on earlier)
+for file in "${!CONFLICTS[@]}"; do
+ IFS=',' read -ra conflict_plans <<< "${CONFLICTS[$file]}"
+ for ((i=1; i<${#conflict_plans[@]}; i++)); do
+ # Each plan depends on previous one in conflict set
+ prev="${conflict_plans[$((i-1))]}"
+ curr="${conflict_plans[$i]}"
+ PLAN_REQUIRES["$curr"]="${PLAN_REQUIRES[$curr]},${prev}"
+ done
+done
```
-File conflict rules:
-- If Plan A and Plan B both modify same file → sequential (B depends on A)
+
+**File conflict rules:**
+- If Plan A and Plan B both modify same file → B depends on A (ordered by plan number)
- If Plan B reads file created by Plan A → B depends on A
-- If Plan B references Plan A's SUMMARY → B depends on A
-```
+- If Plan B references Plan A's SUMMARY in @context → B depends on A
-**4. Categorize plans:**
+**5. Categorize plans:**
| Category | Criteria | Action |
|----------|----------|--------|
@@ -156,18 +216,93 @@ File conflict rules:
| dependent | Requires another plan | Wait for dependency |
| has_checkpoints | Contains checkpoint tasks | Foreground or skip checkpoints |
-**5. Build execution waves:**
+**6. Build execution waves (topological sort):**
-Group plans into waves based on dependencies:
-```
-Wave 1: Plans with no dependencies (can run in parallel)
-Wave 2: Plans that depend only on Wave 1 (run after Wave 1 completes)
-Wave 3: Plans that depend on Wave 2 (run after Wave 2 completes)
-...
+```bash
+# Calculate wave for each plan
+declare -A PLAN_WAVE
+
+calculate_wave() {
+ local plan="$1"
+ [ -n "${PLAN_WAVE[$plan]}" ] && echo "${PLAN_WAVE[$plan]}" && return
+
+ local deps="${PLAN_REQUIRES[$plan]}"
+ local max_dep_wave=0
+
+ if [ -n "$deps" ]; then
+ IFS=',' read -ra dep_array <<< "$deps"
+ for dep in "${dep_array[@]}"; do
+ [ -z "$dep" ] && continue
+ # Only consider deps in current phase (unexecuted)
+ if [[ " ${!PLAN_FILES[*]} " =~ " $dep " ]]; then
+ dep_wave=$(calculate_wave "$dep")
+ [ "$dep_wave" -gt "$max_dep_wave" ] && max_dep_wave="$dep_wave"
+ fi
+ done
+ fi
+
+ PLAN_WAVE[$plan]=$((max_dep_wave + 1))
+ echo "${PLAN_WAVE[$plan]}"
+}
+
+# Calculate waves for all plans
+for plan_id in "${!PLAN_FILES[@]}"; do
+ calculate_wave "$plan_id" > /dev/null
+done
+
+# Group by wave
+declare -A WAVES
+for plan_id in "${!PLAN_WAVE[@]}"; do
+ wave="${PLAN_WAVE[$plan_id]}"
+ WAVES[$wave]="${WAVES[$wave]} $plan_id"
+done
+
+# Output wave structure
+echo "Execution waves:"
+for wave in $(echo "${!WAVES[@]}" | tr ' ' '\n' | sort -n); do
+ plans="${WAVES[$wave]}"
+ checkpoint_note=""
+ for p in $plans; do
+ [ "${PLAN_CHECKPOINTS[$p]}" = "true" ] && checkpoint_note=" (has checkpoints)"
+ done
+ echo " Wave $wave:$plans$checkpoint_note"
+done
```
-**6. Safety rule:**
-If dependency detection is uncertain, default to sequential execution.
+**Example output:**
+```
+Execution waves:
+ Wave 1: 10-01 10-04
+ Wave 2: 10-02
+ Wave 3: 10-03
+```
+
+**7. Handle checkpoints in parallel context:**
+
+Plans with checkpoints require special handling:
+- `checkpoint_handling: "foreground"` → Run in main context (not parallel)
+- `checkpoint_handling: "skip"` → Skip checkpoints during parallel (not recommended)
+
+```bash
+# Separate checkpoint plans
+PARALLEL_PLANS=()
+FOREGROUND_PLANS=()
+
+for plan_id in "${!PLAN_CHECKPOINTS[@]}"; do
+ if [ "${PLAN_CHECKPOINTS[$plan_id]}" = "true" ]; then
+ FOREGROUND_PLANS+=("$plan_id")
+ else
+ PARALLEL_PLANS+=("$plan_id")
+ fi
+done
+
+if [ ${#FOREGROUND_PLANS[@]} -gt 0 ]; then
+ echo "Plans requiring foreground execution: ${FOREGROUND_PLANS[*]}"
+fi
+```
+
+**8. Safety rule:**
+If dependency detection is uncertain (e.g., complex file patterns, unclear requires), default to sequential execution within that wave.