# Open Feedback Round - Start Async Stakeholder Review The workflow execution engine is governed by: {project-root}/_bmad/core/tasks/workflow.xml You MUST have already loaded and processed: {installed_path}/workflow.yaml ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 🔔 OPEN FEEDBACK ROUND ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Call: mcp__github__get_me() current_user = response.login ❌ GitHub MCP not accessible - required for coordination HALT Which document? Enter key (e.g., "user-auth" for PRD, "2" for Epic): document_key = response doc_path = {{docs_dir}}/prd/{{document_key}}.md document_type = 'prd' doc_prefix = 'PRD' doc_label_prefix = 'prd' doc_path = {{docs_dir}}/epics/epic-{{document_key}}.md doc_prefix = 'Epic' doc_label_prefix = 'epic' Read doc_path ❌ Document not found: {{doc_path}} Please ensure the {{document_type}} exists. Use: - "Create PRD" (CP) to create a new PRD - Check that the key is correct HALT doc_content = file_content // Parse document metadata title = extract_between(doc_content, '# PRD: ', '\n') || extract_between(doc_content, '# Epic: ', '\n') || document_key version = extract_field(doc_content, 'Version') || '1' status = extract_field(doc_content, 'Status') || 'draft' stakeholders = extract_stakeholders(doc_content) owner = extract_field(doc_content, 'Product Owner')?.replace('@', '') ⚠️ This {{document_type}} is currently in status: {{status}} Feedback rounds can only be opened for documents in 'draft' or 'feedback' status. Current status suggests this may already be in synthesis or sign-off. Continue anyway? (y/n): HALT 📄 Document: {{title}} 📌 Key: {{doc_label_prefix}}:{{document_key}} 📊 Version: {{version}} 👥 Stakeholders: {{stakeholders.length}} ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 📅 FEEDBACK DEADLINE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ How long should stakeholders have to provide feedback? Days until deadline (default: 5): days = parseInt(response) || 5 deadline = new Date() deadline.setDate(deadline.getDate() + days) deadline_str = deadline.toISOString().split('T')[0] Deadline: {{deadline_str}} ({{days}} days from now) // Build stakeholder checklist checklist = stakeholders.map(s => `- [ ] @${s.replace('@', '')} - ⏳ Pending feedback` ).join('\n') // Build issue body issue_body = `# 📣 ${doc_prefix} Review: ${title} v${version} **Document Key:** \`${doc_label_prefix}:${document_key}\` **Version:** ${version} **Owner:** @${owner || current_user} **Status:** 🟡 Open for Feedback --- ## 📅 Deadline **Feedback Due:** ${deadline_str} --- ## 📋 Document Summary ${extract_summary(doc_content)} --- ## 👥 Stakeholder Feedback Status ${checklist} --- ## 📝 How to Provide Feedback 1. Review the document: \`docs/${document_type}/${document_key}.md\` 2. For each piece of feedback, create a new comment or linked issue: - **Clarification**: Something unclear → \`/feedback clarification\` - **Concern**: Potential issue → \`/feedback concern\` - **Suggestion**: Improvement idea → \`/feedback suggestion\` - **Addition**: Missing requirement → \`/feedback addition\` Or use the workflow: "Submit feedback on ${doc_label_prefix}:${document_key}" --- ## 🔄 Review Status - [ ] All stakeholders have provided feedback - [ ] Feedback synthesized into new version - [ ] Ready for sign-off --- _This review round was opened by @${current_user} on ${new Date().toISOString().split('T')[0]}_ ` Call: mcp__github__search_issues({ query: "repo:{{github_owner}}/{{github_repo}} label:type:{{doc_label_prefix}}-review label:{{doc_label_prefix}}:{{document_key}} is:open" }) ⚠️ An open review round already exists for this document: Issue #{{response.items[0].number}}: {{response.items[0].title}} Would you like to: [1] Use existing review issue [2] Close old and create new [3] Cancel Choice: review_issue = response.items[0] Goto step 4 (skip issue creation) Call: mcp__github__issue_write({ method: 'update', owner: github_owner, repo: github_repo, issue_number: response.items[0].number, state: 'closed', state_reason: 'not_planned' }) HALT labels = [ `type:${doc_label_prefix}-review`, `${doc_label_prefix}:${document_key}`, `version:${version}`, 'review-status:open' ] Call: mcp__github__issue_write({ method: 'create', owner: "{{github_owner}}", repo: "{{github_repo}}", title: "{{doc_prefix}} Review: {{title}} v{{version}}", body: issue_body, labels: labels, assignees: stakeholders.map(s => s.replace('@', '')) }) review_issue = response ✅ Review issue created: #{{review_issue.number}} {{review_issue.html_url}} // Update the Status field in the document updated_content = doc_content .replace(/\*\*Status:\*\* .+/, '**Status:** Feedback') .replace(/\| Feedback Deadline \| .+ \|/, `| Feedback Deadline | ${deadline_str} |`) Write updated_content to doc_path if (document_type === 'prd') { cacheManager.writePrd(document_key, updated_content, { status: 'feedback', review_issue: review_issue.number, feedback_deadline: deadline_str }) } else { cacheManager.writeEpic(document_key, updated_content, { status: 'feedback', review_issue: review_issue.number, feedback_deadline: deadline_str }) } ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 📨 STAKEHOLDER NOTIFICATION ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ mentions = stakeholders.map(s => `@${s.replace('@', '')}`).join(' ') notification = `## 📣 Feedback Requested ${mentions} You have been asked to review this ${doc_prefix}. **Deadline:** ${deadline_str} **Document:** \`docs/${document_type}/${document_key}.md\` Please review and provide your feedback by creating linked feedback issues or comments. --- **Quick Actions:** - View document in repo - Use "Submit feedback" workflow - Comment directly on this issue Thank you for your input! 🙏` Call: mcp__github__add_issue_comment({ owner: "{{github_owner}}", repo: "{{github_repo}}", issue_number: review_issue.number, body: notification }) ✅ Stakeholders notified via GitHub @mentions ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ FEEDBACK ROUND OPENED ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ **Document:** {{title}} v{{version}} **Review Issue:** #{{review_issue.number}} **Deadline:** {{deadline_str}} **Stakeholders Notified:** {{stakeholders.length}} The following stakeholders have been notified: {{stakeholders.map(s => ' • @' + s.replace('@', '')).join('\n')}} --- **Next Steps:** 1. Stakeholders submit feedback via GitHub 2. Monitor progress with: "View feedback for {{doc_label_prefix}}:{{document_key}}" 3. When ready, synthesize with: "Synthesize feedback for {{doc_label_prefix}}:{{document_key}}" **Quick Commands:** - [VF] View Feedback - [SZ] Synthesize Feedback - [PD] PRD Dashboard / [ED] Epic Dashboard ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ## Helper Functions ```javascript // Extract text between markers function extract_between(content, start, end) { const startIdx = content.indexOf(start); if (startIdx === -1) return null; const endIdx = content.indexOf(end, startIdx + start.length); return content.slice(startIdx + start.length, endIdx).trim(); } // Extract field from markdown table or bold format function extract_field(content, field) { // Try bold format: **Field:** value const boldMatch = content.match(new RegExp(`\\*\\*${field}:\\*\\*\\s*(.+?)(?:\\n|$)`)); if (boldMatch) return boldMatch[1].trim(); // Try table format: | Field | value | const tableMatch = content.match(new RegExp(`\\|\\s*${field}\\s*\\|\\s*(.+?)\\s*\\|`)); if (tableMatch) return tableMatch[1].trim(); return null; } // Extract stakeholders from document function extract_stakeholders(content) { const field = extract_field(content, 'Stakeholders'); if (!field) return []; return field .split(/[,\s]+/) .filter(s => s.startsWith('@')) .map(s => s.replace('@', '')); } // Extract summary section from document function extract_summary(content) { // Try to get Vision + Problem Statement const vision = extract_between(content, '## Vision', '##') || extract_between(content, '## Vision', '\n---'); const problem = extract_between(content, '## Problem Statement', '##') || extract_between(content, '## Problem Statement', '\n---'); if (vision || problem) { let summary = ''; if (vision) summary += `**Vision:** ${vision.slice(0, 200)}...\n\n`; if (problem) summary += `**Problem:** ${problem.slice(0, 200)}...`; return summary; } // Fallback: first 500 chars return content.slice(0, 500) + '...'; } ``` ## Natural Language Triggers This workflow responds to: - "Open feedback for [prd-key]" - "Start feedback round for [document]" - "Request feedback on PRD" - Menu trigger: `OF`