better status loading and updating for phase 4

This commit is contained in:
Brian Madison 2025-10-25 14:26:30 -05:00
parent 994f251687
commit 5762941321
14 changed files with 288 additions and 1068 deletions

View File

@ -28,15 +28,19 @@
<action>READ COMPLETE FILES for all items found in the prioritized set. Store content and paths for citation.</action>
</step>
<step n="3" goal="Determine target story from sprint status">
<action>Query sprint-status for next backlog story:</action>
<step n="3" goal="Find next backlog story to draft" tag="sprint-status">
<critical>MUST read COMPLETE sprint-status.yaml file from start to end to preserve order</critical>
<action>Load the FULL file: {{output_folder}}/sprint-status.yaml</action>
<action>Read ALL lines from beginning to end - do not skip any content</action>
<action>Parse the development_status section completely to understand story order</action>
<invoke-workflow path="{project-root}/bmad/bmm/workflows/helpers/sprint-status">
<param>action: get_next_story</param>
<param>filter_status: backlog</param>
</invoke-workflow>
<action>Find the FIRST story (by reading in order from top to bottom) where:
- Key matches pattern: number-number-name (e.g., "1-2-user-auth")
- NOT an epic key (epic-X) or retrospective (epic-X-retrospective)
- Status value equals "backlog"
</action>
<check if="{{result_found}} == false">
<check if="no backlog story found">
<output>📋 No backlog stories found in sprint-status.yaml
All stories are either already drafted or completed.
@ -49,13 +53,16 @@ All stories are either already drafted or completed.
<action>HALT</action>
</check>
<action>Parse {{result_story_key}} to extract epic_num, story_num, and story_title
Example: "1-2-user-authentication" → epic_num=1, story_num=2, title="user-authentication"
<action>Extract from found story key (e.g., "1-2-user-authentication"):
- epic_num: first number before dash (e.g., "1")
- story_num: second number after first dash (e.g., "2")
- story_title: remainder after second dash (e.g., "user-authentication")
</action>
<action>Set {{story_id}} = "{{epic_num}}.{{story_num}}"</action>
<action>Store story_key for later use (e.g., "1-2-user-authentication")</action>
<action>Verify story is enumerated in {{epics_file}}. If not found, HALT with message:</action>
<action>"Story {{result_story_key}} not found in epics.md. Please load PM agent and run correct-course to sync epics, then rerun create-story."</action>
<action>"Story {{story_key}} not found in epics.md. Please load PM agent and run correct-course to sync epics, then rerun create-story."</action>
<action>Check if story file already exists at expected path in {{story_dir}}</action>
<check if="story file exists">
@ -97,19 +104,20 @@ Will update existing story file rather than creating new one.
<template-output file="{default_output_file}">change_log</template-output>
</step>
<step n="8" goal="Validate, save, and optionally generate context">
<step n="8" goal="Validate, save, and mark story drafted" tag="sprint-status">
<invoke-task>Validate against checklist at {installed_path}/checklist.md using bmad/core/tasks/validate-workflow.xml</invoke-task>
<action>Save document unconditionally (non-interactive default). In interactive mode, allow user confirmation.</action>
<invoke-workflow path="{project-root}/bmad/bmm/workflows/helpers/sprint-status">
<param>action: update_story_status</param>
<param>story_key: {{result_story_key}}</param>
<param>new_status: drafted</param>
<param>validate: true</param>
</invoke-workflow>
<!-- Mark story as drafted in sprint status -->
<action>Update {{output_folder}}/sprint-status.yaml</action>
<action>Load the FULL file and read all development_status entries</action>
<action>Find development_status key matching {{story_key}}</action>
<action>Verify current status is "backlog" (expected previous state)</action>
<action>Update development_status[{{story_key}}] = "drafted"</action>
<action>Save file, preserving ALL comments and structure including STATUS DEFINITIONS</action>
<check if="{{result_success}} == false">
<output>⚠️ Could not update story status: {{result_error}}
<check if="story key not found in file">
<output>⚠️ Could not update story status: {{story_key}} not found in sprint-status.yaml
Story file was created successfully, but sprint-status.yaml was not updated.
You may need to run sprint-planning to refresh tracking.
@ -122,9 +130,9 @@ You may need to run sprint-planning to refresh tracking.
**Story Details:**
- Story ID: {{story_id}}
- Story Key: {{result_story_key}}
- Story Key: {{story_key}}
- File: {{story_file}}
- Status: {{result_new_status}} (was {{result_old_status}})
- Status: drafted (was backlog)
**Next Steps:**
1. Review the drafted story in {{story_file}}

View File

@ -15,7 +15,7 @@
<workflow>
<step n="1" goal="Locate and load story from sprint status">
<step n="1" goal="Find next ready story and load it" tag="sprint-status">
<check if="{{story_path}} is provided">
<action>Use {{story_path}} directly</action>
<action>Read COMPLETE story file</action>
@ -23,14 +23,18 @@
<goto>task_check</goto>
</check>
<action>Query sprint-status for ready stories:</action>
<critical>MUST read COMPLETE sprint-status.yaml file from start to end to preserve order</critical>
<action>Load the FULL file: {{output_folder}}/sprint-status.yaml</action>
<action>Read ALL lines from beginning to end - do not skip any content</action>
<action>Parse the development_status section completely to understand story order</action>
<invoke-workflow path="{project-root}/bmad/bmm/workflows/helpers/sprint-status">
<param>action: get_next_story</param>
<param>filter_status: ready-for-dev</param>
</invoke-workflow>
<action>Find the FIRST story (by reading in order from top to bottom) where:
- Key matches pattern: number-number-name (e.g., "1-2-user-auth")
- NOT an epic key (epic-X) or retrospective (epic-X-retrospective)
- Status value equals "ready-for-dev"
</action>
<check if="{{result_found}} == false">
<check if="no ready-for-dev story found">
<output>📋 No ready-for-dev stories found in sprint-status.yaml
**Options:**
@ -41,9 +45,9 @@
<action>HALT</action>
</check>
<action>Use {{result_story_key}} to find story file in {{story_dir}}</action>
<action>Store the found story_key (e.g., "1-2-user-authentication") for later status updates</action>
<action>Find matching story file in {{story_dir}} using story_key pattern</action>
<action>Read COMPLETE story file from discovered path</action>
<action>Store {{result_story_key}} for later status updates</action>
<anchor id="task_check" />
@ -55,32 +59,30 @@
<action if="task requirements ambiguous">ASK user to clarify or HALT</action>
</step>
<step n="1.5" goal="Mark story in-progress in sprint status">
<invoke-workflow path="{project-root}/bmad/bmm/workflows/helpers/sprint-status">
<param>action: get_story_status</param>
<param>story_key: {{result_story_key}}</param>
</invoke-workflow>
<step n="1.5" goal="Mark story in-progress" tag="sprint-status">
<action>Load the FULL file: {{output_folder}}/sprint-status.yaml</action>
<action>Read all development_status entries to find {{story_key}}</action>
<action>Get current status value for development_status[{{story_key}}]</action>
<check if="{{result_status}} == 'ready-for-dev'">
<invoke-workflow path="{project-root}/bmad/bmm/workflows/helpers/sprint-status">
<param>action: update_story_status</param>
<param>story_key: {{result_story_key}}</param>
<param>new_status: in-progress</param>
<param>validate: true</param>
</invoke-workflow>
<check if="{{result_success}} == true">
<output>🚀 Starting work on story {{result_story_key}}
Status updated: {{result_old_status}} → {{result_new_status}}
</output>
</check>
<check if="current status == 'ready-for-dev'">
<action>Update development_status[{{story_key}}] = "in-progress"</action>
<action>Save file, preserving ALL comments and structure including STATUS DEFINITIONS</action>
<output>🚀 Starting work on story {{story_key}}
Status updated: ready-for-dev → in-progress
</output>
</check>
<check if="{{result_status}} == 'in-progress'">
<output>⏯️ Resuming work on story {{result_story_key}}
<check if="current status == 'in-progress'">
<output>⏯️ Resuming work on story {{story_key}}
Story is already marked in-progress
</output>
</check>
<check if="current status is neither ready-for-dev nor in-progress">
<output>⚠️ Unexpected story status: {{current_status}}
Expected ready-for-dev or in-progress. Continuing anyway...
</output>
</check>
</step>
<step n="2" goal="Plan and implement task">
@ -123,22 +125,22 @@ Story is already marked in-progress
<action if="no tasks remain"><goto step="6">Completion</goto></action>
</step>
<step n="6" goal="Story completion sequence">
<step n="6" goal="Story completion and mark for review" tag="sprint-status">
<action>Verify ALL tasks and subtasks are marked [x] (re-scan the story document now)</action>
<action>Run the full regression suite (do not skip)</action>
<action>Confirm File List includes every changed file</action>
<action>Execute story definition-of-done checklist, if the story includes one</action>
<action>Update the story Status to: Ready for Review</action>
<invoke-workflow path="{project-root}/bmad/bmm/workflows/helpers/sprint-status">
<param>action: update_story_status</param>
<param>story_key: {{result_story_key}}</param>
<param>new_status: review</param>
<param>validate: true</param>
</invoke-workflow>
<!-- Mark story ready for review -->
<action>Load the FULL file: {{output_folder}}/sprint-status.yaml</action>
<action>Find development_status key matching {{story_key}}</action>
<action>Verify current status is "in-progress" (expected previous state)</action>
<action>Update development_status[{{story_key}}] = "review"</action>
<action>Save file, preserving ALL comments and structure including STATUS DEFINITIONS</action>
<check if="{{result_success}} == false">
<output>⚠️ Story file updated, but sprint-status update failed: {{result_error}}
<check if="story key not found in file">
<output>⚠️ Story file updated, but sprint-status update failed: {{story_key}} not found
Story is marked Ready for Review in file, but sprint-status.yaml may be out of sync.
</output>
@ -157,10 +159,10 @@ Story is marked Ready for Review in file, but sprint-status.yaml may be out of s
**Story Details:**
- Story ID: {{current_story_id}}
- Story Key: {{result_story_key}}
- Story Key: {{story_key}}
- Title: {{current_story_title}}
- File: {{story_path}}
- Status: {{result_new_status}} (was {{result_old_status}})
- Status: review (was in-progress)
**Next Steps:**
1. Review the implemented story and test the changes

