---
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}`
