Loading...
Loading...
Execute all plans in a phase with wave-based parallelization, running phase execution, or completing phase work. Triggers include "execute phase", "run phase", "execute plans", "run the phase", and "phase execution".
npx skill4agent add gannonh/kata-skills kata-execute-phase--gaps-onlygap_closure: trueMODEL_PROFILE=$(cat .planning/config.json 2>/dev/null | grep -o '"model_profile"[[:space:]]*:[[:space:]]*"[^"]*"' | grep -o '"[^"]*"$' | tr -d '"' || echo "balanced")| Agent | quality | balanced | budget |
|---|---|---|---|
| general-purpose (executor) | opus | sonnet | sonnet |
| kata-verifier | sonnet | sonnet | haiku |
| kata-code-reviewer | opus | sonnet | sonnet |
| kata-*-analyzer | sonnet | sonnet | haiku |
bash "${SKILL_BASE_DIR}/scripts/find-phase.sh" "$PHASE_ARG"PHASE_DIRPLAN_COUNTPHASE_STATE# Move from pending to active when execution begins
# PHASE_STATE is from find-phase.sh output (step 1)
if [ "$PHASE_STATE" = "pending" ]; then
DIR_NAME=$(basename "$PHASE_DIR")
mkdir -p ".planning/phases/active"
mv "$PHASE_DIR" ".planning/phases/active/${DIR_NAME}"
PHASE_DIR=".planning/phases/active/${DIR_NAME}"
echo "Phase moved to active/"
fiPR_WORKFLOW=$(cat .planning/config.json 2>/dev/null | grep -o '"pr_workflow"[[:space:]]*:[[:space:]]*[^,}]*' | grep -o 'true\|false' || echo "false")MILESTONE=$(grep -oE 'v[0-9]+\.[0-9]+(\.[0-9]+)?' .planning/ROADMAP.md | head -1 | tr -d 'v')PHASE_NUM=$(basename "$PHASE_DIR" | sed -E 's/^([0-9]+)-.*/\1/')
SLUG=$(basename "$PHASE_DIR" | sed -E 's/^[0-9]+-//')PHASE_GOAL=$(grep -A 5 "Phase ${PHASE_NUM}:" .planning/ROADMAP.md | grep "Goal:" | head -1 || echo "")
if echo "$PHASE_GOAL" | grep -qi "fix\|bug\|patch"; then
BRANCH_TYPE="fix"
elif echo "$PHASE_GOAL" | grep -qi "doc\|readme\|comment"; then
BRANCH_TYPE="docs"
elif echo "$PHASE_GOAL" | grep -qi "refactor\|restructure\|reorganize"; then
BRANCH_TYPE="refactor"
elif echo "$PHASE_GOAL" | grep -qi "chore\|config\|setup"; then
BRANCH_TYPE="chore"
else
BRANCH_TYPE="feat"
fiBRANCH="${BRANCH_TYPE}/v${MILESTONE}-${PHASE_NUM}-${SLUG}"
if git show-ref --verify --quiet refs/heads/"$BRANCH"; then
git checkout "$BRANCH"
echo "Branch $BRANCH exists, resuming on it"
else
git checkout -b "$BRANCH"
echo "Created branch $BRANCH"
fi--gaps-onlygap_closure: truewave| Wave | Plans | Description |
|---|---|---|
| 1 | 01, 02 | {plan names from frontmatter} |
| 2 | 03 | {plan name} |
general-purpose# Get plan numbers from SUMMARYs that exist after this wave
COMPLETED_PLANS_IN_WAVE=""
for summary in $(find "${PHASE_DIR}" -maxdepth 1 -name "*-SUMMARY.md" 2>/dev/null); do
# Extract plan number from filename (e.g., 04-01-SUMMARY.md -> 01)
plan_num=$(basename "$summary" | sed -E 's/^[0-9]+-([0-9]+)-SUMMARY\.md$/\1/')
# Check if this plan was in the current wave (from frontmatter we read earlier)
if echo "${WAVE_PLANS}" | grep -q "plan-${plan_num}"; then
COMPLETED_PLANS_IN_WAVE="${COMPLETED_PLANS_IN_WAVE} ${plan_num}"
fi
doneGITHUB_ENABLED=$(cat .planning/config.json 2>/dev/null | grep -o '"enabled"[[:space:]]*:[[:space:]]*[^,}]*' | grep -o 'true\|false' || echo "false")
ISSUE_MODE=$(cat .planning/config.json 2>/dev/null | grep -o '"issueMode"[[:space:]]*:[[:space:]]*"[^"]*"' | grep -o '"[^"]*"$' | tr -d '"' || echo "never")GITHUB_ENABLED != trueISSUE_MODE = neverVERSION=$(grep -oE 'v[0-9]+\.[0-9]+(\.[0-9]+)?' .planning/ROADMAP.md | head -1 | tr -d 'v')
ISSUE_NUMBER=$(gh issue list \
--label "phase" \
--milestone "v${VERSION}" \
--json number,title \
--jq ".[] | select(.title | startswith(\"Phase ${PHASE}:\")) | .number" \
2>/dev/null)ISSUE_BODY=$(gh issue view "$ISSUE_NUMBER" --json body --jq '.body' 2>/dev/null)for plan_num in ${COMPLETED_PLANS_IN_WAVE}; do
# Format: Plan 01, Plan 02, etc.
PLAN_ID="Plan $(printf "%02d" $plan_num):"
# Update checkbox: - [ ] -> - [x]
ISSUE_BODY=$(echo "$ISSUE_BODY" | sed "s/^- \[ \] ${PLAN_ID}/- [x] ${PLAN_ID}/")
doneprintf '%s\n' "$ISSUE_BODY" > /tmp/phase-issue-body.md
gh issue edit "$ISSUE_NUMBER" --body-file /tmp/phase-issue-body.md 2>/dev/null \
&& echo "Updated issue #${ISSUE_NUMBER}: checked off Wave ${WAVE_NUM} plans" \
|| echo "Warning: Failed to update issue #${ISSUE_NUMBER}"# Re-read config (bash blocks don't share state)
PR_WORKFLOW=$(cat .planning/config.json 2>/dev/null | grep -o '"pr_workflow"[[:space:]]*:[[:space:]]*[^,}]*' | grep -o 'true\|false' || echo "false")
GITHUB_ENABLED=$(cat .planning/config.json 2>/dev/null | grep -o '"enabled"[[:space:]]*:[[:space:]]*[^,}]*' | head -1 | grep -o 'true\|false' || echo "false")
ISSUE_MODE=$(cat .planning/config.json 2>/dev/null | grep -o '"issueMode"[[:space:]]*:[[:space:]]*"[^"]*"' | grep -o '"[^"]*"$' | tr -d '"' || echo "never")
MILESTONE=$(grep -E "^\- \[.\] \*\*Phase|^### v" .planning/ROADMAP.md | grep -E "In Progress" | grep -oE "v[0-9]+\.[0-9]+(\.[0-9]+)?" | head -1 | tr -d 'v')
[ -z "$MILESTONE" ] && MILESTONE=$(grep -oE 'v[0-9]+\.[0-9]+(\.[0-9]+)?' .planning/ROADMAP.md | head -1 | tr -d 'v')
# PHASE_DIR already set by universal discovery in step 1
PHASE_NUM=$(basename "$PHASE_DIR" | sed -E 's/^([0-9]+)-.*/\1/')
BRANCH=$(git branch --show-current)
if [ "$PR_WORKFLOW" = "true" ]; then
# Check if PR already exists (re-run protection - also handles wave > 1)
EXISTING_PR=$(gh pr list --head "$BRANCH" --json number --jq '.[0].number' 2>/dev/null)
if [ -n "$EXISTING_PR" ]; then
echo "PR #${EXISTING_PR} already exists, skipping creation"
PR_NUMBER="$EXISTING_PR"
else
# Push branch and create draft PR
git push -u origin "$BRANCH"
# Get phase name from ROADMAP.md (format: #### Phase N: Name)
PHASE_NAME=$(grep -E "^#### Phase ${PHASE_NUM}:" .planning/ROADMAP.md | sed -E 's/^#### Phase [0-9]+: //' | xargs)
# Build PR body (Goal is on next line after phase header)
PHASE_GOAL=$(grep -A 3 "^#### Phase ${PHASE_NUM}:" .planning/ROADMAP.md | grep "Goal:" | sed 's/.*Goal:[[:space:]]*//')
# Get phase issue number for linking (if github.enabled)
CLOSES_LINE=""
if [ "$GITHUB_ENABLED" = "true" ] && [ "$ISSUE_MODE" != "never" ]; then
PHASE_ISSUE=$(gh issue list --label phase --milestone "v${MILESTONE}" \
--json number,title --jq ".[] | select(.title | startswith(\"Phase ${PHASE_NUM}:\")) | .number" 2>/dev/null)
[ -n "$PHASE_ISSUE" ] && CLOSES_LINE="Closes #${PHASE_ISSUE}"
# Store PHASE_ISSUE for use in step 10.6 merge path
fi
# Build plans checklist (all unchecked initially)
PLANS_CHECKLIST=""
for plan in $(find "${PHASE_DIR}" -maxdepth 1 -name "*-PLAN.md" 2>/dev/null); do
plan_name=$(grep -m1 "<name>" "$plan" | sed 's/.*<name>//;s/<\/name>.*//' || basename "$plan" | sed 's/-PLAN.md//')
plan_num=$(basename "$plan" | sed -E 's/^[0-9]+-([0-9]+)-PLAN\.md$/\1/')
PLANS_CHECKLIST="${PLANS_CHECKLIST}- [ ] Plan ${plan_num}: ${plan_name}\n"
done
# Collect source_issue references from all plans
SOURCE_ISSUES=""
for plan in $(find "${PHASE_DIR}" -maxdepth 1 -name "*-PLAN.md" 2>/dev/null); do
source_issue=$(grep -m1 "^source_issue:" "$plan" | cut -d':' -f2- | xargs)
if echo "$source_issue" | grep -q "^github:#"; then
issue_num=$(echo "$source_issue" | grep -oE '#[0-9]+')
[ -n "$issue_num" ] && SOURCE_ISSUES="${SOURCE_ISSUES}Closes ${issue_num}\n"
fi
done
SOURCE_ISSUES=$(echo "$SOURCE_ISSUES" | sed '/^$/d') # Remove empty lines
cat > /tmp/pr-body.md << PR_EOF # Create draft PR
gh pr create --draft \
--base main \
--title "v${MILESTONE} Phase ${PHASE_NUM}: ${PHASE_NAME}" \
--body-file /tmp/pr-body.md
PR_NUMBER=$(gh pr list --head "$BRANCH" --json number --jq '.[0].number')
echo "Created draft PR #${PR_NUMBER}"
fi
fi
```
Store PR_NUMBER for step 10.5.
**Note:** PR body checklist items remain unchecked throughout execution. The PR body is static after creation — it does NOT update as plans complete. The GitHub issue (updated after each wave above) is the source of truth for plan progress during execution.git status --porcelaingit add -u && git commit -m "fix({phase}): orchestrator corrections"TEST_SCRIPT=$(cat package.json 2>/dev/null | grep -o '"test"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1)npm testgap_closureWORKFLOW_VERIFIER=$(cat .planning/config.json 2>/dev/null | grep -o '"verifier"[[:space:]]*:[[:space:]]*[^,}]*' | grep -o 'true\|false' || echo "true")workflow.verifierfalsekata-verifierpassedhuman_neededgaps_found/kata-plan-phase {X} --gaps# Validate completion artifacts
PLAN_COUNT=$(find "$PHASE_DIR" -maxdepth 1 -name "*-PLAN.md" 2>/dev/null | wc -l | tr -d ' ')
MISSING=""
if [ "$PLAN_COUNT" -eq 0 ]; then
MISSING="${MISSING}\n- No PLAN.md files found"
fi
for plan in $(find "$PHASE_DIR" -maxdepth 1 -name "*-PLAN.md" 2>/dev/null); do
plan_id=$(basename "$plan" | sed 's/-PLAN\.md$//')
[ ! -f "$PHASE_DIR/${plan_id}-SUMMARY.md" ] && MISSING="${MISSING}\n- Missing SUMMARY.md for ${plan_id}"
done
# Non-gap phases require VERIFICATION.md
IS_GAP=$(find "$PHASE_DIR" -maxdepth 1 -name "*-PLAN.md" -exec grep -l "gap_closure: true" {} + 2>/dev/null | head -1)
if [ -z "$IS_GAP" ] && ! find "$PHASE_DIR" -maxdepth 1 -name "*-VERIFICATION.md" 2>/dev/null | grep -q .; then
MISSING="${MISSING}\n- Missing VERIFICATION.md (required for non-gap phases)"
fi
if [ -z "$MISSING" ]; then
DIR_NAME=$(basename "$PHASE_DIR")
mkdir -p ".planning/phases/completed"
mv "$PHASE_DIR" ".planning/phases/completed/${DIR_NAME}"
PHASE_DIR=".planning/phases/completed/${DIR_NAME}"
echo "Phase validated and moved to completed/"
else
echo "Warning: Phase incomplete:${MISSING}"
fiRequirements:COMMIT_PLANNING_DOCSgit add .planning/ROADMAP.md .planning/STATE.mdgit add .planning/REQUIREMENTS.mddocs({phase}): complete {phase-name} phaseAfter phase completion commit:
```bash
if [ "$PR_WORKFLOW" = "true" ]; then
# Push final commits
git push origin "$BRANCH"
# Mark PR ready for review
gh pr ready
PR_URL=$(gh pr view --json url --jq '.url')
echo "PR marked ready: $PR_URL"
fi
```
Store PR_URL for offer_next output.After PR is ready (or after phase commits if pr_workflow=false), present the user with post-verification options. This is the decision point before proceeding to completion output.
**Control flow:**
- UAT → returns here after completion
- PR review → step 10.7 → returns here
- Merge → executes merge → returns here
- Skip → proceeds to step 11
**IMPORTANT:** Do NOT skip this step. Do NOT proceed directly to step 11. The user must choose how to proceed.
Use AskUserQuestion:
- header: "Phase Complete"
- question: "Phase {X} execution complete. What would you like to do?"
- options:
- "Run UAT (Recommended)" — Walk through deliverables for manual acceptance testing
- "Run PR review" — 6 specialized agents review code quality
- "Merge PR" — (if pr_workflow=true) Merge to main
- "Skip to completion" — Trust automated verification, proceed to next phase/milestone
**Note:** Show "Merge PR" option only if `pr_workflow=true` AND PR exists AND not already merged.
**If user chooses "Run UAT":**
1. Invoke skill: `Skill("kata:kata-verify-work", "{phase}")`
2. UAT skill handles the walkthrough and any issues found
3. After UAT completes, return to this step to ask again (user may want PR review or merge)
**If user chooses "Run PR review":**
4. Invoke skill: `Skill("kata:review-pull-requests")`
5. Display review summary with counts: {N} critical, {M} important, {P} suggestions
6. **STOP and ask what to do with findings** (see step 10.7)
7. After findings handled, return to this step
**If user chooses "Merge PR":**
8. Execute merge:
```bash
gh pr merge "$PR_NUMBER" --merge --delete-branch
git checkout main && git pull
# Explicitly close the phase issue (backup in case Closes #X didn't trigger)
if [ -n "$PHASE_ISSUE" ]; then
gh issue close "$PHASE_ISSUE" --comment "Closed by PR #${PR_NUMBER} merge" 2>/dev/null \
&& echo "Closed issue #${PHASE_ISSUE}" \
|| echo "Note: Issue #${PHASE_ISSUE} may already be closed"
fi
# Close source issues from plans (backup in case Closes #X didn't trigger)
for plan in $(find "${PHASE_DIR}" -maxdepth 1 -name "*-PLAN.md" 2>/dev/null); do
source_issue=$(grep -m1 "^source_issue:" "$plan" | cut -d':' -f2- | xargs)
if echo "$source_issue" | grep -q "^github:#"; then
issue_num=$(echo "$source_issue" | grep -oE '[0-9]+')
gh issue close "$issue_num" --comment "Closed by PR #${PR_NUMBER} merge (source issue for plan)" 2>/dev/null || true
fi
done
```
9. Set MERGED=true
10. Return to this step to ask if user wants UAT or review before continuing
**If user chooses "Skip to completion":**
Continue to step 11.**STOP here. Do not proceed until user chooses an action.**
Use AskUserQuestion with options based on what was found:
- header: "Review Findings"
- question: "How do you want to handle the review findings?"
- options (show only applicable ones):
- "Fix critical issues" — (if critical > 0) Fix critical, then offer to add remaining to backlog
- "Fix critical & important" — (if critical + important > 0) Fix both, then offer to add suggestions to backlog
- "Fix all issues" — (if any issues) Fix everything
- "Add to backlog" — Create issues for all findings without fixing
- "Ignore and continue" — Skip all issues
**After user chooses:**
**Path A: "Fix critical issues"**
1. Fix each critical issue
2. If important or suggestions remain, ask: "Add remaining {N} issues to backlog?"
- "Yes" → Create issues, store TODOS_CREATED count
- "No" → Continue
3. Return to step 10.6 checkpoint
**Path B: "Fix critical & important"**
1. Fix each critical and important issue
2. If suggestions remain, ask: "Add {N} suggestions to backlog?"
- "Yes" → Create issues, store TODOS_CREATED count
- "No" → Continue
3. Return to step 10.6 checkpoint
**Path C: "Fix all issues"**
1. Fix all critical, important, and suggestion issues
2. Return to step 10.6 checkpoint
**Path D: "Add to backlog"**
1. Create issues for all findings using `/kata-add-issue`
2. Store TODOS_CREATED count
3. Return to step 10.6 checkpoint
**Path E: "Ignore and continue"**
1. Return to step 10.6 checkpoint
Store REVIEW_SUMMARY and TODOS_CREATED for offer_next output.
**Note:** After handling findings, return to step 10.6 so user can choose UAT, merge, or skip. The checkpoint loop continues until user explicitly chooses "Skip to completion".<offer_next>| Status | Route |
|---|---|
| Route C (gap closure) |
| Present checklist, then re-route based on approval |
| Route A (next phase) |
| Route B (milestone complete) |
/kata-discuss-phase {Z+1}/clear/kata-plan-phase {Z+1}/kata-verify-work {Z}gh pr view --web@{plan_01_path}{plan_02_path}.planning/STATE.mdreferences/executor-instructions.mdexecutor_instructions_contentTask(prompt="<agent-instructions>\n{executor_instructions_content}\n</agent-instructions>\n\nExecute plan at {plan_01_path}\n\n<plan>\n{plan_01_content}\n</plan>\n\n<project_state>\n{state_content}\n</project_state>", subagent_type="general-purpose", model="{executor_model}")
Task(prompt="<agent-instructions>\n{executor_instructions_content}\n</agent-instructions>\n\nExecute plan at {plan_02_path}\n\n<plan>\n{plan_02_content}\n</plan>\n\n<project_state>\n{state_content}\n</project_state>", subagent_type="general-purpose", model="{executor_model}")
Task(prompt="<agent-instructions>\n{executor_instructions_content}\n</agent-instructions>\n\nExecute plan at {plan_03_path}\n\n<plan>\n{plan_03_content}\n</plan>\n\n<project_state>\n{state_content}\n</project_state>", subagent_type="general-purpose", model="{executor_model}")autonomous: false@./references/phase-execute.mdcheckpoint_handling{type}({phase}-{plan}): {task-name}docs({phase}-{plan}): complete [plan-name] plandocs({phase}): complete {phase-name} phasegit add .git add -Agit add src/