Files
Claude-Code-Workflow/.claude/skills/team-uidesign/roles/reviewer.md
catlog22 1f53f2de27 feat(team-uidesign): integrate ui-ux-pro-max design intelligence
- researcher: add Stream 4 (design intelligence via Skill invocation), generate design-intelligence.json
- designer: consume recommended colors/typography/style for token defaults, add anti-patterns to specs
- reviewer: add 5th audit dimension (Industry Compliance 20%), rebalance weights, anti-pattern checking
- implementer: inject stack guidelines and anti-patterns into code-developer prompts, add validation
- coordinator: add industry selection, industryConfig mapping, update shared memory and session schema
- SKILL.md: update shared memory schema, add design intelligence data flow docs, session directory
2026-02-17 21:51:34 +08:00

317 lines
11 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 intelligence for industry anti-patterns
let designIntelligence = null
try {
designIntelligence = JSON.parse(Read(`${sessionFolder}/research/design-intelligence.json`))
} catch {}
const antiPatterns = designIntelligence?.recommendations?.anti_patterns || []
const industryContext = sharedMemory.industry_context || {}
// 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
5 dimensions scored on 1-10 scale:
| Dimension | Weight | Criteria |
|-----------|--------|----------|
| Consistency | 20% | Token usage, naming conventions, visual uniformity |
| Accessibility | 25% | WCAG AA compliance, ARIA attributes, keyboard nav, contrast |
| Completeness | 20% | All states defined, responsive specs, edge cases |
| Quality | 15% | Token reference integrity, documentation clarity, maintainability |
| Industry Compliance | 20% | Anti-pattern avoidance, UX best practices, design intelligence adherence |
#### 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: [] },
industryCompliance: { 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
// Industry Compliance checks (from design intelligence)
// - Anti-patterns from ui-ux-pro-max not present in design
// - UX best practices followed (recommended style, color usage)
// - Design intelligence recommendations adhered to
// - If antiPatterns available, check each against design artifacts
antiPatterns.forEach(pattern => {
// Check if design violates this anti-pattern
// Flag as HIGH severity if violated
})
}
```
#### 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.20, accessibility: 0.25, completeness: 0.20, quality: 0.15, industryCompliance: 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 +
tokenAudit.industryCompliance.score * weights.industryCompliance
)
// 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 | 20% | ${(tokenAudit.consistency.score * 0.20).toFixed(1)} |
| Accessibility | ${tokenAudit.accessibility.score}/10 | 25% | ${(tokenAudit.accessibility.score * 0.25).toFixed(1)} |
| Completeness | ${tokenAudit.completeness.score}/10 | 20% | ${(tokenAudit.completeness.score * 0.20).toFixed(1)} |
| Quality | ${tokenAudit.quality.score}/10 | 15% | ${(tokenAudit.quality.score * 0.15).toFixed(1)} |
| Industry Compliance | ${tokenAudit.industryCompliance.score}/10 | 20% | ${(tokenAudit.industryCompliance.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不计入总分 |