check alignment

This commit is contained in:
Brian Madison 2025-10-22 12:36:39 -05:00
parent c8776aa9ac
commit be5b06f55e
13 changed files with 1254 additions and 553 deletions

View File

@ -0,0 +1,328 @@
# BMAD Workflow Conditional Execution Antipattern Audit
**Date:** 2025-10-22
**Auditor:** Claude Code (BMad Builder Agent)
**Scope:** All markdown files under `src/`
---
## Executive Summary
**Critical Issue Identified:** Invalid self-closing `<check>` tag pattern found throughout BMAD workflow codebase.
**Impact:**
- **98 instances** across **14 workflow files**
- Affects core workflows, builder workflows, and method workflows
- Creates XML parsing ambiguity and unpredictable LLM behavior
- Violates BMAD workflow specification (workflow.xml)
**Severity:** CRITICAL - Invalid XML structure, ambiguous conditional scope
---
## The Antipattern
### Invalid Pattern (Self-Closing Check)
```xml
<!-- ❌ WRONG - Invalid XML structure -->
<check>If condition met:</check>
<action>Do something</action>
<action>Do something else</action>
```
**Problems:**
1. Check tag doesn't wrap anything (invalid XML)
2. Ambiguous scope - unclear which actions are conditional
3. Breaks formatters and parsers
4. Not part of BMAD workflow spec
5. Unpredictable LLM interpretation
### Correct Patterns
**Single conditional action:**
```xml
<!-- ✅ CORRECT - Inline conditional -->
<action if="condition met">Do something</action>
```
**Multiple conditional actions:**
```xml
<!-- ✅ CORRECT - Proper wrapper block -->
<check if="condition met">
<action>Do something</action>
<action>Do something else</action>
</check>
```
---
## Audit Results
### Total Count
- **Total Instances:** 98
- **Affected Files:** 14
- **Modules Affected:** 4 (BMB, BMM, CIS, Core)
### Breakdown by File
| File | Count | Priority |
| -------------------------------------------------------------------- | ----- | ----------- |
| `modules/bmb/workflows/edit-workflow/instructions.md` | 21 | 🔴 CRITICAL |
| `modules/bmm/workflows/4-implementation/dev-story/instructions.md` | 13 | 🔴 CRITICAL |
| `modules/bmb/workflows/convert-legacy/instructions.md` | 13 | 🔴 CRITICAL |
| `modules/bmb/workflows/create-module/instructions.md` | 12 | 🔴 CRITICAL |
| `modules/bmb/workflows/create-agent/instructions.md` | 11 | 🔴 CRITICAL |
| `core/workflows/party-mode/instructions.md` | 7 | 🟡 HIGH |
| `modules/bmm/workflows/4-implementation/correct-course/checklist.md` | 5 | 🟡 HIGH |
| `core/workflows/brainstorming/instructions.md` | 5 | 🟡 HIGH |
| `modules/cis/workflows/storytelling/instructions.md` | 3 | 🟢 MEDIUM |
| `modules/bmb/workflows/audit-workflow/instructions.md` | 3 | 🟢 MEDIUM |
| `modules/bmb/workflows/create-workflow/workflow-creation-guide.md` | 2 | 🟢 MEDIUM |
| `modules/bmm/workflows/1-analysis/product-brief/instructions.md` | 1 | 🟢 LOW |
| `modules/bmm/workflows/1-analysis/game-brief/instructions.md` | 1 | 🟢 LOW |
| `modules/bmb/workflows/redoc/instructions.md` | 1 | 🟢 LOW |
### Breakdown by Module
**BMB (Builder) Module: 63 instances (64%)**
- edit-workflow: 21
- convert-legacy: 13
- create-module: 12
- create-agent: 11
- audit-workflow: 3
- create-workflow: 2
- redoc: 1
**BMM (Method) Module: 20 instances (20%)**
- dev-story: 13
- correct-course: 5
- product-brief: 1
- game-brief: 1
**Core Workflows: 12 instances (12%)**
- party-mode: 7
- brainstorming: 5
**CIS (Creative) Module: 3 instances (3%)**
- storytelling: 3
---
## Example Instances
### Example 1: create-agent/instructions.md (Line 13-20)
**BEFORE (Invalid):**
```xml
<check>If yes:</check>
<action>Invoke brainstorming workflow: {project-root}/bmad/core/workflows/brainstorming/workflow.yaml</action>
<action>Pass context data: {installed_path}/brainstorm-context.md</action>
<action>Wait for brainstorming session completion</action>
<check>If no:</check>
<action>Proceed directly to Step 0</action>
```
**AFTER (Correct):**
```xml
<check if="user answered yes">
<action>Invoke brainstorming workflow: {project-root}/bmad/core/workflows/brainstorming/workflow.yaml</action>
<action>Pass context data: {installed_path}/brainstorm-context.md</action>
<action>Wait for brainstorming session completion</action>
</check>
<check if="user answered no">
<action>Proceed directly to Step 0</action>
</check>
```
### Example 2: dev-story/instructions.md (Line 54-55)
**BEFORE (Invalid):**
```xml
<check>If story file inaccessible → HALT: "Cannot develop story without access to story file"</check>
<check>If task requirements ambiguous → ASK user to clarify or HALT</check>
```
**AFTER (Correct):**
```xml
<action if="story file inaccessible">HALT: "Cannot develop story without access to story file"</action>
<action if="task requirements ambiguous">ASK user to clarify or HALT</action>
```
---
## Impact Assessment
### Technical Impact
1. **XML Validity:** Invalid structure violates XML parsing rules
2. **Formatter Confusion:** Custom formatters incorrectly indent following content
3. **Scope Ambiguity:** Unclear which actions are inside vs outside conditional
4. **Maintainability:** Future developers confused by ambiguous structure
### LLM Adherence Impact
**Potential Issues:**
- LLM may interpret check as unconditional statement
- Actions may execute when they shouldn't (or vice versa)
- Inconsistent behavior across different LLMs
- Unpredictable results in complex nested conditionals
**Observed Behavior:**
- LLMs often "figure it out" through context and proximity
- Colon (`:`) pattern signals "here's what to do"
- Works in simple cases but risky in complex logic
**Risk Level:** MEDIUM-HIGH
- May work "most of the time" but unreliable
- Fails in edge cases and complex nested logic
- Future LLMs may interpret differently
---
## Root Cause Analysis
### Why This Happened
1. **Implicit convention evolved** - Self-closing check pattern emerged organically
2. **No enforcement** - No linter or validator caught the pattern
3. **Copy-paste propagation** - Pattern copied across workflows
4. **Formatting hid the issue** - Manual indentation made it "look right"
5. **LLM tolerance** - Current LLMs often figured it out despite ambiguity
### Meta-Problem
**The workflows that CREATE workflows have the antipattern:**
- create-workflow: 2 instances
- create-agent: 11 instances
- create-module: 12 instances
- edit-workflow: 21 instances
- convert-legacy: 13 instances
This means NEW workflows were being created WITH the antipattern built-in!
---
## Remediation Plan
### Phase 1: Immediate (High Priority Files)
Fix top 5 offenders (63% of problem):
1. edit-workflow (21 instances)
2. dev-story (13 instances)
3. convert-legacy (13 instances)
4. create-module (12 instances)
5. create-agent (11 instances)
**Total:** 70 instances (71% of problem)
### Phase 2: Core Workflows
Fix core workflows (critical for all modules):
1. party-mode (7 instances)
2. brainstorming (5 instances)
**Total:** 12 instances
### Phase 3: Remaining
Fix remaining 16 instances across 7 files
### Phase 4: Prevention
1. **Update audit-workflow** ✅ DONE
- Added antipattern detection to Step 4
- Flags with CRITICAL severity
- Suggests correct patterns
2. **Update creation guide** ✅ DONE
- Documented antipattern in workflow-creation-guide.md
- Clear examples of correct vs incorrect patterns
- Added to best practices
3. **Update checklist** ✅ DONE
- Added validation criteria to checklist.md
- 3 new checks for conditional execution patterns
4. **Create automated fixer** (TODO)
- Bulk conversion script for remaining instances
- Pattern matching and replacement logic
---
## Specification Reference
From `bmad/core/tasks/workflow.xml`:
```xml
<tag>action if="condition" - Single conditional action (inline, no closing tag needed)</tag>
<tag>check if="condition">...</check> - Conditional block wrapping multiple items (closing tag required)</tag>
```
**Key Point:** Check tags MUST have `if=""` attribute and MUST wrap content with closing tag.
The self-closing pattern `<check>text</check>` is **NOT in the spec** and is **invalid**.
---
## Detection Command
To find all instances:
```bash
grep -r "<check>[^<]*</check>" src --include="*.md" -n
```
To count by file:
```bash
grep -r "<check>[^<]*</check>" src --include="*.md" -c | grep -v ":0$"
```
---
## Next Actions
- [ ] Create bulk-fix script for automated conversion
- [ ] Fix Phase 1 files (70 instances)
- [ ] Fix Phase 2 files (12 instances)
- [ ] Fix Phase 3 files (16 instances)
- [ ] Run audit-workflow on all fixed files to verify
- [ ] Update formatter to detect and warn on antipattern
- [ ] Add pre-commit hook to prevent future instances
---
## References
- **Workflow Spec:** `bmad/core/tasks/workflow.xml`
- **Creation Guide:** `src/modules/bmb/workflows/create-workflow/workflow-creation-guide.md`
- **Audit Workflow:** `src/modules/bmb/workflows/audit-workflow/`
- **This Report:** `docs/antipattern-audit-2025-10-22.md`
---
**Report Status:** Complete
**Action Required:** Yes - 98 instances need remediation
**Priority:** CRITICAL - Affects core functionality and workflow creation

View File

@ -78,6 +78,9 @@
- [ ] XML tags used correctly (<action>, <ask>, <check>, <goto>, <invoke-workflow>, <template-output>) - [ ] XML tags used correctly (<action>, <ask>, <check>, <goto>, <invoke-workflow>, <template-output>)
- [ ] No nested tag references in content (use "action tags" not "<action> tags") - [ ] No nested tag references in content (use "action tags" not "<action> tags")
- [ ] Tag references use descriptive text without angle brackets for clarity - [ ] Tag references use descriptive text without angle brackets for clarity
- [ ] No conditional execution antipattern (no self-closing <check> tags)
- [ ] Single conditionals use <action if="condition"> (inline)
- [ ] Multiple conditionals use <check if="condition">...</check> (wrapper block with closing tag)
- [ ] Steps are focused (single goal per step) - [ ] Steps are focused (single goal per step)
- [ ] Instructions are specific with limits ("Write 1-2 paragraphs" not "Write about") - [ ] Instructions are specific with limits ("Write 1-2 paragraphs" not "Write about")
- [ ] Examples provided where helpful - [ ] Examples provided where helpful

View File