View File

@ -16,13 +16,15 @@
<action>Resolve output file path using workflow variables and initialize by writing the template.</action>
</step>
<step n="1.5" goal="Validate epic in sprint status">
<invoke-workflow path="{project-root}/bmad/bmm/workflows/helpers/sprint-status">
<param>action: get_epic_status</param>
<param>epic_id: {{epic_id}}</param>
</invoke-workflow>
<step n="1.5" goal="Validate epic exists in sprint status" tag="sprint-status">
<critical>MUST read COMPLETE sprint-status.yaml file to find epic status</critical>
<action>Load the FULL file: {{output_folder}}/sprint-status.yaml</action>
<action>Read ALL development_status entries</action>
<check if="{{result_found}} == false">
<action>Look for epic key "epic-{{epic_id}}" in development_status</action>
<action>Get current status value if epic exists</action>
<check if="epic not found">
<output>⚠️ Epic {{epic_id}} not found in sprint-status.yaml
This epic hasn't been registered in the sprint plan yet.
@ -31,7 +33,7 @@ Run sprint-planning workflow to initialize epic tracking.
<action>HALT</action>
</check>
<check if="{{result_status}} == 'contexted'">
<check if="epic status == 'contexted'">
<output> Epic {{epic_id}} already marked as contexted
Continuing to regenerate tech spec...
@ -89,17 +91,18 @@ Continuing to regenerate tech spec...
</template-output>
</step>
<step n="8" goal="Validate and complete">
<step n="8" goal="Validate and mark epic contexted" tag="sprint-status">
<invoke-task>Validate against checklist at {installed_path}/checklist.md using bmad/core/tasks/validate-workflow.xml</invoke-task>
<invoke-workflow path="{project-root}/bmad/bmm/workflows/helpers/sprint-status">
<param>action: update_epic_status</param>
<param>epic_id: {{epic_id}}</param>
<param>new_status: contexted</param>
</invoke-workflow>
<!-- Mark epic as contexted -->
<action>Load the FULL file: {{output_folder}}/sprint-status.yaml</action>
<action>Find development_status key "epic-{{epic_id}}"</action>
<action>Verify current status is "backlog" (expected previous state)</action>
<action>Update development_status["epic-{{epic_id}}"] = "contexted"</action>
<action>Save file, preserving ALL comments and structure including STATUS DEFINITIONS</action>
<check if="{{result_success}} == false">
<output>⚠️ Could not update epic status: {{result_error}}</output>
<check if="epic key not found in file">
<output>⚠️ Could not update epic status: epic-{{epic_id}} not found</output>
</check>
<output>**✅ Tech Spec Generated Successfully, {user_name}!**
@ -108,7 +111,7 @@ Continuing to regenerate tech spec...
- Epic ID: {{epic_id}}
- Epic Title: {{epic_title}}
- Tech Spec File: {{default_output_file}}
- Epic Status: {{result_new_status}} (was {{result_old_status}})
- Epic Status: contexted (was backlog)
**Note:** This is a JIT (Just-In-Time) workflow - run again for other epics as needed.

View File

