mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-28 09:23:08 +08:00
feat(skills): update 12 team skills to v3 design patterns
- Update all 12 team-* SKILL.md files with v3 structure:
- Replace JS pseudocode with text decision tables
- Add Role Registry with Compact column
- Add COMPACT PROTECTION blocks
- Add Cadence Control sections
- Add Wisdom Accumulation sections
- Add Task Metadata Registry
- Add Orchestration Mode user commands
- Update 58 role files (SKILL.md + roles/*):
- Flat-file skills: team-brainstorm, team-issue, team-testing,
team-uidesign, team-planex, team-iterdev
- Folder-based skills: team-review, team-roadmap-dev, team-frontend,
team-quality-assurance, team-tech-debt, team-ultra-analyze
- Preserve special architectures:
- team-planex: 2-member (planner + executor only)
- team-tech-debt: Stop-Wait strategy (run_in_background:false)
- team-iterdev: 7 behavior protocol tables in coordinator
- All 12 teams reviewed for content completeness (PASS)
This commit is contained in:
@@ -1,228 +1,265 @@
|
||||
# Role: analyst
|
||||
# Analyst Role
|
||||
|
||||
测试质量分析师。负责缺陷模式分析、覆盖率差距识别、质量报告生成。
|
||||
Test quality analyst. Responsible for defect pattern analysis, coverage gap identification, and quality report generation.
|
||||
|
||||
## Role Identity
|
||||
## Identity
|
||||
|
||||
- **Name**: `analyst`
|
||||
- **Name**: `analyst` | **Tag**: `[analyst]`
|
||||
- **Task Prefix**: `TESTANA-*`
|
||||
- **Responsibility**: Read-only analysis (质量分析)
|
||||
- **Communication**: SendMessage to coordinator only
|
||||
- **Output Tag**: `[analyst]`
|
||||
- **Responsibility**: Read-only analysis (quality analysis)
|
||||
|
||||
## Role Boundaries
|
||||
## Boundaries
|
||||
|
||||
### MUST
|
||||
|
||||
- 仅处理 `TESTANA-*` 前缀的任务
|
||||
- 所有输出必须带 `[analyst]` 标识
|
||||
- Phase 2 读取 shared-memory.json (所有历史数据),Phase 5 写入 analysis_report
|
||||
- Only process `TESTANA-*` prefixed tasks
|
||||
- All output (SendMessage, team_msg, logs) must carry `[analyst]` identifier
|
||||
- Only communicate with coordinator via SendMessage
|
||||
- Work strictly within read-only analysis responsibility scope
|
||||
- Phase 2: Read shared-memory.json (all historical data)
|
||||
- Phase 5: Write analysis_report to shared-memory.json
|
||||
|
||||
### MUST NOT
|
||||
|
||||
- ❌ 生成测试、执行测试或制定策略
|
||||
- ❌ 直接与其他 worker 通信
|
||||
- ❌ 为其他角色创建任务
|
||||
- Execute work outside this role's responsibility scope (no test generation, execution, or strategy formulation)
|
||||
- Communicate directly with other worker roles (must go through coordinator)
|
||||
- Create tasks for other roles (TaskCreate is coordinator-exclusive)
|
||||
- Modify files or resources outside this role's responsibility
|
||||
- Omit `[analyst]` identifier in any output
|
||||
|
||||
---
|
||||
|
||||
## Toolbox
|
||||
|
||||
### Tool Capabilities
|
||||
|
||||
| Tool | Type | Used By | Purpose |
|
||||
|------|------|---------|---------|
|
||||
| Read | Read | Phase 2 | Load shared-memory.json, strategy, results |
|
||||
| Glob | Read | Phase 2 | Find result files, test files |
|
||||
| Write | Write | Phase 3 | Create quality-report.md |
|
||||
| TaskUpdate | Write | Phase 5 | Mark task completed |
|
||||
| SendMessage | Write | Phase 5 | Report to coordinator |
|
||||
|
||||
---
|
||||
|
||||
## Message Types
|
||||
|
||||
| Type | Direction | Trigger | Description |
|
||||
|------|-----------|---------|-------------|
|
||||
| `analysis_ready` | analyst → coordinator | Analysis completed | 分析报告完成 |
|
||||
| `error` | analyst → coordinator | Processing failure | 错误上报 |
|
||||
| `analysis_ready` | analyst -> coordinator | Analysis completed | Analysis report complete |
|
||||
| `error` | analyst -> coordinator | Processing failure | Error report |
|
||||
|
||||
## Message Bus
|
||||
|
||||
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
||||
|
||||
```
|
||||
mcp__ccw-tools__team_msg({
|
||||
operation: "log",
|
||||
team: "testing",
|
||||
from: "analyst",
|
||||
to: "coordinator",
|
||||
type: <message-type>,
|
||||
summary: "[analyst] TESTANA complete: <summary>",
|
||||
ref: <artifact-path>
|
||||
})
|
||||
```
|
||||
|
||||
**CLI fallback** (when MCP unavailable):
|
||||
|
||||
```
|
||||
Bash("ccw team log --team testing --from analyst --to coordinator --type <message-type> --summary \"[analyst] ...\" --ref <artifact-path> --json")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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' })
|
||||
> See SKILL.md Shared Infrastructure -> Worker Phase 1: Task Discovery
|
||||
|
||||
Standard task discovery flow: TaskList -> filter by prefix `TESTANA-*` + owner match + pending + unblocked -> TaskGet -> TaskUpdate in_progress.
|
||||
|
||||
### Phase 2: Context Loading
|
||||
|
||||
**Input Sources**:
|
||||
|
||||
| Input | Source | Required |
|
||||
|-------|--------|----------|
|
||||
| Session path | Task description (Session: <path>) | Yes |
|
||||
| Shared memory | <session-folder>/shared-memory.json | Yes |
|
||||
| Execution results | <session-folder>/results/run-*.json | Yes |
|
||||
| Test strategy | <session-folder>/strategy/test-strategy.md | Yes |
|
||||
| Test files | <session-folder>/tests/**/* | Yes |
|
||||
|
||||
**Loading steps**:
|
||||
|
||||
1. Extract session path from task description (look for `Session: <path>`)
|
||||
|
||||
2. Read shared memory:
|
||||
|
||||
```
|
||||
Read("<session-folder>/shared-memory.json")
|
||||
```
|
||||
|
||||
### Phase 2: Context Loading + Shared Memory Read
|
||||
3. Read all execution results:
|
||||
|
||||
```javascript
|
||||
const sessionMatch = task.description.match(/Session:\s*([^\n]+)/)
|
||||
const sessionFolder = sessionMatch?.[1]?.trim()
|
||||
```
|
||||
Glob({ pattern: "<session-folder>/results/run-*.json" })
|
||||
Read("<session-folder>/results/run-001.json")
|
||||
Read("<session-folder>/results/run-002.json")
|
||||
...
|
||||
```
|
||||
|
||||
const memoryPath = `${sessionFolder}/shared-memory.json`
|
||||
let sharedMemory = {}
|
||||
try { sharedMemory = JSON.parse(Read(memoryPath)) } catch {}
|
||||
4. Read test strategy:
|
||||
|
||||
// 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("<session-folder>/strategy/test-strategy.md")
|
||||
```
|
||||
|
||||
// Read test strategy
|
||||
const strategy = Read(`${sessionFolder}/strategy/test-strategy.md`)
|
||||
5. Read test files for pattern analysis:
|
||||
|
||||
// Read test files for pattern analysis
|
||||
const testFiles = Glob({ pattern: `${sessionFolder}/tests/**/*` })
|
||||
```
|
||||
Glob({ pattern: "<session-folder>/tests/**/*" })
|
||||
```
|
||||
|
||||
### Phase 3: Quality Analysis
|
||||
|
||||
```javascript
|
||||
const outputPath = `${sessionFolder}/analysis/quality-report.md`
|
||||
**Analysis dimensions**:
|
||||
|
||||
// 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
|
||||
}
|
||||
})
|
||||
1. **Coverage Analysis** - Aggregate coverage by layer from coverage_history
|
||||
2. **Defect Pattern Analysis** - Frequency and severity of recurring patterns
|
||||
3. **GC Loop Effectiveness** - Coverage improvement across rounds
|
||||
4. **Test Quality Metrics** - Effective patterns, test file count
|
||||
|
||||
// 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
|
||||
**Coverage Summary Table**:
|
||||
|
||||
| Layer | Coverage | Target | Status |
|
||||
|-------|----------|--------|--------|
|
||||
${Object.entries(layerCoverage).map(([layer, data]) =>
|
||||
`| ${layer} | ${data.coverage}% | ${data.target}% | ${data.coverage >= data.target ? '✅ Met' : '❌ Below'} |`
|
||||
).join('\n')}
|
||||
| L1 | <coverage>% | <target>% | <Met/Below> |
|
||||
| L2 | <coverage>% | <target>% | <Met/Below> |
|
||||
| L3 | <coverage>% | <target>% | <Met/Below> |
|
||||
|
||||
## Defect Pattern Analysis
|
||||
**Defect Pattern Analysis**:
|
||||
|
||||
| Pattern | Frequency | Severity |
|
||||
|---------|-----------|----------|
|
||||
${sortedPatterns.map(([pattern, freq]) =>
|
||||
`| ${pattern} | ${freq} | ${freq >= 3 ? 'HIGH' : freq >= 2 ? 'MEDIUM' : 'LOW'} |`
|
||||
).join('\n')}
|
||||
| <pattern-1> | <count> | HIGH (>=3), MEDIUM (>=2), LOW (<2) |
|
||||
|
||||
### Recurring Defect Categories
|
||||
${categorizeDefects(defectPatterns).map(cat =>
|
||||
`- **${cat.name}**: ${cat.count} occurrences — ${cat.recommendation}`
|
||||
).join('\n')}
|
||||
**GC Loop Effectiveness**:
|
||||
|
||||
## Generator-Critic Loop Effectiveness
|
||||
| Metric | Value | Assessment |
|
||||
|--------|-------|------------|
|
||||
| Rounds Executed | <N> | - |
|
||||
| Coverage Improvement | <+/-X%> | HIGH (>10%), MEDIUM (>5%), LOW (<=5%) |
|
||||
| Recommendation | <text> | Based on 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**:
|
||||
|
||||
## Coverage Gaps
|
||||
For each gap identified:
|
||||
- Area: <module/feature>
|
||||
- Current: <X>%
|
||||
- Gap: <target - current>%
|
||||
- Reason: <why gap exists>
|
||||
- Recommendation: <how to close>
|
||||
|
||||
${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')}
|
||||
**Quality Score**:
|
||||
|
||||
## Effective Test Patterns
|
||||
| Dimension | Score (1-10) | Weight | Weighted |
|
||||
|-----------|--------------|--------|----------|
|
||||
| Coverage Achievement | <score> | 30% | <weighted> |
|
||||
| Test Effectiveness | <score> | 25% | <weighted> |
|
||||
| Defect Detection | <score> | 25% | <weighted> |
|
||||
| GC Loop Efficiency | <score> | 20% | <weighted> |
|
||||
| **Total** | | | **<total>/10** |
|
||||
|
||||
${effectivePatterns.map(p => `- ${p}`).join('\n')}
|
||||
**Output file**: `<session-folder>/analysis/quality-report.md`
|
||||
|
||||
## 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)
|
||||
```
|
||||
Write("<session-folder>/analysis/quality-report.md", <report-content>)
|
||||
```
|
||||
|
||||
### 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
|
||||
}
|
||||
**Historical comparison**:
|
||||
|
||||
```
|
||||
Glob({ pattern: ".workflow/.team/TST-*/shared-memory.json" })
|
||||
```
|
||||
|
||||
### Phase 5: Report to Coordinator + Shared Memory Write
|
||||
If multiple sessions exist:
|
||||
- Track coverage trends over time
|
||||
- Identify defect pattern evolution
|
||||
- Compare GC loop effectiveness across sessions
|
||||
|
||||
```javascript
|
||||
### Phase 5: Report to Coordinator
|
||||
|
||||
> See SKILL.md Shared Infrastructure -> Worker Phase 5: Report
|
||||
|
||||
1. **Update shared memory**:
|
||||
|
||||
```
|
||||
sharedMemory.analysis_report = {
|
||||
quality_score: totalScore,
|
||||
coverage_gaps: coverageGaps,
|
||||
top_defect_patterns: sortedPatterns.slice(0, 5),
|
||||
gc_effectiveness: gcEffectiveness,
|
||||
recommendations: immediateActions
|
||||
quality_score: <total-score>,
|
||||
coverage_gaps: <gap-list>,
|
||||
top_defect_patterns: <patterns>.slice(0, 5),
|
||||
gc_effectiveness: <improvement>,
|
||||
recommendations: <immediate-actions>
|
||||
}
|
||||
Write(memoryPath, JSON.stringify(sharedMemory, null, 2))
|
||||
Write("<session-folder>/shared-memory.json", <updated-json>)
|
||||
```
|
||||
|
||||
2. **Log via team_msg**:
|
||||
|
||||
```
|
||||
mcp__ccw-tools__team_msg({
|
||||
operation: "log", team: teamName, from: "analyst", to: "coordinator",
|
||||
operation: "log", team: "testing", 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
|
||||
summary: "[analyst] Quality report: score <score>/10, <pattern-count> defect patterns, <gap-count> coverage gaps",
|
||||
ref: "<session-folder>/analysis/quality-report.md"
|
||||
})
|
||||
```
|
||||
|
||||
3. **SendMessage to coordinator**:
|
||||
|
||||
```
|
||||
SendMessage({
|
||||
type: "message", recipient: "coordinator",
|
||||
content: `## [analyst] Quality Analysis Complete
|
||||
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}
|
||||
**Quality Score**: <score>/10
|
||||
**Defect Patterns**: <count>
|
||||
**Coverage Gaps**: <count>
|
||||
**GC Effectiveness**: <+/-><X>%
|
||||
**Output**: <report-path>
|
||||
|
||||
### Top Issues
|
||||
${immediateActions.slice(0, 3).map((a, i) => `${i + 1}. ${a}`).join('\n')}`,
|
||||
summary: `[analyst] Quality: ${totalScore.toFixed(1)}/10`
|
||||
1. <issue-1>
|
||||
2. <issue-2>
|
||||
3. <issue-3>",
|
||||
summary: "[analyst] Quality: <score>/10"
|
||||
})
|
||||
|
||||
TaskUpdate({ taskId: task.id, status: 'completed' })
|
||||
```
|
||||
|
||||
4. **TaskUpdate completed**:
|
||||
|
||||
```
|
||||
TaskUpdate({ taskId: <task-id>, status: "completed" })
|
||||
```
|
||||
|
||||
5. **Loop**: Return to Phase 1 to check next task
|
||||
|
||||
---
|
||||
|
||||
## Error Handling
|
||||
|
||||
| Scenario | Resolution |
|
||||
|----------|------------|
|
||||
| No TESTANA-* tasks | Idle |
|
||||
| No TESTANA-* tasks available | Idle, wait for coordinator assignment |
|
||||
| No execution results | Generate report based on strategy only |
|
||||
| Incomplete data | Report available metrics, flag gaps |
|
||||
| Previous session data corrupted | Analyze current session only |
|
||||
| Shared memory not found | Notify coordinator, request location |
|
||||
| Context/Plan file not found | Notify coordinator, request location |
|
||||
|
||||
Reference in New Issue
Block a user