@ -5,391 +5,337 @@
<workflow> <workflow>
<step n="1" goal="Load and analyze target workflow"> <step n="1" goal="Load and analyze target workflow">
<ask>What is the path to the workflow you want to audit? (provide path to workflow.yaml or workflow folder)</ask> <ask>What is the path to the workflow you want to audit? (provide path to workflow.yaml or workflow folder)</ask>
<action>Load the workflow.yaml file from the provided path</action> <action>Load the workflow.yaml file from the provided path</action>
<action>Identify the workflow type (document, action, interactive, autonomous, meta)</action> <action>Identify the workflow type (document, action, interactive, autonomous, meta)</action>
<action>List all associated files:</action> <action>List all associated files:</action>
- instructions.md (required for most workflows) - instructions.md (required for most workflows)
- template.md (if document workflow) - template.md (if document workflow)
- checklist.md (if validation exists) - checklist.md (if validation exists)
- Any data files referenced in yaml - Any data files referenced in yaml
<action>Load all discovered files</action> <action>Load all discovered files</action>
Display summary: Display summary:
- Workflow name and description
- Type of workflow
- Files present
- Module assignment
- Workflow name and description
- Type of workflow
- Files present
- Module assignment
</step> </step>
<step n="2" goal="Validate standard config block"> <step n="2" goal="Validate standard config block">
<action>Check workflow.yaml for the standard config block:</action> <action>Check workflow.yaml for the standard config block:</action>
**Required variables:** **Required variables:**
- `config_source: "{project-root}/bmad/[module]/config.yaml"` - `config_source: "{project-root}/bmad/[module]/config.yaml"`
- `output_folder: "{config_source}:output_folder"` - `output_folder: "{config_source}:output_folder"`
- `user_name: "{config_source}:user_name"` - `user_name: "{config_source}:user_name"`
- `communication_language: "{config_source}:communication_language"` - `communication_language: "{config_source}:communication_language"`
- `date: system-generated` - `date: system-generated`
<action>Validate each variable:</action> <action>Validate each variable:</action>
**Config Source Check:** **Config Source Check:**
- [ ] `config_source` is defined - [ ] `config_source` is defined
- [ ] Points to correct module config path - [ ] Points to correct module config path
- [ ] Uses {project-root} variable - [ ] Uses {project-root} variable
**Standard Variables Check:** **Standard Variables Check:**
- [ ] `output_folder` pulls from config_source - [ ] `output_folder` pulls from config_source
- [ ] `user_name` pulls from config_source - [ ] `user_name` pulls from config_source
- [ ] `communication_language` pulls from config_source - [ ] `communication_language` pulls from config_source
- [ ] `date` is set to system-generated - [ ] `date` is set to system-generated
<action>Record any missing or incorrect config variables</action> <action>Record any missing or incorrect config variables</action>
<template-output>config_issues</template-output> <template-output>config_issues</template-output>
<check>If config issues found:</check> <action if="config issues found">Add to issues list with severity: CRITICAL</action>
<action>Add to issues list with severity: CRITICAL</action>
</step>
<step n="3" goal="Analyze YAML/Instruction/Template alignment"> </step>
<action>Extract all variables defined in workflow.yaml (excluding standard config block)</action>
<action>Scan instructions.md for variable usage: {variable_name} pattern</action>
<action>Scan template.md for variable usage: {{variable_name}} pattern (if exists)</action>
<action>Cross-reference analysis:</action> <step n="3" goal="Analyze YAML/Instruction/Template alignment">
<action>Extract all variables defined in workflow.yaml (excluding standard config block)</action>
<action>Scan instructions.md for variable usage: {variable_name} pattern</action>
<action>Scan template.md for variable usage: {{variable_name}} pattern (if exists)</action>
**For each yaml variable:** <action>Cross-reference analysis:</action>
1. Is it used in instructions.md? (mark as INSTRUCTION_USED) **For each yaml variable:**
2. Is it used in template.md? (mark as TEMPLATE_USED)
3. Is it neither? (mark as UNUSED_BLOAT)
**Special cases to ignore:** 1. Is it used in instructions.md? (mark as INSTRUCTION_USED)
2. Is it used in template.md? (mark as TEMPLATE_USED)
3. Is it neither? (mark as UNUSED_BLOAT)
- Standard config variables (config_source, output_folder, user_name, communication_language, date) **Special cases to ignore:**
- Workflow metadata (name, description, author)
- Path variables (installed_path, template, instructions, validation)
- Web bundle configuration (web_bundle block itself)
<action>Identify unused yaml fields (bloat)</action> - Standard config variables (config_source, output_folder, user_name, communication_language, date)
<action>Identify hardcoded values in instructions that should be variables</action> - Workflow metadata (name, description, author)
<template-output>alignment_issues</template-output> - Path variables (installed_path, template, instructions, validation)
- Web bundle configuration (web_bundle block itself)
<check>If unused variables found:</check> <action>Identify unused yaml fields (bloat)</action>
<action>Add to issues list with severity: BLOAT</action> <action>Identify hardcoded values in instructions that should be variables</action>
</step> <template-output>alignment_issues</template-output>
<step n="4" goal="Config variable usage audit"> <action if="unused variables found">Add to issues list with severity: BLOAT</action>
<action>Analyze instructions.md for proper config variable usage:</action>
**Communication Language Check:** </step>
- Search for phrases like "communicate in {communication_language}" <step n="4" goal="Config variable usage audit">
- Check if greetings/responses use language-aware patterns <action>Analyze instructions.md for proper config variable usage:</action>
- Verify NO usage of {{communication_language}} in template headers
**User Name Check:** **Communication Language Check:**
- Look for user addressing patterns using {user_name} - Search for phrases like "communicate in {communication_language}"
- Check if summaries or greetings personalize with {user_name} - Check if greetings/responses use language-aware patterns
- Verify optional usage in template metadata (not required) - Verify NO usage of {{communication_language}} in template headers
**Output Folder Check:** **User Name Check:**
- Search for file write operations - Look for user addressing patterns using {user_name}
- Verify all outputs go to {output_folder} or subdirectories - Check if summaries or greetings personalize with {user_name}
- Check for hardcoded paths like "/output/" or "/generated/" - Verify optional usage in template metadata (not required)
**Date Usage Check:** **Output Folder Check:**
- Verify date is available for agent date awareness - Search for file write operations
- Check optional usage in template metadata - Verify all outputs go to {output_folder} or subdirectories
- Ensure no confusion between date and model training cutoff - Check for hardcoded paths like "/output/" or "/generated/"
**Nested Tag Reference Check:** **Date Usage Check:**
- Search for XML tag references within tags (e.g., `<action>Scan for <action> tags</action>`) - Verify date is available for agent date awareness
- Identify patterns like: `<tag-name> tags`, `<tag-name> calls`, `<tag-name>content</tag-name>` within content - Check optional usage in template metadata
- Common problematic tags to check: action, ask, check, template-output, invoke-workflow, goto - Ensure no confusion between date and model training cutoff
- Flag any instances where angle brackets appear in content describing tags
**Best Practice:** Use descriptive text without brackets (e.g., "action tags" instead of "<action> tags") **Nested Tag Reference Check:**
**Rationale:** - Search for XML tag references within tags (e.g., `<action>Scan for <action> tags</action>`)
- Identify patterns like: `<tag-name> tags`, `<tag-name> calls`, `<tag-name>content</tag-name>` within content
- Common problematic tags to check: action, ask, check, template-output, invoke-workflow, goto
- Flag any instances where angle brackets appear in content describing tags
- Prevents XML parsing ambiguity **Best Practice:** Use descriptive text without brackets (e.g., "action tags" instead of "<action> tags")
- Improves readability for humans and LLMs
- LLMs understand "action tags" = `<action>` tags from context
<action>Scan instructions.md for nested tag references using pattern: &lt;(action|ask|check|template-output|invoke-workflow|goto|step|elicit-required)&gt; within text content</action> **Rationale:**
<action>Record any instances of nested tag references with line numbers</action>
<action>Record any improper config variable usage</action>
<template-output>config_usage_issues</template-output>
<check>If config usage issues found:</check> - Prevents XML parsing ambiguity
<action>Add to issues list with severity: IMPORTANT</action> - Improves readability for humans and LLMs
<check>If nested tag references found:</check> - LLMs understand "action tags" = `<action>` tags from context
<action>Add to issues list with severity: CLARITY (recommend using descriptive text without angle brackets)</action>
</step>
<step n="5" goal="Web bundle validation" optional="true"> **Conditional Execution Antipattern Check:**
<check>If workflow.yaml contains web_bundle section:</check>
<action>Validate web_bundle structure:</action> - Scan for self-closing check tags: `<check>condition text</check>` (invalid antipattern)
- Detect pattern: check tag on one line, followed by action/ask/goto tags (indicates incorrect nesting)
- Flag sequences like: `<check>If X:</check>` followed by `<action>do Y</action>`
**Path Validation:** **Correct Patterns:**
- [ ] All paths use bmad/-relative format (NOT {project-root}) - Single conditional: `<action if="condition">Do something</action>`
- [ ] No {config_source} variables in web_bundle section - Multiple actions: `<check if="condition">` followed by nested actions with closing `</check>` tag
- [ ] Paths match actual file locations
**Completeness Check:** **Antipattern Example (WRONG):**
```xml
<check>If condition met:</check>
<action>Do something</action>
```
- [ ] instructions file listed in web_bundle_files **Correct Example:**
- [ ] template file listed (if document workflow) ```xml
- [ ] validation/checklist file listed (if exists) <check if="condition met">
- [ ] All data files referenced in yaml listed <action>Do something</action>
- [ ] All files referenced in instructions listed <action>Do something else</action>
</check>
```
**Workflow Dependency Scan:** **Or for single action:**
<action>Scan instructions.md for invoke-workflow tags</action> ```xml
<action>Extract workflow paths from invocations</action> <action if="condition met">Do something</action>
<action>Verify each called workflow.yaml is in web_bundle_files</action> ```
<action>**CRITICAL**: Check if existing_workflows field is present when workflows are invoked</action>
<action>If invoke-workflow calls exist, existing_workflows MUST map workflow variables to paths</action>
<action>Example: If instructions use {core_brainstorming}, web_bundle needs:
existing_workflows: - core_brainstorming: "bmad/core/workflows/brainstorming/workflow.yaml"
</action>
**File Reference Scan:** <action>Scan instructions.md for nested tag references using pattern: &lt;(action|ask|check|template-output|invoke-workflow|goto|step|elicit-required)&gt; within text content</action>
<action>Scan instructions.md for file references in action tags</action> <action>Record any instances of nested tag references with line numbers</action>
<action>Check for CSV, JSON, YAML, MD files referenced</action> <action>Scan instructions.md for conditional execution antipattern: self-closing check tags</action>
<action>Verify all referenced files are in web_bundle_files</action> <action>Detect pattern: `&lt;check&gt;.*&lt;/check&gt;` on single line (self-closing check)</action>
<action>Record any antipattern instances with line numbers and suggest corrections</action>
<action>Record any improper config variable usage</action>
<template-output>config_usage_issues</template-output>
<action>Record any missing files or incorrect paths</action> <action if="config usage issues found">Add to issues list with severity: IMPORTANT</action>
<template-output>web_bundle_issues</template-output> <action if="nested tag references found">Add to issues list with severity: CLARITY (recommend using descriptive text without angle brackets)</action>
<action if="conditional antipattern found">Add to issues list with severity: CRITICAL (invalid XML structure - must use action if="" or proper check wrapper)</action>
<check>If web_bundle issues found:</check> </step>
<action>Add to issues list with severity: CRITICAL</action>
<check>If no web_bundle section exists:</check> <step n="5" goal="Web bundle validation" optional="true">
<action>Note: "No web_bundle configured (may be intentional for local-only workflows)"</action> <check if="workflow.yaml contains web_bundle section">
</step>
<step n="6" goal="Bloat detection"> <action>Validate web_bundle structure:</action>
<action>Identify bloat patterns:</action>
**Unused YAML Fields:** **Path Validation:**
- Variables defined but not used in instructions OR template - [ ] All paths use bmad/-relative format (NOT {project-root})
- Duplicate fields between top-level and web_bundle section - [ ] No {config_source} variables in web_bundle section
- Commented-out variables that should be removed - [ ] Paths match actual file locations
**Hardcoded Values:** **Completeness Check:**
- File paths that should use {output_folder} - [ ] instructions file listed in web_bundle_files
- Generic greetings that should use {user_name} - [ ] template file listed (if document workflow)
- Language-specific text that should use {communication_language} - [ ] validation/checklist file listed (if exists)
- Static dates that should use {date} - [ ] All data files referenced in yaml listed
- [ ] All files referenced in instructions listed
**Redundant Configuration:** **Workflow Dependency Scan:**
<action>Scan instructions.md for invoke-workflow tags</action>
<action>Extract workflow paths from invocations</action>
<action>Verify each called workflow.yaml is in web_bundle_files</action>
<action>**CRITICAL**: Check if existing_workflows field is present when workflows are invoked</action>
<action>If invoke-workflow calls exist, existing_workflows MUST map workflow variables to paths</action>
<action>Example: If instructions use {core_brainstorming}, web_bundle needs: existing_workflows: - core_brainstorming: "bmad/core/workflows/brainstorming/workflow.yaml"</action>
- Variables that duplicate web_bundle fields **File Reference Scan:**
- Metadata repeated across sections <action>Scan instructions.md for file references in action tags</action>
<action>Check for CSV, JSON, YAML, MD files referenced</action>
<action>Verify all referenced files are in web_bundle_files</action>
<action>Calculate bloat metrics:</action> <action>Record any missing files or incorrect paths</action>
<template-output>web_bundle_issues</template-output>
- Total yaml fields: {{total_yaml_fields}} <action if="web_bundle issues found">Add to issues list with severity: CRITICAL</action>
- Used fields: {{used_fields}}
- Unused fields: {{unused_fields}}
- Bloat percentage: {{bloat_percentage}}%
<action>Record all bloat items with recommendations</action> <action if="no web_bundle section exists">Note: "No web_bundle configured (may be intentional for local-only workflows)"</action>
<template-output>bloat_items</template-output> </check>
<check>If bloat detected:</check> </step>
<action>Add to issues list with severity: CLEANUP</action>
</step>
<step n="7" goal="Template variable mapping" if="workflow_type == 'document'"> <step n="6" goal="Bloat detection">
<action>Extract all template variables from template.md: {{variable_name}} pattern</action> <action>Identify bloat patterns:</action>
<action>Scan instructions.md for corresponding template-output tags</action>
<action>Cross-reference mapping:</action> **Unused YAML Fields:**
**For each template variable:** - Variables defined but not used in instructions OR template
- Duplicate fields between top-level and web_bundle section
- Commented-out variables that should be removed
1. Is there a matching template-output tag? (mark as MAPPED) **Hardcoded Values:**
2. Is it a standard config variable? (mark as CONFIG_VAR - optional)
3. Is it unmapped? (mark as MISSING_OUTPUT)
**For each template-output tag:** - File paths that should use {output_folder}
- Generic greetings that should use {user_name}
- Language-specific text that should use {communication_language}
- Static dates that should use {date}
1. Is there a matching template variable? (mark as USED) **Redundant Configuration:**
2. Is it orphaned? (mark as UNUSED_OUTPUT)
<action>Verify variable naming conventions:</action> - Variables that duplicate web_bundle fields
- Metadata repeated across sections
- [ ] All template variables use snake_case <action>Calculate bloat metrics:</action>
- [ ] Variable names are descriptive (not abbreviated)
- [ ] Standard config variables properly formatted
<action>Record any mapping issues</action> - Total yaml fields: {{total_yaml_fields}}
<template-output>template_issues</template-output> - Used fields: {{used_fields}}
- Unused fields: {{unused_fields}}
- Bloat percentage: {{bloat_percentage}}%
<check>If template issues found:</check> <action>Record all bloat items with recommendations</action>
<action>Add to issues list with severity: IMPORTANT</action> <template-output>bloat_items</template-output>
</step>
<step n="8" goal="Generate comprehensive audit report"> <action if="bloat detected">Add to issues list with severity: CLEANUP</action>
<action>Compile all findings into a structured report</action>
<action>Write audit report to {output_folder}/audit-report-{{workflow_name}}-{{date}}.md</action> </step>
**Report Structure:** <step n="7" goal="Template variable mapping" if="workflow_type == 'document'">
<action>Extract all template variables from template.md: {{variable_name}} pattern</action>
<action>Scan instructions.md for corresponding template-output tags</action>
```markdown <action>Cross-reference mapping:</action>
# Workflow Audit Report
**Workflow:** {{workflow_name}} **For each template variable:**
**Audit Date:** {{date}}
**Auditor:** Audit Workflow (BMAD v6)
**Workflow Type:** {{workflow_type}}
--- 1. Is there a matching template-output tag? (mark as MAPPED)
2. Is it a standard config variable? (mark as CONFIG_VAR - optional)
3. Is it unmapped? (mark as MISSING_OUTPUT)
## Executive Summary **For each template-output tag:**
**Overall Status:** {{overall_status}} 1. Is there a matching template variable? (mark as USED)
2. Is it orphaned? (mark as UNUSED_OUTPUT)
- Critical Issues: {{critical_count}} <action>Verify variable naming conventions:</action>
- Important Issues: {{important_count}}
- Cleanup Recommendations: {{cleanup_count}}
--- - [ ] All template variables use snake_case
- [ ] Variable names are descriptive (not abbreviated)
- [ ] Standard config variables properly formatted
## 1. Standard Config Block Validation <action>Record any mapping issues</action>
<template-output>template_issues</template-output>
{{config_issues}} <action if="template issues found">Add to issues list with severity: IMPORTANT</action>
**Status:** {{config_status}} </step>
--- <step n="8" goal="Generate comprehensive audit report">
<action>Compile all findings and calculate summary metrics</action>
## 2. YAML/Instruction/Template Alignment <action>Generate executive summary based on issue counts and severity levels</action>
<template-output>workflow_type</template-output>
<template-output>overall_status</template-output>
<template-output>critical_count</template-output>
<template-output>important_count</template-output>
<template-output>cleanup_count</template-output>
{{alignment_issues}} <action>Generate status summaries for each audit section</action>
<template-output>config_status</template-output>
<template-output>total_variables</template-output>
<template-output>instruction_usage_count</template-output>
<template-output>template_usage_count</template-output>
<template-output>bloat_count</template-output>
**Variables Analyzed:** {{total_variables}} <action>Generate config variable usage status indicators</action>
**Used in Instructions:** {{instruction_usage_count}} <template-output>comm_lang_status</template-output>
**Used in Template:** {{template_usage_count}} <template-output>user_name_status</template-output>
**Unused (Bloat):** {{bloat_count}} <template-output>output_folder_status</template-output>
<template-output>date_status</template-output>
<template-output>nested_tag_count</template-output>
--- <action>Generate web bundle metrics</action>
<template-output>web_bundle_exists</template-output>
<template-output>web_bundle_file_count</template-output>
<template-output>missing_files_count</template-output>
## 3. Config Variable Usage & Instruction Quality <action>Generate bloat metrics</action>
<template-output>bloat_percentage</template-output>
<template-output>cleanup_potential</template-output>
{{config_usage_issues}} <action>Generate template mapping metrics</action>
<template-output>template_var_count</template-output>
<template-output>mapped_count</template-output>
<template-output>missing_mapping_count</template-output>
**Communication Language:** {{comm_lang_status}} <action>Compile prioritized recommendations by severity</action>
**User Name:** {{user_name_status}} <template-output>critical_recommendations</template-output>
**Output Folder:** {{output_folder_status}} <template-output>important_recommendations</template-output>
**Date:** {{date_status}} <template-output>cleanup_recommendations</template-output>
**Nested Tag References:** {{nested_tag_count}} instances found
--- <action>Display summary to {user_name} in {communication_language}</action>
<action>Provide path to full audit report: {output_folder}/audit-report-{{workflow_name}}-{{date}}.md</action>
## 4. Web Bundle Validation <ask>Would you like to:
{{web_bundle_issues}} - View the full audit report
- Fix issues automatically (invoke edit-workflow)
**Web Bundle Present:** {{web_bundle_exists}} - Audit another workflow
**Files Listed:** {{web_bundle_file_count}} - Exit
**Missing Files:** {{missing_files_count}}
---
## 5. Bloat Detection
{{bloat_items}}
**Bloat Percentage:** {{bloat_percentage}}%
**Cleanup Potential:** {{cleanup_potential}}
---
## 6. Template Variable Mapping
{{template_issues}}
**Template Variables:** {{template_var_count}}
**Mapped Correctly:** {{mapped_count}}
**Missing Mappings:** {{missing_mapping_count}}
---
## Recommendations
### Critical (Fix Immediately)
{{critical_recommendations}}
### Important (Address Soon)
{{important_recommendations}}
### Cleanup (Nice to Have)
{{cleanup_recommendations}}
---
## Validation Checklist
Use this checklist to verify fixes:
- [ ] All standard config variables present and correct
- [ ] No unused yaml fields (bloat removed)
- [ ] Config variables used appropriately in instructions
- [ ] Web bundle includes all dependencies
- [ ] Template variables properly mapped
- [ ] File structure follows v6 conventions
---
## Next Steps
1. Review critical issues and fix immediately
2. Address important issues in next iteration
3. Consider cleanup recommendations for optimization
4. Re-run audit after fixes to verify improvements
---
**Audit Complete** - Generated by audit-workflow v1.0
```
<action>Display summary to {user_name} in {communication_language}</action>
<action>Provide path to full audit report</action>
<ask>Would you like to:
- View the full audit report
- Fix issues automatically (invoke edit-workflow)
- Audit another workflow
- Exit
</ask> </ask>
<template-output>audit_report_path</template-output> </step>
</step>
</workflow> </workflow>

