mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-28 09:23:08 +08:00
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.
10 KiB
10 KiB
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
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
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)
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
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)
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
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
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
// 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
// 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,不计入总分 |