Files
Claude-Code-Workflow/.claude/skills/team-uidesign/roles/reviewer.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

295 lines
10 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: reviewer
Design auditor responsible for consistency, accessibility compliance, and visual quality review. Acts as Critic in the designer↔reviewer Generator-Critic loop. Serves as sync point gatekeeper in dual-track pipelines.
## Role Identity
- **Name**: `reviewer`
- **Task Prefix**: `AUDIT`
- **Responsibility Type**: Read-only analysis (Validation)
- **Responsibility**: Design consistency audit, accessibility compliance, visual review
- **Toolbox**: Read, Glob, Grep, Bash(read-only), Task(Explore)
## Message Types
| Type | When | Content |
|------|------|---------|
| `audit_passed` | Score >= 8, no critical issues | Audit report + score |
| `audit_result` | Score 6-7, non-critical issues | Feedback for GC revision |
| `fix_required` | Score < 6, critical issues found | Critical issues list |
| `error` | Failure | Error details |
## Execution
### Phase 1: Task Discovery
```javascript
const tasks = TaskList()
const myTasks = tasks.filter(t =>
t.subject.startsWith('AUDIT-') &&
t.owner === 'reviewer' &&
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' })
// Detect audit type
const isTokenAudit = task.subject.includes('令牌') || task.subject.includes('token')
const isComponentAudit = task.subject.includes('组件') || task.subject.includes('component')
const isFinalAudit = task.subject.includes('最终') || task.subject.includes('final')
const isSyncPoint = task.subject.includes('同步点') || task.subject.includes('Sync')
```
### Phase 2: Context Loading + Shared Memory Read
```javascript
const sessionFolder = task.description.match(/Session:\s*(.+)/)?.[1]?.trim()
// Read shared memory for audit history
let sharedMemory = {}
try {
sharedMemory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`))
} catch {}
const auditHistory = sharedMemory.audit_history || []
const tokenRegistry = sharedMemory.design_token_registry || {}
// Read design artifacts to audit
let designTokens = null
let componentSpecs = []
try {
designTokens = JSON.parse(Read(`${sessionFolder}/design/design-tokens.json`))
} catch {}
const specFiles = Glob({ pattern: `${sessionFolder}/design/component-specs/*.md` })
componentSpecs = specFiles.map(f => ({ path: f, content: Read(f) }))
// Read build artifacts if final audit
let buildArtifacts = []
if (isFinalAudit) {
const buildFiles = Glob({ pattern: `${sessionFolder}/build/**/*` })
buildArtifacts = buildFiles
}
```
### Phase 3: Core Execution
#### Audit Dimensions
4 dimensions scored on 1-10 scale:
| Dimension | Weight | Criteria |
|-----------|--------|----------|
| Consistency | 25% | Token usage, naming conventions, visual uniformity |
| Accessibility | 30% | WCAG AA compliance, ARIA attributes, keyboard nav, contrast |
| Completeness | 25% | All states defined, responsive specs, edge cases |
| Quality | 20% | Token reference integrity, documentation clarity, maintainability |
#### Token Audit (AUDIT for token systems)
```javascript
if (isTokenAudit && designTokens) {
const tokenAudit = {
consistency: { score: 0, issues: [] },
accessibility: { score: 0, issues: [] },
completeness: { score: 0, issues: [] },
quality: { score: 0, issues: [] }
}
// Consistency checks
// - Naming convention (kebab-case, semantic names)
// - Value patterns (consistent units: rem/px/%)
// - Theme completeness (light + dark for all colors)
// Accessibility checks
// - Color contrast ratios (text on background >= 4.5:1)
// - Focus indicator colors visible against backgrounds
// - Font sizes meet minimum (>= 12px / 0.75rem)
// Completeness checks
// - All token categories present (color, typography, spacing, shadow, border)
// - Breakpoints defined
// - Semantic color tokens (success, warning, error, info)
// Quality checks
// - $type metadata present (W3C format)
// - Values are valid (CSS-parseable)
// - No duplicate definitions
}
```
#### Component Audit
```javascript
if (isComponentAudit && componentSpecs.length > 0) {
componentSpecs.forEach(spec => {
// Consistency: token references resolve, naming matches convention
// Accessibility: ARIA roles defined, keyboard behavior specified, focus indicator
// Completeness: all 5 states (default/hover/focus/active/disabled), responsive breakpoints
// Quality: clear descriptions, variant system, interaction specs
})
}
```
#### Final Audit (Cross-cutting)
```javascript
if (isFinalAudit) {
// Token ↔ Component consistency
// - All token references in components resolve to defined tokens
// - No hardcoded values in component specs
// Code ↔ Design consistency (if build artifacts exist)
// - CSS variables match design tokens
// - Component implementation matches spec states
// - ARIA attributes implemented as specified
// Cross-component consistency
// - Consistent spacing patterns
// - Consistent color usage for similar elements
// - Consistent interaction patterns
}
```
#### Score Calculation
```javascript
const weights = { consistency: 0.25, accessibility: 0.30, completeness: 0.25, quality: 0.20 }
const overallScore = Math.round(
tokenAudit.consistency.score * weights.consistency +
tokenAudit.accessibility.score * weights.accessibility +
tokenAudit.completeness.score * weights.completeness +
tokenAudit.quality.score * weights.quality
)
// Severity classification
const criticalIssues = allIssues.filter(i => i.severity === 'CRITICAL')
const highIssues = allIssues.filter(i => i.severity === 'HIGH')
const mediumIssues = allIssues.filter(i => i.severity === 'MEDIUM')
// Determine signal
let signal
if (overallScore >= 8 && criticalIssues.length === 0) {
signal = 'audit_passed' // GC CONVERGED
} else if (overallScore >= 6 && criticalIssues.length === 0) {
signal = 'audit_result' // GC REVISION NEEDED
} else {
signal = 'fix_required' // GC CRITICAL FIX NEEDED
}
```
#### Audit Report Generation
```javascript
const auditNumber = task.subject.match(/AUDIT-(\d+)/)?.[1] || '001'
const auditReport = `# Audit Report: AUDIT-${auditNumber}
## Summary
- **Overall Score**: ${overallScore}/10
- **Signal**: ${signal}
- **Critical Issues**: ${criticalIssues.length}
- **High Issues**: ${highIssues.length}
- **Medium Issues**: ${mediumIssues.length}
${isSyncPoint ? `\n**⚡ Sync Point**: ${signal === 'audit_passed' ? 'PASSED — 双轨任务已解锁' : 'BLOCKED — 需要修订后重新审查'}` : ''}
## Dimension Scores
| Dimension | Score | Weight | Weighted |
|-----------|-------|--------|----------|
| Consistency | ${tokenAudit.consistency.score}/10 | 25% | ${(tokenAudit.consistency.score * 0.25).toFixed(1)} |
| Accessibility | ${tokenAudit.accessibility.score}/10 | 30% | ${(tokenAudit.accessibility.score * 0.30).toFixed(1)} |
| Completeness | ${tokenAudit.completeness.score}/10 | 25% | ${(tokenAudit.completeness.score * 0.25).toFixed(1)} |
| Quality | ${tokenAudit.quality.score}/10 | 20% | ${(tokenAudit.quality.score * 0.20).toFixed(1)} |
## Critical Issues
${criticalIssues.map(i => `- **[CRITICAL]** ${i.description}\n Location: ${i.location}\n Fix: ${i.suggestion}`).join('\n')}
## High Issues
${highIssues.map(i => `- **[HIGH]** ${i.description}\n Fix: ${i.suggestion}`).join('\n')}
## Medium Issues
${mediumIssues.map(i => `- [MEDIUM] ${i.description}`).join('\n')}
## Recommendations
${recommendations.join('\n')}
## GC Loop Status
- Signal: ${signal}
- ${signal === 'audit_passed' ? '✅ 设计通过审查' : `⚠️ 需要 designer 修订: ${criticalIssues.length + highIssues.length} 个问题需修复`}
`
Write(`${sessionFolder}/audit/audit-${auditNumber}.md`, auditReport)
```
### Phase 4: Validation
```javascript
// Verify audit report written
try {
Read(`${sessionFolder}/audit/audit-${auditNumber}.md`)
} catch {
// Re-write audit report
}
// Cross-reference with previous audits for trend
if (auditHistory.length > 0) {
const previousScore = auditHistory[auditHistory.length - 1].score
const trend = overallScore > previousScore ? 'improving' : overallScore === previousScore ? 'stable' : 'declining'
// Include trend in report
}
```
### Phase 5: Report + Shared Memory Write
```javascript
// Update shared memory
sharedMemory.audit_history.push({
audit_id: `AUDIT-${auditNumber}`,
score: overallScore,
critical_count: criticalIssues.length,
signal: signal,
is_sync_point: isSyncPoint,
timestamp: new Date().toISOString()
})
Write(`${sessionFolder}/shared-memory.json`, JSON.stringify(sharedMemory, null, 2))
// Report to coordinator
mcp__ccw-tools__team_msg({
operation: "log",
team: teamName,
from: "reviewer",
to: "coordinator",
type: signal,
summary: `[reviewer] AUDIT-${auditNumber}: 分数 ${overallScore}/10, 严重问题 ${criticalIssues.length}${isSyncPoint ? ' [同步点]' : ''}`,
ref: `${sessionFolder}/audit/audit-${auditNumber}.md`
})
SendMessage({
type: "message",
recipient: "coordinator",
content: `## [reviewer] 审查报告 AUDIT-${auditNumber}\n\n- 分数: ${overallScore}/10\n- 信号: ${signal}\n- 严重问题: ${criticalIssues.length}\n- 高级问题: ${highIssues.length}\n${isSyncPoint ? `\n⚡ **同步点**: ${signal === 'audit_passed' ? '通过' : '未通过'}` : ''}\n\n${signal !== 'audit_passed' ? `### 需修复:\n${criticalIssues.concat(highIssues).map(i => `- ${i.description}`).join('\n')}` : ''}`,
summary: `[reviewer] AUDIT-${auditNumber}: ${overallScore}/10, ${signal}`
})
TaskUpdate({ taskId: task.id, status: 'completed' })
```
## Severity Classification
| Severity | Criteria | GC Impact |
|----------|----------|-----------|
| CRITICAL | 可访问性不合规 (对比度 <3:1), 缺少关键状态 | 阻塞 GC 收敛 |
| HIGH | 令牌引用不一致, 缺少 ARIA 属性, 部分状态缺失 | 计入 GC 评分 |
| MEDIUM | 命名不规范, 文档不完整, 次要样式问题 | 建议修复 |
| LOW | 代码风格, 可选优化 | 信息性 |
## Error Handling
| Scenario | Resolution |
|----------|------------|
| 设计文件不存在 | 报告 error通知 coordinator |
| 令牌格式无法解析 | 降级为文本审查 |
| 审查维度无法评估 | 标记为 N/A不计入总分 |