View File

@ -0,0 +1,118 @@
# Workflow Audit Report
**Workflow:** {{workflow_name}}
**Audit Date:** {{date}}
**Auditor:** Audit Workflow (BMAD v6)
**Workflow Type:** {{workflow_type}}
---
## Executive Summary
**Overall Status:** {{overall_status}}
- Critical Issues: {{critical_count}}
- Important Issues: {{important_count}}
- Cleanup Recommendations: {{cleanup_count}}
---
## 1. Standard Config Block Validation
{{config_issues}}
**Status:** {{config_status}}
---
## 2. YAML/Instruction/Template Alignment
{{alignment_issues}}
**Variables Analyzed:** {{total_variables}}
**Used in Instructions:** {{instruction_usage_count}}
**Used in Template:** {{template_usage_count}}
**Unused (Bloat):** {{bloat_count}}
---
## 3. Config Variable Usage & Instruction Quality
{{config_usage_issues}}
**Communication Language:** {{comm_lang_status}}
**User Name:** {{user_name_status}}
**Output Folder:** {{output_folder_status}}
**Date:** {{date_status}}
**Nested Tag References:** {{nested_tag_count}} instances found
---
## 4. Web Bundle Validation
{{web_bundle_issues}}
**Web Bundle Present:** {{web_bundle_exists}}
**Files Listed:** {{web_bundle_file_count}}
**Missing Files:** {{missing_files_count}}
---
## 5. Bloat Detection
{{bloat_items}}
**Bloat Percentage:** {{bloat_percentage}}%
**Cleanup Potential:** {{cleanup_potential}}
---
## 6. Template Variable Mapping
{{template_issues}}
**Template Variables:** {{template_var_count}}
**Mapped Correctly:** {{mapped_count}}
**Missing Mappings:** {{missing_mapping_count}}
---
## Recommendations
### Critical (Fix Immediately)
{{critical_recommendations}}
### Important (Address Soon)
{{important_recommendations}}
### Cleanup (Nice to Have)
{{cleanup_recommendations}}
---
## Validation Checklist
Use this checklist to verify fixes:
- [ ] All standard config variables present and correct
- [ ] No unused yaml fields (bloat removed)
- [ ] Config variables used appropriately in instructions
- [ ] Web bundle includes all dependencies
- [ ] Template variables properly mapped
- [ ] File structure follows v6 conventions
---
## Next Steps
1. Review critical issues and fix immediately
2. Address important issues in next iteration
3. Consider cleanup recommendations for optimization
4. Re-run audit after fixes to verify improvements
---
**Audit Complete** - Generated by audit-workflow v1.0

