460 lines
17 KiB
Markdown
460 lines
17 KiB
Markdown
<purpose>
|
|
Execute all plans in a phase using wave-based parallel execution. Orchestrator stays lean — delegates plan execution to subagents.
|
|
</purpose>
|
|
|
|
<core_principle>
|
|
Orchestrator coordinates, not executes. Each subagent loads the full execute-plan context. Orchestrator: discover plans → analyze deps → group waves → spawn agents → handle checkpoints → collect results.
|
|
</core_principle>
|
|
|
|
<required_reading>
|
|
read STATE.md before any operation to load project context.
|
|
</required_reading>
|
|
|
|
<process>
|
|
|
|
<step name="initialize" priority="first">
|
|
Load all context in one call:
|
|
|
|
```bash
|
|
INIT=$(node "./.opencode/get-shit-done/bin/gsd-tools.cjs" init execute-phase "${PHASE_ARG}")
|
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
```
|
|
|
|
Parse JSON for: `executor_model`, `verifier_model`, `commit_docs`, `parallelization`, `branching_strategy`, `branch_name`, `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `plans`, `incomplete_plans`, `plan_count`, `incomplete_count`, `state_exists`, `roadmap_exists`, `phase_req_ids`.
|
|
|
|
**If `phase_found` is false:** Error — phase directory not found.
|
|
**If `plan_count` is 0:** Error — no plans found in phase.
|
|
**If `state_exists` is false but `.planning/` exists:** Offer reconstruct or continue.
|
|
|
|
When `parallelization` is false, plans within a wave execute sequentially.
|
|
|
|
**Sync chain flag with intent** — if user invoked manually (no `--auto`), clear the ephemeral chain flag from any previous interrupted `--auto` chain. This does NOT touch `workflow.auto_advance` (the user's persistent settings preference). Must happen before any config reads (checkpoint handling also reads auto-advance flags):
|
|
```bash
|
|
if [[ ! "$ARGUMENTS" =~ --auto ]]; then
|
|
node "./.opencode/get-shit-done/bin/gsd-tools.cjs" config-set workflow._auto_chain_active false 2>/dev/null
|
|
fi
|
|
```
|
|
</step>
|
|
|
|
<step name="handle_branching">
|
|
Check `branching_strategy` from init:
|
|
|
|
**"none":** Skip, continue on current branch.
|
|
|
|
**"phase" or "milestone":** Use pre-computed `branch_name` from init:
|
|
```bash
|
|
git checkout -b "$BRANCH_NAME" 2>/dev/null || git checkout "$BRANCH_NAME"
|
|
```
|
|
|
|
All subsequent commits go to this branch. User handles merging.
|
|
</step>
|
|
|
|
<step name="validate_phase">
|
|
From init JSON: `phase_dir`, `plan_count`, `incomplete_count`.
|
|
|
|
Report: "Found {plan_count} plans in {phase_dir} ({incomplete_count} incomplete)"
|
|
</step>
|
|
|
|
<step name="discover_and_group_plans">
|
|
Load plan inventory with wave grouping in one call:
|
|
|
|
```bash
|
|
PLAN_INDEX=$(node "./.opencode/get-shit-done/bin/gsd-tools.cjs" phase-plan-index "${PHASE_NUMBER}")
|
|
```
|
|
|
|
Parse JSON for: `phase`, `plans[]` (each with `id`, `wave`, `autonomous`, `objective`, `files_modified`, `task_count`, `has_summary`), `waves` (map of wave number → plan IDs), `incomplete`, `has_checkpoints`.
|
|
|
|
**Filtering:** Skip plans where `has_summary: true`. If `--gaps-only`: also skip non-gap_closure plans. If all filtered: "No matching incomplete plans" → exit.
|
|
|
|
Report:
|
|
```
|
|
## Execution Plan
|
|
|
|
**Phase {X}: {Name}** — {total_plans} plans across {wave_count} waves
|
|
|
|
| Wave | Plans | What it builds |
|
|
|------|-------|----------------|
|
|
| 1 | 01-01, 01-02 | {from plan objectives, 3-8 words} |
|
|
| 2 | 01-03 | ... |
|
|
```
|
|
</step>
|
|
|
|
<step name="execute_waves">
|
|
Execute each wave in sequence. Within a wave: parallel if `PARALLELIZATION=true`, sequential if `false`.
|
|
|
|
**For each wave:**
|
|
|
|
1. **Describe what's being built (BEFORE spawning):**
|
|
|
|
read each plan's `<objective>`. Extract what's being built and why.
|
|
|
|
```
|
|
---
|
|
## Wave {N}
|
|
|
|
**{Plan ID}: {Plan Name}**
|
|
{2-3 sentences: what this builds, technical approach, why it matters}
|
|
|
|
Spawning {count} agent(s)...
|
|
---
|
|
```
|
|
|
|
- Bad: "Executing terrain generation plan"
|
|
- Good: "Procedural terrain generator using Perlin noise — creates height maps, biome zones, and collision meshes. Required before vehicle physics can interact with ground."
|
|
|
|
2. **Spawn executor agents:**
|
|
|
|
Pass paths only — executors read files themselves with their fresh 200k context.
|
|
This keeps orchestrator context lean (~10-15%).
|
|
|
|
```
|
|
task(
|
|
subagent_type="gsd-executor",
|
|
model="{executor_model}",
|
|
prompt="
|
|
<objective>
|
|
Execute plan {plan_number} of phase {phase_number}-{phase_name}.
|
|
Commit each task atomically. Create SUMMARY.md. Update STATE.md and ROADMAP.md.
|
|
</objective>
|
|
|
|
<execution_context>
|
|
@./.opencode/get-shit-done/workflows/execute-plan.md
|
|
@./.opencode/get-shit-done/templates/summary.md
|
|
@./.opencode/get-shit-done/references/checkpoints.md
|
|
@./.opencode/get-shit-done/references/tdd.md
|
|
</execution_context>
|
|
|
|
<files_to_read>
|
|
read these files at execution start using the read tool:
|
|
- {phase_dir}/{plan_file} (Plan)
|
|
- .planning/STATE.md (State)
|
|
- .planning/config.json (Config, if exists)
|
|
- ./AGENTS.md (Project instructions, if exists — follow project-specific guidelines and coding conventions)
|
|
- .OpenCode/skills/ or .agents/skills/ (Project skills, if either exists — list skills, read SKILL.md for each, follow relevant rules during implementation)
|
|
</files_to_read>
|
|
|
|
<success_criteria>
|
|
- [ ] All tasks executed
|
|
- [ ] Each task committed individually
|
|
- [ ] SUMMARY.md created in plan directory
|
|
- [ ] STATE.md updated with position and decisions
|
|
- [ ] ROADMAP.md updated with plan progress (via `roadmap update-plan-progress`)
|
|
</success_criteria>
|
|
"
|
|
)
|
|
```
|
|
|
|
3. **Wait for all agents in wave to complete.**
|
|
|
|
4. **Report completion — spot-check claims first:**
|
|
|
|
For each SUMMARY.md:
|
|
- Verify first 2 files from `key-files.created` exist on disk
|
|
- Check `git log --oneline --all --grep="{phase}-{plan}"` returns ≥1 commit
|
|
- Check for `## Self-Check: FAILED` marker
|
|
|
|
If ANY spot-check fails: report which plan failed, route to failure handler — ask "Retry plan?" or "Continue with remaining waves?"
|
|
|
|
If pass:
|
|
```
|
|
---
|
|
## Wave {N} Complete
|
|
|
|
**{Plan ID}: {Plan Name}**
|
|
{What was built — from SUMMARY.md}
|
|
{Notable deviations, if any}
|
|
|
|
{If more waves: what this enables for next wave}
|
|
---
|
|
```
|
|
|
|
- Bad: "Wave 2 complete. Proceeding to Wave 3."
|
|
- Good: "Terrain system complete — 3 biome types, height-based texturing, physics collision meshes. Vehicle physics (Wave 3) can now reference ground surfaces."
|
|
|
|
5. **Handle failures:**
|
|
|
|
**Known OpenCode bug (classifyHandoffIfNeeded):** If an agent reports "failed" with error containing `classifyHandoffIfNeeded is not defined`, this is a OpenCode runtime bug — not a GSD or agent issue. The error fires in the completion handler AFTER all tool calls finish. In this case: run the same spot-checks as step 4 (SUMMARY.md exists, git commits present, no Self-Check: FAILED). If spot-checks PASS → treat as **successful**. If spot-checks FAIL → treat as real failure below.
|
|
|
|
For real failures: report which plan failed → ask "Continue?" or "Stop?" → if continue, dependent plans may also fail. If stop, partial completion report.
|
|
|
|
6. **Execute checkpoint plans between waves** — see `<checkpoint_handling>`.
|
|
|
|
7. **Proceed to next wave.**
|
|
</step>
|
|
|
|
<step name="checkpoint_handling">
|
|
Plans with `autonomous: false` require user interaction.
|
|
|
|
**Auto-mode checkpoint handling:**
|
|
|
|
read auto-advance config (chain flag + user preference):
|
|
```bash
|
|
AUTO_CHAIN=$(node "./.opencode/get-shit-done/bin/gsd-tools.cjs" config-get workflow._auto_chain_active 2>/dev/null || echo "false")
|
|
AUTO_CFG=$(node "./.opencode/get-shit-done/bin/gsd-tools.cjs" config-get workflow.auto_advance 2>/dev/null || echo "false")
|
|
```
|
|
|
|
When executor returns a checkpoint AND (`AUTO_CHAIN` is `"true"` OR `AUTO_CFG` is `"true"`):
|
|
- **human-verify** → Auto-spawn continuation agent with `{user_response}` = `"approved"`. Log `⚡ Auto-approved checkpoint`.
|
|
- **decision** → Auto-spawn continuation agent with `{user_response}` = first option from checkpoint details. Log `⚡ Auto-selected: [option]`.
|
|
- **human-action** → Present to user (existing behavior below). Auth gates cannot be automated.
|
|
|
|
**Standard flow (not auto-mode, or human-action type):**
|
|
|
|
1. Spawn agent for checkpoint plan
|
|
2. Agent runs until checkpoint task or auth gate → returns structured state
|
|
3. Agent return includes: completed tasks table, current task + blocker, checkpoint type/details, what's awaited
|
|
4. **Present to user:**
|
|
```
|
|
## Checkpoint: [Type]
|
|
|
|
**Plan:** 03-03 Dashboard Layout
|
|
**Progress:** 2/3 tasks complete
|
|
|
|
[Checkpoint Details from agent return]
|
|
[Awaiting section from agent return]
|
|
```
|
|
5. User responds: "approved"/"done" | issue description | decision selection
|
|
6. **Spawn continuation agent (NOT resume)** using continuation-prompt.md template:
|
|
- `{completed_tasks_table}`: From checkpoint return
|
|
- `{resume_task_number}` + `{resume_task_name}`: Current task
|
|
- `{user_response}`: What user provided
|
|
- `{resume_instructions}`: Based on checkpoint type
|
|
7. Continuation agent verifies previous commits, continues from resume point
|
|
8. Repeat until plan completes or user stops
|
|
|
|
**Why fresh agent, not resume:** Resume relies on internal serialization that breaks with parallel tool calls. Fresh agents with explicit state are more reliable.
|
|
|
|
**Checkpoints in parallel waves:** Agent pauses and returns while other parallel agents may complete. Present checkpoint, spawn continuation, wait for all before next wave.
|
|
</step>
|
|
|
|
<step name="aggregate_results">
|
|
After all waves:
|
|
|
|
```markdown
|
|
## Phase {X}: {Name} Execution Complete
|
|
|
|
**Waves:** {N} | **Plans:** {M}/{total} complete
|
|
|
|
| Wave | Plans | Status |
|
|
|------|-------|--------|
|
|
| 1 | plan-01, plan-02 | ✓ Complete |
|
|
| CP | plan-03 | ✓ Verified |
|
|
| 2 | plan-04 | ✓ Complete |
|
|
|
|
### Plan Details
|
|
1. **03-01**: [one-liner from SUMMARY.md]
|
|
2. **03-02**: [one-liner from SUMMARY.md]
|
|
|
|
### Issues Encountered
|
|
[Aggregate from SUMMARYs, or "None"]
|
|
```
|
|
</step>
|
|
|
|
<step name="close_parent_artifacts">
|
|
**For decimal/polish phases only (X.Y pattern):** Close the feedback loop by resolving parent UAT and debug artifacts.
|
|
|
|
**Skip if** phase number has no decimal (e.g., `3`, `04`) — only applies to gap-closure phases like `4.1`, `03.1`.
|
|
|
|
**1. Detect decimal phase and derive parent:**
|
|
```bash
|
|
# Check if phase_number contains a decimal
|
|
if [[ "$PHASE_NUMBER" == *.* ]]; then
|
|
PARENT_PHASE="${PHASE_NUMBER%%.*}"
|
|
fi
|
|
```
|
|
|
|
**2. Find parent UAT file:**
|
|
```bash
|
|
PARENT_INFO=$(node "./.opencode/get-shit-done/bin/gsd-tools.cjs" find-phase "${PARENT_PHASE}" --raw)
|
|
# Extract directory from PARENT_INFO JSON, then find UAT file in that directory
|
|
```
|
|
|
|
**If no parent UAT found:** Skip this step (gap-closure may have been triggered by VERIFICATION.md instead).
|
|
|
|
**3. Update UAT gap statuses:**
|
|
|
|
read the parent UAT file's `## Gaps` section. For each gap entry with `status: failed`:
|
|
- Update to `status: resolved`
|
|
|
|
**4. Update UAT frontmatter:**
|
|
|
|
If all gaps now have `status: resolved`:
|
|
- Update frontmatter `status: diagnosed` → `status: resolved`
|
|
- Update frontmatter `updated:` timestamp
|
|
|
|
**5. Resolve referenced debug sessions:**
|
|
|
|
For each gap that has a `debug_session:` field:
|
|
- read the debug session file
|
|
- Update frontmatter `status:` → `resolved`
|
|
- Update frontmatter `updated:` timestamp
|
|
- Move to resolved directory:
|
|
```bash
|
|
mkdir -p .planning/debug/resolved
|
|
mv .planning/debug/{slug}.md .planning/debug/resolved/
|
|
```
|
|
|
|
**6. Commit updated artifacts:**
|
|
```bash
|
|
node "./.opencode/get-shit-done/bin/gsd-tools.cjs" commit "docs(phase-${PARENT_PHASE}): resolve UAT gaps and debug sessions after ${PHASE_NUMBER} gap closure" --files .planning/phases/*${PARENT_PHASE}*/*-UAT.md .planning/debug/resolved/*.md
|
|
```
|
|
</step>
|
|
|
|
<step name="verify_phase_goal">
|
|
Verify phase achieved its GOAL, not just completed tasks.
|
|
|
|
```
|
|
task(
|
|
prompt="Verify phase {phase_number} goal achievement.
|
|
Phase directory: {phase_dir}
|
|
Phase goal: {goal from ROADMAP.md}
|
|
Phase requirement IDs: {phase_req_ids}
|
|
Check must_haves against actual codebase.
|
|
Cross-reference requirement IDs from PLAN frontmatter against REQUIREMENTS.md — every ID MUST be accounted for.
|
|
Create VERIFICATION.md.",
|
|
subagent_type="gsd-verifier",
|
|
model="{verifier_model}"
|
|
)
|
|
```
|
|
|
|
read status:
|
|
```bash
|
|
grep "^status:" "$PHASE_DIR"/*-VERIFICATION.md | cut -d: -f2 | tr -d ' '
|
|
```
|
|
|
|
| Status | Action |
|
|
|--------|--------|
|
|
| `passed` | → update_roadmap |
|
|
| `human_needed` | Present items for human testing, get approval or feedback |
|
|
| `gaps_found` | Present gap summary, offer `/gsd-plan-phase {phase} --gaps` |
|
|
|
|
**If human_needed:**
|
|
```
|
|
## ✓ Phase {X}: {Name} — Human Verification Required
|
|
|
|
All automated checks passed. {N} items need human testing:
|
|
|
|
{From VERIFICATION.md human_verification section}
|
|
|
|
"approved" → continue | Report issues → gap closure
|
|
```
|
|
|
|
**If gaps_found:**
|
|
```
|
|
## ⚠ Phase {X}: {Name} — Gaps Found
|
|
|
|
**Score:** {N}/{M} must-haves verified
|
|
**Report:** {phase_dir}/{phase_num}-VERIFICATION.md
|
|
|
|
### What's Missing
|
|
{Gap summaries from VERIFICATION.md}
|
|
|
|
---
|
|
## ▶ Next Up
|
|
|
|
`/gsd-plan-phase {X} --gaps`
|
|
|
|
*`/new` first → fresh context window*
|
|
|
|
Also: `cat {phase_dir}/{phase_num}-VERIFICATION.md` — full report
|
|
Also: `/gsd-verify-work {X}` — manual testing first
|
|
```
|
|
|
|
Gap closure cycle: `/gsd-plan-phase {X} --gaps` reads VERIFICATION.md → creates gap plans with `gap_closure: true` → user runs `/gsd-execute-phase {X} --gaps-only` → verifier re-runs.
|
|
</step>
|
|
|
|
<step name="update_roadmap">
|
|
**Mark phase complete and update all tracking files:**
|
|
|
|
```bash
|
|
COMPLETION=$(node "./.opencode/get-shit-done/bin/gsd-tools.cjs" phase complete "${PHASE_NUMBER}")
|
|
```
|
|
|
|
The CLI handles:
|
|
- Marking phase checkbox `[x]` with completion date
|
|
- Updating Progress table (Status → Complete, date)
|
|
- Updating plan count to final
|
|
- Advancing STATE.md to next phase
|
|
- Updating REQUIREMENTS.md traceability
|
|
|
|
Extract from result: `next_phase`, `next_phase_name`, `is_last_phase`.
|
|
|
|
```bash
|
|
node "./.opencode/get-shit-done/bin/gsd-tools.cjs" commit "docs(phase-{X}): complete phase execution" --files .planning/ROADMAP.md .planning/STATE.md .planning/REQUIREMENTS.md {phase_dir}/*-VERIFICATION.md
|
|
```
|
|
</step>
|
|
|
|
<step name="offer_next">
|
|
|
|
**Exception:** If `gaps_found`, the `verify_phase_goal` step already presents the gap-closure path (`/gsd-plan-phase {X} --gaps`). No additional routing needed — skip auto-advance.
|
|
|
|
**No-transition check (spawned by auto-advance chain):**
|
|
|
|
Parse `--no-transition` flag from $ARGUMENTS.
|
|
|
|
**If `--no-transition` flag present:**
|
|
|
|
Execute-phase was spawned by plan-phase's auto-advance. Do NOT run transition.md.
|
|
After verification passes and roadmap is updated, return completion status to parent:
|
|
|
|
```
|
|
## PHASE COMPLETE
|
|
|
|
Phase: ${PHASE_NUMBER} - ${PHASE_NAME}
|
|
Plans: ${completed_count}/${total_count}
|
|
Verification: {Passed | Gaps Found}
|
|
|
|
[Include aggregate_results output]
|
|
```
|
|
|
|
STOP. Do not proceed to auto-advance or transition.
|
|
|
|
**If `--no-transition` flag is NOT present:**
|
|
|
|
**Auto-advance detection:**
|
|
|
|
1. Parse `--auto` flag from $ARGUMENTS
|
|
2. read both the chain flag and user preference (chain flag already synced in init step):
|
|
```bash
|
|
AUTO_CHAIN=$(node "./.opencode/get-shit-done/bin/gsd-tools.cjs" config-get workflow._auto_chain_active 2>/dev/null || echo "false")
|
|
AUTO_CFG=$(node "./.opencode/get-shit-done/bin/gsd-tools.cjs" config-get workflow.auto_advance 2>/dev/null || echo "false")
|
|
```
|
|
|
|
**If `--auto` flag present OR `AUTO_CHAIN` is true OR `AUTO_CFG` is true (AND verification passed with no gaps):**
|
|
|
|
```
|
|
╔══════════════════════════════════════════╗
|
|
║ AUTO-ADVANCING → TRANSITION ║
|
|
║ Phase {X} verified, continuing chain ║
|
|
╚══════════════════════════════════════════╝
|
|
```
|
|
|
|
Execute the transition workflow inline (do NOT use task — orchestrator context is ~10-15%, transition needs phase completion data already in context):
|
|
|
|
read and follow `./.opencode/get-shit-done/workflows/transition.md`, passing through the `--auto` flag so it propagates to the next phase invocation.
|
|
|
|
**If neither `--auto` nor `AUTO_CFG` is true:**
|
|
|
|
The workflow ends. The user runs `/gsd-progress` or invokes the transition workflow manually.
|
|
</step>
|
|
|
|
</process>
|
|
|
|
<context_efficiency>
|
|
Orchestrator: ~10-15% context. Subagents: fresh 200k each. No polling (task blocks). No context bleed.
|
|
</context_efficiency>
|
|
|
|
<failure_handling>
|
|
- **classifyHandoffIfNeeded false failure:** Agent reports "failed" but error is `classifyHandoffIfNeeded is not defined` → OpenCode bug, not GSD. Spot-check (SUMMARY exists, commits present) → if pass, treat as success
|
|
- **Agent fails mid-plan:** Missing SUMMARY.md → report, ask user how to proceed
|
|
- **Dependency chain breaks:** Wave 1 fails → Wave 2 dependents likely fail → user chooses attempt or skip
|
|
- **All agents in wave fail:** Systemic issue → stop, report for investigation
|
|
- **Checkpoint unresolvable:** "Skip this plan?" or "Abort phase execution?" → record partial progress in STATE.md
|
|
</failure_handling>
|
|
|
|
<resumption>
|
|
Re-run `/gsd-execute-phase {phase}` → discover_plans finds completed SUMMARYs → skips them → resumes from first incomplete plan → continues wave execution.
|
|
|
|
STATE.md tracks: last completed plan, current wave, pending checkpoints.
|
|
</resumption>
|