feat: add epic chain report generator
- Add chain-report-template.md with placeholders for metrics aggregation - Add epic-metrics-template.yaml schema for per-epic metrics collection - Add step-10-generate-report.md with report generation instructions - Update epic-chain workflow.yaml with report variables - Add [CR] chain-report trigger to SM agent menu - Update instructions.md with report generation and metrics collection docs 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
2f9dc39c0b
commit
57fda0915b
|
|
@ -57,3 +57,7 @@ agent:
|
|||
- trigger: UV or fuzzy match on uat-validate
|
||||
workflow: "{project-root}/_bmad/bmm/workflows/5-validation/uat-validate/workflow.yaml"
|
||||
description: "[UV] Validate epic against UAT scenarios with self-healing fix loop on failure"
|
||||
|
||||
- trigger: CR or fuzzy match on chain-report
|
||||
exec: "{project-root}/_bmad/bmm/workflows/4-implementation/epic-chain/steps/step-10-generate-report.md"
|
||||
description: "[CR] Generate execution report from completed epic chain metrics"
|
||||
|
|
|
|||
|
|
@ -320,3 +320,39 @@ After each epic completes, generate handoff:
|
|||
| Story execution fails | Log failure, continue to next story, report in summary |
|
||||
| Epic fails completely | Pause chain, ask user whether to continue or abort |
|
||||
| Context handoff fails | Log warning, continue without handoff |
|
||||
|
||||
---
|
||||
|
||||
## Report Generation
|
||||
|
||||
After chain completion, generate an execution report using step 10:
|
||||
|
||||
<step n="10" goal="Generate chain execution report">
|
||||
<action>Load step file: `{installed_path}/steps/step-10-generate-report.md`</action>
|
||||
|
||||
This step:
|
||||
1. Loads metrics from `{metrics_folder}/epic-{id}-metrics.yaml` for each epic
|
||||
2. Aggregates timing, story counts, issues, and UAT results
|
||||
3. Builds dependency graph visualization
|
||||
4. Calculates token/cost estimates
|
||||
5. Renders the report template
|
||||
6. Saves to `{chain_report_file}`
|
||||
|
||||
**Trigger manually:** `*chain-report` or `*CR`
|
||||
|
||||
**Output:** `{sprint_artifacts}/chain-execution-report.md`
|
||||
</step>
|
||||
|
||||
## Metrics Collection
|
||||
|
||||
During epic execution, metrics are collected to `{metrics_folder}/epic-{id}-metrics.yaml`:
|
||||
|
||||
| Metric | Source | Description |
|
||||
|--------|--------|-------------|
|
||||
| Timing | Shell script | Start/end timestamps per epic |
|
||||
| Story counts | Story file status | Completed/failed/skipped counts |
|
||||
| UAT results | uat-validate | Gate status, fix attempts |
|
||||
| Issues | Dev/review phases | Problems encountered |
|
||||
| Git info | git log | Commit counts, SHAs |
|
||||
|
||||
See `templates/epic-metrics-template.yaml` for full schema.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,242 @@
|
|||
# Step 10: Generate Chain Execution Report
|
||||
|
||||
## Purpose
|
||||
|
||||
Generate a comprehensive execution report after the epic chain completes, aggregating metrics from all epics into a single document.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- All epics in the chain have completed (success or failure)
|
||||
- Metrics files exist at `{metrics_folder}/epic-{id}-metrics.yaml` for each epic
|
||||
- Chain plan file exists at `{chain_plan_file}`
|
||||
|
||||
## Inputs
|
||||
|
||||
| Input | Location | Required |
|
||||
|-------|----------|----------|
|
||||
| Chain Plan | `{chain_plan_file}` | Yes |
|
||||
| Epic Metrics | `{metrics_folder}/epic-{id}-metrics.yaml` | Yes (per epic) |
|
||||
| Story Files | `{stories_location}/*.md` | For story counts |
|
||||
| UAT Documents | `{uat_location}/epic-{id}-uat.md` | For UAT summary |
|
||||
|
||||
## Process
|
||||
|
||||
### 10.1 Load All Metrics Files
|
||||
|
||||
For each epic in the chain plan:
|
||||
|
||||
```yaml
|
||||
# Load from {metrics_folder}/epic-{id}-metrics.yaml
|
||||
epic_id: "1"
|
||||
epic_name: "Foundation, CLI & Deployment"
|
||||
|
||||
execution:
|
||||
start_time: "2026-01-02T13:40:00Z"
|
||||
end_time: "2026-01-02T15:10:00Z"
|
||||
duration_seconds: 5400
|
||||
|
||||
stories:
|
||||
total: 7
|
||||
completed: 7
|
||||
failed: 0
|
||||
skipped: 0
|
||||
|
||||
validation:
|
||||
gate_status: "PASS"
|
||||
fix_attempts: 0
|
||||
|
||||
issues: []
|
||||
```
|
||||
|
||||
### 10.2 Calculate Aggregate Metrics
|
||||
|
||||
**Timing:**
|
||||
- `start_time` = earliest epic start time
|
||||
- `end_time` = latest epic end time
|
||||
- `duration` = end_time - start_time (formatted as "Xh Ym")
|
||||
- `avg_story_time` = total_duration / total_stories (formatted as "X minutes")
|
||||
|
||||
**Counts:**
|
||||
- `epic_count` = number of epics in chain
|
||||
- `story_count` = sum of all stories across epics
|
||||
- `completed_count` = sum of completed stories
|
||||
- `failed_count` = sum of failed stories
|
||||
- `completion_pct` = (completed_count / story_count) * 100
|
||||
|
||||
**Status:**
|
||||
- `chain_status` = "COMPLETE" if all epics passed, otherwise "PARTIAL" or "FAILED"
|
||||
|
||||
### 10.3 Build Timeline Table
|
||||
|
||||
For each epic, create a row:
|
||||
|
||||
```markdown
|
||||
| {epic_id} | {epic_name} | {story_count} | {duration} | {status} |
|
||||
```
|
||||
|
||||
Duration format: "X.X hours (Xs)" or "~X.X hours"
|
||||
|
||||
### 10.4 Build Dependency Graph
|
||||
|
||||
**ASCII Format:**
|
||||
```
|
||||
Epic 1 (Foundation)
|
||||
├── Epic 2 (Event Ingestion) ──┐
|
||||
│ └── Epic 3 (Workflow) ─┼── Epic 7 (Observability)
|
||||
└── Epic 5 (AI Copilot) ───────┘
|
||||
```
|
||||
|
||||
**Table Format:**
|
||||
For each epic with dependencies:
|
||||
```markdown
|
||||
| {epic_id} | {depends_on_ids} | {reason} |
|
||||
```
|
||||
|
||||
### 10.5 Generate Per-Epic Summary
|
||||
|
||||
For each epic, generate a section:
|
||||
|
||||
```markdown
|
||||
### Epic {id}: {name} ({story_count} stories)
|
||||
|
||||
{brief_description_from_epic_file}
|
||||
|
||||
**Stories:**
|
||||
{list_story_ids_and_titles}
|
||||
```
|
||||
|
||||
### 10.6 Compile Issues Section
|
||||
|
||||
Aggregate all issues from metrics files:
|
||||
|
||||
```markdown
|
||||
### {issue_type}
|
||||
|
||||
**Issue:** {description}
|
||||
**Impact:** {affected_stories}
|
||||
**Resolution:** {how_resolved}
|
||||
|
||||
**Affected Stories:**
|
||||
{list_of_story_ids}
|
||||
```
|
||||
|
||||
If no issues: "No significant issues encountered during execution."
|
||||
|
||||
### 10.7 Generate UAT Summary
|
||||
|
||||
For each epic:
|
||||
|
||||
```markdown
|
||||
| {epic_id} | {uat_doc_path} | {scenario_count} | {auto_passed}/{automatable} | {fix_attempts} | {gate_status} |
|
||||
```
|
||||
|
||||
**Fix History Section:**
|
||||
If any epic required self-healing fixes:
|
||||
|
||||
```markdown
|
||||
### Epic {id} Fix History
|
||||
|
||||
- **Attempt 1:** Fixed {scenario_ids}, committed {commit_hash}
|
||||
- **Attempt 2:** Fixed remaining issues, all scenarios passing
|
||||
```
|
||||
|
||||
### 10.8 Calculate Token Estimates
|
||||
|
||||
Per epic (based on story count):
|
||||
|
||||
```
|
||||
calls_per_story = 2 (dev + review)
|
||||
input_per_call = 8000 tokens
|
||||
output_per_call = 4000 tokens
|
||||
|
||||
epic_calls = stories * calls_per_story
|
||||
epic_input = epic_calls * input_per_call
|
||||
epic_output = epic_calls * output_per_call
|
||||
epic_total = epic_input + epic_output
|
||||
```
|
||||
|
||||
**Cost Calculation:**
|
||||
```
|
||||
sonnet_input_rate = $3 / 1M tokens
|
||||
sonnet_output_rate = $15 / 1M tokens
|
||||
opus_input_rate = $15 / 1M tokens
|
||||
opus_output_rate = $75 / 1M tokens
|
||||
```
|
||||
|
||||
### 10.9 Generate Conclusion
|
||||
|
||||
Based on results:
|
||||
|
||||
**All Passed:**
|
||||
```
|
||||
The {project_name} was successfully implemented through automated AI-driven
|
||||
development using the BMAD Epic Chain workflow. All {story_count} stories
|
||||
across {epic_count} epics were completed in approximately {duration}.
|
||||
|
||||
The system provides:
|
||||
{list_key_capabilities_from_epics}
|
||||
```
|
||||
|
||||
**Partial Success:**
|
||||
```
|
||||
The epic chain completed with {completed_count}/{story_count} stories successful.
|
||||
{failed_count} stories require attention before the system is production-ready.
|
||||
|
||||
See Issues Encountered section for details on failures and recommended actions.
|
||||
```
|
||||
|
||||
### 10.10 Render Template
|
||||
|
||||
Load template from `{installed_path}/templates/chain-report-template.md`
|
||||
|
||||
Replace all `{variable}` placeholders with calculated values.
|
||||
|
||||
### 10.11 Save Report
|
||||
|
||||
Write rendered report to: `{chain_report_file}`
|
||||
|
||||
Default: `{sprint_artifacts}/chain-execution-report.md`
|
||||
|
||||
## Outputs
|
||||
|
||||
| Output | Location | Description |
|
||||
|--------|----------|-------------|
|
||||
| Execution Report | `{chain_report_file}` | Complete chain execution report |
|
||||
|
||||
## Console Output
|
||||
|
||||
After generating:
|
||||
|
||||
```
|
||||
═══════════════════════════════════════════════════════════
|
||||
CHAIN EXECUTION REPORT GENERATED
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Report: {chain_report_file}
|
||||
|
||||
Summary:
|
||||
Epics: {epic_count}
|
||||
Stories: {completed_count}/{story_count} completed
|
||||
Duration: {duration}
|
||||
Status: {chain_status}
|
||||
|
||||
{if issues}
|
||||
Issues: {issue_count} issues logged (see report)
|
||||
{endif}
|
||||
|
||||
{if uat_failures}
|
||||
UAT: {uat_pass_count}/{epic_count} epics passed validation
|
||||
{fix_total} self-healing fixes applied
|
||||
{endif}
|
||||
|
||||
═══════════════════════════════════════════════════════════
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
| Error | Action |
|
||||
|-------|--------|
|
||||
| Metrics file missing | Log warning, use defaults (0 duration, unknown status) |
|
||||
| Chain plan missing | Error - cannot generate report without plan |
|
||||
| Template missing | Use inline default template |
|
||||
| Write fails | Error with path, suggest manual copy |
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
# {project_name} - Epic Chain Execution Report
|
||||
|
||||
## Executive Summary
|
||||
|
||||
**Project:** {project_name}
|
||||
**Execution Method:** BMAD Epic Chain (automated AI-driven development)
|
||||
**Status:** {chain_status}
|
||||
|
||||
| Metric | Value |
|
||||
|--------|-------|
|
||||
| Total Epics | {epic_count} |
|
||||
| Total Stories | {story_count} |
|
||||
| Start Time | {start_time} |
|
||||
| End Time | {end_time} |
|
||||
| Total Duration | {duration} |
|
||||
| Average per Story | {avg_story_time} |
|
||||
|
||||
---
|
||||
|
||||
## Timeline
|
||||
|
||||
### Epic Execution Duration
|
||||
|
||||
| Epic | Name | Stories | Duration | Status |
|
||||
|------|------|---------|----------|--------|
|
||||
{epic_timeline_rows}
|
||||
| **Total** | | **{story_count}** | **{duration}** | **{completion_pct}%** |
|
||||
|
||||
---
|
||||
|
||||
## Dependency Graph
|
||||
|
||||
```
|
||||
{dependency_graph_ascii}
|
||||
```
|
||||
|
||||
### Explicit Dependencies
|
||||
|
||||
| Epic | Depends On | Reason |
|
||||
|------|------------|--------|
|
||||
{dependency_table_rows}
|
||||
|
||||
---
|
||||
|
||||
## What Was Built
|
||||
|
||||
{per_epic_summary}
|
||||
|
||||
---
|
||||
|
||||
## Issues Encountered
|
||||
|
||||
{issues_section}
|
||||
|
||||
---
|
||||
|
||||
## UAT Validation Summary
|
||||
|
||||
| Epic | UAT Doc | Scenarios | Auto-Passed | Fix Attempts | Status |
|
||||
|------|---------|-----------|-------------|--------------|--------|
|
||||
{uat_status_rows}
|
||||
|
||||
### Self-Healing Fix History
|
||||
|
||||
{fix_history_section}
|
||||
|
||||
---
|
||||
|
||||
## Artifacts Generated
|
||||
|
||||
| Artifact | Location | Description |
|
||||
|----------|----------|-------------|
|
||||
| Story Files | `{stories_location}` | {story_count} completed stories with dev & review records |
|
||||
| UAT Documents | `{uat_location}` | {epic_count} User Acceptance Test documents |
|
||||
| Epic Files | `{epics_location}` | {epic_count} epic definition files |
|
||||
| Handoffs | `{handoffs_location}` | Cross-epic context transfer documents |
|
||||
| Chain Plan | `{chain_plan_file}` | Execution plan with dependencies |
|
||||
| Metrics | `{metrics_folder}` | Per-epic execution metrics |
|
||||
|
||||
---
|
||||
|
||||
## Estimated Token Usage
|
||||
|
||||
| Epic | Stories | Est. Calls | Est. Input | Est. Output | Est. Total |
|
||||
|------|---------|------------|------------|-------------|------------|
|
||||
{token_estimate_rows}
|
||||
| **Total** | **{story_count}** | **{total_calls}** | **~{total_input}** | **~{total_output}** | **~{total_tokens}** |
|
||||
|
||||
### Cost Estimates
|
||||
|
||||
| Model | Input Cost | Output Cost | Total |
|
||||
|-------|------------|-------------|-------|
|
||||
| Claude Sonnet 3.5 ($3/$15 per 1M) | ~${sonnet_input_cost} | ~${sonnet_output_cost} | ~${sonnet_total_cost} |
|
||||
| Claude Opus ($15/$75 per 1M) | ~${opus_input_cost} | ~${opus_output_cost} | ~${opus_total_cost} |
|
||||
|
||||
*Note: These are estimates based on ~8K input / ~4K output tokens per story. Actual usage may vary.*
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Review UAT Documents** - Review the {epic_count} UAT documents in `{uat_location}`
|
||||
2. **Execute UAT Validation** - Run `*uat-validate` for each epic to verify implementations
|
||||
3. **Manual Acceptance Testing** - Execute manual test scenarios from UAT docs
|
||||
4. **Code Review** - Review generated code for refinements
|
||||
5. **Integration Testing** - Test cross-epic integrations
|
||||
6. **Deploy to Staging** - Deploy complete system to staging environment
|
||||
|
||||
---
|
||||
|
||||
## Conclusion
|
||||
|
||||
{conclusion_text}
|
||||
|
||||
---
|
||||
|
||||
*Report generated: {generation_timestamp}*
|
||||
*BMAD Method Epic Chain v1.0*
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
# Epic Metrics Template
|
||||
# Generated per-epic during epic-execute workflow
|
||||
# Aggregated by chain report generator
|
||||
|
||||
# Epic identification
|
||||
epic_id: "{epic_id}"
|
||||
epic_name: "{epic_name}"
|
||||
epic_file: "{epic_file_path}"
|
||||
|
||||
# Execution timing
|
||||
execution:
|
||||
start_time: "{start_timestamp}" # ISO 8601 format
|
||||
end_time: "{end_timestamp}" # ISO 8601 format
|
||||
duration_seconds: 0 # Calculated from start/end
|
||||
duration_formatted: "" # Human readable, e.g., "1.5 hours"
|
||||
|
||||
# Story counts
|
||||
stories:
|
||||
total: 0
|
||||
completed: 0
|
||||
failed: 0
|
||||
skipped: 0
|
||||
in_review: 0
|
||||
|
||||
# Per-story timing (optional, for detailed reports)
|
||||
story_timing: []
|
||||
# - story_id: "1-1"
|
||||
# title: "Initialize Monorepo"
|
||||
# start_time: ""
|
||||
# end_time: ""
|
||||
# duration_seconds: 0
|
||||
# status: "completed" # completed | failed | skipped
|
||||
|
||||
# UAT validation results
|
||||
uat:
|
||||
document_generated: false
|
||||
document_path: ""
|
||||
scenarios:
|
||||
total: 0
|
||||
automatable: 0
|
||||
semi_automated: 0
|
||||
manual_only: 0
|
||||
|
||||
# Validation gate results
|
||||
validation:
|
||||
gate_executed: false
|
||||
gate_mode: "quick" # quick | full | skip
|
||||
timestamp: ""
|
||||
results:
|
||||
passed: 0
|
||||
failed: 0
|
||||
skipped: 0
|
||||
gate_status: "PENDING" # PASS | FAIL | PENDING | SKIPPED
|
||||
blocking_issues: []
|
||||
|
||||
# Self-healing fix loop tracking
|
||||
fix_attempts: 0
|
||||
fix_history: []
|
||||
# Example fix_history entry:
|
||||
# - attempt: 1
|
||||
# timestamp: ""
|
||||
# failed_scenarios: ["scenario-3", "scenario-5"]
|
||||
# fix_context: "docs/sprint-artifacts/uat-fix-context-1-1.md"
|
||||
# fix_commit: "abc123"
|
||||
# result: "partial" # success | partial | failed
|
||||
|
||||
# Issues encountered during execution
|
||||
issues: []
|
||||
# Example issue entry:
|
||||
# - type: "signaling_mismatch"
|
||||
# story: "1-3"
|
||||
# description: "Story completed but output format didn't match expected"
|
||||
# severity: "low" # low | medium | high | blocker
|
||||
# resolved: true
|
||||
# resolution: "manual_status_update"
|
||||
|
||||
# Dependencies (from chain plan)
|
||||
dependencies:
|
||||
requires: [] # Epic IDs this epic depends on
|
||||
enables: [] # Epic IDs that depend on this epic
|
||||
|
||||
# Git information
|
||||
git:
|
||||
commits: 0 # Number of commits for this epic
|
||||
branch: "" # Branch used (if feature branch)
|
||||
first_commit: "" # SHA of first commit
|
||||
last_commit: "" # SHA of last commit
|
||||
|
||||
# Estimated token usage
|
||||
tokens:
|
||||
estimated_calls: 0 # stories * 2 (dev + review)
|
||||
estimated_input: 0 # estimated_calls * 8000
|
||||
estimated_output: 0 # estimated_calls * 4000
|
||||
estimated_total: 0 # input + output
|
||||
|
|
@ -27,13 +27,25 @@ variables:
|
|||
stories_location: "{sprint_artifacts}"
|
||||
|
||||
# Chain configuration (can be overridden by user)
|
||||
chain_mode: "sequential" # sequential | parallel | dependency-aware
|
||||
analysis_depth: "standard" # quick | standard | thorough
|
||||
chain_mode: "sequential" # sequential | parallel | dependency-aware
|
||||
analysis_depth: "standard" # quick | standard | thorough
|
||||
|
||||
# Output locations
|
||||
chain_plan_file: "{sprint_artifacts}/chain-plan.yaml"
|
||||
chain_log_file: "{sprint_artifacts}/chain-execution.log"
|
||||
|
||||
# Report generation
|
||||
chain_report_file: "{sprint_artifacts}/chain-execution-report.md"
|
||||
metrics_folder: "{sprint_artifacts}/metrics"
|
||||
generate_report: true
|
||||
|
||||
# UAT locations
|
||||
uat_location: "{output_folder}/uat"
|
||||
handoffs_location: "{sprint_artifacts}/handoffs"
|
||||
|
||||
# Report template
|
||||
report_template: "{installed_path}/templates/chain-report-template.md"
|
||||
|
||||
# Input file patterns
|
||||
input_file_patterns:
|
||||
epics:
|
||||
|
|
|
|||
Loading…
Reference in New Issue