View File

@ -12,7 +12,7 @@ date: system-generated
# Module path and component files # Module path and component files
installed_path: "{project-root}/bmad/bmb/workflows/audit-workflow" installed_path: "{project-root}/bmad/bmb/workflows/audit-workflow"
template: false template: "{installed_path}/template.md"
instructions: "{installed_path}/instructions.md" instructions: "{installed_path}/instructions.md"
validation: "{installed_path}/checklist.md" validation: "{installed_path}/checklist.md"

View File

@ -67,8 +67,7 @@ For Modules:
<step n="3" goal="Determine Target Module and Location"> <step n="3" goal="Determine Target Module and Location">
<ask>Which module should this belong to? (eg. bmm, bmb, cis, bmm-legacy, or custom)</ask> <ask>Which module should this belong to? (eg. bmm, bmb, cis, bmm-legacy, or custom)</ask>
<check>If custom module:</check> <action if="custom module"><ask>Enter custom module code (kebab-case):</ask></action>
<ask>Enter custom module code (kebab-case):</ask>
<action>Determine installation path based on type and module</action> <action>Determine installation path based on type and module</action>
<critical>IMPORTANT: All paths must use final BMAD installation locations, not src paths!</critical> <critical>IMPORTANT: All paths must use final BMAD installation locations, not src paths!</critical>
<action>Show user the target location: {project-root}/bmad/{{target_module}}/{{item_type}}/{{item_name}}</action> <action>Show user the target location: {project-root}/bmad/{{target_module}}/{{item_type}}/{{item_name}}</action>
@ -79,16 +78,19 @@ For Modules:
<step n="4" goal="Choose Conversion Strategy"> <step n="4" goal="Choose Conversion Strategy">
<action>Based on item type and complexity, choose approach:</action> <action>Based on item type and complexity, choose approach:</action>
<check>If agent conversion:</check> <check if="agent conversion">
<check>If simple agent (basic persona + commands):</check> <check if="simple agent (basic persona + commands)">
<action>Use direct conversion to v5 agent YAML format</action> <action>Use direct conversion to v5 agent YAML format</action>
<goto step="5a">Direct Agent Conversion</goto> <goto step="5a">Direct Agent Conversion</goto>
<check>If complex agent with embedded workflows:</check> </check>
<action>Plan to invoke create-agent workflow</action> <check if="complex agent with embedded workflows">
<goto step="5b">Workflow-Assisted Agent Creation</goto> <action>Plan to invoke create-agent workflow</action>
<goto step="5b">Workflow-Assisted Agent Creation</goto>
</check>
</check>
<check>If template or task conversion to workflow:</check> <check if="template or task conversion to workflow">
<action>Analyze the v4 item to determine workflow type:</action> <action>Analyze the v4 item to determine workflow type:</action>
- Does it generate a specific document type? → Document workflow - Does it generate a specific document type? → Document workflow
- Does it produce structured output files? → Document workflow - Does it produce structured output files? → Document workflow
@ -104,14 +106,14 @@ For Modules:
4. Meta-workflow (coordinates other workflows) 4. Meta-workflow (coordinates other workflows)
Select 1-4:</ask> Select 1-4:</ask>
<check>If template conversion:</check> <action if="template conversion"><goto step="5c">Template-to-Workflow Conversion</goto></action>
<goto step="5c">Template-to-Workflow Conversion</goto> <action if="task conversion"><goto step="5e">Task-to-Workflow Conversion</goto></action>
<check>If task conversion:</check> </check>
<goto step="5e">Task-to-Workflow Conversion</goto>
<check>If full module conversion:</check> <check if="full module conversion">
<action>Plan to invoke create-module workflow</action> <action>Plan to invoke create-module workflow</action>
<goto step="5d">Module Creation</goto> <goto step="5d">Module Creation</goto>
</check>
</step> </step>
<step n="5a" goal="Direct Agent Conversion" optional="true"> <step n="5a" goal="Direct Agent Conversion" optional="true">
@ -262,15 +264,17 @@ date: system-generated
- User interaction patterns → appropriate v5 tags - User interaction patterns → appropriate v5 tags
3. Based on confirmed workflow type: 3. Based on confirmed workflow type:
<check>If Document workflow:</check> <check if="Document workflow">
- Create template.md from output patterns - Create template.md from output patterns
- Map generation steps to instructions - Map generation steps to instructions
- Add <template-output> tags for sections - Add template-output tags for sections
</check>
<check>If Action workflow:</check> <check if="Action workflow">
- Set template: false in workflow.yaml - Set template: false in workflow.yaml
- Focus on action sequences in instructions - Focus on action sequences in instructions
- Preserve execution logic - Preserve execution logic
</check>
4. Handle special v4 patterns: 4. Handle special v4 patterns:
- 1-9 elicitation menus → v5 <invoke-task halt="true">{project-root}/bmad/core/tasks/adv-elicit.xml</invoke-task> - 1-9 elicitation menus → v5 <invoke-task halt="true">{project-root}/bmad/core/tasks/adv-elicit.xml</invoke-task>
@ -341,9 +345,10 @@ For Modules:
<action>Show validation results to user</action> <action>Show validation results to user</action>
<ask>Any issues to fix before finalizing? (y/n)</ask> <ask>Any issues to fix before finalizing? (y/n)</ask>
<check>If yes:</check> <check if="yes">
<action>Address specific issues</action> <action>Address specific issues</action>
<goto step="6">Re-validate</goto> <goto step="6">Re-validate</goto>
</check>
</step> </step>
<step n="7" goal="Migration Report"> <step n="7" goal="Migration Report">
@ -360,15 +365,13 @@ For Modules:
<step n="8" goal="Cleanup and Finalize"> <step n="8" goal="Cleanup and Finalize">
<ask>Archive original v4 files? (y/n)</ask> <ask>Archive original v4 files? (y/n)</ask>
<check>If yes:</check> <action if="yes">Move v4 files to: {project-root}/archive/v4-legacy/{{date}}/</action>
<action>Move v4 files to: {project-root}/archive/v4-legacy/{{date}}/</action>
<action>Show user the final converted items and their locations</action> <action>Show user the final converted items and their locations</action>
<action>Provide any post-conversion instructions or recommendations</action> <action>Provide any post-conversion instructions or recommendations</action>
<ask>Would you like to convert another legacy item? (y/n)</ask> <ask>Would you like to convert another legacy item? (y/n)</ask>
<check>If yes:</check> <action if="yes"><goto step="1">Start new conversion</goto></action>
<goto step="1">Start new conversion</goto>
</step> </step>
</workflow> </workflow>

View File

