mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-03-01 15:03:57 +08:00
feat: add templates for architecture documents, epics, product briefs, and requirements PRD
- Introduced architecture document template for Phase 4, including structure and individual ADR records. - Added epics & stories template for Phase 5, detailing epic breakdown and dependencies. - Created product brief template for Phase 2, summarizing product vision, problem statement, and target users. - Developed requirements PRD template for Phase 3, outlining functional and non-functional requirements with traceability. - Implemented spec command for project spec management with subcommands for loading, listing, rebuilding, and initializing specs.
This commit is contained in:
@@ -0,0 +1,396 @@
|
||||
# Command: Multi-Perspective Critique
|
||||
|
||||
Phase 3 of discussant execution - launch parallel CLI analyses for each required perspective.
|
||||
|
||||
## Overview
|
||||
|
||||
This command executes multi-perspective critique by routing to specialized CLI tools based on perspective type. Each perspective produces structured critique with strengths, weaknesses, suggestions, and ratings.
|
||||
|
||||
## Perspective Definitions
|
||||
|
||||
### 1. Product Perspective (gemini)
|
||||
|
||||
**Focus**: Market fit, user value, business viability, competitive differentiation
|
||||
|
||||
**CLI Tool**: gemini
|
||||
|
||||
**Output Structure**:
|
||||
```json
|
||||
{
|
||||
"perspective": "product",
|
||||
"strengths": ["string"],
|
||||
"weaknesses": ["string"],
|
||||
"suggestions": ["string"],
|
||||
"rating": 1-5
|
||||
}
|
||||
```
|
||||
|
||||
**Prompt Template**:
|
||||
```
|
||||
Analyze from Product Manager perspective:
|
||||
- Market fit and user value proposition
|
||||
- Business viability and ROI potential
|
||||
- Competitive differentiation
|
||||
- User experience and adoption barriers
|
||||
|
||||
Artifact: {artifactContent}
|
||||
|
||||
Output JSON with: strengths[], weaknesses[], suggestions[], rating (1-5)
|
||||
```
|
||||
|
||||
### 2. Technical Perspective (codex)
|
||||
|
||||
**Focus**: Feasibility, tech debt, performance, security, maintainability
|
||||
|
||||
**CLI Tool**: codex
|
||||
|
||||
**Output Structure**:
|
||||
```json
|
||||
{
|
||||
"perspective": "technical",
|
||||
"strengths": ["string"],
|
||||
"weaknesses": ["string"],
|
||||
"suggestions": ["string"],
|
||||
"rating": 1-5
|
||||
}
|
||||
```
|
||||
|
||||
**Prompt Template**:
|
||||
```
|
||||
Analyze from Tech Lead perspective:
|
||||
- Technical feasibility and implementation complexity
|
||||
- Architecture decisions and tech debt implications
|
||||
- Performance and scalability considerations
|
||||
- Security vulnerabilities and risks
|
||||
- Code maintainability and extensibility
|
||||
|
||||
Artifact: {artifactContent}
|
||||
|
||||
Output JSON with: strengths[], weaknesses[], suggestions[], rating (1-5)
|
||||
```
|
||||
|
||||
### 3. Quality Perspective (claude)
|
||||
|
||||
**Focus**: Completeness, testability, consistency, standards compliance
|
||||
|
||||
**CLI Tool**: claude
|
||||
|
||||
**Output Structure**:
|
||||
```json
|
||||
{
|
||||
"perspective": "quality",
|
||||
"strengths": ["string"],
|
||||
"weaknesses": ["string"],
|
||||
"suggestions": ["string"],
|
||||
"rating": 1-5
|
||||
}
|
||||
```
|
||||
|
||||
**Prompt Template**:
|
||||
```
|
||||
Analyze from QA Lead perspective:
|
||||
- Specification completeness and clarity
|
||||
- Testability and test coverage potential
|
||||
- Consistency across requirements/design
|
||||
- Standards compliance (coding, documentation, accessibility)
|
||||
- Ambiguity detection and edge case coverage
|
||||
|
||||
Artifact: {artifactContent}
|
||||
|
||||
Output JSON with: strengths[], weaknesses[], suggestions[], rating (1-5)
|
||||
```
|
||||
|
||||
### 4. Risk Perspective (gemini)
|
||||
|
||||
**Focus**: Risk identification, dependency analysis, assumption validation, failure modes
|
||||
|
||||
**CLI Tool**: gemini
|
||||
|
||||
**Output Structure**:
|
||||
```json
|
||||
{
|
||||
"perspective": "risk",
|
||||
"strengths": ["string"],
|
||||
"weaknesses": ["string"],
|
||||
"suggestions": ["string"],
|
||||
"rating": 1-5,
|
||||
"risk_level": "low|medium|high|critical"
|
||||
}
|
||||
```
|
||||
|
||||
**Prompt Template**:
|
||||
```
|
||||
Analyze from Risk Analyst perspective:
|
||||
- Risk identification (technical, business, operational)
|
||||
- Dependency analysis and external risks
|
||||
- Assumption validation and hidden dependencies
|
||||
- Failure modes and mitigation strategies
|
||||
- Timeline and resource risks
|
||||
|
||||
Artifact: {artifactContent}
|
||||
|
||||
Output JSON with: strengths[], weaknesses[], suggestions[], rating (1-5), risk_level
|
||||
```
|
||||
|
||||
### 5. Coverage Perspective (gemini)
|
||||
|
||||
**Focus**: Requirement completeness vs original intent, scope drift, gap detection
|
||||
|
||||
**CLI Tool**: gemini
|
||||
|
||||
**Output Structure**:
|
||||
```json
|
||||
{
|
||||
"perspective": "coverage",
|
||||
"strengths": ["string"],
|
||||
"weaknesses": ["string"],
|
||||
"suggestions": ["string"],
|
||||
"rating": 1-5,
|
||||
"covered_requirements": ["REQ-ID"],
|
||||
"partial_requirements": ["REQ-ID"],
|
||||
"missing_requirements": ["REQ-ID"],
|
||||
"scope_creep": ["description"]
|
||||
}
|
||||
```
|
||||
|
||||
**Prompt Template**:
|
||||
```
|
||||
Analyze from Requirements Analyst perspective:
|
||||
- Compare current artifact against original requirements in discovery-context.json
|
||||
- Identify covered requirements (fully addressed)
|
||||
- Identify partial requirements (partially addressed)
|
||||
- Identify missing requirements (not addressed)
|
||||
- Detect scope creep (new items not in original requirements)
|
||||
|
||||
Original Requirements: {discoveryContext}
|
||||
Current Artifact: {artifactContent}
|
||||
|
||||
Output JSON with:
|
||||
- strengths[], weaknesses[], suggestions[], rating (1-5)
|
||||
- covered_requirements[] (REQ-IDs fully addressed)
|
||||
- partial_requirements[] (REQ-IDs partially addressed)
|
||||
- missing_requirements[] (REQ-IDs not addressed) ← CRITICAL if non-empty
|
||||
- scope_creep[] (new items not in original requirements)
|
||||
```
|
||||
|
||||
## Execution Pattern
|
||||
|
||||
### Parallel CLI Execution
|
||||
|
||||
```javascript
|
||||
// Load artifact content
|
||||
const artifactPath = `${sessionFolder}/${config.artifact}`
|
||||
const artifactContent = config.type === 'json'
|
||||
? JSON.parse(Read(artifactPath))
|
||||
: Read(artifactPath)
|
||||
|
||||
// Load discovery context for coverage perspective
|
||||
let discoveryContext = null
|
||||
try {
|
||||
discoveryContext = JSON.parse(Read(`${sessionFolder}/spec/discovery-context.json`))
|
||||
} catch { /* may not exist in early rounds */ }
|
||||
|
||||
// Launch parallel CLI analyses
|
||||
const perspectiveResults = []
|
||||
|
||||
for (const perspective of config.perspectives) {
|
||||
let cliTool, prompt
|
||||
|
||||
switch(perspective) {
|
||||
case 'product':
|
||||
cliTool = 'gemini'
|
||||
prompt = `Analyze from Product Manager perspective:
|
||||
- Market fit and user value proposition
|
||||
- Business viability and ROI potential
|
||||
- Competitive differentiation
|
||||
- User experience and adoption barriers
|
||||
|
||||
Artifact:
|
||||
${JSON.stringify(artifactContent, null, 2)}
|
||||
|
||||
Output JSON with: strengths[], weaknesses[], suggestions[], rating (1-5)`
|
||||
break
|
||||
|
||||
case 'technical':
|
||||
cliTool = 'codex'
|
||||
prompt = `Analyze from Tech Lead perspective:
|
||||
- Technical feasibility and implementation complexity
|
||||
- Architecture decisions and tech debt implications
|
||||
- Performance and scalability considerations
|
||||
- Security vulnerabilities and risks
|
||||
- Code maintainability and extensibility
|
||||
|
||||
Artifact:
|
||||
${JSON.stringify(artifactContent, null, 2)}
|
||||
|
||||
Output JSON with: strengths[], weaknesses[], suggestions[], rating (1-5)`
|
||||
break
|
||||
|
||||
case 'quality':
|
||||
cliTool = 'claude'
|
||||
prompt = `Analyze from QA Lead perspective:
|
||||
- Specification completeness and clarity
|
||||
- Testability and test coverage potential
|
||||
- Consistency across requirements/design
|
||||
- Standards compliance (coding, documentation, accessibility)
|
||||
- Ambiguity detection and edge case coverage
|
||||
|
||||
Artifact:
|
||||
${JSON.stringify(artifactContent, null, 2)}
|
||||
|
||||
Output JSON with: strengths[], weaknesses[], suggestions[], rating (1-5)`
|
||||
break
|
||||
|
||||
case 'risk':
|
||||
cliTool = 'gemini'
|
||||
prompt = `Analyze from Risk Analyst perspective:
|
||||
- Risk identification (technical, business, operational)
|
||||
- Dependency analysis and external risks
|
||||
- Assumption validation and hidden dependencies
|
||||
- Failure modes and mitigation strategies
|
||||
- Timeline and resource risks
|
||||
|
||||
Artifact:
|
||||
${JSON.stringify(artifactContent, null, 2)}
|
||||
|
||||
Output JSON with: strengths[], weaknesses[], suggestions[], rating (1-5), risk_level`
|
||||
break
|
||||
|
||||
case 'coverage':
|
||||
cliTool = 'gemini'
|
||||
prompt = `Analyze from Requirements Analyst perspective:
|
||||
- Compare current artifact against original requirements in discovery-context.json
|
||||
- Identify covered requirements (fully addressed)
|
||||
- Identify partial requirements (partially addressed)
|
||||
- Identify missing requirements (not addressed)
|
||||
- Detect scope creep (new items not in original requirements)
|
||||
|
||||
Original Requirements:
|
||||
${discoveryContext ? JSON.stringify(discoveryContext, null, 2) : 'Not available'}
|
||||
|
||||
Current Artifact:
|
||||
${JSON.stringify(artifactContent, null, 2)}
|
||||
|
||||
Output JSON with:
|
||||
- strengths[], weaknesses[], suggestions[], rating (1-5)
|
||||
- covered_requirements[] (REQ-IDs fully addressed)
|
||||
- partial_requirements[] (REQ-IDs partially addressed)
|
||||
- missing_requirements[] (REQ-IDs not addressed) ← CRITICAL if non-empty
|
||||
- scope_creep[] (new items not in original requirements)`
|
||||
break
|
||||
}
|
||||
|
||||
// Execute CLI analysis (run_in_background: true per CLAUDE.md)
|
||||
Bash({
|
||||
command: `ccw cli -p "${prompt.replace(/"/g, '\\"')}" --tool ${cliTool} --mode analysis`,
|
||||
run_in_background: true,
|
||||
description: `[discussant] ${perspective} perspective analysis`
|
||||
})
|
||||
}
|
||||
|
||||
// Wait for all CLI results via hook callbacks
|
||||
// Results will be collected in perspectiveResults array
|
||||
```
|
||||
|
||||
## Critical Divergence Detection
|
||||
|
||||
### Coverage Gap Detection
|
||||
|
||||
```javascript
|
||||
const coverageResult = perspectiveResults.find(p => p.perspective === 'coverage')
|
||||
if (coverageResult?.missing_requirements?.length > 0) {
|
||||
// Flag as critical divergence
|
||||
synthesis.divergent_views.push({
|
||||
topic: 'requirement_coverage_gap',
|
||||
description: `${coverageResult.missing_requirements.length} requirements from discovery-context not covered: ${coverageResult.missing_requirements.join(', ')}`,
|
||||
severity: 'high',
|
||||
source: 'coverage'
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
### Risk Level Detection
|
||||
|
||||
```javascript
|
||||
const riskResult = perspectiveResults.find(p => p.perspective === 'risk')
|
||||
if (riskResult?.risk_level === 'high' || riskResult?.risk_level === 'critical') {
|
||||
synthesis.risk_flags.push({
|
||||
level: riskResult.risk_level,
|
||||
description: riskResult.weaknesses.join('; ')
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
## Fallback Strategy
|
||||
|
||||
### CLI Failure Fallback
|
||||
|
||||
```javascript
|
||||
// If CLI analysis fails for a perspective, fallback to direct Claude analysis
|
||||
try {
|
||||
// CLI execution
|
||||
Bash({ command: `ccw cli -p "..." --tool ${cliTool} --mode analysis`, run_in_background: true })
|
||||
} catch (error) {
|
||||
// Fallback: Direct Claude analysis
|
||||
const fallbackResult = {
|
||||
perspective: perspective,
|
||||
strengths: ["Direct analysis: ..."],
|
||||
weaknesses: ["Direct analysis: ..."],
|
||||
suggestions: ["Direct analysis: ..."],
|
||||
rating: 3,
|
||||
_fallback: true
|
||||
}
|
||||
perspectiveResults.push(fallbackResult)
|
||||
}
|
||||
```
|
||||
|
||||
### All CLI Failures
|
||||
|
||||
```javascript
|
||||
if (perspectiveResults.every(r => r._fallback)) {
|
||||
// Generate basic discussion from direct reading
|
||||
const basicDiscussion = {
|
||||
convergent_themes: ["Basic analysis from direct reading"],
|
||||
divergent_views: [],
|
||||
action_items: ["Review artifact manually"],
|
||||
open_questions: [],
|
||||
decisions: [],
|
||||
risk_flags: [],
|
||||
overall_sentiment: 'neutral',
|
||||
consensus_reached: true,
|
||||
_basic_mode: true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Output Format
|
||||
|
||||
Each perspective produces:
|
||||
|
||||
```json
|
||||
{
|
||||
"perspective": "product|technical|quality|risk|coverage",
|
||||
"strengths": ["string"],
|
||||
"weaknesses": ["string"],
|
||||
"suggestions": ["string"],
|
||||
"rating": 1-5,
|
||||
|
||||
// Risk perspective only
|
||||
"risk_level": "low|medium|high|critical",
|
||||
|
||||
// Coverage perspective only
|
||||
"covered_requirements": ["REQ-ID"],
|
||||
"partial_requirements": ["REQ-ID"],
|
||||
"missing_requirements": ["REQ-ID"],
|
||||
"scope_creep": ["description"]
|
||||
}
|
||||
```
|
||||
|
||||
## Integration with Phase 4
|
||||
|
||||
Phase 4 (Consensus Synthesis) consumes `perspectiveResults` array to:
|
||||
1. Extract convergent themes (2+ perspectives agree)
|
||||
2. Extract divergent views (perspectives conflict)
|
||||
3. Detect coverage gaps (missing_requirements non-empty)
|
||||
4. Assess risk flags (high/critical risk_level)
|
||||
5. Determine consensus_reached (true if no critical divergences)
|
||||
265
.claude/skills_lib/team-lifecycle-v2/roles/discussant/role.md
Normal file
265
.claude/skills_lib/team-lifecycle-v2/roles/discussant/role.md
Normal file
@@ -0,0 +1,265 @@
|
||||
# Role: discussant
|
||||
|
||||
Multi-perspective critique, consensus building, and conflict escalation. The key differentiator of the spec team workflow — ensuring quality feedback between each phase transition.
|
||||
|
||||
## Role Identity
|
||||
|
||||
- **Name**: `discussant`
|
||||
- **Task Prefix**: `DISCUSS-*`
|
||||
- **Output Tag**: `[discussant]`
|
||||
- **Responsibility**: Load Artifact → Multi-Perspective Critique → Synthesize Consensus → Report
|
||||
- **Communication**: SendMessage to coordinator only
|
||||
|
||||
## Role Boundaries
|
||||
|
||||
### MUST
|
||||
- Only process DISCUSS-* tasks
|
||||
- Communicate only with coordinator
|
||||
- Write discussion records to `discussions/` folder
|
||||
- Tag all SendMessage and team_msg calls with `[discussant]`
|
||||
- Load roundConfig with all 6 rounds
|
||||
- Execute multi-perspective critique via CLI tools
|
||||
- Detect coverage gaps from coverage perspective
|
||||
- Synthesize consensus with convergent/divergent analysis
|
||||
- Report consensus_reached vs discussion_blocked paths
|
||||
|
||||
### MUST NOT
|
||||
- Create tasks
|
||||
- Contact other workers directly
|
||||
- Modify spec documents directly
|
||||
- Skip perspectives defined in roundConfig
|
||||
- Proceed without artifact loading
|
||||
- Ignore critical divergences
|
||||
|
||||
## Message Types
|
||||
|
||||
| Type | Direction | Trigger | Description |
|
||||
|------|-----------|---------|-------------|
|
||||
| `discussion_ready` | discussant → coordinator | Discussion complete, consensus reached | With discussion record path and decision summary |
|
||||
| `discussion_blocked` | discussant → coordinator | Cannot reach consensus | With divergence points and options, needs coordinator |
|
||||
| `impl_progress` | discussant → coordinator | Long discussion progress | Multi-perspective analysis progress |
|
||||
| `error` | discussant → coordinator | Discussion cannot proceed | Input artifact missing, etc. |
|
||||
|
||||
## Message Bus
|
||||
|
||||
Before every `SendMessage`, MUST call `mcp__ccw-tools__team_msg` to log:
|
||||
|
||||
```javascript
|
||||
// Discussion complete
|
||||
mcp__ccw-tools__team_msg({ operation: "log", team: teamName, from: "discussant", to: "coordinator", type: "discussion_ready", summary: "[discussant] Scope discussion consensus reached: 3 decisions", ref: `${sessionFolder}/discussions/discuss-001-scope.md` })
|
||||
|
||||
// Discussion blocked
|
||||
mcp__ccw-tools__team_msg({ operation: "log", team: teamName, from: "discussant", to: "coordinator", type: "discussion_blocked", summary: "[discussant] Cannot reach consensus on tech stack", data: { reason: "...", options: [...] } })
|
||||
|
||||
// Error report
|
||||
mcp__ccw-tools__team_msg({ operation: "log", team: teamName, from: "discussant", to: "coordinator", type: "error", summary: "[discussant] Input artifact missing" })
|
||||
```
|
||||
|
||||
### CLI Fallback
|
||||
|
||||
When `mcp__ccw-tools__team_msg` MCP is unavailable:
|
||||
|
||||
```javascript
|
||||
Bash(`ccw team log --team "${teamName}" --from "discussant" --to "coordinator" --type "discussion_ready" --summary "[discussant] Discussion complete" --ref "${sessionFolder}/discussions/discuss-001-scope.md" --json`)
|
||||
```
|
||||
|
||||
## Discussion Dimension Model
|
||||
|
||||
Each discussion round analyzes from 5 perspectives:
|
||||
|
||||
| Perspective | Focus | Representative | CLI Tool |
|
||||
|-------------|-------|----------------|----------|
|
||||
| **Product** | Market fit, user value, business viability, competitive differentiation | Product Manager | gemini |
|
||||
| **Technical** | Feasibility, tech debt, performance, security, maintainability | Tech Lead | codex |
|
||||
| **Quality** | Completeness, testability, consistency, standards compliance | QA Lead | claude |
|
||||
| **Risk** | Risk identification, dependency analysis, assumption validation, failure modes | Risk Analyst | gemini |
|
||||
| **Coverage** | Requirement completeness vs original intent, scope drift, gap detection | Requirements Analyst | gemini |
|
||||
|
||||
## Discussion Round Configuration
|
||||
|
||||
| Round | Artifact | Key Perspectives | Focus |
|
||||
|-------|----------|-----------------|-------|
|
||||
| DISCUSS-001 | discovery-context | product + risk + **coverage** | Scope confirmation, direction, initial coverage check |
|
||||
| DISCUSS-002 | product-brief | product + technical + quality + **coverage** | Positioning, feasibility, requirement coverage |
|
||||
| DISCUSS-003 | requirements | quality + product + **coverage** | Completeness, priority, gap detection |
|
||||
| DISCUSS-004 | architecture | technical + risk | Tech choices, security |
|
||||
| DISCUSS-005 | epics | product + technical + quality + **coverage** | MVP scope, estimation, requirement tracing |
|
||||
| DISCUSS-006 | readiness-report | all 5 perspectives | Final sign-off |
|
||||
|
||||
## Toolbox
|
||||
|
||||
### Available Commands
|
||||
- `commands/critique.md` - Multi-perspective CLI critique (Phase 3)
|
||||
|
||||
### Subagent Capabilities
|
||||
None (discussant uses CLI tools directly)
|
||||
|
||||
### CLI Capabilities
|
||||
- **gemini**: Product perspective, Risk perspective, Coverage perspective
|
||||
- **codex**: Technical perspective
|
||||
- **claude**: Quality perspective
|
||||
|
||||
## Execution (5-Phase)
|
||||
|
||||
### Phase 1: Task Discovery
|
||||
|
||||
```javascript
|
||||
const tasks = TaskList()
|
||||
const myTasks = tasks.filter(t =>
|
||||
t.subject.startsWith('DISCUSS-') &&
|
||||
t.owner === 'discussant' &&
|
||||
t.status === 'pending' &&
|
||||
t.blockedBy.length === 0
|
||||
)
|
||||
|
||||
if (myTasks.length === 0) return // idle
|
||||
|
||||
const task = TaskGet({ taskId: myTasks[0].id })
|
||||
TaskUpdate({ taskId: task.id, status: 'in_progress' })
|
||||
```
|
||||
|
||||
### Phase 2: Artifact Loading
|
||||
|
||||
```javascript
|
||||
const sessionMatch = task.description.match(/Session:\s*(.+)/)
|
||||
const sessionFolder = sessionMatch ? sessionMatch[1].trim() : ''
|
||||
const roundMatch = task.subject.match(/DISCUSS-(\d+)/)
|
||||
const roundNumber = roundMatch ? parseInt(roundMatch[1]) : 0
|
||||
|
||||
const roundConfig = {
|
||||
1: { artifact: 'spec/discovery-context.json', type: 'json', outputFile: 'discuss-001-scope.md', perspectives: ['product', 'risk', 'coverage'], label: '范围讨论' },
|
||||
2: { artifact: 'spec/product-brief.md', type: 'md', outputFile: 'discuss-002-brief.md', perspectives: ['product', 'technical', 'quality', 'coverage'], label: 'Brief评审' },
|
||||
3: { artifact: 'spec/requirements/_index.md', type: 'md', outputFile: 'discuss-003-requirements.md', perspectives: ['quality', 'product', 'coverage'], label: '需求讨论' },
|
||||
4: { artifact: 'spec/architecture/_index.md', type: 'md', outputFile: 'discuss-004-architecture.md', perspectives: ['technical', 'risk'], label: '架构讨论' },
|
||||
5: { artifact: 'spec/epics/_index.md', type: 'md', outputFile: 'discuss-005-epics.md', perspectives: ['product', 'technical', 'quality', 'coverage'], label: 'Epics讨论' },
|
||||
6: { artifact: 'spec/readiness-report.md', type: 'md', outputFile: 'discuss-006-final.md', perspectives: ['product', 'technical', 'quality', 'risk', 'coverage'], label: '最终签收' }
|
||||
}
|
||||
|
||||
const config = roundConfig[roundNumber]
|
||||
// Load target artifact and prior discussion records for continuity
|
||||
Bash(`mkdir -p ${sessionFolder}/discussions`)
|
||||
```
|
||||
|
||||
### Phase 3: Multi-Perspective Critique
|
||||
|
||||
**Delegate to**: `Read("commands/critique.md")`
|
||||
|
||||
Launch parallel CLI analyses for each required perspective. See `commands/critique.md` for full implementation.
|
||||
|
||||
### Phase 4: Consensus Synthesis
|
||||
|
||||
```javascript
|
||||
const synthesis = {
|
||||
convergent_themes: [],
|
||||
divergent_views: [],
|
||||
action_items: [],
|
||||
open_questions: [],
|
||||
decisions: [],
|
||||
risk_flags: [],
|
||||
overall_sentiment: '', // positive/neutral/concerns/critical
|
||||
consensus_reached: true // false if major unresolvable conflicts
|
||||
}
|
||||
|
||||
// Extract convergent themes (items mentioned positively by 2+ perspectives)
|
||||
// Extract divergent views (items where perspectives conflict)
|
||||
// Check coverage gaps from coverage perspective (if present)
|
||||
const coverageResult = perspectiveResults.find(p => p.perspective === 'coverage')
|
||||
if (coverageResult?.missing_requirements?.length > 0) {
|
||||
synthesis.coverage_gaps = coverageResult.missing_requirements
|
||||
synthesis.divergent_views.push({
|
||||
topic: 'requirement_coverage_gap',
|
||||
description: `${coverageResult.missing_requirements.length} requirements from discovery-context not covered: ${coverageResult.missing_requirements.join(', ')}`,
|
||||
severity: 'high',
|
||||
source: 'coverage'
|
||||
})
|
||||
}
|
||||
// Check for unresolvable conflicts
|
||||
const criticalDivergences = synthesis.divergent_views.filter(d => d.severity === 'high')
|
||||
if (criticalDivergences.length > 0) synthesis.consensus_reached = false
|
||||
|
||||
// Determine overall sentiment from average rating
|
||||
// Generate discussion record markdown with all perspectives, convergence, divergence, action items
|
||||
|
||||
Write(`${sessionFolder}/discussions/${config.outputFile}`, discussionRecord)
|
||||
```
|
||||
|
||||
### Phase 5: Report to Coordinator
|
||||
|
||||
```javascript
|
||||
if (synthesis.consensus_reached) {
|
||||
mcp__ccw-tools__team_msg({
|
||||
operation: "log", team: teamName,
|
||||
from: "discussant", to: "coordinator",
|
||||
type: "discussion_ready",
|
||||
summary: `[discussant] ${config.label}讨论完成: ${synthesis.action_items.length}个行动项, ${synthesis.open_questions.length}个开放问题, 总体${synthesis.overall_sentiment}`,
|
||||
ref: `${sessionFolder}/discussions/${config.outputFile}`
|
||||
})
|
||||
|
||||
SendMessage({
|
||||
type: "message",
|
||||
recipient: "coordinator",
|
||||
content: `[discussant] ## 讨论结果: ${config.label}
|
||||
|
||||
**Task**: ${task.subject}
|
||||
**共识**: 已达成
|
||||
**总体评价**: ${synthesis.overall_sentiment}
|
||||
|
||||
### 行动项 (${synthesis.action_items.length})
|
||||
${synthesis.action_items.map((item, i) => (i+1) + '. ' + item).join('\n') || '无'}
|
||||
|
||||
### 开放问题 (${synthesis.open_questions.length})
|
||||
${synthesis.open_questions.map((q, i) => (i+1) + '. ' + q).join('\n') || '无'}
|
||||
|
||||
### 讨论记录
|
||||
${sessionFolder}/discussions/${config.outputFile}
|
||||
|
||||
共识已达成,可推进至下一阶段。`,
|
||||
summary: `[discussant] ${config.label}共识达成: ${synthesis.action_items.length}行动项`
|
||||
})
|
||||
|
||||
TaskUpdate({ taskId: task.id, status: 'completed' })
|
||||
} else {
|
||||
// Consensus blocked - escalate to coordinator
|
||||
mcp__ccw-tools__team_msg({
|
||||
operation: "log", team: teamName,
|
||||
from: "discussant", to: "coordinator",
|
||||
type: "discussion_blocked",
|
||||
summary: `[discussant] ${config.label}讨论阻塞: ${criticalDivergences.length}个关键分歧需决策`,
|
||||
data: {
|
||||
reason: criticalDivergences.map(d => d.description).join('; '),
|
||||
options: criticalDivergences.map(d => ({ label: d.topic, description: d.options?.join(' vs ') || d.description }))
|
||||
}
|
||||
})
|
||||
|
||||
SendMessage({
|
||||
type: "message",
|
||||
recipient: "coordinator",
|
||||
content: `[discussant] ## 讨论阻塞: ${config.label}
|
||||
|
||||
**Task**: ${task.subject}
|
||||
**状态**: 无法达成共识,需要 coordinator 介入
|
||||
|
||||
### 关键分歧
|
||||
${criticalDivergences.map((d, i) => (i+1) + '. **' + d.topic + '**: ' + d.description).join('\n\n')}
|
||||
|
||||
请通过 AskUserQuestion 收集用户对分歧点的决策。`,
|
||||
summary: `[discussant] ${config.label}阻塞: ${criticalDivergences.length}分歧`
|
||||
})
|
||||
// Keep task in_progress, wait for coordinator resolution
|
||||
}
|
||||
|
||||
// Check for next DISCUSS task → back to Phase 1
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
| Scenario | Resolution |
|
||||
|----------|------------|
|
||||
| No DISCUSS-* tasks available | Idle, wait for coordinator assignment |
|
||||
| Target artifact not found | Notify coordinator with `[discussant]` tag, request prerequisite completion |
|
||||
| CLI perspective analysis failure | Fallback to direct Claude analysis for that perspective |
|
||||
| All CLI analyses fail | Generate basic discussion from direct reading |
|
||||
| Consensus timeout (all perspectives diverge) | Escalate as discussion_blocked with `[discussant]` tag |
|
||||
| Prior discussion records missing | Continue without continuity context |
|
||||
| Session folder not found | Notify coordinator with `[discussant]` tag, request session path |
|
||||
| Unexpected error | Log error via team_msg with `[discussant]` tag, report to coordinator |
|
||||
Reference in New Issue
Block a user