@ -20,30 +20,40 @@ FACILITATION NOTES:
<workflow>
<step n="1" goal="Epic Context Discovery">
<step n="1" goal="Epic Context Discovery and verify completion" tag="sprint-status">
<action>Help the user identify which epic was just completed through natural conversation</action>
<action>Attempt to auto-detect by checking {output_folder}/stories/ for the highest numbered completed story and extracting the epic number</action>
<action>If auto-detection succeeds, confirm with user: "It looks like Epic {{epic_number}} was just completed - is that correct?"</action>
<action>If auto-detection fails or user indicates different epic, ask them to share which epic they just completed</action>
<action>Verify epic completion status in sprint-status:</action>
<action>Verify epic completion status:</action>
<invoke-workflow path="{project-root}/bmad/bmm/workflows/helpers/sprint-status">
<param>action: check_epic_complete</param>
<param>epic_id: {{epic_number}}</param>
</invoke-workflow>
<action>Load the FULL file: {{output_folder}}/sprint-status.yaml</action>
<action>Read ALL development_status entries</action>
<check if="{{result_complete}} == false">
<action>Find all stories for epic {{epic_number}}:
- Look for keys starting with "{{epic_number}}-" (e.g., "1-1-", "1-2-", etc.)
- Exclude epic key itself ("epic-{{epic_number}}")
- Exclude retrospective key ("epic-{{epic_number}}-retrospective")
</action>
<action>Count total stories found for this epic</action>
<action>Count stories with status = "done"</action>
<action>Collect list of pending story keys (status != "done")</action>
<action>Determine if complete: true if all stories are done, false otherwise</action>
<check if="epic is not complete">
<output>⚠️ Epic {{epic_number}} is not yet complete for retrospective
**Epic Status:**
- Total Stories: {{result_total_stories}}
- Completed (Done): {{result_done_stories}}
- Pending: {{result_total_stories - result_done_stories}}
- Total Stories: {{total_stories}}
- Completed (Done): {{done_stories}}
- Pending: {{pending_count}}
**Pending Stories:**
{{result_pending_stories}}
{{pending_story_list}}
**Options:**
@ -61,8 +71,8 @@ FACILITATION NOTES:
<action if="user says yes">Set {{partial_retrospective}} = true</action>
</check>
<check if="{{result_complete}} == true">
<output>✅ Epic {{epic_number}} is complete - all {{result_done_stories}} stories done!
<check if="epic is complete">
<output>✅ Epic {{epic_number}} is complete - all {{done_stories}} stories done!
Ready to proceed with retrospective.
</output>
@ -403,27 +413,32 @@ See you at sprint planning once prep work is done!"
```
<action>Save retrospective summary to: {output_folder}/retrospectives/epic-{{completed_number}}-retro-{{date}}.md</action>
</step>
<invoke-workflow path="{project-root}/bmad/bmm/workflows/helpers/sprint-status">
<param>action: complete_retrospective</param>
<param>epic_id: {{completed_number}}</param>
</invoke-workflow>
<step n="9" goal="Mark retrospective completed in sprint status" tag="sprint-status">
<action>Load the FULL file: {{output_folder}}/sprint-status.yaml</action>
<action>Find development_status key "epic-{{completed_number}}-retrospective"</action>
<action>Verify current status is "optional" (expected previous state)</action>
<action>Update development_status["epic-{{completed_number}}-retrospective"] = "completed"</action>
<action>Save file, preserving ALL comments and structure including STATUS DEFINITIONS</action>
<check if="{{result_success}} == true">
<check if="update successful">
<output>✅ Retrospective marked as completed in sprint-status.yaml
Retrospective key: {{result_retro_key}}
Status: {{result_old_status}} → {{result_new_status}}
Retrospective key: epic-{{completed_number}}-retrospective
Status: optional → completed
</output>
</check>
<check if="{{result_success}} == false">
<output>⚠️ Could not update retrospective status: {{result_error}}
<check if="retrospective key not found">
<output>⚠️ Could not update retrospective status: epic-{{completed_number}}-retrospective not found
Retrospective document was saved, but sprint-status.yaml may need manual update.
</output>
</check>
</step>
<step n="10" goal="Final summary">
<action>Confirm all action items have been captured</action>
<action>Remind user to schedule prep sprint if needed</action>
<output>**✅ Retrospective Complete, {user_name}!**
@ -431,7 +446,7 @@ Retrospective document was saved, but sprint-status.yaml may need manual update.
**Epic Review:**
- Epic {{completed_number}}: {{epic_title}} reviewed
- Retrospective Status: {{result_new_status}}
- Retrospective Status: completed
- Retrospective saved: {output_folder}/retrospectives/epic-{{completed_number}}-retro-{{date}}.md
- Action Items: {{action_count}}
- Preparation Tasks: {{prep_task_count}}

View File

@ -14,7 +14,7 @@
<workflow>
<step n="1" goal="Locate story and verify review status">
<step n="1" goal="Find story ready for review" tag="sprint-status">
<check if="{{story_path}} is provided">
<action>Use {{story_path}} directly</action>
<action>Read COMPLETE file and parse sections</action>
@ -22,15 +22,21 @@
<goto>verify_status</goto>
</check>
<action>Query sprint-status for review stories:</action>
<critical>MUST read COMPLETE sprint-status.yaml file from start to end to preserve order</critical>
<action>Load the FULL file: {{output_folder}}/sprint-status.yaml</action>
<action>Read ALL lines from beginning to end - do not skip any content</action>
<action>Parse the development_status section completely</action>
<invoke-workflow path="{project-root}/bmad/bmm/workflows/helpers/sprint-status">
<param>action: list_stories</param>
<param>filter_status: review</param>
<param>limit: 10</param>
</invoke-workflow>
<action>Find ALL stories (reading in order from top to bottom) where:
- Key matches pattern: number-number-name (e.g., "1-2-user-auth")
- NOT an epic key (epic-X) or retrospective (epic-X-retrospective)
- Status value equals "review"
</action>
<check if="{{result_count}} == 0">
<action>Collect up to 10 review story keys in order (limit for display purposes)</action>
<action>Count total review stories found</action>
<check if="no review stories found">
<output>📋 No stories in review status found
**Options:**
@ -42,14 +48,14 @@
<action>Display available review stories:
**Stories Ready for Review ({{result_count}} found):**
**Stories Ready for Review ({{review_count}} found):**
{{result_story_list}}
{{list_of_review_story_keys}}
</action>
<ask if="{{non_interactive}} == false">Select story to review (enter story key or number):</ask>
<action if="{{non_interactive}} == true">Auto-select first story from result_stories</action>
<action if="{{non_interactive}} == true">Auto-select first story from the list</action>
<action>Resolve selected story_key and find file path in {{story_dir}}</action>
<action>Resolve {{story_path}} and read the COMPLETE file</action>
@ -118,26 +124,25 @@
<action>Save the story file.</action>
</step>
<step n="7.5" goal="Update sprint-status based on review outcome">
<step n="7.5" goal="Update sprint status based on review outcome" tag="sprint-status">
<action>Determine target status based on review outcome:
- If {{outcome}} == "Approve" → target_status = "done"
- If {{outcome}} == "Changes Requested" → target_status = "in-progress"
- If {{outcome}} == "Blocked" → target_status = "review" (stay in review)
</action>
<invoke-workflow path="{project-root}/bmad/bmm/workflows/helpers/sprint-status">
<param>action: update_story_status</param>
<param>story_key: {{story_key}}</param>
<param>new_status: {{target_status}}</param>
<param>validate: true</param>
</invoke-workflow>
<action>Load the FULL file: {{output_folder}}/sprint-status.yaml</action>
<action>Read all development_status entries to find {{story_key}}</action>
<action>Verify current status is "review" (expected previous state)</action>
<action>Update development_status[{{story_key}}] = {{target_status}}</action>
<action>Save file, preserving ALL comments and structure including STATUS DEFINITIONS</action>
<check if="{{result_success}} == true">
<output>✅ Sprint status updated: {{result_old_status}} → {{result_new_status}}</output>
<check if="update successful">
<output>✅ Sprint status updated: review → {{target_status}}</output>
</check>
<check if="{{result_success}} == false">
<output>⚠️ Could not update sprint-status: {{result_error}}
<check if="story key not found">
<output>⚠️ Could not update sprint-status: {{story_key}} not found
Review was saved to story file, but sprint-status.yaml may be out of sync.
</output>
@ -170,7 +175,7 @@ Review was saved to story file, but sprint-status.yaml may be out of sync.
- Story: {{epic_num}}.{{story_num}}
- Story Key: {{story_key}}
- Review Outcome: {{outcome}}
- Sprint Status: {{result_new_status}}
- Sprint Status: {{target_status}}
- Action Items: {{action_item_count}}
**Next Steps:**

View File

@ -11,12 +11,52 @@
<critical>DOCUMENT OUTPUT: Technical XML context file. Concise, structured, project-relative paths only. User skill level ({user_skill_level}) affects conversation style ONLY, not context content.</critical>
<workflow>
<step n="1" goal="Locate story and initialize output">
<action>If {{story_path}} provided and valid → use it; else auto-discover from {{story_dir}}.</action>
<action>Auto-discovery: read {{story_dir}} (dev_story_location). If invalid/missing or contains no .md files, ASK for a story file path or directory to scan.</action>
<action>If a directory is provided, list markdown files named "story-*.md" recursively; sort by last modified time; display top {{story_selection_limit}} with index, filename, path, modified time.</action>
<ask optional="true" if="{{non_interactive}} == false">"Select a story (1-{{story_selection_limit}}) or enter a path:"</ask>
<action>If {{non_interactive}} == true: choose the most recently modified story automatically. If none found, HALT with a clear message to provide 'story_path' or 'story_dir'. Else resolve selection into {{story_path}} and READ COMPLETE file.</action>
<step n="1" goal="Find drafted story from sprint status" tag="sprint-status">
<action>If {{story_path}} provided and valid → use it; extract story_key from filename/metadata; GOTO initialize_context</action>
<critical>MUST read COMPLETE sprint-status.yaml file from start to end to preserve order</critical>
<action>Load the FULL file: {{output_folder}}/sprint-status.yaml</action>
<action>Read ALL lines from beginning to end - do not skip any content</action>
<action>Parse the development_status section completely</action>
<action>Find ALL stories (reading in order from top to bottom) where:
- Key matches pattern: number-number-name (e.g., "1-2-user-auth")
- NOT an epic key (epic-X) or retrospective (epic-X-retrospective)
- Status value equals "drafted"
</action>
<action>Collect up to 10 drafted story keys in order (limit for display purposes)</action>
<action>Count total drafted stories found</action>
<check if="no drafted stories found">
<output>📋 No drafted stories found in sprint-status.yaml
All stories are either still in backlog or already marked ready/in-progress/done.
**Options:**
1. Run `create-story` to draft more stories
2. Run `sprint-planning` to refresh story tracking
</output>
<action>HALT</action>
</check>
<action>Display available drafted stories:
**Drafted Stories Available ({{drafted_count}} found):**
{{list_of_drafted_story_keys}}
</action>
<ask if="{{non_interactive}} == false">Select the drafted story to generate context for (enter story key or number):</ask>
<action if="{{non_interactive}} == true">Auto-select first story from the list</action>
<action>Resolve selected story_key from user input or auto-selection</action>
<action>Find matching story file in {{story_dir}} using story_key pattern</action>
<action>Resolve {{story_path}} and READ COMPLETE file</action>
<anchor id="initialize_context" />
<action>Extract {{epic_id}}, {{story_id}}, {{story_title}}, {{story_status}} from filename/content; parse sections: Story, Acceptance Criteria, Tasks/Subtasks, Dev Notes.</action>
<action>Extract user story fields (asA, iWant, soThat).</action>
<action>Store project root path for relative path conversion: extract from {project-root} variable.</action>
@ -91,16 +131,36 @@
<invoke-task>Validate against checklist at {installed_path}/checklist.md using bmad/core/tasks/validate-workflow.xml</invoke-task>
</step>
<step n="7" goal="Update story status and context reference">
<action>Open {{story_path}}; if Status == 'Draft' then set to 'ContextReadyDraft'; otherwise leave unchanged.</action>
<step n="7" goal="Update story file and mark ready for dev" tag="sprint-status">
<action>Open {{story_path}}</action>
<action>Find the "Status:" line (usually at the top)</action>
<action>Update story file: Change Status to "Ready"</action>
<action>Under 'Dev Agent Record' → 'Context Reference' (create if missing), add or update a list item for {default_output_file}.</action>
<action>Save the story file.</action>
<!-- Update sprint status to mark ready-for-dev -->
<action>Load the FULL file: {{output_folder}}/sprint-status.yaml</action>
<action>Find development_status key matching {{story_key}}</action>
<action>Verify current status is "drafted" (expected previous state)</action>
<action>Update development_status[{{story_key}}] = "ready-for-dev"</action>
<action>Save file, preserving ALL comments and structure including STATUS DEFINITIONS</action>
<check if="story key not found in file">
<output>⚠️ Story file updated, but could not update sprint-status: {{story_key}} not found
You may need to run sprint-planning to refresh tracking.
</output>
</check>
<output>**✅ Story Context Generated Successfully, {user_name}!**
**Story Details:**
- Story ID: {{story_id}}
- Story Key: {{story_key}}
- Title: {{story_title}}
- Context File: {{default_output_file}}
- Story Status: Ready (was Draft)
- Sprint Status: ready-for-dev (was drafted)
**Next Steps:**
1. Load DEV agent (bmad/bmm/agents/dev.md)

View File

@ -10,19 +10,26 @@
<critical>This workflow is run by DEV agent AFTER user confirms a story is approved (Definition of Done is complete)</critical>
<critical>Workflow: Update story file status to Done</critical>
<step n="1" goal="Find reviewed story and mark done">
<step n="1" goal="Find reviewed story to mark done" tag="sprint-status">
<action>If {{story_path}} is provided → use it directly; extract story_key from filename or metadata; GOTO mark_done</action>
<action>Otherwise query sprint-status for reviewed stories:</action>
<critical>MUST read COMPLETE sprint-status.yaml file from start to end to preserve order</critical>
<action>Load the FULL file: {{output_folder}}/sprint-status.yaml</action>
<action>Read ALL lines from beginning to end - do not skip any content</action>
<action>Parse the development_status section completely</action>
<invoke-workflow path="{project-root}/bmad/bmm/workflows/helpers/sprint-status">
<param>action: list_stories</param>
<param>filter_status: review</param>
<param>limit: 10</param>
</invoke-workflow>
<action>Find ALL stories (reading in order from top to bottom) where:
<check if="{{result_count}} == 0">
- Key matches pattern: number-number-name (e.g., "1-2-user-auth")
- NOT an epic key (epic-X) or retrospective (epic-X-retrospective)
- Status value equals "review"
</action>
<action>Collect up to 10 review story keys in order (limit for display purposes)</action>
<action>Count total review stories found</action>
<check if="no review stories found">
<output>📋 No stories in review status found
All stories are either still in development or already done.
@ -38,9 +45,9 @@ All stories are either still in development or already done.
<action>Display available reviewed stories:
**Stories Ready to Mark Done ({{result_count}} found):**
**Stories Ready to Mark Done ({{review_count}} found):**
{{result_story_list}}
{{list_of_review_story_keys}}
</action>
@ -69,16 +76,17 @@ All stories are either still in development or already done.
</action>
<action>Save the story file</action>
</step>
<invoke-workflow path="{project-root}/bmad/bmm/workflows/helpers/sprint-status">
<param>action: update_story_status</param>
<param>story_key: {{story_key}}</param>
<param>new_status: done</param>
<param>validate: true</param>
</invoke-workflow>
<step n="2" goal="Update sprint status to done" tag="sprint-status">
<action>Load the FULL file: {{output_folder}}/sprint-status.yaml</action>
<action>Find development_status key matching {{story_key}}</action>
<action>Verify current status is "review" (expected previous state)</action>
<action>Update development_status[{{story_key}}] = "done"</action>
<action>Save file, preserving ALL comments and structure including STATUS DEFINITIONS</action>
<check if="{{result_success}} == false">
<output>⚠️ Story file updated, but could not update sprint-status: {{result_error}}
<check if="story key not found in file">
<output>⚠️ Story file updated, but could not update sprint-status: {{story_key}} not found
Story is marked Done in file, but sprint-status.yaml may be out of sync.
</output>
@ -86,12 +94,12 @@ Story is marked Done in file, but sprint-status.yaml may be out of sync.
</step>
<step n="2" goal="Confirm completion to user">
<step n="3" goal="Confirm completion to user">
<output>**Story Approved and Marked Done, {user_name}!**
✅ Story file updated: `{{story_file}}` → Status: Done
✅ Sprint status updated: {{result_old_status}} → {{result_new_status}}
✅ Sprint status updated: review → done
**Completed Story:**

View File

@ -10,19 +10,26 @@
<critical>This workflow is run by SM agent AFTER user reviews a drafted story and confirms it's ready for development</critical>
<critical>Simple workflow: Update story file status to Ready</critical>
<step n="1" goal="Find drafted story and mark as ready">
<step n="1" goal="Find drafted story to mark ready" tag="sprint-status">
<action>If {{story_path}} is provided → use it directly; extract story_key from filename or metadata; GOTO mark_ready</action>
<action>Otherwise query sprint-status for drafted stories:</action>
<critical>MUST read COMPLETE sprint-status.yaml file from start to end to preserve order</critical>
<action>Load the FULL file: {{output_folder}}/sprint-status.yaml</action>
<action>Read ALL lines from beginning to end - do not skip any content</action>
<action>Parse the development_status section completely</action>
<invoke-workflow path="{project-root}/bmad/bmm/workflows/helpers/sprint-status">
<param>action: list_stories</param>
<param>filter_status: drafted</param>
<param>limit: 10</param>
</invoke-workflow>
<action>Find ALL stories (reading in order from top to bottom) where:
<check if="{{result_count}} == 0">
- Key matches pattern: number-number-name (e.g., "1-2-user-auth")
- NOT an epic key (epic-X) or retrospective (epic-X-retrospective)
- Status value equals "drafted"
</action>
<action>Collect up to 10 drafted story keys in order (limit for display purposes)</action>
<action>Count total drafted stories found</action>
<check if="no drafted stories found">
<output>📋 No drafted stories found in sprint-status.yaml
All stories are either still in backlog or already marked ready/in-progress/done.
@ -37,14 +44,14 @@ All stories are either still in backlog or already marked ready/in-progress/done
<action>Display available drafted stories:
**Drafted Stories Available ({{result_count}} found):**
**Drafted Stories Available ({{drafted_count}} found):**
{{result_story_list}}
{{list_of_drafted_story_keys}}
</action>
<ask if="{{non_interactive}} == false">Select the drafted story to mark as Ready (enter story key or number):</ask>
<action if="{{non_interactive}} == true">Auto-select first story from result_stories</action>
<action if="{{non_interactive}} == true">Auto-select first story from the list</action>
<action>Resolve selected story_key from user input or auto-selection</action>
<action>Find matching story file in {{story_dir}} using story_key pattern</action>
@ -57,16 +64,17 @@ All stories are either still in backlog or already marked ready/in-progress/done
<action>Find the "Status:" line (usually at the top)</action>
<action>Update story file: Change Status to "Ready"</action>
<action>Save the story file</action>
</step>
<invoke-workflow path="{project-root}/bmad/bmm/workflows/helpers/sprint-status">
<param>action: update_story_status</param>
<param>story_key: {{story_key}}</param>
<param>new_status: ready-for-dev</param>
<param>validate: true</param>
</invoke-workflow>
<step n="2" goal="Update sprint status to ready-for-dev" tag="sprint-status">
<action>Load the FULL file: {{output_folder}}/sprint-status.yaml</action>
<action>Find development_status key matching {{story_key}}</action>
<action>Verify current status is "drafted" (expected previous state)</action>
<action>Update development_status[{{story_key}}] = "ready-for-dev"</action>
<action>Save file, preserving ALL comments and structure including STATUS DEFINITIONS</action>
<check if="{{result_success}} == false">
<output>⚠️ Story file updated, but could not update sprint-status: {{result_error}}
<check if="story key not found in file">
<output>⚠️ Story file updated, but could not update sprint-status: {{story_key}} not found
You may need to run sprint-planning to refresh tracking.
</output>
@ -74,12 +82,12 @@ You may need to run sprint-planning to refresh tracking.
</step>
<step n="2" goal="Confirm completion to user">
<step n="3" goal="Confirm completion to user">
<output>**Story Marked Ready for Development, {user_name}!**
✅ Story file updated: `{{story_file}}` → Status: Ready
✅ Sprint status updated: {{result_old_status}} → {{result_new_status}}
✅ Sprint status updated: drafted → ready-for-dev
**Story Details:**

View File

@ -1,292 +0,0 @@
# Sprint Status Helper
**Purpose:** Utility workflow for reading and updating `sprint-status.yaml` tracking file used across Phase 4 implementation workflows.
**Location:** `src/modules/bmm/workflows/helpers/sprint-status/`
**Status File:** `{output_folder}/sprint-status.yaml` (created by sprint-planning workflow)
---
## Quick Reference
### Usage Pattern
```xml
<invoke-workflow path="{project-root}/bmad/bmm/workflows/helpers/sprint-status">
<param>action: ACTION_NAME</param>
<param>PARAM_NAME: value</param>
<!-- Optional params -->
</invoke-workflow>
<!-- Use returned variables -->
<action>Do something with {{result_*}} variables</action>
```
---
## Available Actions
### Read Operations
| Action | Purpose | Key Parameters | Key Returns |
| --------------------- | ---------------------------- | --------------------------------------- | ----------------------------------------------------------------------------- |
| `get_next_story` | Find first story by status | `filter_status`, `epic_filter` | `result_found`, `result_story_key`, `result_epic_id`, `result_story_id` |
| `list_stories` | Get all matching stories | `filter_status`, `epic_filter`, `limit` | `result_count`, `result_stories`, `result_story_list` |
| `get_story_status` | Check story's current status | `story_key` | `result_found`, `result_status` |
| `get_epic_status` | Check epic status + stats | `epic_id` | `result_status`, `result_story_count`, `result_done_count`, `result_complete` |
| `check_epic_complete` | Verify all stories done | `epic_id` | `result_complete`, `result_pending_stories` |
| `get_metadata` | Get project info from file | none | `result_project`, `result_story_location`, `result_generated_date` |
| `get_file_path` | Get file location | none | `result_file_path`, `result_exists` |
### Write Operations
| Action | Purpose | Key Parameters | Key Returns |
| ------------------------ | ---------------------- | ------------------------------------- | ---------------------------------------------------------- |
| `update_story_status` | Change story status | `story_key`, `new_status`, `validate` | `result_success`, `result_old_status`, `result_new_status` |
| `update_epic_status` | Mark epic as contexted | `epic_id`, `new_status` | `result_success`, `result_old_status`, `result_new_status` |
| `complete_retrospective` | Mark epic retro done | `epic_id` | `result_success`, `result_retro_key` |
### Utility Operations
| Action | Purpose | Key Parameters | Key Returns |
| --------------------- | ------------------------------- | -------------------------- | --------------------------------------------------------- |
| `validate_transition` | Check if status change is legal | `from_status`, `to_status` | `result_valid`, `result_message`, `result_suggested_path` |
---
## Status Flow Reference
**Epic Status:**
```
backlog → contexted
```
**Story Status:**
```
backlog → drafted → ready-for-dev → in-progress → review → done
↑_________ Corrections allowed (backward movement) ________
```
**Retrospective Status:**
```
optional ↔ completed
```
---
## Common Patterns
### Pattern 1: Find and Update Next Story
```xml
<!-- Find next backlog story -->
<invoke-workflow path="{project-root}/bmad/bmm/workflows/helpers/sprint-status">
<param>action: get_next_story</param>
<param>filter_status: backlog</param>
</invoke-workflow>
<check if="{{result_found}} == true">
<action>Work on story: {{result_story_key}}</action>
<!-- Update status after work -->
<invoke-workflow path="{project-root}/bmad/bmm/workflows/helpers/sprint-status">
<param>action: update_story_status</param>
<param>story_key: {{result_story_key}}</param>
<param>new_status: drafted</param>
</invoke-workflow>
</check>
<check if="{{result_found}} == false">
<output>No backlog stories available</output>
</check>
```
### Pattern 2: List Stories for User Selection
```xml
<!-- Get all drafted stories -->
<invoke-workflow path="{project-root}/bmad/bmm/workflows/helpers/sprint-status">
<param>action: list_stories</param>
<param>filter_status: drafted</param>
<param>limit: 10</param>
</invoke-workflow>
<check if="{{result_count}} > 0">
<output>Available drafted stories ({{result_count}} found):
{{result_story_list}}
</output>
<ask>Select a story to work on:</ask>
</check>
```
### Pattern 3: Check Epic Completion Before Retrospective
```xml
<!-- Verify epic is complete -->
<invoke-workflow path="{project-root}/bmad/bmm/workflows/helpers/sprint-status">
<param>action: check_epic_complete</param>
<param>epic_id: 1</param>
</invoke-workflow>
<check if="{{result_complete}} == true">
<output>Epic 1 is complete! Ready for retrospective.</output>
<!-- Mark retrospective as completed -->
<invoke-workflow path="{project-root}/bmad/bmm/workflows/helpers/sprint-status">
<param>action: complete_retrospective</param>
<param>epic_id: 1</param>
</invoke-workflow>
</check>
<check if="{{result_complete}} == false">
<output>Epic 1 has {{result_total_stories - result_done_stories}} pending stories:
{{result_pending_stories}}
</output>
</check>
```
### Pattern 4: Validate Before Update
```xml
<!-- Check if transition is legal first -->
<invoke-workflow path="{project-root}/bmad/bmm/workflows/helpers/sprint-status">
<param>action: validate_transition</param>
<param>from_status: drafted</param>
<param>to_status: in-progress</param>
</invoke-workflow>
<check if="{{result_valid}} == false">
<output>Cannot transition directly from drafted to in-progress.
{{result_suggested_path}}
</output>
<action>HALT</action>
</check>
```
### Pattern 5: Mark Epic Contexted
```xml
<!-- After creating epic tech context -->
<invoke-workflow path="{project-root}/bmad/bmm/workflows/helpers/sprint-status">
<param>action: update_epic_status</param>
<param>epic_id: {{epic_num}}</param>
<param>new_status: contexted</param>
</invoke-workflow>
```
---
## Return Variables
**All actions return:**
- `result_success`: `true` | `false`
- `result_error`: Error message (if `result_success == false`)
**Common additional returns:**
- `result_found`: `true` | `false` (for query operations)
- `result_status`: Current status value
- `result_old_status`: Previous status (for updates)
- `result_new_status`: Updated status (for updates)
- `result_story_key`: Story key like "1-1-story-name"
- `result_epic_id`: Epic number extracted from key
- `result_story_id`: Story number extracted from key
---
## Error Handling
**File Not Found:**
```xml
<check if="{{result_error}} == 'file_not_found'">
<output>Sprint status file not found.
Run sprint-planning workflow first to initialize tracking.
</output>
<action>HALT</action>
</check>
```
**Story Not Found:**
```xml
<check if="{{result_found}} == false">
<output>Story {{story_key}} not found in sprint-status.yaml.
Run sprint-planning to refresh tracking.
</output>
</check>
```
**Invalid Transition:**
```xml
<check if="{{result_success}} == false AND {{result_validation_message}} != ''">
<output>{{result_error}}
{{result_validation_message}}
</output>
</check>
```
---
## Options
| Parameter | Default | Description |
| ------------- | ------- | ---------------------------------------------------------- |
| `validate` | `true` | Enforce legal status transitions for `update_story_status` |
| `dry_run` | `false` | Test update without saving (for debugging) |
| `show_output` | `true` | Helper displays status messages (✅/❌/📋) |
---
## Integration Checklist
When adding sprint-status helper to a workflow:
- [ ] Add `sprint_status_file` variable to workflow.yaml if needed
- [ ] Use `invoke-workflow` with correct action parameter
- [ ] Check `result_success` and `result_found` before proceeding
- [ ] Handle `result_error == 'file_not_found'` case
- [ ] Use returned `result_*` variables in workflow logic
- [ ] Update status at appropriate workflow steps
---
## Workflow Integration Map
| Workflow | Actions Used | When |
| --------------------- | ------------------------------------------------- | ------------------------------------------- |
| **epic-tech-context** | `get_epic_status`<br>`update_epic_status` | Check epic exists → Mark contexted |
| **create-story** | `get_next_story`<br>`update_story_status` | Find backlog → Mark drafted |
| **story-ready** | `list_stories`<br>`update_story_status` | List drafted → Mark ready-for-dev |
| **story-context** | `get_next_story` | Find drafted (read-only) |
| **dev-story** | `get_next_story`<br>`update_story_status` (2x) | Find ready → Mark in-progress → Mark review |
| **review-story** | `list_stories`<br>`update_story_status` | List review → Update based on outcome |
| **story-done** | `list_stories`<br>`update_story_status` | List review → Mark done |
| **retrospective** | `check_epic_complete`<br>`complete_retrospective` | Verify complete → Mark retro done |
---
## Notes
- **Source of Truth:** File system is authoritative. Sprint-planning regenerates from epics + file detection.
- **Refresh Strategy:** Re-run sprint-planning anytime to resync tracking with actual files.
- **Concurrency:** Not designed for concurrent access. Single-user CLI workflow execution.
- **Alpha Status:** No backward compatibility. Re-run sprint-planning with latest version before using.
---
## Examples in Context
See individual workflow instructions in `src/modules/bmm/workflows/4-implementation/` for integration examples.
**Helper Files:**
- `workflow.yaml` - Interface definition
- `instructions.md` - Action implementation logic
- `README.md` - This file

View File

@ -1,542 +0,0 @@
# Sprint Status Helper - Workflow Instructions
<critical>The workflow execution engine is governed by: {project-root}/bmad/core/tasks/workflow.xml</critical>
<critical>You MUST have already loaded and processed: {installed_path}/workflow.yaml</critical>
<critical>Communicate all responses in {communication_language}</critical>
<critical>This is a HELPER workflow - it performs operations on sprint-status.yaml and returns results to the calling workflow via variables</critical>
<workflow>
<step n="1" goal="Validate action parameter and load sprint status file">
<action>Check if {{action}} parameter is provided and not empty</action>
<check if="{{action}} is empty or not provided">
<action>Set result_success = false</action>
<action>Set result_error = "Action parameter is required. See workflow.yaml for supported actions."</action>
<output>❌ Sprint Status Helper Error: No action specified</output>
<action>HALT - return to calling workflow with error</action>
</check>
<action>Check if sprint status file exists at {status_file}</action>
<check if="file does not exist">
<action>Set result_success = false</action>
<action>Set result_error = "file_not_found"</action>
<action>Set result_file_path = {status_file}</action>
<check if="{{show_output}} == true">
<output>❌ Sprint status file not found at: {status_file}
Please run the sprint-planning workflow first to initialize tracking.
</output>
</check>
<action>HALT - return to calling workflow with error</action>
</check>
<action>Read complete sprint status file from {status_file}</action>
<action>Parse YAML structure into memory</action>
<action>Extract metadata fields: generated, project, project_key, tracking_system, story_location</action>
<action>Extract development_status map: all epic and story keys with their current status values</action>
<check if="YAML parsing fails">
<action>Set result_success = false</action>
<action>Set result_error = "Invalid YAML format in sprint-status.yaml"</action>
<output>❌ Sprint status file is malformed. Run sprint-planning to regenerate.</output>
<action>HALT - return to calling workflow with error</action>
</check>
</step>
<step n="2" goal="Dispatch to action handler">
<action>Route to appropriate action handler based on {{action}} value</action>
<check if="{{action}} == 'get_next_story'">
<goto step="3">Get Next Story</goto>
</check>
<check if="{{action}} == 'list_stories'">
<goto step="4">List Stories</goto>
</check>
<check if="{{action}} == 'get_story_status'">
<goto step="5">Get Story Status</goto>
</check>
<check if="{{action}} == 'get_epic_status'">
<goto step="6">Get Epic Status</goto>
</check>
<check if="{{action}} == 'check_epic_complete'">
<goto step="7">Check Epic Complete</goto>
</check>
<check if="{{action}} == 'update_story_status'">
<goto step="8">Update Story Status</goto>
</check>
<check if="{{action}} == 'update_epic_status'">
<goto step="9">Update Epic Status</goto>
</check>
<check if="{{action}} == 'complete_retrospective'">
<goto step="10">Complete Retrospective</goto>
</check>
<check if="{{action}} == 'validate_transition'">
<goto step="11">Validate Transition</goto>
</check>
<check if="{{action}} == 'get_metadata'">
<goto step="12">Get Metadata</goto>
</check>
<check if="{{action}} == 'get_file_path'">
<goto step="13">Get File Path</goto>
</check>
<check if="action does not match any handler">
<action>Set result_success = false</action>
<action>Set result_error = "Unknown action: {{action}}"</action>
<output>❌ Unknown action: {{action}}
Supported actions: get_next_story, list_stories, get_story_status, get_epic_status, check_epic_complete, update_story_status, update_epic_status, complete_retrospective, validate_transition, get_metadata, get_file_path
</output>
<action>HALT - return to calling workflow with error</action>
</check>
</step>
<!-- ========================================
ACTION HANDLERS - READ OPERATIONS
======================================== -->
<step n="3" goal="Action: get_next_story">
<action>Filter development_status map to find stories (keys matching pattern: number-number-name, not epic-X or epic-X-retrospective)</action>
<check if="{{filter_status}} is provided and not empty">
<action>Further filter to only stories where status == {{filter_status}}</action>
</check>
<check if="{{epic_filter}} is provided and not empty">
<action>Further filter to only stories from epic {{epic_filter}} (keys starting with "{{epic_filter}}-")</action>
</check>
<action>From filtered list, select the FIRST story (stories are in order in the file)</action>
<check if="story found">
<action>Extract story key (e.g., "1-1-user-authentication")</action>
<action>Parse epic_id from key (first number before dash)</action>
<action>Parse story_id from key (second number after first dash)</action>
<action>Get current status value from development_status map</action>
<action>Set result_found = true</action>
<action>Set result_story_key = extracted story key</action>
<action>Set result_story_status = current status</action>
<action>Set result_epic_id = extracted epic id</action>
<action>Set result_story_id = extracted story id</action>
<action>Set result_success = true</action>
<check if="{{show_output}} == true">
<output>📋 Next {{filter_status}} story: {{result_story_key}} (Epic {{result_epic_id}}, Story {{result_story_id}})</output>
</check>
</check>
<check if="no story found">
<action>Set result_found = false</action>
<action>Set result_story_key = ""</action>
<action>Set result_story_status = ""</action>
<action>Set result_epic_id = ""</action>
<action>Set result_story_id = ""</action>
<action>Set result_success = true</action>
<check if="{{show_output}} == true">
<output> No {{filter_status}} stories found{{#if epic_filter}} in {{epic_filter}}{{/if}}</output>
</check>
</check>
<action>COMPLETE - return to calling workflow</action>
</step>
<step n="4" goal="Action: list_stories">
<action>Filter development_status map to find all stories (keys matching pattern: number-number-name)</action>
<check if="{{filter_status}} is provided and not empty">
<action>Further filter to only stories where status == {{filter_status}}</action>
</check>
<check if="{{epic_filter}} is provided and not empty">
<action>Further filter to only stories from epic {{epic_filter}}</action>
</check>
<action>Collect all matching story keys into an array</action>
<action>Apply limit: if more than {{limit}} stories, take first {{limit}} only</action>
<action>Set result_count = number of stories found (before limit applied)</action>
<action>Set result_stories = array of story keys ["1-1-auth", "1-2-nav", ...]</action>
<action>Set result_story_list = comma-separated string of keys "1-1-auth, 1-2-nav, ..."</action>
<action>Set result_success = true</action>
<check if="{{show_output}} == true">
<output>📋 Found {{result_count}} {{filter_status}} stories{{#if epic_filter}} in {{epic_filter}}{{/if}}{{#if result_count > limit}} (showing first {{limit}}){{/if}}</output>
</check>
<action>COMPLETE - return to calling workflow</action>
</step>
<step n="5" goal="Action: get_story_status">
<action>Validate {{story_key}} is provided</action>
<check if="{{story_key}} is empty">
<action>Set result_success = false</action>
<action>Set result_error = "story_key parameter required for get_story_status"</action>
<action>HALT - return to calling workflow with error</action>
</check>
<action>Look up {{story_key}} in development_status map</action>
<check if="story key found">
<action>Get status value from map</action>
<action>Set result_found = true</action>
<action>Set result_status = status value</action>
<action>Set result_success = true</action>
<check if="{{show_output}} == true">
<output>📋 Story {{story_key}} status: {{result_status}}</output>
</check>
</check>
<check if="story key not found">
<action>Set result_found = false</action>
<action>Set result_status = ""</action>
<action>Set result_success = true</action>
<check if="{{show_output}} == true">
<output>⚠️ Story {{story_key}} not found in sprint-status.yaml</output>
</check>
</check>
<action>COMPLETE - return to calling workflow</action>
</step>
<step n="6" goal="Action: get_epic_status">
<action>Validate {{epic_id}} is provided</action>
<check if="{{epic_id}} is empty">
<action>Set result_success = false</action>
<action>Set result_error = "epic_id parameter required for get_epic_status"</action>
<action>HALT - return to calling workflow with error</action>
</check>
<action>Construct epic key: "epic-{{epic_id}}" (e.g., "epic-1")</action>
<action>Look up epic key in development_status map</action>
<check if="epic key found">
<action>Get status value from map</action>
<action>Count total stories in this epic (keys starting with "{{epic_id}}-")</action>
<action>Count done stories in this epic (keys starting with "{{epic_id}}-" where status == "done")</action>
<action>Determine if complete: true if done_count == story_count AND all stories exist</action>
<action>Set result_found = true</action>
<action>Set result_status = epic status value</action>
<action>Set result_story_count = total story count</action>
<action>Set result_done_count = done story count</action>
<action>Set result_complete = true/false based on completion check</action>
<action>Set result_success = true</action>
<check if="{{show_output}} == true">
<output>📋 Epic {{epic_id}} status: {{result_status}} ({{result_done_count}}/{{result_story_count}} stories done)</output>
</check>
</check>
<check if="epic key not found">
<action>Set result_found = false</action>
<action>Set result_status = ""</action>
<action>Set result_story_count = 0</action>
<action>Set result_done_count = 0</action>
<action>Set result_complete = false</action>
<action>Set result_success = true</action>
<check if="{{show_output}} == true">
<output>⚠️ Epic {{epic_id}} not found in sprint-status.yaml</output>
</check>
</check>
<action>COMPLETE - return to calling workflow</action>
</step>
<step n="7" goal="Action: check_epic_complete">
<action>Validate {{epic_id}} is provided</action>
<check if="{{epic_id}} is empty">
<action>Set result_success = false</action>
<action>Set result_error = "epic_id parameter required for check_epic_complete"</action>
<action>HALT - return to calling workflow with error</action>
</check>
<action>Find all stories for epic {{epic_id}} (keys starting with "{{epic_id}}-")</action>
<action>Count total stories found</action>
<action>Count stories with status == "done"</action>
<action>Collect list of pending stories (status != "done")</action>
<action>Determine complete: true if all stories are done, false otherwise</action>
<action>Set result_complete = true/false</action>
<action>Set result_total_stories = total count</action>
<action>Set result_done_stories = done count</action>
<action>Set result_pending_stories = array of pending story keys</action>
<action>Set result_success = true</action>
<check if="{{show_output}} == true">
<output>📊 Epic {{epic_id}}: {{result_done_stories}}/{{result_total_stories}} stories complete{{#if result_complete}} ✅{{/if}}</output>
</check>
<action>COMPLETE - return to calling workflow</action>
</step>
<!-- ========================================
ACTION HANDLERS - WRITE OPERATIONS
======================================== -->
<step n="8" goal="Action: update_story_status">
<action>Validate {{story_key}} is provided</action>
<action>Validate {{new_status}} is provided</action>
<check if="{{story_key}} is empty OR {{new_status}} is empty">
<action>Set result_success = false</action>
<action>Set result_error = "story_key and new_status parameters required for update_story_status"</action>
<action>HALT - return to calling workflow with error</action>
</check>
<action>Look up {{story_key}} in development_status map</action>
<check if="story key not found">
<action>Set result_success = false</action>
<action>Set result_error = "Story {{story_key}} not found in sprint-status.yaml"</action>
<check if="{{show_output}} == true">
<output>❌ Story {{story_key}} not found in tracking file</output>
</check>
<action>HALT - return to calling workflow with error</action>
</check>
<action>Get current status (old_status) from map</action>
<check if="{{validate}} == true">
<action>Check if transition from old_status → {{new_status}} is legal</action>
<action>Define legal transitions:
- backlog → drafted
- drafted → ready-for-dev OR drafted (re-edit)
- ready-for-dev → in-progress OR drafted (corrections)
- in-progress → review OR in-progress (continue work)
- review → done OR in-progress (corrections needed)
- done → done (idempotent)
</action>
<check if="transition is NOT legal">
<action>Set result_success = false</action>
<action>Set result_error = "Invalid transition: {{old_status}} → {{new_status}}"</action>
<action>Set result_validation_message = "Stories must follow workflow: backlog → drafted → ready-for-dev → in-progress → review → done"</action>
<check if="{{show_output}} == true">
<output>❌ Invalid status transition for {{story_key}}: {{old_status}} → {{new_status}}
Legal workflow path: backlog → drafted → ready-for-dev → in-progress → review → done
Stories can move backward for corrections (e.g., review → in-progress)
</output>
</check>
<action>HALT - return to calling workflow with error</action>
</check>
</check>
<check if="{{dry_run}} == false">
<action>Update development_status map: set {{story_key}} = {{new_status}}</action>
<action>Write updated YAML back to {status_file}</action>
<action>Preserve all metadata and comments in file</action>
<action>Maintain story order in development_status section</action>
</check>
<action>Set result_success = true</action>
<action>Set result_old_status = old_status</action>
<action>Set result_new_status = {{new_status}}</action>
<action>Set result_story_key = {{story_key}}</action>
<check if="{{show_output}} == true">
<output>✅ Updated sprint-status: {{story_key}} → {{new_status}}{{#if dry_run}} (DRY RUN - not saved){{/if}}</output>
</check>
<action>COMPLETE - return to calling workflow</action>
</step>
<step n="9" goal="Action: update_epic_status">
<action>Validate {{epic_id}} is provided</action>
<action>Validate {{new_status}} is provided</action>
<check if="{{epic_id}} is empty OR {{new_status}} is empty">
<action>Set result_success = false</action>
<action>Set result_error = "epic_id and new_status parameters required for update_epic_status"</action>
<action>HALT - return to calling workflow with error</action>
</check>
<action>Construct epic key: "epic-{{epic_id}}"</action>
<action>Look up epic key in development_status map</action>
<check if="epic key not found">
<action>Set result_success = false</action>
<action>Set result_error = "Epic {{epic_id}} not found in sprint-status.yaml"</action>
<check if="{{show_output}} == true">
<output>❌ Epic {{epic_id}} not found in tracking file</output>
</check>
<action>HALT - return to calling workflow with error</action>
</check>
<action>Get current status (old_status) from map</action>
<check if="{{dry_run}} == false">
<action>Update development_status map: set "epic-{{epic_id}}" = {{new_status}}</action>
<action>Write updated YAML back to {status_file}</action>
</check>
<action>Set result_success = true</action>
<action>Set result_old_status = old_status</action>
<action>Set result_new_status = {{new_status}}</action>
<check if="{{show_output}} == true">
<output>✅ Updated sprint-status: epic-{{epic_id}} → {{new_status}}{{#if dry_run}} (DRY RUN - not saved){{/if}}</output>
</check>
<action>COMPLETE - return to calling workflow</action>
</step>
<step n="10" goal="Action: complete_retrospective">
<action>Validate {{epic_id}} is provided</action>
<check if="{{epic_id}} is empty">
<action>Set result_success = false</action>
<action>Set result_error = "epic_id parameter required for complete_retrospective"</action>
<action>HALT - return to calling workflow with error</action>
</check>
<action>Construct retrospective key: "epic-{{epic_id}}-retrospective"</action>
<action>Look up retrospective key in development_status map</action>
<check if="retrospective key not found">
<action>Set result_success = false</action>
<action>Set result_error = "Retrospective for epic {{epic_id}} not found in sprint-status.yaml"</action>
<check if="{{show_output}} == true">
<output>❌ Epic {{epic_id}} retrospective not found in tracking file</output>
</check>
<action>HALT - return to calling workflow with error</action>
</check>
<action>Get current status (old_status) from map</action>
<check if="{{dry_run}} == false">
<action>Update development_status map: set "epic-{{epic_id}}-retrospective" = "completed"</action>
<action>Write updated YAML back to {status_file}</action>
</check>
<action>Set result_success = true</action>
<action>Set result_retro_key = "epic-{{epic_id}}-retrospective"</action>
<action>Set result_old_status = old_status</action>
<action>Set result_new_status = "completed"</action>
<check if="{{show_output}} == true">
<output>✅ Updated sprint-status: epic-{{epic_id}}-retrospective → completed{{#if dry_run}} (DRY RUN - not saved){{/if}}</output>
</check>
<action>COMPLETE - return to calling workflow</action>
</step>
<!-- ========================================
ACTION HANDLERS - UTILITY OPERATIONS
======================================== -->
<step n="11" goal="Action: validate_transition">
<action>Validate {{from_status}} and {{to_status}} are provided</action>
<check if="{{from_status}} is empty OR {{to_status}} is empty">
<action>Set result_success = false</action>
<action>Set result_error = "from_status and to_status parameters required for validate_transition"</action>
<action>HALT - return to calling workflow with error</action>
</check>
<action>Check if transition {{from_status}} → {{to_status}} is legal</action>
<action>Legal transitions for stories: - backlog → drafted: ✓ - drafted → ready-for-dev: ✓ - drafted → drafted: ✓ (re-edit) - ready-for-dev → in-progress: ✓ - ready-for-dev → drafted: ✓ (corrections) - in-progress → review: ✓ - in-progress → in-progress: ✓ (continue) - review → done: ✓ - review → in-progress: ✓ (corrections needed) - done → done: ✓ (idempotent) - All other transitions: ✗
</action>
<check if="transition is legal">
<action>Set result_valid = true</action>
<action>Set result_message = "Legal transition: {{from_status}} → {{to_status}}"</action>
<action>Set result_success = true</action>
</check>
<check if="transition is NOT legal">
<action>Set result_valid = false</action>
<action>Set result_message = "Invalid transition: {{from_status}} → {{to_status}}"</action>
<action>Set result_suggested_path = "backlog → drafted → ready-for-dev → in-progress → review → done"</action>
<action>Set result_success = true</action>
</check>
<check if="{{show_output}} == true">
<output>{{#if result_valid}}✅{{else}}❌{{/if}} {{result_message}}</output>
</check>
<action>COMPLETE - return to calling workflow</action>
</step>
<step n="12" goal="Action: get_metadata">
<action>Extract metadata from loaded sprint status file</action>
<action>Set result_project = metadata.project value</action>
<action>Set result_project_key = metadata.project_key value</action>
<action>Set result_tracking_system = metadata.tracking_system value</action>
<action>Set result_story_location = metadata.story_location value</action>
<action>Set result_generated_date = metadata.generated value</action>
<action>Set result_success = true</action>
<check if="{{show_output}} == true">
<output>📋 Sprint Status Metadata:
- Project: {{result_project}}
- Tracking: {{result_tracking_system}}
- Stories: {{result_story_location}}
- Generated: {{result_generated_date}}
</output>
</check>
<action>COMPLETE - return to calling workflow</action>
</step>
<step n="13" goal="Action: get_file_path">
<action>This action was already completed in step 1 when we loaded the file</action>
<action>Set result_file_path = {status_file}</action>
<action>Set result_exists = true (because we successfully loaded it in step 1)</action>
<action>Set result_success = true</action>
<check if="{{show_output}} == true">
<output>📁 Sprint status file: {{result_file_path}}</output>
</check>
<action>COMPLETE - return to calling workflow</action>
</step>
</workflow>

View File

@ -1,53 +0,0 @@
name: sprint-status
description: "Helper workflow for reading and updating sprint-status.yaml tracking file. Provides query and update operations for Phase 4 implementation workflows."
author: "BMad Method"
# Critical variables
config_source: "{project-root}/bmad/bmm/config.yaml"
output_folder: "{config_source}:output_folder"
communication_language: "{config_source}:communication_language"
date: system-generated
# Workflow components
installed_path: "{project-root}/bmad/bmm/workflows/helpers/sprint-status"
instructions: "{installed_path}/instructions.md"
template: false
# Sprint status file location
status_file: "{output_folder}/sprint-status.yaml"
# Input parameters (provided by calling workflow)
# Action is REQUIRED - all others depend on the action type
variables:
action: "" # REQUIRED: get_next_story | list_stories | get_story_status | get_epic_status | check_epic_complete | update_story_status | update_epic_status | complete_retrospective | validate_transition | get_metadata | get_file_path
# Query parameters
story_key: "" # For: get_story_status, update_story_status
epic_id: "" # For: get_epic_status, check_epic_complete, update_epic_status, complete_retrospective
filter_status: "" # For: get_next_story, list_stories - values: backlog | drafted | ready-for-dev | in-progress | review | done
epic_filter: "" # For: get_next_story, list_stories - limit to specific epic (e.g., "epic-1")
limit: 10 # For: list_stories - max results to return
# Update parameters
new_status: "" # For: update_story_status, update_epic_status - target status
# Validation parameters
from_status: "" # For: validate_transition
to_status: "" # For: validate_transition
# Options
validate: true # For: update_story_status - enforce legal transitions
dry_run: false # For: update operations - test without saving
show_output: true # Show helper messages (caller can override)
# Output variables (returned to calling workflow)
# All results are prefixed with result_* for clarity
# Specific variables depend on action - see instructions.md for details
# Common returns (most actions):
# result_success: true | false
# result_error: error message (if failed)
#
# Action-specific returns documented in instructions.md
web_bundle: false

View File

@ -160,6 +160,9 @@ Is that correct? (y/n or tell me what's different)</ask>
<check if="answer == y">
<action>Save status file to {output_folder}/bmm-workflow-status.md</action>
<output>✅ Status file created! Next up: {{next_agent}} agent, run `{{next_command}}`</output>
<check if="next_agent !== current_agent">
<output>It is strongly recommended to clear the context or start a new chat and load the next agent to execute the next command from that agents help menu, unless there is something else I can do for you first.</output>
</check>
</check>
</step>

View File

@ -57,7 +57,7 @@ phases:
agent: "architect"
command: "validate-architecture"
- id: "solutioning-gate-check"
required: true
recommended: true
agent: "architect"
command: "solutioning-gate-check"
note: "Validate PRD + UX + architecture cohesion before implementation"

View File

@ -7,17 +7,12 @@ Aside from stability and bug fixes found during the alpha period - the main focu
- NPX installer
- github pipelines, branch protection, vulnerability scanners
- subagent injections reenabled
- Solutioning Architecture
- is not asking for advanced elicitation
- the order of the document needs to rework the start to first align on what type of project architecture it is
- the architect put out some other not asked for documents as part of the final step
- the architect started dumping out the epic 1 tech spec with way too much prescriptive code in it
- both the PRD and the solutioning process need to work in more of the questioning before dumping out a section (this might be happening since so much is already known from the brief though)
- the UX Agent ux-spec process needs updates to be MUCH more interactive
- the UX agent needs to be given commands to generate comps or mock ups in HTML - it works really well, just need to make it an actual thing the agent offers to do
- docs docs docs
--- done ---
- Done - UX Expert replaced with UX Designer and has a massively improved create-design workflow.
- Done - Architecture Reworked, searches web, more user interactive
- Done - Sprint Status Workflow to generate the story status tracker
- Done - Brownfield v6 integrated into the workflow.
- Done - Full workflow single file tracking.