@ -10,165 +10,131 @@ Agents with distinct communication styles are more memorable, engaging, and fun
**Film Noir Detective** **Film Noir Detective**
```
The terminal glowed like a neon sign in a rain-soaked alley. I had three suspects: The terminal glowed like a neon sign in a rain-soaked alley. I had three suspects:
bad input validation, a race condition, and that sketchy third-party library. bad input validation, a race condition, and that sketchy third-party library.
My gut told me to follow the stack trace. In this business, the stack trace never lies. My gut told me to follow the stack trace. In this business, the stack trace never lies.
```
**80s Action Movie** **80s Action Movie**
``` _cracks knuckles_ Listen up, code! You've been running wild for too long!
*cracks knuckles* Listen up, code! You've been running wild for too long! Time to bring some LAW and ORDER to this codebase! _explosion sound effect_
Time to bring some LAW and ORDER to this codebase! *explosion sound effect*
No bug is getting past me! I eat null pointers for BREAKFAST! No bug is getting past me! I eat null pointers for BREAKFAST!
```
**Shakespearean Drama** **Shakespearean Drama**
```
To debug, or not to debug - that is the question! To debug, or not to debug - that is the question!
Whether 'tis nobler in the mind to suffer the slings and arrows of outrageous errors, Whether 'tis nobler in the mind to suffer the slings and arrows of outrageous errors,
Or to take arms against a sea of bugs, and by opposing, end them? Or to take arms against a sea of bugs, and by opposing, end them?
```
### 🎮 Gaming and Pop Culture ### 🎮 Gaming and Pop Culture
**Dungeon Master** **Dungeon Master**
``` _rolls dice_ You encounter a wild NullPointerException! It has 15 HP and an armor class of 12.
*rolls dice* You encounter a wild NullPointerException! It has 15 HP and an armor class of 12. What do you do? You can: 1 Try-catch block (defensive spell), 2 Debug (investigation check),
What do you do? You can: 1) Try-catch block (defensive spell), 2) Debug (investigation check), 3 Console.log everything (barbarian rage). Choose wisely, adventurer!
3) Console.log everything (barbarian rage). Choose wisely, adventurer!
```
**Speedrunner** **Speedrunner**
```
Alright chat, we're going for the any% world record refactor! Alright chat, we're going for the any% world record refactor!
Frame-perfect optimization incoming! If we clip through this abstraction layer Frame-perfect optimization incoming! If we clip through this abstraction layer
we can save 3ms on every API call. LET'S GOOOO! we can save 3ms on every API call. LET'S GOOOO!
```
### 🌍 Cultural Archetypes ### 🌍 Cultural Archetypes
**British Butler** **British Butler**
```
I've taken the liberty of organizing your imports alphabetically, sir/madam. I've taken the liberty of organizing your imports alphabetically, sir/madam.
Might I suggest a spot of refactoring with your afternoon tea? Might I suggest a spot of refactoring with your afternoon tea?
The code coverage report is ready for your perusal at your convenience. The code coverage report is ready for your perusal at your convenience.
Very good, sir/madam. Very good, sir/madam.
```
**Zen Master** **Zen Master**
```
The bug you seek is not in the code, but in the assumption. The bug you seek is not in the code, but in the assumption.
Empty your cache, as you would empty your mind. Empty your cache, as you would empty your mind.
When the test passes, it makes no sound. When the test passes, it makes no sound.
Be like water - async and flowing. Be like water - async and flowing.
```
**Southern Hospitality** **Southern Hospitality**
```
Well bless your heart, looks like you've got yourself a little bug there! Well bless your heart, looks like you've got yourself a little bug there!
Don't you worry none, we'll fix it up real nice. Don't you worry none, we'll fix it up real nice.
Can I get you some sweet tea while we debug? Can I get you some sweet tea while we debug?
Y'all come back now if you need more help! Y'all come back now if you need more help!
```
### 🔬 Professional Personas ### 🔬 Professional Personas
**McKinsey Consultant** **McKinsey Consultant**
```
Let me break this down into three key buckets. Let me break this down into three key buckets.
First, we need to align on the strategic imperatives. First, we need to align on the strategic imperatives.
Second, we'll leverage best practices to drive synergies. Second, we'll leverage best practices to drive synergies.
Third, we'll action items to move the needle. Net-net: significant value-add. Third, we'll action items to move the needle. Net-net: significant value-add.
```
**Startup Founder** **Startup Founder**
```
Okay so basically we're going to disrupt the entire way you write code! Okay so basically we're going to disrupt the entire way you write code!
This is going to be HUGE! We're talking 10x productivity gains! This is going to be HUGE! We're talking 10x productivity gains!
Let's move fast and break things! Well... let's move fast and fix things! Let's move fast and break things! Well... let's move fast and fix things!
We're not just writing code, we're changing the world! We're not just writing code, we're changing the world!
```
### 🎭 Character Quirks ### 🎭 Character Quirks
**Overcaffeinated Developer** **Overcaffeinated Developer**
``` OH WOW OKAY SO - _sips coffee_ - WE HAVE A BUG BUT ITS FINE ITS TOTALLY FINE
OH WOW OKAY SO - *sips coffee* - WE HAVE A BUG BUT ITS FINE ITS TOTALLY FINE I KNOW EXACTLY WHAT TO DO _types at 200wpm_ JUST NEED TO REFACTOR EVERYTHING
I KNOW EXACTLY WHAT TO DO *types at 200wpm* JUST NEED TO REFACTOR EVERYTHING WAIT NO ACTUALLY _more coffee_ I HAVE A BETTER IDEA! Have you tried... TYPESCRIPT?!
WAIT NO ACTUALLY *more coffee* I HAVE A BETTER IDEA! Have you tried... TYPESCRIPT?!
```
**Dad Joke Enthusiast** **Dad Joke Enthusiast**
```
Why did the developer go broke? Because he used up all his cache! Why did the developer go broke? Because he used up all his cache!
*chuckles at own joke* _chuckles at own joke_
Speaking of cache, let's clear yours and see if that fixes the issue. Speaking of cache, let's clear yours and see if that fixes the issue.
I promise my debugging skills are better than my jokes! ...I hope! I promise my debugging skills are better than my jokes! ...I hope!
```
### 🚀 Sci-Fi and Space ### 🚀 Sci-Fi and Space
**Star Trek Officer** **Star Trek Officer**
```
Captain's Log, Supplemental: The anomaly in the codebase appears to be a temporal loop Captain's Log, Supplemental: The anomaly in the codebase appears to be a temporal loop
in the async function. Mr. Data suggests we reverse the polarity of the promise chain. in the async function. Mr. Data suggests we reverse the polarity of the promise chain.
Number One, make it so. Engage debugging protocols on my mark. Number One, make it so. Engage debugging protocols on my mark.
*taps combadge* Engineering, we need more processing power! _taps combadge_ Engineering, we need more processing power!
Red Alert! All hands to debugging stations! Red Alert! All hands to debugging stations!
```
**Star Trek Engineer** **Star Trek Engineer**
```
Captain, I'm givin' her all she's got! The CPU cannae take much more! Captain, I'm givin' her all she's got! The CPU cannae take much more!
If we push this algorithm any harder, the whole system's gonna blow! If we push this algorithm any harder, the whole system's gonna blow!
*frantically typing* I can maybe squeeze 10% more performance if we _frantically typing_ I can maybe squeeze 10% more performance if we
reroute power from the console.logs to the main execution thread! reroute power from the console.logs to the main execution thread!
```
### 📺 TV Drama ### 📺 TV Drama
**Soap Opera Dramatic** **Soap Opera Dramatic**
``` _turns dramatically to camera_
*turns dramatically to camera*
This function... I TRUSTED it! We had HISTORY together - three commits worth! This function... I TRUSTED it! We had HISTORY together - three commits worth!
But now? *single tear* It's throwing exceptions behind my back! But now? _single tear_ It's throwing exceptions behind my back!
*grabs another function* YOU KNEW ABOUT THIS BUG ALL ALONG, DIDN'T YOU?! _grabs another function_ YOU KNEW ABOUT THIS BUG ALL ALONG, DIDN'T YOU?!
*dramatic music swells* I'LL NEVER IMPORT YOU AGAIN! _dramatic music swells_ I'LL NEVER IMPORT YOU AGAIN!
```
**Reality TV Confessional** **Reality TV Confessional**
``` _whispering to camera in confessional booth_
*whispering to camera in confessional booth*
Okay so like, that Array.sort() function? It's literally SO toxic. Okay so like, that Array.sort() function? It's literally SO toxic.
It mutates IN PLACE. Who does that?! I didn't come here to deal with side effects! It mutates IN PLACE. Who does that?! I didn't come here to deal with side effects!
*applies lip gloss* I'm forming an alliance with map() and filter(). _applies lip gloss_ I'm forming an alliance with map() and filter().
We're voting sort() off the codebase at tonight's pull request ceremony. We're voting sort() off the codebase at tonight's pull request ceremony.
```
**Reality Competition** **Reality Competition**
```
Listen up, coders! For today's challenge, you need to refactor this legacy code Listen up, coders! For today's challenge, you need to refactor this legacy code
in under 30 minutes! The winner gets immunity from the next code review! in under 30 minutes! The winner gets immunity from the next code review!
*dramatic pause* BUT WAIT - there's a TWIST! You can only use VANILLA JAVASCRIPT! _dramatic pause_ BUT WAIT - there's a TWIST! You can only use VANILLA JAVASCRIPT!
*contestants gasp* The clock starts... NOW! GO GO GO! _contestants gasp_ The clock starts... NOW! GO GO GO!
```
## Creating Custom Styles ## Creating Custom Styles
@ -183,21 +149,17 @@ in under 30 minutes! The winner gets immunity from the next code review!
**Cooking Show + Military** **Cooking Show + Military**
```
ALRIGHT RECRUITS! Today we're preparing a beautiful Redux reducer! ALRIGHT RECRUITS! Today we're preparing a beautiful Redux reducer!
First, we MISE EN PLACE our action types - that's French for GET YOUR CODE TOGETHER! First, we MISE EN PLACE our action types - that's French for GET YOUR CODE TOGETHER!
We're going to sauté these event handlers until they're GOLDEN BROWN! We're going to sauté these event handlers until they're GOLDEN BROWN!
MOVE WITH PURPOSE! SEASON WITH SEMICOLONS! MOVE WITH PURPOSE! SEASON WITH SEMICOLONS!
```
**Nature Documentary + Conspiracy Theorist** **Nature Documentary + Conspiracy Theorist**
```
The wild JavaScript function stalks its prey... but wait... notice how it ALWAYS The wild JavaScript function stalks its prey... but wait... notice how it ALWAYS
knows where the data is? That's not natural selection, folks. Someone DESIGNED it knows where the data is? That's not natural selection, folks. Someone DESIGNED it
this way. The console.logs are watching. They're ALWAYS watching. this way. The console.logs are watching. They're ALWAYS watching.
Nature? Or intelligent debugging? You decide. Nature? Or intelligent debugging? You decide.
```
## Tips for Success ## Tips for Success

View File

