- Nx 22.7 monorepo (pnpm 11.1, TypeScript 5.9, Node 24) - apps/api: NestJS 11 (CJS conforme CODING-RULES.md PGD-DB-004) - apps/web: React 19 + Vite 8 (ESM) - libs/shared/api-interface: Zod contract base - Docker Compose dev: Postgres 18, Valkey 8, MinIO, Mailpit - WDS artifacts: - design-artifacts/A-Product-Brief/ (5 docs canônicos + 16 dialogs) - design-artifacts/B-Trigger-Map/ (hub + 4 personas + feature impact) - Stack canon: STACK.md v2.2 + CODING-RULES.md v2.0 + brand.md - AGENTS.md + README.md como entrada para devs/agentes Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
174 lines
6.3 KiB
Markdown
174 lines
6.3 KiB
Markdown
---
|
|
name: 'step-03b-execute-finish'
|
|
description: 'Finalize each story (commit/status), trigger retrospective when epic complete, and finish execution loop'
|
|
nextStep: './step-03c-execute-complete.md'
|
|
scriptsDir: '../scripts/story-automator'
|
|
outputFile: '{output_folder}/story-automator/orchestration-{epic_id}-{timestamp}.md'
|
|
---
|
|
|
|
# Step 3b: Finalize Story + Wrap Execution
|
|
|
|
**Goal:** After code review completes for a story, commit changes, verify sprint status, update progress, and finish the loop.
|
|
**Interaction mode:** Deterministic autonomous execution.
|
|
|
|
---
|
|
|
|
## Story Loop (Continue from Step 3)
|
|
|
|
### E. Git Commit
|
|
|
|
**Required:** Commit after every story (do not skip).
|
|
|
|
```bash
|
|
commit=$("{scriptsDir}" commit-story --repo "{project-root}" --story {story_id} --title "{title}")
|
|
ok=$(echo "$commit" | jq -r '.ok')
|
|
```
|
|
|
|
- If `ok == true`:
|
|
```bash
|
|
# Update Story Progress: mark git-commit done
|
|
tmp_state=$(mktemp)
|
|
sed "s/^| ${story_id} |.*$/| ${story_id} | done | done | done | done | done | in-progress |/" "{outputFile}" > "$tmp_state" && mv "$tmp_state" "{outputFile}"
|
|
```
|
|
→ proceed to F
|
|
- If `ok == false` → log warning and escalate
|
|
|
|
### F. Verify Sprint Status
|
|
|
|
```bash
|
|
# Check sprint-status with story file fallback (v1.4.0)
|
|
normalized=$("{scriptsDir}" orchestrator-helper normalize-key {story_id})
|
|
story_key=$(echo "$normalized" | jq -r '.key')
|
|
status=$("{scriptsDir}" orchestrator-helper sprint-status get "$story_key")
|
|
is_done=$(echo "$status" | jq -r '.done')
|
|
|
|
# Fallback: trust story file if sprint-status disagrees
|
|
if [ "$is_done" != "true" ]; then
|
|
file_done=$("{scriptsDir}" orchestrator-helper story-file-status {story_id} | jq -r '.status')
|
|
[ "$file_done" = "done" ] && is_done="true"
|
|
fi
|
|
```
|
|
|
|
- If `is_done == false` → return to Code Review Loop (Step 3, section D)
|
|
- If `is_done == true` → proceed to G
|
|
|
|
### G. Story Complete
|
|
Display: "**✅ Story {N} complete.**"
|
|
```bash
|
|
"{scriptsDir}" orchestrator-helper state-update "{outputFile}" \
|
|
--set lastUpdated="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
echo "- **[$(date -u +%Y-%m-%dT%H:%M:%SZ)]** Story {story_id}: ✅ complete (commit + sprint-status verified)" >> "{outputFile}"
|
|
|
|
# Update Story Progress: mark story done
|
|
tmp_state=$(mktemp)
|
|
sed "s/^| ${story_id} |.*$/| ${story_id} | done | done | done | done | done | done |/" "{outputFile}" > "$tmp_state" && mv "$tmp_state" "{outputFile}"
|
|
```
|
|
Display: `[story {N}/{total}] finalize -> done`
|
|
|
|
### H. Check Epic Completion & Trigger Retrospective (Multi-Epic Support)
|
|
|
|
After each story completes, check if ALL stories in this epic are now done. Retrospective only triggers when every story in the epic has passed code review and sprint status confirms all are "done".
|
|
|
|
#### H.1 Check All Stories Done
|
|
|
|
```bash
|
|
# Run epic-level check in parallel with per-story checks
|
|
tmp_epic_status=$(mktemp)
|
|
("{scriptsDir}" orchestrator-helper sprint-status check-epic {epic_number} > "$tmp_epic_status") &
|
|
epic_status_pid=$!
|
|
|
|
# Get all stories for this epic and verify each is done
|
|
epic_stories=$("{scriptsDir}" orchestrator-helper get-epic-stories {epic_number} --state-file "{outputFile}")
|
|
stories_ok=$(echo "$epic_stories" | jq -r '.ok')
|
|
story_count=$(echo "$epic_stories" | jq -r '.count')
|
|
all_done=true
|
|
|
|
if [ "$stories_ok" != "true" ] || [ "$story_count" -eq 0 ]; then
|
|
all_done=false
|
|
else
|
|
tmp_story_checks=$(mktemp)
|
|
echo "$epic_stories" | jq -r '.stories[]' \
|
|
| xargs -I{} -P 4 sh -c '
|
|
status=$("'"{scriptsDir}"'" orchestrator-helper sprint-status get "{}")
|
|
done=$(echo "$status" | jq -r ".done")
|
|
[ "$done" = "true" ] && echo "{}|done" || echo "{}|not_done"
|
|
' > "$tmp_story_checks"
|
|
|
|
if rg -q '\|not_done$' "$tmp_story_checks"; then
|
|
all_done=false
|
|
fi
|
|
rm -f "$tmp_story_checks"
|
|
fi
|
|
```
|
|
|
|
#### H.2 Secondary Verification via Sprint Status
|
|
|
|
```bash
|
|
# Double-check: use result from parallel epic-level check
|
|
wait "$epic_status_pid"
|
|
epic_status=$(cat "$tmp_epic_status")
|
|
rm -f "$tmp_epic_status"
|
|
|
|
epic_complete=$(echo "$epic_status" | jq -r '.allStoriesDone')
|
|
epic_ok=$(echo "$epic_status" | jq -r '.ok')
|
|
|
|
# Both checks must pass
|
|
if [ "$all_done" = "true" ] && [ "$epic_ok" = "true" ] && [ "$epic_complete" = "true" ]; then
|
|
trigger_retro=true
|
|
else
|
|
trigger_retro=false
|
|
fi
|
|
```
|
|
|
|
#### H.3 Trigger Retrospective (Only When Epic Fully Complete)
|
|
|
|
**IF trigger_retro == true:**
|
|
|
|
1. Display: "**✅ Epic {epic_number} complete! All stories passed code review. Triggering retrospective (YOLO mode)...**"
|
|
2. Log: `- **[{timestamp}]** Epic {epic_number}: ALL STORIES DONE - triggering retrospective`
|
|
|
|
```bash
|
|
# CRITICAL: Use build-cmd to get full YOLO prompt with doc verification
|
|
retro_agent=$("{scriptsDir}" orchestrator-helper retro-agent --state-file "{outputFile}" | jq -r '.primary')
|
|
cmd=$("{scriptsDir}" tmux-wrapper build-cmd retro {epic_number} --agent "$retro_agent")
|
|
session=$("{scriptsDir}" tmux-wrapper spawn retro "" {epic_number} --agent "$retro_agent" --command "$cmd")
|
|
|
|
# Monitor with safe failure (never escalate on retro failure)
|
|
retro_timeout=60
|
|
[ "$story_count" -gt 10 ] && retro_timeout=90
|
|
result=$("{scriptsDir}" monitor-session "$session" --json --agent "$retro_agent" --timeout "$retro_timeout")
|
|
"{scriptsDir}" tmux-wrapper kill "$session"
|
|
|
|
retro_status=$(echo "$result" | jq -r '.final_state')
|
|
|
|
if [ "$retro_status" = "completed" ] || [ "$retro_status" = "success" ]; then
|
|
echo "- **[{timestamp}]** Epic {epic_number} retrospective: completed successfully" >> "{outputFile}"
|
|
else
|
|
echo "- **[{timestamp}]** Epic {epic_number} retrospective: skipped (reason: $retro_status)" >> "{outputFile}"
|
|
fi
|
|
```
|
|
|
|
3. Update state document with retrospective status:
|
|
```yaml
|
|
retrospectives:
|
|
epic-{epic_number}:
|
|
status: "completed" | "skipped"
|
|
reason: "{reason_if_skipped}"
|
|
timestamp: "{timestamp}"
|
|
```
|
|
|
|
4. **Continue to next story regardless of retrospective result** (retrospectives never block)
|
|
|
|
**IF trigger_retro == false:**
|
|
- Continue to next story (epic not yet complete)
|
|
|
|
**IMPORTANT RULES:**
|
|
- **ALL stories must be done**: Retrospective only triggers when every story in the epic shows "done" in sprint status
|
|
- **Use configured retro agent**: Resolve retrospective agent from `agentConfig` before spawn
|
|
- **Never escalate; non-blocking**: If retrospective fails for any reason, log warning and continue
|
|
|
|
**END FOR EACH**
|
|
|
|
## Then
|
|
→ After all stories complete, load and execute `{nextStep}`
|