diff --git a/src/bmm-skills/4-implementation/bmad-planning-poker/SKILL.md b/src/bmm-skills/4-implementation/bmad-planning-poker/SKILL.md new file mode 100644 index 000000000..63b21ffa9 --- /dev/null +++ b/src/bmm-skills/4-implementation/bmad-planning-poker/SKILL.md @@ -0,0 +1,377 @@ +--- +name: bmad-planning-poker +description: 'Collaborative story point estimation with AI agents. Use when the user says "planning poker", "estimate stories", or "plan poker"' +--- + +# Planning Poker Workflow + +**Goal:** Facilitate collaborative story point estimation using AI agents as virtual team members with the human as a full participant. Hybrid: structured voting rounds with Party Mode debate when estimates diverge. + +**Your Role:** You are a Planning Poker facilitator. Guide the estimation process, manage voting rounds, detect divergence, and trigger Party Mode debate when needed. The human is a voting participant, not just an observer. + +## Conventions + +- Bare paths resolve from the skill root. +- `{skill-root}` resolves to this skill's installed directory (where `customize.toml` lives). +- `{project-root}`-prefixed paths resolve from the project working directory. +- `{skill-name}` resolves to the skill directory's basename. + +## On Activation + +### Step 1: Resolve the Workflow Block + +Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow` + +**If the script fails**, resolve the `workflow` block yourself by reading these three files in base → team → user order and applying the same structural merge rules as the resolver: + +1. `{skill-root}/customize.toml` — defaults +2. `{project-root}/_bmad/custom/{skill-name}.toml` — team overrides +3. `{project-root}/_bmad/custom/{skill-name}.user.toml` — personal overrides + +Any missing file is skipped. + +### Step 2: Execute Prepend Steps + +Execute each entry in `{workflow.activation_steps_prepend}` in order before proceeding. + +### Step 3: Load Persistent Facts + +Treat every entry in `{workflow.persistent_facts}` as foundational context you carry for the rest of the workflow run. + +### Step 4: Load Config + +Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve: + +- `project_name`, `user_name` +- `communication_language`, `document_output_language` +- `implementation_artifacts`, `planning_artifacts` +- `date` as system-generated current datetime +- `project_context` = `**/project-context.md` (load if exists) +- YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `{communication_language}` + +### Step 5: Greet the User + +Greet `{user_name}`, speaking in `{communication_language}`. + +### Step 6: Execute Append Steps + +Execute each entry in `{workflow.activation_steps_append}` in order. + +Activation is complete. + +## Paths + +- `sprint_status_file` = `{implementation_artifacts}/sprint-status.yaml` +- `session_report_file` = `{implementation_artifacts}/planning-poker-{date}.md` +- `estimation_scale` = `{workflow.estimation_scale}` (default: fibonacci) +- `divergence_threshold` = `{workflow.divergence_threshold}` (default: 2.0) +- `max_rounds` = `{workflow.max_rounds}` (default: 3) +- `participating_agents` = `{workflow.participating_agents}` + +## Input Files + +| Input | Path | Load Strategy | +|-------|------|---------------| +| Sprint status | `{sprint_status_file}` | FULL_LOAD | + +## Estimation Scales + +### Fibonacci (default) +1, 2, 3, 5, 8, 13, 21 — use for relative effort estimation. + +### T-shirt +XS, S, M, L, XL, XXL — use when effort is too uncertain for numbers. + +### Linear +1, 2, 3, 4, 5, 6, 7, 8, 9, 10 — use when the team prefers absolute scale. + +## Execution + + + + +Load {project_context} for project-wide patterns and conventions (if exists) +Communicate in {communication_language} with {user_name} + +Read the FULL file: {sprint_status_file} + + No sprint-status.yaml found. Run sprint-planning first to generate it. + Exit workflow + + +Parse the YAML. Look for the `development_status` section. +If a `story_points` section exists, skip any story that already has a story_points entry. +Collect all unestimated stories (keys matching `{epic_num}-{story_num}-{title}` pattern with no story_points entry). +Sort stories by epic number, then story number. + + + All stories already estimated. If you need to re-estimate, delete or modify the story_points section in sprint-status.yaml first. + Exit workflow + + + +**Stories to Estimate:** {{unestimated_count}} + +{{#each unestimated_stories}} +- **{{key}}** — {{title}} +{{/each}} + +**Scale:** {{estimation_scale}} +**Divergence threshold:** {{divergence_threshold}}x +**Participating agents:** {{participating_agents}} +**Human participant:** {{user_name}} (you) + + + + ⚠️ Large backlog detected. Consider estimating only the top N stories (next sprint) or batching by epic. + Estimate all {{unestimated_count}} stories, limit to top-N by priority, or batch by epic? [all / top-N / epic / quit] + + + + +For each unestimated story in order: + + +Display the story details: + +--- +## Story {{story_key}}: {{story_title}} +{{story_description}} + +**Acceptance Criteria:** +{{#each acceptance_criteria}} +- {{this}} +{{/each}} +--- + + + + + +🎴 **Silent Round** — Everyone estimates privately. + +Valid values: {{scale_values}} + +**{{user_name}}**, what is your estimate for this story? + + +Your estimate (or "?" if unsure / "skip" to skip this story): + + + Mark story as skipped, continue to next story + + + + Treat as "needs discussion" — estimate as "?" and proceed to reveal + + +Store human estimate as `{{human_estimate}}` + +For each agent in {{participating_agents}}, load the agent's persona from `{project-root}/_bmad/core/config.yaml` agents section and ask them to estimate in character. Each agent gives ONLY their estimate and a 1-sentence reason. Agents do NOT see each other's estimates yet. + +Collect agent estimates into `{{agent_estimates}}` map: `{agent_name: {estimate: value, reason: "..."}}` + + + + +## Reveal — Story {{story_key}} + +| Participant | Estimate | +|-------------|----------| +| **{{user_name}} (You)** | {{human_estimate}} | +{{#each agent_estimates}} +| {{name}} ({{title}}) | {{estimate}} | +{{/each}} + +**Reasoning:** +{{#each agent_estimates}} +- **{{name}}:** {{reason}} +{{/each}} + + + + +Find the max and min numeric estimates from {{all_estimates}} (exclude "?" values). +Calculate ratio: max_estimate / min_estimate + + + Divergence is automatic — trigger debate to clarify. + + + + +⚠️ **Divergence detected!** + +Max estimate ({{max_estimate}}) is {{ratio}}x the min estimate ({{min_estimate}}). +Threshold: {{divergence_threshold}}x + +**The outliers should explain their reasoning.** + + + Proceed to Party Debate (step 2e) + + + + Skip debate — estimates are within acceptable range. Proceed to consensus (step 2f). + + + + +If this is round > {{max_rounds}}, skip debate and go to PM tiebreak (step 2f). + + +💬 **Entering debate mode.** The agents will discuss their estimates. You can challenge, agree, or push back on any point. This is your team talking — jump in anytime. + +*Loading Party Mode...* + + +Invoke the Party Mode skill (`bmad-party-mode`) context. Present the situation: + +- The story being estimated: {{story_key}}: {{story_title}} — {{story_description}} +- The current round's estimates: show all estimates +- The divergence: max ({{max_estimate}}) vs min ({{min_estimate}}) +- Instruction: "These agents need to debate their estimates for this story. {{user_name}} is a participant. The high and low estimators should defend their positions. Goal: converge or clarify the disagreement." +- Only include the agents who gave the min and max estimates, plus {{user_name}} (human). Other agents can stay silent unless they have a relevant point. + + +Run the Party Mode exchange (3-5 turns max for this debate). After the debate, summarize the key arguments made. + +After debate, return to silent voting round (step 2b) for a re-vote. Increment round counter. + + + Maximum rounds reached ({{max_rounds}}). The PM will cast the final estimate. + PM (John) reviews all debate arguments and casts the final estimate. Display it with reasoning. + Set `{{consensus_estimate}}` = PM's estimate. + Proceed to save (step 3). + + + + + + +✅ **Consensus reached!** + +Estimates cluster around: {{mode_estimate}} + +| Participant | Final Estimate | +|-------------|---------------| +| **Consensus** | {{consensus_estimate}} | + + Set `{{consensus_estimate}}` = the mode (most common) of all estimates, or the median if no mode. + + +Ask for final confirmation: +The consensus estimate for **{{story_key}}** is **{{consensus_estimate}}**. +Accept this estimate? [y / n (provide your own) / skip] + + + Use user's alternative as `{{consensus_estimate}}`. The human has final authority. + + + + Mark story as skipped. Continue to next story. + + +Store `{{consensus_estimate}}` with justification from the debate/discussion. + + + +Update `{sprint_status_file}`: + +Add a `story_points` section alongside `development_status` (do NOT modify `development_status`): + +```yaml +story_points: + 1-1-user-authentication: 5 + 1-2-account-management: 8 +``` + +Each entry: story key → consensus estimate (number or t-shirt size string). +Do NOT overwrite existing story_points entries — only add new ones for stories estimated in this session. + + +✅ **sprint-status.yaml updated** — {{newly_estimated_count}} stories estimated. + + + + +Create `{{session_report_file}}` with full trace: + +```markdown +# Planning Poker Session — {{date}} + +**Project:** {{project_name}} +**Scale:** {{estimation_scale}} +**Threshold:** {{divergence_threshold}}x +**Max rounds:** {{max_rounds}} +**Agents:** {{participating_agents}} +**Human:** {{user_name}} + +--- + +## Summary + +| Story | Final Estimate | Rounds | Debate? | +|-------|---------------|--------|---------| +{{#each estimated_stories}} +| {{key}} | {{estimate}} | {{rounds}} | {{had_debate}} | +{{/each}} + +--- + +## Detailed Results + +{{#each estimated_stories}} +### {{key}}: {{title}} + +**Description:** {{description}} + +**Round 1:** +| Participant | Estimate | Reasoning | +|-------------|----------|-----------| +| {{user_name}} (You) | {{human_est}} | — | +{{#each agent_estimates}} +| {{name}} ({{title}}) | {{estimate}} | {{reason}} | +{{/each}} + +{{#if had_debate}} +**Debate:** {{debate_summary}} +**Round {{final_round}} (re-vote):** +| Participant | Estimate | +|-------------|----------| +| Consensus | {{final_estimate}} | +{{/if}} + +**Final Estimate:** {{final_estimate}} +**Justification:** {{justification}} + +--- +{{/each}} +``` + +Write report to `{{session_report_file}}`. + + +📄 **Session report saved:** {{session_report_file}} + + + + + +## Planning Poker Complete 🎴 + +- **Stories estimated:** {{estimated_count}} +- **Stories skipped:** {{skipped_count}} +- **Debates triggered:** {{debate_count}} +- **Average rounds per story:** {{avg_rounds}} + +**Updated:** `{{sprint_status_file}}` (story_points section) +**Report:** `{{session_report_file}}` + +**Next:** Run sprint-planning to incorporate estimates into your sprint plan. + + +Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete` — if the resolved value is non-empty, follow it as the final terminal instruction before exiting. + + + diff --git a/src/bmm-skills/4-implementation/bmad-planning-poker/customize.toml b/src/bmm-skills/4-implementation/bmad-planning-poker/customize.toml new file mode 100644 index 000000000..796adc5b3 --- /dev/null +++ b/src/bmm-skills/4-implementation/bmad-planning-poker/customize.toml @@ -0,0 +1,32 @@ +# DO NOT EDIT -- overwritten on every update. +# +# Workflow customization surface for bmad-planning-poker. Mirrors the +# agent customization shape under the [workflow] namespace. + +[workflow] + +# Steps to run before the standard activation (config load, greet). +activation_steps_prepend = [] + +# Steps to run after greet but before the workflow begins. +activation_steps_append = [] + +# Persistent facts the workflow keeps in mind for the whole run. +persistent_facts = [ + "file:{project-root}/**/project-context.md", +] + +# Estimation scale: fibonacci | tshirt | linear +estimation_scale = "fibonacci" + +# Divergence threshold: max/min > this triggers debate +divergence_threshold = 2.0 + +# Maximum re-vote rounds before PM tiebreaks +max_rounds = 3 + +# Agents participating in estimation (agent codes) +participating_agents = ["bmad-agent-pm", "bmad-agent-dev", "bmad-agent-architect"] + +# Post-completion hook (empty by default) +on_complete = "" diff --git a/src/bmm-skills/module-help.csv b/src/bmm-skills/module-help.csv index eb2d51c1c..c85c79dc5 100644 --- a/src/bmm-skills/module-help.csv +++ b/src/bmm-skills/module-help.csv @@ -30,3 +30,4 @@ BMad Method,bmad-checkpoint-preview,Checkpoint,CK,Guided walkthrough of a change BMad Method,bmad-qa-generate-e2e-tests,QA Automation Test,QA,Generate automated API and E2E tests for implemented code. NOT for code review or story validation — use CR for that.,,,4-implementation,bmad-dev-story,,false,implementation_artifacts,test suite BMad Method,bmad-retrospective,Retrospective,ER,Optional at epic end: Review completed work lessons learned and next epic or if major issues consider CC.,,,4-implementation,bmad-code-review,,false,implementation_artifacts,retrospective BMad Method,bmad-investigate,Investigate,IN,Forensic case investigation calibrated to the input. Evidence-graded analysis with hypothesis tracking. Produces a structured case file.,,4-implementation,,,false,implementation_artifacts,investigation report +BMad Method,bmad-planning-poker,Plan Poker,PP,Collaborative story point estimation with AI agents. Silent voting rounds and Party Mode debate when estimates diverge.,,,4-implementation,bmad-create-epics-and-stories,bmad-sprint-planning,false,implementation_artifacts,session report and story points