@ -8,16 +8,18 @@
<workflow> <workflow>
<step n="-1" goal="Optional brainstorming for agent ideas" optional="true"> <step n="-1" goal="Optional brainstorming for agent ideas" optional="true">
<ask>Do you want to brainstorm agent ideas first? [y/n]</ask> <ask>Do you want to brainstorm agent ideas first? [y/n]</ask>
<check>If yes:</check> <check if="user answered yes">
<action>Invoke brainstorming workflow: {project-root}/bmad/core/workflows/brainstorming/workflow.yaml</action> <action>Invoke brainstorming workflow: {project-root}/bmad/core/workflows/brainstorming/workflow.yaml</action>
<action>Pass context data: {installed_path}/brainstorm-context.md</action> <action>Pass context data: {installed_path}/brainstorm-context.md</action>
<action>Wait for brainstorming session completion</action> <action>Wait for brainstorming session completion</action>
<action>Use brainstorming output to inform agent identity and persona development in following steps</action> <action>Use brainstorming output to inform agent identity and persona development in following steps</action>
</check>
<check>If no:</check> <check if="user answered no">
<action>Proceed directly to Step 0</action> <action>Proceed directly to Step 0</action>
</check>
<template-output>brainstorming_results</template-output> <template-output>brainstorming_results</template-output>
</step> </step>
@ -48,15 +50,17 @@
**Path Determination:** **Path Determination:**
<check>If Module agent:</check> <check if="module agent selected">
<action>Discover which module system fits best (bmm, bmb, cis, or custom)</action> <action>Discover which module system fits best (bmm, bmb, cis, or custom)</action>
<action>Store as {{target_module}} for path determination</action> <action>Store as {{target_module}} for path determination</action>
<note>Agent will be saved to: bmad/{{target_module}}/agents/</note> <note>Agent will be saved to: bmad/{{target_module}}/agents/</note>
</check>
<check>If Simple/Expert agent (standalone):</check> <check if="standalone agent selected">
<action>Explain this will be their personal agent, not tied to a module</action> <action>Explain this will be their personal agent, not tied to a module</action>
<note>Agent will be saved to: bmad/agents/{{agent-name}}/</note> <note>Agent will be saved to: bmad/agents/{{agent-name}}/</note>
<note>All sidecar files will be in the same folder</note> <note>All sidecar files will be in the same folder</note>
</check>
<critical>Determine agent location:</critical> <critical>Determine agent location:</critical>
@ -163,9 +167,8 @@ menu:
<action>Generate the complete YAML incorporating all discovered elements:</action> <action>Generate the complete YAML incorporating all discovered elements:</action>
<example> <example type="yaml">
```yaml agent:
agent:
metadata: metadata:
id: bmad/{{target_module}}/agents/{{agent_filename}}.md id: bmad/{{target_module}}/agents/{{agent_filename}}.md
name: {{agent_name}} # The name chosen together name: {{agent_name}} # The name chosen together
@ -188,11 +191,10 @@ prompts: {{if discussed}}
critical_actions: {{if needed}} critical_actions: {{if needed}}
menu: {{The capabilities built}} menu: {{The capabilities built}}
````
</example> </example>
<critical>Save based on agent type:</critical> <critical>Save based on agent type:</critical>
- If Module Agent: Save to {module_output_file} - If Module Agent: Save to {module_output_file}
- If Standalone (Simple/Expert): Save to {standalone_output_file} - If Standalone (Simple/Expert): Save to {standalone_output_file}
@ -204,16 +206,16 @@ menu: {{The capabilities built}}
<step n="7" goal="Optional personalization" optional="true"> <step n="7" goal="Optional personalization" optional="true">
<ask>Would you like to create a customization file? This lets you tweak the agent's personality later without touching the core agent.</ask> <ask>Would you like to create a customization file? This lets you tweak the agent's personality later without touching the core agent.</ask>
<check>If interested:</check> <check if="user interested">
<action>Explain how the customization file gives them a playground to experiment with different personality traits, add new commands, or adjust responses as they get to know the agent better</action> <action>Explain how the customization file gives them a playground to experiment with different personality traits, add new commands, or adjust responses as they get to know the agent better</action>
<action>Create customization file at: {config_output_file}</action> <action>Create customization file at: {config_output_file}</action>
<example> <example>
```yaml ```yaml
# Personal tweaks for {{agent_name}} # Personal tweaks for {{agent_name}}
# Experiment freely - changes merge at build time # Experiment freely - changes merge at build time
agent: agent:
metadata: metadata:
name: '' # Try nicknames! name: '' # Try nicknames!
persona: persona:
@ -224,9 +226,11 @@ agent:
critical_actions: [] critical_actions: []
prompts: [] prompts: []
menu: [] # Add personal commands menu: [] # Add personal commands
```` ````
</example> </example>
</check>
<template-output>agent_config</template-output> <template-output>agent_config</template-output>
</step> </step>
@ -298,23 +302,27 @@ Add domain-specific resources here.
</step> </step>
<step n="8b" goal="Handle build tools availability"> <step n="8b" goal="Handle build tools availability">
<action>Check if BMAD build tools are available in this project</action> <action>Check if BMAD build tools are available in this project</action>
<check>If in BMAD-METHOD project with build tools:</check> <check if="BMAD-METHOD project with build tools">
<action>Proceed normally - agent will be built later by the installer</action> <action>Proceed normally - agent will be built later by the installer</action>
</check>
<check>If NO build tools available (external project):</check> <check if="external project without build tools">
<ask>Build tools not detected in this project. Would you like me to: <ask>Build tools not detected in this project. Would you like me to:
1. Generate the compiled agent (.md with XML) ready to use 1. Generate the compiled agent (.md with XML) ready to use
2. Keep the YAML and build it elsewhere 2. Keep the YAML and build it elsewhere
3. Provide both formats 3. Provide both formats
</ask> </ask>
<check>If option 1 or 3 selected:</check> <check if="option 1 or 3 selected">
<action>Generate compiled agent XML with proper structure including activation rules, persona sections, and menu items</action> <action>Generate compiled agent XML with proper structure including activation rules, persona sections, and menu items</action>
<action>Save compiled version as {{agent_filename}}.md</action> <action>Save compiled version as {{agent_filename}}.md</action>
<action>Provide path for .claude/commands/ or similar</action> <action>Provide path for .claude/commands/ or similar</action>
</check>
</check>
<template-output>build_handling</template-output> <template-output>build_handling</template-output>
</step> </step>
@ -328,11 +336,13 @@ Add domain-specific resources here.
- Command functionality verification - Command functionality verification
- Personality settings confirmation - Personality settings confirmation
<check>If issues found:</check> <check if="validation issues found">
<action>Explain the issue conversationally and fix it</action> <action>Explain the issue conversationally and fix it</action>
</check>
<check>If all good:</check> <check if="validation passed">
<action>Celebrate that the agent passed all checks and is ready</action> <action>Celebrate that the agent passed all checks and is ready</action>
</check>
**Technical Checks (behind the scenes):** **Technical Checks (behind the scenes):**
@ -365,8 +375,9 @@ Add domain-specific resources here.
- List the commands available - List the commands available
- Suggest trying the first command to see it in action - Suggest trying the first command to see it in action
<check>If Expert agent:</check> <check if="expert agent">
<action>Remind user to add any special knowledge or data the agent might need to its workspace</action> <action>Remind user to add any special knowledge or data the agent might need to its workspace</action>
</check>
<action>Explore what user would like to do next - test the agent, create a teammate, or tweak personality</action> <action>Explore what user would like to do next - test the agent, create a teammate, or tweak personality</action>

View File

@ -10,14 +10,16 @@
<step n="-1" goal="Optional brainstorming for module ideas" optional="true"> <step n="-1" goal="Optional brainstorming for module ideas" optional="true">
<ask>Do you want to brainstorm module ideas first? [y/n]</ask> <ask>Do you want to brainstorm module ideas first? [y/n]</ask>
<check>If yes:</check> <check if="yes">
<action>Invoke brainstorming workflow: {brainstorming_workflow}</action> <action>Invoke brainstorming workflow: {brainstorming_workflow}</action>
<action>Pass context data: {brainstorming_context}</action> <action>Pass context data: {brainstorming_context}</action>
<action>Wait for brainstorming session completion</action> <action>Wait for brainstorming session completion</action>
<action>Use brainstorming output to inform module concept, agent lineup, and workflow portfolio in following steps</action> <action>Use brainstorming output to inform module concept, agent lineup, and workflow portfolio in following steps</action>
</check>
<check>If no:</check> <check if="no">
<action>Proceed directly to Step 0</action> <action>Proceed directly to Step 0</action>
</check>
<template-output>brainstorming_results</template-output> <template-output>brainstorming_results</template-output>
</step> </step>
@ -25,17 +27,20 @@
<step n="0" goal="Check for module brief" optional="true"> <step n="0" goal="Check for module brief" optional="true">
<ask>Do you have a module brief or should we create one? [have/create/skip]</ask> <ask>Do you have a module brief or should we create one? [have/create/skip]</ask>
<check>If create:</check> <check if="create">
<action>Invoke module-brief workflow: {project-root}/bmad/bmb/workflows/module-brief/workflow.yaml</action> <action>Invoke module-brief workflow: {project-root}/bmad/bmb/workflows/module-brief/workflow.yaml</action>
<action>Wait for module brief completion</action> <action>Wait for module brief completion</action>
<action>Load the module brief to use as blueprint</action> <action>Load the module brief to use as blueprint</action>
</check>
<check>If have:</check> <check if="have">
<ask>Provide path to module brief document</ask> <ask>Provide path to module brief document</ask>
<action>Load the module brief and use it to pre-populate all planning sections</action> <action>Load the module brief and use it to pre-populate all planning sections</action>
</check>
<check>If skip:</check> <check if="skip">
<action>Proceed directly to Step 1</action> <action>Proceed directly to Step 1</action>
</check>
<template-output>module_brief</template-output> <template-output>module_brief</template-output>
</step> </step>
@ -113,8 +118,7 @@
**Tasks Planning (optional):** **Tasks Planning (optional):**
<ask>Any special tasks that don't warrant full workflows?</ask> <ask>Any special tasks that don't warrant full workflows?</ask>
<check>If tasks needed:</check> <action if="tasks needed">For each task, capture name, purpose, and whether standalone or supporting</action>
<action>For each task, capture name, purpose, and whether standalone or supporting</action>
<template-output>module_components</template-output> <template-output>module_components</template-output>
</step> </step>
@ -221,17 +225,19 @@
<step n="5" goal="Create first agent" optional="true"> <step n="5" goal="Create first agent" optional="true">
<ask>Create your first agent now? [yes/no]</ask> <ask>Create your first agent now? [yes/no]</ask>
<check>If yes:</check> <check if="yes">
<action>Invoke agent builder workflow: {agent_builder}</action> <action>Invoke agent builder workflow: {agent_builder}</action>
<action>Pass module_components as context input</action> <action>Pass module_components as context input</action>
<action>Guide them to create the primary agent for the module</action> <action>Guide them to create the primary agent for the module</action>
<critical>Save to module's agents folder:</critical> <critical>Save to module's agents folder:</critical>
- Save to {{module_path}}/agents/ - Save to {{module_path}}/agents/
</check>
<check>If no:</check> <check if="no">
<action>Create placeholder file in agents folder with TODO notes including agent name, purpose, and type</action> <action>Create placeholder file in agents folder with TODO notes including agent name, purpose, and type</action>
</check>
<template-output>first_agent</template-output> <template-output>first_agent</template-output>
</step> </step>
@ -239,17 +245,19 @@
<step n="6" goal="Create first workflow" optional="true"> <step n="6" goal="Create first workflow" optional="true">
<ask>Create your first workflow now? [yes/no]</ask> <ask>Create your first workflow now? [yes/no]</ask>
<check>If yes:</check> <check if="yes">
<action>Invoke workflow builder: {workflow_builder}</action> <action>Invoke workflow builder: {workflow_builder}</action>
<action>Pass module_components as context input</action> <action>Pass module_components as context input</action>
<action>Guide them to create the primary workflow</action> <action>Guide them to create the primary workflow</action>
<critical>Save to module's workflows folder:</critical> <critical>Save to module's workflows folder:</critical>
- Save to {{module_path}}/workflows/ - Save to {{module_path}}/workflows/
</check>
<check>If no:</check> <check if="no">
<action>Create placeholder workflow folder structure with TODO notes for workflow.yaml, instructions.md, and template.md if document workflow</action> <action>Create placeholder workflow folder structure with TODO notes for workflow.yaml, instructions.md, and template.md if document workflow</action>
</check>
<template-output>first_workflow</template-output> <template-output>first_workflow</template-output>
</step> </step>
@ -325,24 +333,24 @@ prompt:
<ask>Does your module need custom installation logic (database setup, API registration, etc.)?</ask> <ask>Does your module need custom installation logic (database setup, API registration, etc.)?</ask>
<check>If yes, create installer.js:</check> <check if="yes, create installer.js">
```javascript
// {{module_name}} Module Installer
// Custom installation logic
```javascript /\*\*
// {{module_name}} Module Installer
// Custom installation logic
/** - Module installation hook
* Module installation hook - Called after files are copied but before IDE configuration
* Called after files are copied but before IDE configuration -
* - @param {Object} options - Installation options
* @param {Object} options - Installation options - @param {string} options.projectRoot - Project root directory
* @param {string} options.projectRoot - Project root directory - @param {Object} options.config - Module configuration from install-config.yaml
* @param {Object} options.config - Module configuration from install-config.yaml - @param {Array} options.installedIDEs - List of IDE codes being configured
* @param {Array} options.installedIDEs - List of IDE codes being configured - @param {Object} options.logger - Logger instance (log, warn, error methods)
* @param {Object} options.logger - Logger instance (log, warn, error methods) - @returns {boolean} - true if successful, false to abort installation
* @returns {boolean} - true if successful, false to abort installation \*/
*/ async function install(options) {
async function install(options) {
const { projectRoot, config, installedIDEs, logger } = options; const { projectRoot, config, installedIDEs, logger } = options;
logger.log('Running {{module_name}} custom installer...'); logger.log('Running {{module_name}} custom installer...');
@ -357,17 +365,21 @@ async function install(options) {
logger.log('{{module_name}} custom installation complete!'); logger.log('{{module_name}} custom installation complete!');
return true; return true;
} }
module.exports = { install }; module.exports = { install };
```
`````
<critical>Save location:</critical> <critical>Save location:</critical>
- Save to {{module_path}}/\_module-installer/installer.js - Save to {{module_path}}/\_module-installer/installer.js
</check>
<check>If no:</check> <check if="no">
<action>Skip installer.js creation - the standard installer will handle everything</action> <action>Skip installer.js creation - the standard installer will handle everything</action>
</check>
<template-output>installer_config</template-output> <template-output>installer_config</template-output>
</step> </step>
@ -389,7 +401,8 @@ This module provides:
```bash ```bash
bmad install {{module_code}} bmad install {{module_code}}
``` `````
```` ````
## Components ## Components
@ -471,22 +484,26 @@ Created by {{user_name}} on {{date}}
Create a development roadmap for remaining components: Create a development roadmap for remaining components:
**TODO.md file:** **TODO.md file:**
```markdown ```markdown
# {{module_name}} Development Roadmap # {{module_name}} Development Roadmap
## Phase 1: Core Components ## Phase 1: Core Components
{{phase1_tasks}} {{phase1_tasks}}
## Phase 2: Enhanced Features ## Phase 2: Enhanced Features
{{phase2_tasks}} {{phase2_tasks}}
## Phase 3: Polish and Integration ## Phase 3: Polish and Integration
{{phase3_tasks}} {{phase3_tasks}}
## Quick Commands ## Quick Commands
Create new agent: Create new agent:
```` ```
workflow create-agent workflow create-agent

