chore: initial monorepo scaffold + WDS Phase 1+2 artifacts

- 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>
This commit is contained in:
2026-05-27 14:34:20 +00:00
commit 17c08e6392
3631 changed files with 855518 additions and 0 deletions

View File

@@ -0,0 +1,139 @@
---
name: 'step-01-init'
description: 'Check for existing state and route appropriately'
nextStep: './step-02-preflight.md'
continueStep: './step-01b-continue.md'
outputFolder: '{output_folder}/story-automator'
outputFile: '{outputFolder}/init-log-{timestamp}.md'
rules: '../data/orchestrator-rules.md'
scripts: '../scripts/story-automator'
ensureStopHook: '../scripts/story-automator'
stateHelper: '../scripts/story-automator'
settingsFile: '{project-root}/.claude/settings.json'
---
# Step 1: Initialize
**Goal:** Verify safeguards, check for existing state → resume or start fresh.
---
## Do
### 1. Verify Stop Hook Installation
**CRITICAL:** The Stop hook prevents premature stopping during orchestration.
Use script to ensure the Stop hook exists:
```bash
result=$("{ensureStopHook}" ensure-stop-hook --settings "{settingsFile}" \
--command "{scripts} stop-hook" --timeout 10)
ok=$(echo "$result" | jq -r '.ok')
changed=$(echo "$result" | jq -r '.changed')
verification_state=$(echo "$result" | jq -r '.verificationState // "verified"')
message=$(echo "$result" | jq -r '.message // ""') # Helper returns provider-specific restart/setup guidance for Claude or Codex.
```
The settings path is used for Claude; Codex resolves `.codex/hooks.json` and `.codex/config.toml` from the project root.
**IF ok == false:** Report error and STOP.
**IF changed == true:**
Display:
```
**Stop Hook Installed**
<message from helper>
This prevents the orchestrator from randomly stopping mid-workflow.
⚠️ **Please restart this active agent session** for the hook to take effect.
After restarting, run the story-automator workflow again.
```
**HALT** - Do not proceed until user restarts
**IF verification_state == "pending_trust":**
Display:
```
**Stop Hook Pending Codex Trust**
<message from helper>
Trust this project in Codex, then restart Codex and run the story-automator workflow again.
```
**HALT** - Do not proceed until Codex can run the hook
**IF changed == false:**
Display: "✓ Stop hook verified"
Continue to step 2
### 2. Load Rules
Load `{rules}` once. These apply to all subsequent steps.
### 3. Check for Existing State
Search `{outputFolder}` for `orchestration-*.md` files.
Use deterministic state listing:
```bash
state_list=$("{stateHelper}" orchestrator-helper state-list "{outputFolder}")
latest_incomplete=$(echo "$state_list" | jq -r '.files | map(select(.status == "COMPLETE" | not)) | sort_by(.lastUpdated) | last | .path // empty')
```
**IF latest_incomplete is non-empty:**
- Display: "**Found existing orchestration in progress.**"
- Show: epic name, current story, current step, last updated
- → Load `{continueStep}`
- **STOP** (don't continue below)
**IF none found:**
- Continue to step 4
### 4. Welcome
Display:
```
**Welcome to Story Automator.**
I'll automate story implementation by spawning isolated sessions,
handling code review loops, and committing completed stories.
Everything is logged for full resumability.
```
### 5. Check Sprint Status (MANDATORY)
```bash
has_status=$("{stateHelper}" orchestrator-helper sprint-status exists)
sprint_ok=$(echo "$has_status" | jq -r '.exists')
```
**IF sprint_ok == false:** ABORT immediately.
Display:
```
**❌ Sprint status file not found.**
Expected: `_bmad-output/implementation-artifacts/sprint-status.yaml`
This file is required before running the story automator.
Please run the **sprint-planning** workflow first to generate it.
```
**HALT** - Do not proceed.
**IF sprint_ok == true:**
- Store for later reference during preflight
- Will be used to check if earlier stories need completion
### 6. Setup
Ensure `{outputFolder}` exists.
Append an initialization entry to `{outputFile}`:
```bash
printf \"[%s] init: stop-hook=%s existing_state=%s\\n\" \
\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\" \"${changed}\" \"${latest_incomplete}\" >> \"{outputFile}\"
```
**Note:** Marker file path is resolved by `orchestrator-helper marker path` in step-02b-preflight-finalize after epic/story context is established.
---
## Then
→ Load `{nextStep}`

View File

@@ -0,0 +1,200 @@
---
name: 'step-01b-continue'
description: 'Handle workflow continuation from previous session'
outputFolder: '{output_folder}/story-automator'
outputFile: '{outputFolder}/orchestration-{epic_id}-{timestamp}.md'
preflightStep: './step-02-preflight.md'
preflightConfigStep: './step-02a-preflight-config.md'
preflightFinalizeStep: './step-02b-preflight-finalize.md'
executeStep: './step-03-execute.md'
executeReviewStep: './step-03a-execute-review.md'
executeFinishStep: './step-03b-execute-finish.md'
executeCompleteStep: './step-03c-execute-complete.md'
wrapupStep: './step-04-wrapup.md'
stateFilePattern: '{outputFolder}/orchestration-*.md'
stateHelper: '../scripts/story-automator'
ensureMarkerGitignore: '../scripts/story-automator'
deriveProjectSlug: '../scripts/story-automator'
listSessions: '../scripts/story-automator'
sprintCompare: '../scripts/story-automator'
tmuxCommands: '../data/tmux-commands.md'
# Optional: provided by workflow.md when using Resume mode (skips state search)
resumeStatePath: ''
---
# Step 1b: Continue Previous Session
**Goal:** Load existing state and let user choose how to proceed.
---
## Do
### 1. Load State Document
**IF `{resumeStatePath}` is provided (from workflow.md Resume routing):**
Use it directly: `state_file="{resumeStatePath}"`
**ELSE (called from step-01-init or no path provided):**
Find the most recent incomplete state document using `{stateFilePattern}`:
```bash
result=$("{stateHelper}" orchestrator-helper state-latest-incomplete "{outputFolder}")
state_file=$(echo "$result" | jq -r '.path // empty')
```
**IF state_file is empty:** Display "No incomplete orchestration found." and HALT.
**Then extract from state_file:**
- `epic`, `epicName`, `storyRange`
- `currentStep`, `status`
- `stepsCompleted`, `storiesCompleted`
- Last action from action log
Use deterministic summary:
```bash
summary=$("{stateHelper}" orchestrator-helper state-summary "$state_file")
```
### 2. Verify Against Sprint Status
Load `_bmad-output/implementation-artifacts/sprint-status.yaml`.
**Compare with state document (run in parallel with session inventory):**
- Check if earlier stories (before `currentStory`) are marked `done` in sprint-status
- If any earlier stories are NOT `done`:
```
**Warning:** Stories {X, Y} are not complete in sprint-status.yaml.
[B]atch them first - Add to queue before continuing
[S]kip - Continue from current story anyway
```
**Wait.**
- If B: Add incomplete stories to beginning of queue
- If S: Note skip in action log, continue
Use deterministic parallel baseline:
```bash
tmp_compare=$(mktemp)
tmp_sessions=$(mktemp)
("{sprintCompare}" sprint-compare --state "$state_file" --sprint "_bmad-output/implementation-artifacts/sprint-status.yaml" > "$tmp_compare") &
compare_pid=$!
project_slug=$(echo "$("{deriveProjectSlug}" derive-project-slug --project-root "{project-root}")" | jq -r '.slug')
("{listSessions}" list-sessions --slug "$project_slug" > "$tmp_sessions") &
sessions_pid=$!
wait "$compare_pid"
wait "$sessions_pid"
compare=$(cat "$tmp_compare")
sessions=$(cat "$tmp_sessions")
rm -f "$tmp_compare" "$tmp_sessions"
incomplete=$(echo "$compare" | jq -r '.incomplete | join(", ")')
session_count=$(echo "$sessions" | jq -r '.count')
```
### 3. Check Active Sessions
Using `{tmuxCommands}`, check for existing T-Mux sessions for THIS PROJECT ONLY.
**Generate project slug first:**
```bash
project_slug=$(echo "$("{deriveProjectSlug}" derive-project-slug --project-root "{project-root}")" | jq -r '.slug')
```
**Then list sessions matching:** `sa-{project_slug}-*`
This ensures we only see sessions spawned by THIS project's story-automator, not sessions from other projects.
Use `sessions` and `session_count` from step 2 parallel baseline.
### 4. Present Status
```
**Resuming: {epicName}**
Status: {status}
Progress: {storiesCompleted}/{totalStories} stories
Current: Story {N}, Step: {currentStep}
Last action: {lastAction}
Active sessions: {count or 'None'}
```
### 5. Present Options
```
[R]esume - Continue from where you left off
[V]iew - See action log details
[M]odify - Change overrides or context
[S]tart Over - Restart this epic (keeps backup)
[X]Abort - Cancel orchestration
```
**Wait for user input.**
#### Menu Handling Logic:
- IF R: Create marker file, then route based on `status` and `currentStep`:
- READY → `{preflightFinalizeStep}`
- INITIALIZING → `{preflightConfigStep}`
- IN_PROGRESS / PAUSED → route by `currentStep`:
- `step-03-execute` or `create` or `dev` → `{executeStep}`
- `step-03a-execute-review` or `auto` or `review` → `{executeReviewStep}`
- `step-03b-execute-finish` or `commit` or `retro` → `{executeFinishStep}`
- `step-03c-execute-complete` → `{executeCompleteStep}`
- (default) → `{executeStep}`
- EXECUTION_COMPLETE → `{wrapupStep}`
- COMPLETE → `{wrapupStep}`
- ABORTED → display warning and redisplay this menu
- IF V: Show last 20 action log entries, then redisplay this menu
- IF M: Allow override changes, save, then redisplay this menu
- IF S: Rename state to `.backup-{timestamp}` then load `{preflightStep}` (new state will be created at `{outputFile}`)
- IF X: Set status="ABORTED", display confirmation, end workflow
- IF Any other: help user respond, then redisplay this menu
#### EXECUTION RULES:
- ALWAYS halt and wait for user input after presenting menu
- ONLY route to a step after handling the selected option
- After non-routing options, return to this menu
- Keep prompts concise; if user is unsure, ask one clarifying question before redisplaying options
### 6. Handle Choice
| Choice | Action |
|--------|--------|
| **R** | **First:** Create marker file (see below), **then** route based on `status` |
| **V** | Show last 20 action log entries → redisplay options |
| **M** | Allow override changes, save → redisplay options |
| **S** | Rename state to `.backup-{timestamp}` → `{preflightStep}` |
| **X** | Set status="ABORTED", display confirmation, end workflow |
#### On [R]esume: Create Marker File BEFORE Routing
**CRITICAL:** Only create marker file when user confirms resume. This prevents stop hook from firing during menu wait.
Create the active runtime marker with orchestration context:
```json
{
"epic": "{epic}",
"currentStory": "{currentStory}",
"storiesRemaining": {remaining_count},
"stateFile": "{state_document_path}",
"startedAt": "{timestamp}"
}
```
Use deterministic marker creation:
```bash
marker_info=$("{stateHelper}" orchestrator-helper marker path)
marker_entry=$(echo "$marker_info" | jq -r '.entry')
"{ensureMarkerGitignore}" ensure-marker-gitignore --gitignore ".gitignore" --entry "$marker_entry"
"{stateHelper}" orchestrator-helper marker create --epic "{epic}" --story "{currentStory}" \
--remaining {remaining_count} --state-file "{state_document_path}" \
--project-slug "$project_slug" --pid "$$" --heartbeat "{timestamp}"
```
**Then** route per Menu Handling Logic in section 5 above.
---
## Then
→ Load appropriate step based on choice

View File

@@ -0,0 +1,200 @@
---
name: 'step-02-preflight'
description: 'Gather epic, story selection, and complexity analysis'
nextStep: './step-02a-preflight-config.md'
outputFolder: '{output_folder}/story-automator'
outputFile: '{outputFolder}/preflight-{epic_id}-{timestamp}.md'
parseEpic: '../scripts/story-automator'
parseStoryRange: '../scripts/story-automator'
parseStory: '../scripts/story-automator'
stateHelper: '../scripts/story-automator'
defaultEpicPath: '{output_folder}/planning-artifacts/epics.md'
defaultSprintStatusFile: '{output_folder}/implementation-artifacts/sprint-status.yaml'
complexityRules: '../data/complexity-rules.json'
complexityScoring: '../data/complexity-scoring.md'
preflightRequirements: '../data/preflight-requirements.md'
---
# Step 2: Pre-flight (Epic + Complexity)
**Goal:** Gather epic, story range, complexity analysis, and custom instructions.
**Interaction mode:** Collaborative discovery and clarification.
---
## 🚨 BEFORE STARTING: Load Requirements
**CRITICAL:** Load and read `{preflightRequirements}` FIRST. It contains MANDATORY sequence rules, FORBIDDEN patterns, and verification gates that MUST be followed.
---
## Do
### 1. Confirm Epic File
```
**Epic source**
Default epic file: `{defaultEpicPath}`
Use this file? [Y/n]
```
If user confirms (Y/Enter), set `epic_path="{defaultEpicPath}"`.
If user says no, ask for epic file path and set `epic_path` from response.
If confirmed default does not exist, tell user and request explicit path.
**Wait.**
### 2. Review Epic
Parse epic file deterministically:
```bash
epic_json=$("{parseEpic}" parse-epic --file "{epic_path}")
epic_name=$(echo "$epic_json" | jq -r '.epicTitle')
story_count=$(echo "$epic_json" | jq -r '.count')
story_titles=$(echo "$epic_json" | jq -r '.stories[] | "\(.storyId) \(.title)"')
story_ids_csv=$(echo "$epic_json" | jq -r '.stories[] | .storyId' | paste -sd, -)
sprint_exists=$("{stateHelper}" orchestrator-helper sprint-status exists)
story_status_rows="(sprint-status unavailable at {defaultSprintStatusFile})"
if [ "$sprint_exists" = "true" ]; then
story_status_rows=$(echo "$epic_json" | jq -r '.stories[] | .storyId' | while read -r sid; do
status_json=$("{stateHelper}" orchestrator-helper sprint-status get "$sid")
st=$(echo "$status_json" | jq -r '.status // "unknown"')
printf -- "- %s | %s\n" "$sid" "$st"
done)
fi
```
Display:
```
**Epic:** {epic_name}
Stories found:
1. {storyId} {title}
2. {storyId} {title}
...
Total: {story_count}
Current sprint-status ({defaultSprintStatusFile}):
{story_status_rows}
Which stories? (e.g., `1-3`, `all`, `1,3,5`)
```
If user hesitates, suggest `all` as default and confirm.
**Wait.**
### 3. Read Stories and Compute Complexity (MANDATORY - DO NOT SKIP)
> **🚨 CRITICAL:** This step MUST use the Python helper for complexity scoring. NEVER manually assess complexity by reading story content.
For each story in range, extract complexity **programmatically**:
**3a. Parse story range:**
```bash
range_json=$("{parseStoryRange}" parse-story-range --input "{user_selection}" --total "$story_count" --ids "$story_ids_csv")
selected_ids=$(echo "$range_json" | jq -r '.storyIds[]')
selected_count=$(echo "$range_json" | jq -r '.count')
first_story_id=$(echo "$range_json" | jq -r '.storyIds[0]')
epic_id=$(echo "$first_story_id" | cut -d. -f1)
```
**3b. Get complexity for EACH story using Python helper:**
```bash
# Initialize accumulator - REQUIRED
stories_json='[]'
# For EACH story_id in selected_ids, run:
story_json=$("{parseStory}" parse-story --epic "{epic_path}" --story "$story_id" --rules "{complexityRules}")
# Extract and accumulate - REQUIRED
story_title=$(echo "$story_json" | jq -r '.title')
story_level=$(echo "$story_json" | jq -r '.complexity.level')
story_score=$(echo "$story_json" | jq -r '.complexity.score')
story_reasons=$(echo "$story_json" | jq -r '.complexity.reasons // []')
stories_json=$(echo "$stories_json" | jq -c --arg id "$story_id" --arg title "$story_title" --arg level "$story_level" --argjson score "$story_score" --argjson reasons "$story_reasons" \
'. + [{storyId:$id,title:$title,complexity:{level:$level,score:$score,reasons:$reasons}}]')
```
Refer to `{complexityScoring}` for scoring criteria and thresholds.
**Parallelism Policy (MANDATORY):**
- If `selected_count >= 4`: run per-story complexity parsing in parallel subprocesses (max 4 workers).
- If `selected_count < 4`: run sequentially.
- In both modes, return only summary fields to parent context: `storyId`, `title`, `complexity.level`, `complexity.score`, `complexity.reasons`.
```bash
# Deterministic threshold
if [ "$selected_count" -ge 4 ]; then
# Parallel mode (max 4 workers)
tmp_story_complexity=$(mktemp)
printf "%s\n" $selected_ids | xargs -I{} -P 4 sh -c '
"{parseStory}" parse-story --epic "{epic_path}" --story "{}" --rules "{complexityRules}" \
| jq -c "{storyId:.storyId,title:.title,complexity:.complexity}"
' > "$tmp_story_complexity"
stories_json=$(jq -s '.' "$tmp_story_complexity")
rm -f "$tmp_story_complexity"
else
# Sequential mode
stories_json='[]'
for story_id in $selected_ids; do
story_json=$("{parseStory}" parse-story --epic "{epic_path}" --story "$story_id" --rules "{complexityRules}")
stories_json=$(echo "$stories_json" | jq -c --argjson s "$(echo "$story_json" | jq -c '{storyId:.storyId,title:.title,complexity:.complexity}')" '. + [$s]')
done
fi
```
**3c. Display Complexity Matrix (REQUIRED):**
Display the Complexity Matrix using the template from `{preflightRequirements}`.
**3d. VERIFICATION GATE:**
Follow the verification gate from `{preflightRequirements}` before proceeding.
---
### 4. Custom Instructions
```
**Any custom instructions?**
Examples:
- "Always run tests after changes"
- "Prioritize stories 3 and 5"
- "Be extra careful with database migrations"
- "Use strict typing throughout"
Enter instructions or 'none':
```
If user is unsure, recommend `none` and continue.
**Wait.**
Store response as `custom_instructions` (use "" for none).
### 5. Proceed to Configuration
Persist preflight snapshot before continuing:
```bash
mkdir -p "{outputFolder}"
cat > "{outputFile}" <<EOF
# Preflight Snapshot
- Timestamp: {timestamp}
- Epic path: {epic_path}
- Epic name: {epic_name}
- Story count: {story_count}
- Selected count: {selected_count}
- Selected IDs: {selected_ids}
- Custom instructions: {custom_instructions}
## Complexity Summary
$(echo "$stories_json" | jq -r '.[] | "- \(.storyId) | \(.complexity.level) | score=\(.complexity.score)"')
EOF
```
Carry forward: `epic_path`, `epic_name`, `story_count`, `story_ids_csv`, `range_json`, `selected_ids`, `selected_count`, `stories_json`, `epic_id`, `first_story_id`, `custom_instructions`.
---
## Then
→ Load and execute `{nextStep}`

View File

@@ -0,0 +1,162 @@
---
name: 'step-02a-preflight-config'
description: 'Configure agents and execution settings, then create state document'
nextStep: './step-02b-preflight-finalize.md'
stateTemplate: '../templates/state-document.md'
outputFolder: '{output_folder}/story-automator'
outputFile: '{outputFolder}/orchestration-{epic_id}-{timestamp}.md'
buildStateDoc: '../scripts/story-automator'
agentConfigPrompts: '../data/agent-config-prompts.md'
agentConfigPresets: '../data/agent-config-presets.json'
---
# Step 2a: Pre-flight Configuration
**Goal:** Configure agents and execution settings, then create the orchestration state document.
**Interaction mode:** Guided configuration (collaborative inputs, deterministic state creation).
---
## Prerequisites
- Step 2 completed.
- Variables available: `epic_id`, `epic_name`, `range_json`, `stories_json`, `selected_count`, `custom_instructions`.
---
## Do
### 1. Configure Execution Preferences
> **PREREQUISITE:** Step 2 (preflight) MUST be complete. The Complexity Matrix MUST have been displayed. If not, STOP and complete step 2 first.
```
**Execution Settings:**
1. **Skip the 'automate' step (test automation)?** [N]o (default) / [Y]es
2. **Max parallel sessions?** (tmux sessions running concurrently, default: 1)
Enter choices (e.g., `N 1` or `Y 3`):
```
**Wait.**
Store responses as `skip_automate` (true/false) and `max_parallel` (integer).
### 2. Configure Agent (Complexity-Aware)
Using the complexity data from `stories_json`, present agent configuration options that reference the actual complexity breakdown.
**2a. Check for Saved Presets**
```bash
presets_result=$("{buildStateDoc}" agent-config list --file "{agentConfigPresets}")
preset_count=$(echo "$presets_result" | jq -r '.count')
```
Store `preset_count` — this determines whether [L]oad option appears in the menu.
**2b. Present Complexity-Based Agent Options**
Display prompts from `{agentConfigPrompts}`, selecting the appropriate table variant:
- If `skip_automate` is false: show table WITH `auto` column
- If `skip_automate` is true: show table WITHOUT `auto` column
- If `preset_count > 0`: include [L]oad saved option
- If `preset_count == 0`: omit [L] option
**Wait.**
**2c. Handle Selection**
- **IF S:** Build `agent_config_json` from defaults (no save prompt).
- **IF U or C:** Follow Uniform/Custom prompts from `{agentConfigPrompts}`, build `agent_config_json`, then proceed to **2d (Save Prompt)**.
- **IF L:** Follow Load Saved Preset prompt from `{agentConfigPrompts}`. Load preset config as `agent_config_json` (no save prompt).
```bash
# Example shape with complexity-based config (auto column included when not skipped)
agent_config_json='{
"complexityBased": true,
"low": {"create":{"primary":"...","fallback":"..."},"dev":{...},"auto":{...},"review":{...}},
"medium": {"create":{...},"dev":{...},"auto":{...},"review":{...}},
"high": {"create":{...},"dev":{...},"auto":{...},"review":{...}},
"auto": {"skip": $skip_automate}
}'
```
Store:
- `agent_config_json` = full config object
- `primary_agent` = default primary (for backwards compatibility)
**2d. Save Prompt (U/C only)**
Only when user chose **[U]niform** or **[C]ustom**, follow the Save Configuration prompt from `{agentConfigPrompts}`:
```bash
# If user provides a name:
"{buildStateDoc}" agent-config save --file "{agentConfigPresets}" --name "$save_name" --config-json "$agent_config_json"
```
### 3. Review
Display configuration summary:
- Epic and story range
- Custom instructions (if any)
- Agent configuration
- Execution settings
Pause for confirmation before starting execution.
### 3b. Confirm Autonomous Start (Optional Checkpoint)
Before creating state and launching autonomous phases, confirm:
```
Proceed with autonomous execution after preflight? [Y/n]
```
**Wait.**
- If `Y`/Enter: continue.
- If `n`: return to Step 1 (settings) for adjustments.
### 4. Create State Document
From `{stateTemplate}`:
- Generate: `orchestration-{epic_id}-{timestamp}.md`
- Fill frontmatter with all config
- Initialize story progress table
- Set status: "READY"
- Save to `{outputFolder}`
Deterministic creation:
```bash
agent_cmd="claude --dangerously-skip-permissions"
if [ "$primary_agent" = "codex" ]; then agent_cmd="codex exec --full-auto"; fi
config_json=$(jq -n \
--arg epic "$epic_id" \
--arg epicName "$epic_name" \
--argjson storyRange "$(echo "$range_json" | jq '.storyIds')" \
--arg status "READY" \
--arg currentStory "null" \
--arg currentStep "preflight" \
--arg aiCommand "$agent_cmd" \
--arg customInstructions "$custom_instructions" \
--argjson overrides "{\"skipAutomate\":$skip_automate,\"maxParallel\":$max_parallel}" \
--argjson agentConfig "$agent_config_json" \
'{epic:$epic,epicName:$epicName,storyRange:$storyRange,status:$status,currentStory:null,currentStep:$currentStep,aiCommand:$aiCommand,customInstructions:$customInstructions,overrides:$overrides,agentConfig:$agentConfig}'
)
state_result=$("{buildStateDoc}" build-state-doc --template "{stateTemplate}" --output-folder "{outputFolder}" --config-json "$config_json")
state_path=$(echo "$state_result" | jq -r '.path')
```
Display: "**State document created.**"
Record: `state_path` is the resolved `{outputFile}` for this run.
### 5. Auto-Proceed to Finalize
Persist any preflight notes to `{outputFile}`, update frontmatter (append `step-02-preflight` and `step-02a-preflight-config`, set `lastUpdated`).
---
## Then
→ Load, read entire file, and execute `{nextStep}`

View File

@@ -0,0 +1,79 @@
---
name: 'step-02b-preflight-finalize'
description: 'Finalize preflight and start execution'
nextStep: './step-03-execute.md'
outputFolder: '{output_folder}/story-automator'
outputFile: '{outputFolder}/orchestration-{epic_id}-{timestamp}.md'
stateHelper: '../scripts/story-automator'
ensureMarkerGitignore: '../scripts/story-automator'
deriveProjectSlug: '../scripts/story-automator'
markerFormat: '../data/marker-file-format.md'
---
# Step 2b: Pre-flight Finalize
**Goal:** Finalize preflight artifacts, create marker, and start execution.
**Interaction mode:** Deterministic auto-proceed.
---
## Do
### 1. Create Complexity + Agents Files
Derive deterministic filenames:
```bash
state_base=$(basename "{outputFile}" .md)
complexity_path="{outputFolder}/complexity-${state_base}.json"
agents_dir="{outputFolder}/agents"
agents_path="$agents_dir/agents-${state_base}.md"
```
Write complexity file:
```bash
mkdir -p "$(dirname "$complexity_path")"
echo "$stories_json" | jq -c '{stories:.}' > "$complexity_path"
```
Build deterministic agents file:
```bash
mkdir -p "$agents_dir"
"{stateHelper}" orchestrator-helper agents-build \
--state-file "{outputFile}" \
--complexity-file "$complexity_path" \
--output "$agents_path" \
--config-json "$agent_config_json"
```
Update state frontmatter with file paths:
```bash
agents_path_json=$(printf '%s' "$agents_path" | jq -R '.')
complexity_path_json=$(printf '%s' "$complexity_path" | jq -R '.')
"{stateHelper}" orchestrator-helper state-update "{outputFile}" \
--set "agentsFile=$agents_path_json" \
--set "complexityFile=$complexity_path_json"
```
### 2. Create Marker and Begin Execution
**Create marker file** (see `{markerFormat}` for JSON structure):
```bash
# Resolve the active marker path for the selected runtime layout and gitignore it.
marker_info=$("{stateHelper}" orchestrator-helper marker path)
marker_entry=$(echo "$marker_info" | jq -r '.entry')
"{ensureMarkerGitignore}" ensure-marker-gitignore --gitignore ".gitignore" --entry "$marker_entry"
# Create marker
project_slug=$(echo "$("{deriveProjectSlug}" derive-project-slug --project-root "{project-root}")" | jq -r '.slug')
"{stateHelper}" orchestrator-helper marker create --epic "$epic_id" --story "$first_story_id" \
--remaining "$selected_count" --state-file "{outputFile}" \
--project-slug "$project_slug" --pid "$$" --heartbeat "{timestamp}"
```
Set status="IN_PROGRESS", log "Execution started".
Update frontmatter (append `step-02b-preflight-finalize`, set `lastUpdated`).
---
## Then
→ Load, read entire file, and execute `{nextStep}`

View File

@@ -0,0 +1,199 @@
---
name: 'step-03-execute'
description: 'Autonomous execution loop - create and dev stories'
nextStep: './step-03a-execute-review.md'
dataFileIndex: '../data/data-file-index.md'
scriptsDir: '../scripts/story-automator'
outputFolder: '{output_folder}/story-automator'
stateFilePattern: '{outputFolder}/orchestration-*.md'
outputFile: '{outputFolder}/orchestration-{epic_id}-{timestamp}.md'
retryStrategy: '../data/retry-fallback-strategy.md'
executionPatterns: '../data/execution-patterns.md'
subagentPrompts: '../data/subagent-prompts.md'
---
## 🚨 CRITICAL: Load Data File Index FIRST
**BEFORE ANY EXECUTION**, load and read `{dataFileIndex}` completely.
**DO NOT proceed until you have read the index and loaded the required files.**
---
Set: `scripts="{scriptsDir}"`
## 🚨 CRITICAL: CLI Contract Check (Interface Drift Guard)
Before running any story loop logic, verify required helper commands/flags still exist.
```bash
# Core command availability
"$scripts" tmux-wrapper --help >/dev/null
"$scripts" monitor-session --help >/dev/null
"$scripts" orchestrator-helper --help >/dev/null
# Required spawn contract: --command must exist
"$scripts" tmux-wrapper spawn --help | grep -q -- "--command"
# Build command contract must be available
"$scripts" tmux-wrapper build-cmd --help >/dev/null
```
If any check fails: **STOP and escalate immediately** with "helper CLI contract changed".
---
# Step 3: Execute Build Cycle
**Goal:** Autonomously execute all stories. Escalate only when decisions needed.
**Interaction mode:** Deterministic autonomous execution.
---
## Setup
Load from state document (located via `{stateFilePattern}`; output folder `{outputFolder}`; resolved path stored as `{outputFile}` for this run):
- `storyRange`, `currentStory`, `currentStep`
- `overrides` (skipAutomate, maxParallel)
- `customInstructions`
Resolve agent configuration using deterministic agents file (see `{retryStrategy}` for full function):
```bash
state_file="{outputFile}"
# resolve_agent_for_task "{task}" "$state_file" "{story_id}" -> sets primary_agent,fallback_agent
```
**IF resuming** (currentStory set): Skip to that point in loop.
**IF fresh**: Display "**Starting build cycle for {count} stories...**"
## 🚨 CRITICAL: Execution Patterns
**BEFORE executing any steps, read `{executionPatterns}` for:**
- FORBIDDEN patterns (never chain multiple workflow steps)
- REQUIRED patterns (verify state after each step)
- Monitoring failure fallback sequence
**Key rule:** Each step (create/dev/auto/review) MUST be executed and monitored separately. NEVER chain steps in loops.
## Story Loop
> **⚠️ SPAWN PATTERN - READ THIS:**
> Every `story-automator tmux-wrapper spawn` call **MUST** include `--command` with the built command:
> ```bash
> session=$("$scripts" tmux-wrapper spawn {step} {epic} {story_id} \
> --agent "$agent" \
> --command "$("$scripts" tmux-wrapper build-cmd {step} {story_id} --agent "$agent")")
> ```
> **Missing `--command` = session sits idle → `never_active` failure!**
**FOR EACH story in range:**
```bash
"$scripts" orchestrator-helper state-update "$state_file" \
--set currentStory={story_id} --set currentStep=step-03-execute \
--set lastUpdated="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo "- **[$(date -u +%Y-%m-%dT%H:%M:%SZ)]** Starting story {story_id}" >> "$state_file"
# Initialize Story Progress row
tmp_state=$(mktemp)
awk -v row="| {story_id} | - | - | - | - | - | in-progress |" '
/^<!-- Progress rows -->$/ { print row }
{ print }
' "$state_file" > "$tmp_state" && mv "$tmp_state" "$state_file"
```
Display: "**Story {N}/{total}: {title}**"
Use compact operator output format for routine progress:
```text
[story {N}/{total}] {step} -> {state} (agent={agent}, retries={attempts})
```
After any session completes (create/dev/auto/review): `"$scripts" tmux-wrapper kill "$session"`
**MANDATORY log pre-filter (all sessions):** Before any deep parsing, pre-filter logs with a single grep/regex pass and pass only focused output forward.
```bash
log_file=$(echo "$result" | jq -r '.output_file')
log_focus=$(grep -nE "SUCCESS|FAIL|ERROR|CRITICAL|WARN|RETRY|ESCALATE" "$log_file" | head -n 120)
if [ -z "$log_focus" ]; then
log_focus=$(tail -n 120 "$log_file")
fi
```
If multiple logs exist, run one grep/regex pass across all log files and forward only matched lines + file names.
**Compact result contract (required):**
- Return only: `next_action`, `confidence`, `error_class`, `retryable`, `reasons`, `session_id`
- Do not pass full raw logs to parent flow unless escalation explicitly requires evidence payload
### A. Create Story
*Skip if story file exists*
**Apply retry/fallback pattern from `{retryStrategy}`:** Up to 5 attempts, alternating agents, network-aware delays.
```bash
# Retry loop: see {retryStrategy}
session=$("$scripts" tmux-wrapper spawn create {epic} {story_id} \
--agent "$current_agent" \
--command "$("$scripts" tmux-wrapper build-cmd create {story_id} --agent "$current_agent" --state-file "$state_file")")
result=$("$scripts" monitor-session "$session" --json --agent "$current_agent")
"$scripts" tmux-wrapper kill "$session"
validation=$("$scripts" orchestrator-helper verify-step create {story_id} --state-file "$state_file")
```
- If `validation.verified == true`:
```bash
# Update Story Progress: mark create-story done
tmp_state=$(mktemp)
sed "s/^| ${story_id} |.*$/| ${story_id} | done | - | - | - | - | in-progress |/" "$state_file" > "$tmp_state" && mv "$tmp_state" "$state_file"
```
→ proceed to B
- If `validation.verified == false` AND attempts < 5 → retry with next agent (see `{retryStrategy}`)
- If `validation.verified == false` AND attempts == 5 → escalate (all retries exhausted)
### B. Dev Story
**Apply retry/fallback pattern from `{retryStrategy}`:** Up to 5 attempts, alternating agents.
```bash
# Retry loop with agent alternation: see {retryStrategy}
session=$("$scripts" tmux-wrapper spawn dev {epic} {story_id} \
--agent "$current_agent" \
--command "$("$scripts" tmux-wrapper build-cmd dev {story_id} --agent "$current_agent" --state-file "$state_file")")
result=$("$scripts" monitor-session "$session" --json --agent "$current_agent")
"$scripts" tmux-wrapper kill "$session"
```
**Session Parsing Contract (required):**
- Preferred: use Session Output Parser prompt from `{subagentPrompts}` on `result.output_file`
- Fallback: use local parser below
- Return normalized schema only: `next_action`, `confidence`, `error_class`, `reasons`
```bash
parsed=$("$scripts" orchestrator-helper parse-output "$(printf '%s' "$result" | jq -r '.output_file')" dev)
next_action=$(echo "$parsed" | jq -r '.next_action')
confidence=$(echo "$parsed" | jq -r '.confidence // 0.0')
error_class=$(echo "$parsed" | jq -r '.error_class // "none"')
reasons=$(echo "$parsed" | jq -c '.reasons // []')
```
- If `next_action == "proceed"`:
```bash
# Update Story Progress: mark dev-story done
tmp_state=$(mktemp)
sed "s/^| ${story_id} |.*$/| ${story_id} | done | done | - | - | - | in-progress |/" "$state_file" > "$tmp_state" && mv "$tmp_state" "$state_file"
```
→ proceed to C (next step)
- If `next_action == "retry"` OR `result.final_state == "crashed"`:
- Attempts < 5 → retry with next agent (see `{retryStrategy}`)
- Plateau detected (same task 3x) → DEFER story, continue to next
- Attempts == 5 → escalate (all retries exhausted)
## Auto-Proceed to Review Phase
Display: "**Dev story complete. Proceeding to automate and code review...**"
```bash
"$scripts" orchestrator-helper state-update "$state_file" \
--set currentStep=step-03a-execute-review \
--set lastUpdated="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo "- **[$(date -u +%Y-%m-%dT%H:%M:%SZ)]** Dev complete, proceeding to review phase" >> "$state_file"
```
## Then
→ Immediately load and execute `{nextStep}`

View File

@@ -0,0 +1,119 @@
---
name: 'step-03a-execute-review'
description: 'Autonomous execution loop - automate and code review'
nextStep: './step-03b-execute-finish.md'
scriptsDir: '../scripts/story-automator'
outputFile: '{output_folder}/story-automator/orchestration-{epic_id}-{timestamp}.md'
retryStrategy: '../data/retry-fallback-strategy.md'
reviewLoop: '../data/code-review-loop.md'
---
# Step 3a: Execute Review Phase
**Goal:** Run automate (guardrails) and code review loop for the current story.
**Interaction mode:** Deterministic autonomous execution.
---
## Prerequisites
- Step 3 completed (create-story and dev-story done)
- State document updated with current story progress
Set: `scripts="{scriptsDir}"`
---
## Story Loop (Continue from Step 3)
### C. Automate (Guardrails)
*Skip if `overrides.skipAutomate`*
**Apply retry/fallback pattern from `{retryStrategy}`:** Non-blocking, but still retry on failure.
```bash
# --command required (see Spawn Pattern in step-03)
session=$("$scripts" tmux-wrapper spawn auto {epic} {story_id} \
--agent "$current_agent" \
--command "$("$scripts" tmux-wrapper build-cmd auto {story_id} --agent "$current_agent" --state-file "$state_file")")
result=$("$scripts" monitor-session "$session" --json --agent "$current_agent")
"$scripts" tmux-wrapper kill "$session"
```
- SUCCESS:
```bash
# Update Story Progress: mark automate done
tmp_state=$(mktemp)
sed "s/^| ${story_id} |.*$/| ${story_id} | done | done | done | - | - | in-progress |/" "{outputFile}" > "$tmp_state" && mv "$tmp_state" "{outputFile}"
```
Display: `[story {N}/{total}] automate -> done`
→ proceed to D
- FAILURE → retry up to 3 attempts (non-blocking, so fewer retries), then log warning:
```bash
# Update Story Progress: mark automate skipped
tmp_state=$(mktemp)
sed "s/^| ${story_id} |.*$/| ${story_id} | done | done | skip | - | - | in-progress |/" "{outputFile}" > "$tmp_state" && mv "$tmp_state" "{outputFile}"
```
Display: `[story {N}/{total}] automate -> skip (non-blocking)`
→ proceed to D
### D. Code Review Loop
**See `{reviewLoop}` for complete script-based review cycle with v2.3 per-task agent configuration.**
**MANDATORY log-summary contract (every review cycle):**
- Run a single grep/regex pass over review output first.
- Return only compact fields to parent flow: `next_action`, `confidence`, `error_class`, `issues_count`, `top_issues`.
- Do not carry full log payloads forward unless escalation requires raw evidence.
```bash
review_log=$(echo "$result" | jq -r '.output_file')
review_focus=$(grep -nE "SUCCESS|FAIL|ERROR|CRITICAL|WARN|RETRY|ESCALATE|ISSUE" "$review_log" | head -n 120)
if [ -z "$review_focus" ]; then
review_focus=$(tail -n 120 "$review_log")
fi
# Compact subprocess-style summary contract for parent flow
review_summary=$("$scripts" orchestrator-helper parse-output "$review_log" review --state-file "$state_file" | jq -c '
{
next_action: (.next_action // "retry"),
confidence: (.confidence // 0),
error_class: (.error_class // "unknown"),
issues_count: ((.issues // []) | length),
top_issues: ((.issues // [])[:3])
}
')
```
Key points:
- Up to 5 cycles using `story-automator tmux-wrapper spawn review` + `story-automator monitor-session`
- **Agent:** Uses per-task config from state document (`resolve_agent_for_task "review"`)
- **Verification:** Uses `--workflow review --story-key` for sprint-status verification
- **States:** `completed` (verified):
```bash
# Update Story Progress: mark code-review done
tmp_state=$(mktemp)
sed "s/^| ${story_id} |.*$/| ${story_id} | done | done | done | done | - | in-progress |/" "{outputFile}" > "$tmp_state" && mv "$tmp_state" "{outputFile}"
```
Display: `[story {N}/{total}] review -> done`
→ E | `incomplete` → count as failed attempt, retry until maxCycles, then CRITICAL escalate (Trigger #8)
- Exit loop when sprint-status shows "done"
- If `review_summary.next_action` is ambiguous, ask one clarifying question before escalating.
---
## Auto-Proceed to Finalization
Display: "**Code review complete. Proceeding to finalize commits and status checks...**"
```bash
"$scripts" orchestrator-helper state-update "{outputFile}" \
--set currentStep=step-03b-execute-finish \
--set lastUpdated="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo "- **[$(date -u +%Y-%m-%dT%H:%M:%SZ)]** Code review complete, proceeding to finalization" >> "{outputFile}"
```
---
## Then
→ Immediately load and execute `{nextStep}`

View File

@@ -0,0 +1,173 @@
---
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}`

View File

@@ -0,0 +1,68 @@
---
name: 'step-03c-execute-complete'
description: 'Post-loop completion summary, parallelism notes, and transition to wrapup'
nextStep: './step-04-wrapup.md'
scriptsDir: '../scripts/story-automator'
outputFile: '{output_folder}/story-automator/orchestration-{epic_id}-{timestamp}.md'
executionPatterns: '../data/execution-patterns.md'
retryStrategy: '../data/retry-fallback-strategy.md'
triggers: '../data/escalation-triggers.md'
---
# Step 3c: Execution Complete
**Goal:** Summarize results after all stories finish, persist final status, and transition to wrapup.
**Interaction mode:** Deterministic auto-proceed.
---
## All Complete
Display:
```
**All {count} stories completed!**
If `{count} <= 10`:
| Story | Status |
|-------|--------|
{summary_table}
If `{count} > 10`:
- Completed: {completed_count}
- Warnings: {warning_count}
- Escalations: {escalation_count}
- See state log for full per-story table.
Proceeding to wrap-up...
```
```bash
"{scriptsDir}" orchestrator-helper state-update "{outputFile}" \
--set status=EXECUTION_COMPLETE --set lastUpdated="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo "- **[$(date -u +%Y-%m-%dT%H:%M:%SZ)]** All stories complete — execution finished" >> "{outputFile}"
```
## Parallelism & Escalation
**Parallelism:** When `overrides.maxParallel > 1`, batch independent stories into concurrent groups:
1. Check story dependency graph — only stories with no shared file dependencies can run in parallel
2. Spawn up to `maxParallel` tmux sessions simultaneously (each runs steps A→F independently)
3. Wait for all sessions in the batch to complete before starting the next batch
4. Epic completion check (H) runs only after all batches finish
See `{executionPatterns}` for forbidden patterns and session isolation rules.
**Escalation:** See `{triggers}` for trigger definitions and `{retryStrategy}` for retry/fallback patterns. Escalation only after exhausting all retry attempts.
## Auto-Proceed to Wrap-up
Display: "**Execution loop complete. Proceeding to wrap-up...**"
```bash
"{scriptsDir}" orchestrator-helper state-update "{outputFile}" \
--set currentStep=step-04-wrapup \
--set lastUpdated="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
```
## Then
→ Immediately load and execute `{nextStep}`

View File

@@ -0,0 +1,132 @@
---
name: 'step-04-wrapup'
description: 'Finalize: summary, learnings, recommendations (terminal step)'
learningsFile: '{output_folder}/story-automator/learnings.md'
templates: '../data/wrapup-templates.md'
stateFilePattern: '{output_folder}/story-automator/orchestration-*.md'
outputFile: '{output_folder}/story-automator/orchestration-{epic_id}-{timestamp}.md'
stateHelper: '../scripts/story-automator'
stateMetrics: '../scripts/story-automator'
reportRetentionPolicy: '../data/report-retention-policy.md'
---
# Step 4: Wrap-up
**Goal:** Generate summary, capture learnings, finalize state.
**Interaction mode:** Structured wrap-up with recommendation output.
---
## Do
### 1. Load Final State
From state document (located via `{stateFilePattern}`; resolved path stored as `{outputFile}` for this run), extract:
- Story progress table
- Action log
- Session references
Calculate:
- Stories completed vs total
- Code review cycles
- Escalations encountered
Use the existing state document path from execution, and derive `story_range_csv` from frontmatter `storyRange`.
Deterministic metrics:
```bash
metrics=$("{stateMetrics}" state-metrics --state "{state_document_path}")
```
Parallel optimization (metrics + retention policy extraction):
```bash
tmp_metrics=$(mktemp)
tmp_retention=$(mktemp)
("{stateMetrics}" state-metrics --state "{state_document_path}" > "$tmp_metrics") &
metrics_pid=$!
(awk '/^```bash/{flag=1;next}/^```/{flag=0}flag{print}' "{reportRetentionPolicy}" > "$tmp_retention") &
retention_pid=$!
wait "$metrics_pid"
wait "$retention_pid"
metrics=$(cat "$tmp_metrics")
retention_cmds=$(cat "$tmp_retention")
rm -f "$tmp_metrics" "$tmp_retention"
```
**Optimization (data ops):** If action log exceeds 200 lines, use compact summary by default.
```bash
log_block=$(awk '/^## Action Log/{flag=1;next}/^## /{if(flag){exit}}flag{print}' "{state_document_path}")
log_lines=$(printf "%s\n" "$log_block" | wc -l | tr -d ' ')
if [ "$log_lines" -gt 200 ]; then
log_focus=$(printf "%s\n" "$log_block" | tail -n 50)
else
log_focus="$log_block"
fi
```
### 2. Generate Summary
From `{templates}`, use **Summary Report Template**.
Fill in all stats and display to user.
### 3. Capture Learnings
Analyze run for patterns:
- Common code review issues
- Steps needing escalation
- Timing patterns
- What worked well
**IF `{learningsFile}` exists:** Load and merge
**ELSE:** Create new
Append entry using **Learnings Entry Template** from `{templates}`.
### 4. Recommendations
From `{templates}`, use **Recommendations Template**.
Present actionable suggestions based on patterns observed.
### 4b. Validation Report Housekeeping
Load `{reportRetentionPolicy}` and apply its retention guidance when needed.
If validation report history is large, run the suggested maintenance command from that policy file.
### 5. Finalize State
Update state document:
- `status = 'COMPLETE'`
- `completedAt = {timestamp}`
- Append final summary to action log
Display: "**State document finalized.**"
### 6. Remove Marker File
Remove the active runtime marker:
```bash
"{stateHelper}" orchestrator-helper marker remove
```
This allows the Stop hook to stop normally after workflow completion by clearing the marker from the active runtime layout.
### 7. Workflow Complete
Display:
```
**🎉 Story Automator workflow complete!**
All stories have been processed through the build cycle.
Retrospectives were triggered automatically when each epic completed (during execution loop).
State document: {outputFile}
Learnings: {learningsFile}
```
Persist final state to `{outputFile}`.
---
## End
**Workflow terminates here.** Retrospectives are now handled within the execution loop (step-03b) when each epic completes, not as a separate terminal step.