Files
Claude-Code-Workflow/.claude/skills/team-testing/roles/analyst.md
catlog22 0d56396710 feat: Add 4 new team skills with Generator-Critic loops, shared memory, and dynamic pipelines
Create team-brainstorm (ideator↔challenger GC, quick/deep/full pipelines),
team-testing (generator↔executor GC, L1/L2/L3 test layers),
team-iterdev (developer↔reviewer GC, task-ledger sprint tracking),
and team-uidesign (designer↔reviewer GC, CP-9 dual-track with sync points).
Each team includes SKILL.md router, 5 roles, and team-config.json.
2026-02-15 18:09:57 +08:00

229 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Role: analyst
测试质量分析师。负责缺陷模式分析、覆盖率差距识别、质量报告生成。
## Role Identity
- **Name**: `analyst`
- **Task Prefix**: `TESTANA-*`
- **Responsibility**: Read-only analysis (质量分析)
- **Communication**: SendMessage to coordinator only
- **Output Tag**: `[analyst]`
## Role Boundaries
### MUST
- 仅处理 `TESTANA-*` 前缀的任务
- 所有输出必须带 `[analyst]` 标识
- Phase 2 读取 shared-memory.json (所有历史数据)Phase 5 写入 analysis_report
### MUST NOT
- ❌ 生成测试、执行测试或制定策略
- ❌ 直接与其他 worker 通信
- ❌ 为其他角色创建任务
## Message Types
| Type | Direction | Trigger | Description |
|------|-----------|---------|-------------|
| `analysis_ready` | analyst → coordinator | Analysis completed | 分析报告完成 |
| `error` | analyst → coordinator | Processing failure | 错误上报 |
## Execution (5-Phase)
### Phase 1: Task Discovery
```javascript
const tasks = TaskList()
const myTasks = tasks.filter(t =>
t.subject.startsWith('TESTANA-') &&
t.owner === 'analyst' &&
t.status === 'pending' &&
t.blockedBy.length === 0
)
if (myTasks.length === 0) return
const task = TaskGet({ taskId: myTasks[0].id })
TaskUpdate({ taskId: task.id, status: 'in_progress' })
```
### Phase 2: Context Loading + Shared Memory Read
```javascript
const sessionMatch = task.description.match(/Session:\s*([^\n]+)/)
const sessionFolder = sessionMatch?.[1]?.trim()
const memoryPath = `${sessionFolder}/shared-memory.json`
let sharedMemory = {}
try { sharedMemory = JSON.parse(Read(memoryPath)) } catch {}
// Read all execution results
const resultFiles = Glob({ pattern: `${sessionFolder}/results/run-*.json` })
const results = resultFiles.map(f => {
try { return JSON.parse(Read(f)) } catch { return null }
}).filter(Boolean)
// Read test strategy
const strategy = Read(`${sessionFolder}/strategy/test-strategy.md`)
// Read test files for pattern analysis
const testFiles = Glob({ pattern: `${sessionFolder}/tests/**/*` })
```
### Phase 3: Quality Analysis
```javascript
const outputPath = `${sessionFolder}/analysis/quality-report.md`
// 1. Coverage Analysis
const coverageHistory = sharedMemory.coverage_history || []
const layerCoverage = {}
coverageHistory.forEach(c => {
if (!layerCoverage[c.layer] || c.timestamp > layerCoverage[c.layer].timestamp) {
layerCoverage[c.layer] = c
}
})
// 2. Defect Pattern Analysis
const defectPatterns = sharedMemory.defect_patterns || []
const patternFrequency = {}
defectPatterns.forEach(p => {
patternFrequency[p] = (patternFrequency[p] || 0) + 1
})
const sortedPatterns = Object.entries(patternFrequency)
.sort(([,a], [,b]) => b - a)
// 3. GC Loop Effectiveness
const gcRounds = sharedMemory.gc_round || 0
const gcEffectiveness = coverageHistory.length >= 2
? coverageHistory[coverageHistory.length - 1].coverage - coverageHistory[0].coverage
: 0
// 4. Test Quality Metrics
const totalTests = sharedMemory.generated_tests?.length || 0
const effectivePatterns = sharedMemory.effective_test_patterns || []
const reportContent = `# Quality Analysis Report
**Session**: ${sessionFolder}
**Pipeline**: ${sharedMemory.pipeline}
**GC Rounds**: ${gcRounds}
**Total Test Files**: ${totalTests}
## Coverage Summary
| Layer | Coverage | Target | Status |
|-------|----------|--------|--------|
${Object.entries(layerCoverage).map(([layer, data]) =>
`| ${layer} | ${data.coverage}% | ${data.target}% | ${data.coverage >= data.target ? '✅ Met' : '❌ Below'} |`
).join('\n')}
## Defect Pattern Analysis
| Pattern | Frequency | Severity |
|---------|-----------|----------|
${sortedPatterns.map(([pattern, freq]) =>
`| ${pattern} | ${freq} | ${freq >= 3 ? 'HIGH' : freq >= 2 ? 'MEDIUM' : 'LOW'} |`
).join('\n')}
### Recurring Defect Categories
${categorizeDefects(defectPatterns).map(cat =>
`- **${cat.name}**: ${cat.count} occurrences — ${cat.recommendation}`
).join('\n')}
## Generator-Critic Loop Effectiveness
- **Rounds Executed**: ${gcRounds}
- **Coverage Improvement**: ${gcEffectiveness > 0 ? '+' : ''}${gcEffectiveness.toFixed(1)}%
- **Effectiveness**: ${gcEffectiveness > 10 ? 'HIGH' : gcEffectiveness > 5 ? 'MEDIUM' : 'LOW'}
- **Recommendation**: ${gcRounds > 2 && gcEffectiveness < 5 ? 'Diminishing returns — consider manual intervention' : 'GC loop effective'}
## Coverage Gaps
${identifyCoverageGaps(sharedMemory).map(gap =>
`### ${gap.area}\n- **Current**: ${gap.current}%\n- **Gap**: ${gap.gap}%\n- **Reason**: ${gap.reason}\n- **Recommendation**: ${gap.recommendation}\n`
).join('\n')}
## Effective Test Patterns
${effectivePatterns.map(p => `- ${p}`).join('\n')}
## Recommendations
### Immediate Actions
${immediateActions.map((a, i) => `${i + 1}. ${a}`).join('\n')}
### Long-term Improvements
${longTermActions.map((a, i) => `${i + 1}. ${a}`).join('\n')}
## Quality Score
| Dimension | Score | Weight | Weighted |
|-----------|-------|--------|----------|
| Coverage Achievement | ${coverageScore}/10 | 30% | ${(coverageScore * 0.3).toFixed(1)} |
| Test Effectiveness | ${effectivenessScore}/10 | 25% | ${(effectivenessScore * 0.25).toFixed(1)} |
| Defect Detection | ${defectScore}/10 | 25% | ${(defectScore * 0.25).toFixed(1)} |
| GC Loop Efficiency | ${gcScore}/10 | 20% | ${(gcScore * 0.2).toFixed(1)} |
| **Total** | | | **${totalScore.toFixed(1)}/10** |
`
Write(outputPath, reportContent)
```
### Phase 4: Trend Analysis (if historical data available)
```javascript
// Compare with previous sessions if available
const previousSessions = Glob({ pattern: '.workflow/.team/TST-*/shared-memory.json' })
if (previousSessions.length > 1) {
// Track coverage trends, defect pattern evolution
}
```
### Phase 5: Report to Coordinator + Shared Memory Write
```javascript
sharedMemory.analysis_report = {
quality_score: totalScore,
coverage_gaps: coverageGaps,
top_defect_patterns: sortedPatterns.slice(0, 5),
gc_effectiveness: gcEffectiveness,
recommendations: immediateActions
}
Write(memoryPath, JSON.stringify(sharedMemory, null, 2))
mcp__ccw-tools__team_msg({
operation: "log", team: teamName, from: "analyst", to: "coordinator",
type: "analysis_ready",
summary: `[analyst] Quality report: score ${totalScore.toFixed(1)}/10, ${sortedPatterns.length} defect patterns, ${coverageGaps.length} coverage gaps`,
ref: outputPath
})
SendMessage({
type: "message", recipient: "coordinator",
content: `## [analyst] Quality Analysis Complete
**Quality Score**: ${totalScore.toFixed(1)}/10
**Defect Patterns**: ${sortedPatterns.length}
**Coverage Gaps**: ${coverageGaps.length}
**GC Effectiveness**: ${gcEffectiveness > 0 ? '+' : ''}${gcEffectiveness.toFixed(1)}%
**Output**: ${outputPath}
### Top Issues
${immediateActions.slice(0, 3).map((a, i) => `${i + 1}. ${a}`).join('\n')}`,
summary: `[analyst] Quality: ${totalScore.toFixed(1)}/10`
})
TaskUpdate({ taskId: task.id, status: 'completed' })
```
## Error Handling
| Scenario | Resolution |
|----------|------------|
| No TESTANA-* tasks | Idle |
| No execution results | Generate report based on strategy only |
| Incomplete data | Report available metrics, flag gaps |
| Previous session data corrupted | Analyze current session only |