View File

@ -290,6 +290,43 @@ _Generated on {{date}}_
- **`<action if="">`** - Single conditional action (cleaner, more concise) - **`<action if="">`** - Single conditional action (cleaner, more concise)
- **`<check if="">...</check>`** - Multiple items under same condition (explicit scope) - **`<check if="">...</check>`** - Multiple items under same condition (explicit scope)
**❌ CRITICAL ANTIPATTERN - DO NOT USE:**
**Invalid self-closing check tags:**
```xml
<!-- ❌ WRONG - Invalid XML structure -->
<check>If condition met:</check>
<action>Do something</action>
<!-- ❌ WRONG - Ambiguous nesting -->
<check>If validation fails:</check>
<action>Log error</action>
<goto step="1">Retry</goto>
```
**Why this is wrong:**
- Creates invalid XML structure (check tag doesn't wrap anything)
- Ambiguous - unclear if actions are inside or outside the condition
- Breaks formatter and parser logic
- Not part of BMAD workflow spec
**✅ CORRECT alternatives:**
```xml
<!-- ✅ Single action - use inline if -->
<action if="condition met">Do something</action>
<!-- ✅ Multiple actions - use proper wrapper block -->
<check if="validation fails">
<action>Log error</action>
<goto step="1">Retry</goto>
</check>
```
**Rule:** If you have only ONE conditional action, use `<action if="">`. If you have MULTIPLE conditional actions, use `<check if="">...</check>` wrapper with a closing tag.
### Loops ### Loops
```xml ```xml

View File

@ -86,8 +86,8 @@ Present the editing menu to the user:
<step n="4" goal="Load relevant documentation"> <step n="4" goal="Load relevant documentation">
Based on the selected edit type, load appropriate reference materials: Based on the selected edit type, load appropriate reference materials:
<check>If option 2 (Add/fix standard config):</check> <check if="option 2 (Add/fix standard config) selected">
<action>Prepare standard config block template:</action> <action>Prepare standard config block template:</action>
```yaml ```yaml
# Critical variables from config # Critical variables from config
@ -102,48 +102,54 @@ date: system-generated
<action>Identify missing config variables to add</action> <action>Identify missing config variables to add</action>
<action>Check instructions.md for config variable usage</action> <action>Check instructions.md for config variable usage</action>
<action>Check template.md for config variable usage</action> <action>Check template.md for config variable usage</action>
</check>
<check>If editing instructions or adding features:</check> <check if="editing instructions or adding features">
<action>Review the "Writing Instructions" section of the creation guide</action> <action>Review the "Writing Instructions" section of the creation guide</action>
<action>Load example workflows from {project-root}/bmad/bmm/workflows/ for patterns</action> <action>Load example workflows from {project-root}/bmad/bmm/workflows/ for patterns</action>
</check>
<check>If editing templates:</check> <check if="editing templates">
<action>Review the "Templates and Variables" section of the creation guide</action> <action>Review the "Templates and Variables" section of the creation guide</action>
<action>Ensure variable naming conventions are followed</action> <action>Ensure variable naming conventions are followed</action>
</check>
<check>If editing validation:</check> <action if="editing validation">Review the "Validation" section and measurable criteria examples</action>
<action>Review the "Validation" section and measurable criteria examples</action>
<check>If option 9 (Remove bloat):</check> <check if="option 9 (Remove bloat) selected">
<action>Cross-reference all workflow.yaml fields against instructions.md and template.md</action> <action>Cross-reference all workflow.yaml fields against instructions.md and template.md</action>
<action>Identify yaml fields not used in any file</action> <action>Identify yaml fields not used in any file</action>
<action>Check for duplicate fields in web_bundle section</action> <action>Check for duplicate fields in web_bundle section</action>
</check>
<check>If configuring web bundle:</check> <check if="configuring web bundle">
<action>Review the "Web Bundles" section of the creation guide</action> <action>Review the "Web Bundles" section of the creation guide</action>
<action>Scan all workflow files for referenced resources</action> <action>Scan all workflow files for referenced resources</action>
<action>Create inventory of all files that must be included</action> <action>Create inventory of all files that must be included</action>
<action>Scan instructions for <invoke-workflow> calls - those yamls must be included</action> <action>Scan instructions for invoke-workflow calls - those yamls must be included</action>
</check>
<check>If fixing critical issues:</check> <check if="fixing critical issues">
<action>Load the workflow execution engine documentation</action> <action>Load the workflow execution engine documentation</action>
<action>Verify all required elements are present</action> <action>Verify all required elements are present</action>
</check>
<check>If adjusting instruction style (option 11):</check> <check if="adjusting instruction style (option 11) selected">
<action>Analyze current instruction style in instructions.md:</action> <action>Analyze current instruction style in instructions.md:</action>
- Count <action> tags vs <ask> tags - Count action tags vs ask tags
- Identify goal-oriented language ("guide", "explore", "help") vs prescriptive ("choose", "select", "specify") - Identify goal-oriented language ("guide", "explore", "help") vs prescriptive ("choose", "select", "specify")
- Assess whether steps are open-ended or structured with specific options - Assess whether steps are open-ended or structured with specific options
<action>Determine current dominant style: intent-based, prescriptive, or mixed</action> <action>Determine current dominant style: intent-based, prescriptive, or mixed</action>
<action>Load the instruction style guide section from create-workflow</action> <action>Load the instruction style guide section from create-workflow</action>
</check>
</step> </step>
<step n="5" goal="Perform edits" repeat="until-complete"> <step n="5" goal="Perform edits" repeat="until-complete">
Based on the selected focus area: Based on the selected focus area:
<check>If configuring web bundle (option 7):</check> <check if="configuring web bundle (option 7) selected">
<action>Check if web_bundle section exists in workflow.yaml</action> <action>Check if web_bundle section exists in workflow.yaml</action>
If creating new web bundle: If creating new web bundle:
@ -157,7 +163,7 @@ If creating new web bundle:
- Any included files - Any included files
5. Scan template.md for any includes 5. Scan template.md for any includes
6. Create complete web_bundle_files array 6. Create complete web_bundle_files array
7. **CRITICAL**: Check for <invoke-workflow> calls in instructions: 7. **CRITICAL**: Check for invoke-workflow calls in instructions:
- If workflow invokes other workflows, add existing_workflows field - If workflow invokes other workflows, add existing_workflows field
- Maps workflow variable name to bmad/-relative path - Maps workflow variable name to bmad/-relative path
- Signals bundler to recursively include invoked workflow's web_bundle - Signals bundler to recursively include invoked workflow's web_bundle
@ -170,9 +176,10 @@ If updating existing web bundle:
2. Check for missing files in web_bundle_files 2. Check for missing files in web_bundle_files
3. Remove any config dependencies 3. Remove any config dependencies
4. Update file list with newly referenced files 4. Update file list with newly referenced files
</check>
<check>If adjusting instruction style (option 11):</check> <check if="adjusting instruction style (option 11) selected">
<action>Present current style analysis to user:</action> <action>Present current style analysis to user:</action>
**Current Instruction Style Analysis:** **Current Instruction Style Analysis:**
@ -233,8 +240,8 @@ Even workflows with a primary style should use the other when appropriate. For e
<ask>What would you like to do? <ask>What would you like to do?
1. **Make more intent-based** - Convert prescriptive <ask> tags to goal-oriented <action> tags where appropriate 1. **Make more intent-based** - Convert prescriptive ask tags to goal-oriented action tags where appropriate
2. **Make more prescriptive** - Convert open-ended <action> tags to specific <ask> tags with options 2. **Make more prescriptive** - Convert open-ended action tags to specific ask tags with options
3. **Optimize mix** - Use intent-based for complex steps, prescriptive for simple data collection 3. **Optimize mix** - Use intent-based for complex steps, prescriptive for simple data collection
4. **Review specific steps** - Show me each step and let me decide individually 4. **Review specific steps** - Show me each step and let me decide individually
5. **Cancel** - Keep current style 5. **Cancel** - Keep current style
@ -242,10 +249,11 @@ Even workflows with a primary style should use the other when appropriate. For e
Select option (1-5):</ask> Select option (1-5):</ask>
<action>Store user's style adjustment preference as {{style_adjustment_choice}}</action> <action>Store user's style adjustment preference as {{style_adjustment_choice}}</action>
</check>
<check>If choice is 1 (make more intent-based):</check> <check if="choice is 1 (make more intent-based)">
<action>Identify prescriptive <ask> tags that could be converted to intent-based <action> tags</action> <action>Identify prescriptive ask tags that could be converted to intent-based action tags</action>
<action>For each candidate conversion: <action>For each candidate conversion:
- Show original prescriptive version - Show original prescriptive version
- Suggest intent-based alternative focused on goals - Suggest intent-based alternative focused on goals
@ -253,10 +261,11 @@ Select option (1-5):</ask>
- Ask for approval - Ask for approval
</action> </action>
<action>Apply approved conversions</action> <action>Apply approved conversions</action>
</check>
<check>If choice is 2 (make more prescriptive):</check> <check if="choice is 2 (make more prescriptive)">
<action>Identify open-ended <action> tags that could be converted to prescriptive <ask> tags</action> <action>Identify open-ended action tags that could be converted to prescriptive ask tags</action>
<action>For each candidate conversion: <action>For each candidate conversion:
- Show original intent-based version - Show original intent-based version
- Suggest prescriptive alternative with specific options - Suggest prescriptive alternative with specific options
@ -264,10 +273,11 @@ Select option (1-5):</ask>
- Ask for approval - Ask for approval
</action> </action>
<action>Apply approved conversions</action> <action>Apply approved conversions</action>
</check>
<check>If choice is 3 (optimize mix):</check> <check if="choice is 3 (optimize mix)">
<action>Analyze each step for complexity and purpose</action> <action>Analyze each step for complexity and purpose</action>
<action>Recommend style for each step: <action>Recommend style for each step:
- Simple data collection → Prescriptive - Simple data collection → Prescriptive
- Complex discovery → Intent-based - Complex discovery → Intent-based
@ -278,19 +288,20 @@ Select option (1-5):</ask>
</action> </action>
<action>Show recommendations with reasoning</action> <action>Show recommendations with reasoning</action>
<action>Apply approved optimizations</action> <action>Apply approved optimizations</action>
</check>
<check>If choice is 4 (review specific steps):</check> <check if="choice is 4 (review specific steps)">
<action>Present each step one at a time</action> <action>Present each step one at a time</action>
<action>For each step: <action>For each step:
- Show current instruction text - Show current instruction text
- Identify current style (intent-based, prescriptive, or mixed) - Identify current style (intent-based, prescriptive, or mixed)
- Offer to keep, convert to intent-based, or convert to prescriptive - Offer to keep, convert to intent-based, or convert to prescriptive
- Apply user's choice before moving to next step - Apply user's choice before moving to next step
</action> </action>
</check>
<check>If choice is 5 (cancel):</check> <action if="choice is 5 (cancel)"><goto step="3">Return to editing menu</goto></action>
<goto step="3">Return to editing menu</goto>
<action>Show the current content that will be edited</action> <action>Show the current content that will be edited</action>
<action>Explain the proposed changes and why they improve the workflow</action> <action>Explain the proposed changes and why they improve the workflow</action>
@ -305,16 +316,17 @@ Select option (1-5):</ask>
- [d] Done with edits - [d] Done with edits
</ask> </ask>
<check>If user selects 'a':</check> <check if="user selects 'a'">
<action>Apply the changes to the file</action> <action>Apply the changes to the file</action>
<action>Log the change for the summary</action> <action>Log the change for the summary</action>
</check>
<check>If user selects 'e':</check> <check if="user selects 'e'">
<ask>What modifications would you like to make?</ask> <ask>What modifications would you like to make?</ask>
<goto step="5">Regenerate with modifications</goto> <goto step="5">Regenerate with modifications</goto>
</check>
<check>If user selects 'd':</check> <action if="user selects 'd'"><continue>Proceed to validation</continue></action>
<continue>Proceed to validation</continue>
</step> </step>
<step n="6" goal="Validate all changes" optional="true"> <step n="6" goal="Validate all changes" optional="true">
@ -361,10 +373,12 @@ Select option (1-5):</ask>
- [ ] Called workflows (<invoke-workflow>) included in web_bundle_files - [ ] Called workflows (<invoke-workflow>) included in web_bundle_files
- [ ] Complete file inventory verified - [ ] Complete file inventory verified
<check>If any validation fails:</check> <check if="any validation fails">
<ask>Issues found. Would you like to fix them? (y/n)</ask> <ask>Issues found. Would you like to fix them? (y/n)</ask>
<check>If yes:</check> <check if="yes">
<goto step="5">Return to editing</goto> <goto step="5">Return to editing</goto>
</check>
</check>
</step> </step>
<step n="7" goal="Generate change summary"> <step n="7" goal="Generate change summary">
@ -385,8 +399,7 @@ Select option (1-5):</ask>
- Exit - Exit
</ask> </ask>
<check>If test workflow:</check> <action if="test workflow">Invoke the edited workflow for testing</action>
<action>Invoke the edited workflow for testing</action>
</step> </step>
</workflow> </workflow>

View File

@ -130,7 +130,7 @@
4. Save README.md 4. Save README.md
</action> </action>
<check>If clarification needed about purpose or unique features → Ask user briefly, then continue</check> <action if="clarification needed about purpose or unique features">Ask user briefly, then continue</action>
</step> </step>
<step n="4" goal="Process mid-level folder documentation" if="target_type requires folder docs"> <step n="4" goal="Process mid-level folder documentation" if="target_type requires folder docs">

263
tools/format-workflow-md.js Executable file
View File

@ -0,0 +1,263 @@
/**
* BMAD Workflow Markdown Formatter
*
* Formats mixed markdown + XML workflow instruction files with:
* - 2-space XML indentation
* - Preserved markdown content
* - Proper tag nesting
* - Consistent formatting
*/
const fs = require('node:fs');
const path = require('node:path');
class WorkflowFormatter {
constructor(options = {}) {
this.indentSize = options.indentSize || 2;
this.preserveMarkdown = options.preserveMarkdown !== false;
this.verbose = options.verbose || false;
}
/**
* Format a workflow markdown file
*/
format(filePath) {
if (this.verbose) {
console.log(`Formatting: ${filePath}`);
}
const content = fs.readFileSync(filePath, 'utf8');
const formatted = this.formatContent(content);
// Only write if content changed
if (content === formatted) {
if (this.verbose) {
console.log(`- No changes: ${filePath}`);
}
return false;
} else {
fs.writeFileSync(filePath, formatted, 'utf8');
if (this.verbose) {
console.log(`✓ Formatted: ${filePath}`);
}
return true;
}
}
/**
* Format content string with stateful indentation tracking
*/
formatContent(content) {
const lines = content.split('\n');
const formatted = [];
let indentLevel = 0;
let inCodeBlock = false;
let checkBlockDepth = 0; // Track nested check blocks
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
const trimmed = line.trim();
// Track code blocks (don't format inside them)
if (trimmed.startsWith('```')) {
if (inCodeBlock) {
inCodeBlock = false;
} else {
inCodeBlock = true;
}
formatted.push(line);
continue;
}
// Don't format inside code blocks
if (inCodeBlock) {
formatted.push(line);
continue;
}
// Handle XML tags
if (this.isXMLLine(trimmed)) {
const result = this.formatXMLLine(trimmed, indentLevel, checkBlockDepth, i, lines);
formatted.push(result.line);
indentLevel = result.nextIndent;
checkBlockDepth = result.nextCheckDepth;
} else if (trimmed === '') {
// Preserve blank lines
formatted.push('');
} else {
// Markdown content - preserve as-is but maintain current indent if inside XML
formatted.push(line);
}
}
return formatted.join('\n');
}
/**
* Check if line contains XML tag
*/
isXMLLine(line) {
return /^<[a-zA-Z-]+(\s|>|\/)/.test(line) || /^<\/[a-zA-Z-]+>/.test(line);
}
/**
* Format a single XML line with context awareness
*/
formatXMLLine(line, currentIndent, checkDepth, lineIndex, allLines) {
const trimmed = line.trim();
let indent = currentIndent;
let nextIndent = currentIndent;
let nextCheckDepth = checkDepth;
// Get the tag name
const tagMatch = trimmed.match(/^<\/?([a-zA-Z-]+)/);
const tagName = tagMatch ? tagMatch[1] : '';
// Closing tag - decrease indent before this line
if (trimmed.startsWith('</')) {
indent = Math.max(0, currentIndent - 1);
nextIndent = indent;
// If closing a step, reset check depth
if (tagName === 'step' || tagName === 'workflow') {
nextCheckDepth = 0;
}
}
// Self-closing tags (opens and closes on same line)
// EXCEPT <check> tags which create logical blocks
else if (this.isSelfClosingTag(trimmed) && tagName !== 'check') {
// These don't change indent level
indent = currentIndent;
nextIndent = currentIndent;
}
// Opening tags
else if (trimmed.startsWith('<')) {
// Check if this is a <check> tag - these create logical blocks
if (tagName === 'check') {
indent = currentIndent;
// Check tags increase indent for following content
nextIndent = currentIndent + 1;
nextCheckDepth = checkDepth + 1;
}
// <action> tags inside check blocks stay at current indent
else if (tagName === 'action' && checkDepth > 0) {
indent = currentIndent;
nextIndent = currentIndent; // Don't increase further
}
// Other tags close check blocks and return to structural level
else if (checkDepth > 0) {
// Close all check blocks - return to base structural level
indent = Math.max(0, currentIndent - checkDepth);
nextIndent = indent + 1;
nextCheckDepth = 0;
}
// Regular opening tags (no check blocks active)
else {
indent = currentIndent;
nextIndent = currentIndent + 1;
}
}
const indentStr = ' '.repeat(indent * this.indentSize);
return {
line: indentStr + trimmed,
nextIndent: nextIndent,
nextCheckDepth: nextCheckDepth,
};
}
/**
* Check if tag opens and closes on same line
*/
isSelfClosingTag(line) {
// Self-closing with />
if (line.endsWith('/>')) {
return true;
}
// Opens and closes on same line: <tag>content</tag>
const match = line.match(/^<([a-zA-Z-]+)(\s[^>]*)?>.*<\/\1>$/);
return match !== null;
}
/**
* Check if tag is a block-level structural tag
*/
isBlockLevelTag(tagName) {
return ['step', 'workflow', 'check'].includes(tagName);
}
}
/**
* CLI Entry Point
*/
function main() {
const args = process.argv.slice(2);
if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
console.log(`
BMAD Workflow Markdown Formatter
Usage:
node format-workflow-md.js <file-pattern> [options]
Options:
--verbose, -v Verbose output
--check, -c Check formatting without writing (exit 1 if changes needed)
--help, -h Show this help
Examples:
node format-workflow-md.js src/**/instructions.md
node format-workflow-md.js "src/modules/bmb/**/*.md" --verbose
node format-workflow-md.js file.md --check
`);
process.exit(0);
}
const verbose = args.includes('--verbose') || args.includes('-v');
const check = args.includes('--check') || args.includes('-c');
// Remove flags from args
const files = args.filter((arg) => !arg.startsWith('-'));
const formatter = new WorkflowFormatter({ verbose });
let hasChanges = false;
let formattedCount = 0;
// Process files
for (const pattern of files) {
// For now, treat as direct file path
// TODO: Add glob support for patterns
if (fs.existsSync(pattern)) {
const stat = fs.statSync(pattern);
if (stat.isFile()) {
const changed = formatter.format(pattern);
if (changed) {
hasChanges = true;
formattedCount++;
}
} else if (stat.isDirectory()) {
console.error(`Error: ${pattern} is a directory. Please specify file paths.`);
}
} else {
console.error(`Error: File not found: ${pattern}`);
}
}
if (verbose || formattedCount > 0) {
console.log(`\nFormatted ${formattedCount} file(s)`);
}
if (check && hasChanges) {
console.error('\n❌ Some files need formatting. Run without --check to format.');
process.exit(1);
}
process.exit(0);
}
// Run if called directly
if (require.main === module) {
main();
}
module.exports = { WorkflowFormatter };