diff --git a/commands/gsd/execute-phase.md b/commands/gsd/execute-phase.md index 3827dd741..4e54e3ec1 100644 --- a/commands/gsd/execute-phase.md +++ b/commands/gsd/execute-phase.md @@ -45,30 +45,25 @@ Phase: $ARGUMENTS - Check which have *-SUMMARY.md (already complete) - Build list of incomplete plans -3. **Analyze dependencies** - - Read each plan's `` section - - Detect cross-references to other plans' outputs - - Build dependency graph - -4. **Group into waves** - - Wave 1: Plans with no dependencies - - Wave N: Plans depending only on earlier waves +3. **Group by wave** + - Read `wave` from each plan's frontmatter + - Group plans by wave number - Report wave structure to user -5. **Execute waves** - For each wave: +4. **Execute waves** + For each wave in order: - Fill subagent-task-prompt template for each plan - Spawn all agents in wave simultaneously (parallel Task calls) - Wait for completion (Task blocks) - Verify SUMMARYs created - Proceed to next wave -6. **Aggregate results** +5. **Aggregate results** - Collect summaries from all plans - Report phase completion status - Update ROADMAP.md -7. **Offer next steps** +6. **Offer next steps** - More phases → `/gsd:plan-phase {next}` - Milestone complete → `/gsd:complete-milestone` @@ -89,22 +84,13 @@ All three run in parallel. Task tool blocks until all complete. **No polling.** No background agents. No TaskOutput loops. - -Before adding a plan to a parallel wave, scan for checkpoints: - -```bash -grep -c 'type="checkpoint' {plan_path} -``` - -**If checkpoints > 0:** -- Plan requires user interaction -- Execute in main context OR as solo subagent (not parallel) -- User interaction flows through normally - -**If checkpoints = 0:** -- Fully autonomous -- Safe for parallel wave execution - + +Plans with `autonomous: false` in frontmatter have checkpoints: +- Run in their assigned wave (can be parallel with other plans) +- Pause at checkpoint, return to orchestrator +- Orchestrator presents checkpoint to user +- User responds, orchestrator resumes agent + During execution, handle discoveries automatically: diff --git a/get-shit-done/references/plan-format.md b/get-shit-done/references/plan-format.md index e3780f076..38c9bf226 100644 --- a/get-shit-done/references/plan-format.md +++ b/get-shit-done/references/plan-format.md @@ -18,6 +18,7 @@ Every PLAN.md starts with YAML frontmatter: phase: XX-name plan: NN type: execute +wave: N # Execution wave (1, 2, 3...). Pre-computed at plan time. depends_on: [] # Plan IDs this plan requires (e.g., ["01-01"]) files_modified: [] # Files this plan modifies autonomous: true # false if plan has checkpoints @@ -30,17 +31,15 @@ domain: [optional] # Domain skill if loaded | `phase` | Yes | Phase identifier (e.g., `01-foundation`) | | `plan` | Yes | Plan number within phase (e.g., `01`, `02`) | | `type` | Yes | `execute` for standard plans, `tdd` for TDD plans | -| `depends_on` | Yes | Array of plan IDs this plan requires. **Empty = Wave 1 candidate** | -| `files_modified` | Yes | Files this plan touches. Used for conflict detection | +| `wave` | Yes | Execution wave number (1, 2, 3...). Pre-computed during planning. | +| `depends_on` | Yes | Array of plan IDs this plan requires. | +| `files_modified` | Yes | Files this plan touches. | | `autonomous` | Yes | `true` if no checkpoints, `false` if has checkpoints | | `domain` | No | Domain skill if loaded (e.g., `next-js`) | -**Wave assignment:** `/gsd:execute-phase` reads `depends_on` and `files_modified` to build execution waves: -- `depends_on: []` + no file conflicts → Wave 1 (parallel) -- `depends_on: ["XX-YY"]` → runs after plan XX-YY completes -- Shared `files_modified` → sequential by plan number +**Wave is pre-computed:** `/gsd:plan-phase` assigns wave numbers based on `depends_on`. `/gsd:execute-phase` reads `wave` directly from frontmatter and groups plans by wave number. No runtime dependency analysis needed. -**Checkpoint detection:** Plans with `autonomous: false` require user interaction. Execute after parallel wave or in main context. +**Checkpoint handling:** Plans with `autonomous: false` require user interaction. They run in their assigned wave but pause at checkpoints. @@ -51,6 +50,7 @@ Every PLAN.md follows this XML structure: phase: XX-name plan: NN type: execute +wave: N depends_on: [] files_modified: [path/to/file.ts] autonomous: true diff --git a/get-shit-done/templates/phase-prompt.md b/get-shit-done/templates/phase-prompt.md index b01d3896f..bbcc70f45 100644 --- a/get-shit-done/templates/phase-prompt.md +++ b/get-shit-done/templates/phase-prompt.md @@ -13,8 +13,9 @@ Template for `.planning/phases/XX-name/{phase}-{plan}-PLAN.md` - executable phas phase: XX-name plan: NN type: execute -depends_on: [] # Plan IDs this plan requires (e.g., ["01-01"]). Empty = parallel candidate. -files_modified: [] # Files this plan modifies. Used for conflict detection. +wave: N # Execution wave (1, 2, 3...). Pre-computed at plan time. +depends_on: [] # Plan IDs this plan requires (e.g., ["01-01"]). +files_modified: [] # Files this plan modifies. autonomous: true # false if plan has checkpoints requiring user interaction domain: [optional - if domain skill loaded] --- @@ -125,12 +126,13 @@ After completion, create `.planning/phases/XX-name/{phase}-{plan}-SUMMARY.md` | `phase` | Yes | Phase identifier (e.g., `01-foundation`) | | `plan` | Yes | Plan number within phase (e.g., `01`, `02`) | | `type` | Yes | Always `execute` for standard plans, `tdd` for TDD plans | -| `depends_on` | Yes | Array of plan IDs this plan requires. **Empty = Wave 1 candidate** | -| `files_modified` | Yes | Files this plan touches. Used for conflict detection | +| `wave` | Yes | Execution wave number (1, 2, 3...). Pre-computed at plan time. | +| `depends_on` | Yes | Array of plan IDs this plan requires. | +| `files_modified` | Yes | Files this plan touches. | | `autonomous` | Yes | `true` if no checkpoints, `false` if has checkpoints | | `domain` | No | Domain skill if loaded (e.g., `next-js`) | -**Wave assignment:** `/gsd:execute-phase` reads `depends_on` to build execution waves. Plans with `depends_on: []` and no file conflicts with sibling plans run in Wave 1 (parallel). +**Wave is pre-computed:** Wave numbers are assigned during `/gsd:plan-phase`. Execute-phase reads `wave` directly from frontmatter and groups plans by wave number. No runtime dependency analysis needed. --- @@ -142,16 +144,19 @@ After completion, create `.planning/phases/XX-name/{phase}-{plan}-SUMMARY.md` ```yaml # Plan 01 - User feature +wave: 1 depends_on: [] files_modified: [src/models/user.ts, src/api/users.ts] autonomous: true # Plan 02 - Product feature (no overlap with Plan 01) +wave: 1 depends_on: [] files_modified: [src/models/product.ts, src/api/products.ts] autonomous: true # Plan 03 - Order feature (no overlap) +wave: 1 depends_on: [] files_modified: [src/models/order.ts, src/api/orders.ts] autonomous: true @@ -163,28 +168,31 @@ All three run in parallel (Wave 1) - no dependencies, no file conflicts. ```yaml # Plan 01 - Auth foundation +wave: 1 depends_on: [] files_modified: [src/lib/auth.ts, src/middleware/auth.ts] autonomous: true # Plan 02 - Protected features (needs auth) +wave: 2 depends_on: ["01"] files_modified: [src/features/dashboard.ts] autonomous: true ``` -Plan 02 waits for Plan 01 - genuine dependency on auth types/middleware. +Plan 02 in Wave 2 waits for Plan 01 in Wave 1 - genuine dependency on auth types/middleware. **Checkpoint plan:** ```yaml # Plan 03 - UI with verification +wave: 3 depends_on: ["01", "02"] files_modified: [src/components/Dashboard.tsx] autonomous: false # Has checkpoint:human-verify ``` -Runs after Wave 1, pauses at checkpoint, orchestrator presents to user, resumes on approval. +Wave 3 runs after Waves 1 and 2. Pauses at checkpoint, orchestrator presents to user, resumes on approval. @@ -289,6 +297,7 @@ See `~/.claude/get-shit-done/references/tdd.md` for TDD plan structure. phase: 03-features plan: 01 type: execute +wave: 1 depends_on: [] files_modified: [src/features/user/model.ts, src/features/user/api.ts, src/features/user/UserList.tsx] autonomous: true @@ -347,6 +356,7 @@ After completion, create `.planning/phases/03-features/03-01-SUMMARY.md` phase: 03-features plan: 03 type: execute +wave: 2 depends_on: ["03-01", "03-02"] files_modified: [src/components/Dashboard.tsx] autonomous: false @@ -446,7 +456,7 @@ files_modified: [...] ## Guidelines - Always use XML structure for Claude parsing -- Include `depends_on`, `files_modified`, `autonomous` in every plan +- Include `wave`, `depends_on`, `files_modified`, `autonomous` in every plan - Prefer vertical slices over horizontal layers - Only reference prior SUMMARYs when genuinely needed - Group checkpoints with related auto tasks in same plan diff --git a/get-shit-done/workflows/execute-phase.md b/get-shit-done/workflows/execute-phase.md index 05586d7dd..d2e1a0190 100644 --- a/get-shit-done/workflows/execute-phase.md +++ b/get-shit-done/workflows/execute-phase.md @@ -68,68 +68,50 @@ ls -1 "$PHASE_DIR"/*-SUMMARY.md 2>/dev/null | sort ``` For each plan, read frontmatter to extract: -- `depends_on: []` - Plan IDs this plan requires -- `files_modified: []` - Files this plan touches +- `wave: N` - Execution wave (pre-computed) - `autonomous: true/false` - Whether plan has checkpoints Build plan inventory: - Plan path - Plan ID (e.g., "03-01") -- Dependencies -- Files modified +- Wave number - Autonomous flag - Completion status (SUMMARY exists = complete) Skip completed plans. If all complete, report "Phase already executed" and exit. - -Build dependency graph from frontmatter: + +Read `wave` from each plan's frontmatter and group by wave number: -**Direct dependencies:** -- `depends_on: ["03-01"]` → this plan depends on 03-01 - -**File conflict dependencies:** -- If two plans modify same file, later plan (by number) depends on earlier - -**Build graph:** +```bash +# For each plan, extract wave from frontmatter +for plan in $PHASE_DIR/*-PLAN.md; do + wave=$(grep "^wave:" "$plan" | cut -d: -f2 | tr -d ' ') + autonomous=$(grep "^autonomous:" "$plan" | cut -d: -f2 | tr -d ' ') + echo "$plan:$wave:$autonomous" +done ``` -plan-01: {deps: [], files: [src/user.ts], autonomous: true} -plan-02: {deps: [], files: [src/product.ts], autonomous: true} -plan-03: {deps: ["plan-01"], files: [src/dashboard.tsx], autonomous: false} -plan-04: {deps: ["plan-02"], files: [src/cart.ts], autonomous: true} -plan-05: {deps: ["plan-03", "plan-04"], files: [src/checkout.ts], autonomous: true} + +**Group plans:** ``` - - - -Group plans into execution waves based on dependencies: - -**Wave assignment algorithm:** -1. Wave 1: All plans with no dependencies AND autonomous=true -2. Non-autonomous plans with no dependencies: execute after Wave 1, before Wave 2 -3. Wave N: Plans whose dependencies are all in earlier waves - -**Separate checkpoint plans:** -Plans with `autonomous: false` execute in main context (not parallel subagent) to handle user interaction. - -**Example:** -``` -Wave 1 (parallel): [plan-01, plan-02] -Checkpoint: [plan-03] - has human-verify, runs in main context -Wave 2 (parallel): [plan-04] -Wave 3: [plan-05] +waves = { + 1: [plan-01, plan-02], + 2: [plan-03, plan-04], + 3: [plan-05] +} ``` +**No dependency analysis needed.** Wave numbers are pre-computed during `/gsd:plan-phase`. + Report wave structure to user: ``` Execution Plan: Wave 1 (parallel): 03-01, 03-02 - Checkpoint: 03-03 (requires user verification) - Wave 2 (parallel): 03-04 + Wave 2 (parallel): 03-03 [checkpoint], 03-04 Wave 3: 03-05 -Total: 5 plans in 3 waves + 1 checkpoint +Total: 5 plans in 3 waves ``` diff --git a/get-shit-done/workflows/plan-phase.md b/get-shit-done/workflows/plan-phase.md index 72b663614..1cf95c20b 100644 --- a/get-shit-done/workflows/plan-phase.md +++ b/get-shit-done/workflows/plan-phase.md @@ -367,6 +367,37 @@ For each plan, determine: - `autonomous: true|false` - has checkpoints requiring user interaction? + +**Compute wave numbers before writing plans.** + +Wave assignment algorithm (run in memory before writing any files): + +``` +waves = {} # plan_id -> wave_number + +for each plan in plan_order: + if plan.depends_on is empty: + plan.wave = 1 + else: + # Wave = max wave of dependencies + 1 + plan.wave = max(waves[dep] for dep in plan.depends_on) + 1 + + waves[plan.id] = plan.wave +``` + +**Example:** + +``` +Plan 01: depends_on: [] → wave: 1 +Plan 02: depends_on: [] → wave: 1 +Plan 03: depends_on: ["01"] → wave: 2 +Plan 04: depends_on: ["02"] → wave: 2 +Plan 05: depends_on: ["03", "04"] → wave: 3 +``` + +Store wave number with each plan in memory. Write to frontmatter in next step. + + **Group tasks into plans based on dependency waves and autonomy.** @@ -521,14 +552,15 @@ Each plan follows template structure with: phase: XX-name plan: NN type: execute -depends_on: [] # Plan IDs this plan requires. Empty = Wave 1 candidate. -files_modified: [] # Files this plan touches. Used for conflict detection. +wave: N # Execution wave (1, 2, 3...). Computed at plan time. +depends_on: [] # Plan IDs this plan requires. +files_modified: [] # Files this plan touches. autonomous: true # false if plan has checkpoints requiring user interaction domain: [optional] --- ``` -**Wave assignment is automatic:** `/gsd:execute-phase` reads `depends_on` to build waves. Plans with empty `depends_on` and no file conflicts run in Wave 1 (parallel). +**Wave is pre-computed:** Wave numbers are assigned during planning (see `assign_waves` step). `/gsd:execute-phase` reads `wave` directly from frontmatter and groups plans by wave number. No runtime dependency analysis needed. **Context section - parallel-aware:**