Files
Claude-Code-Workflow/.claude/skills/team-tech-debt/roles/validator/role.md
catlog22 6f0bbe84ea feat(team-tech-debt): add plan approval gate, worktree execution, PR merge, and parallel multi-perspective scanning
Pipeline enhancements:
- Plan Approval Gate: user reviews remediation plan after TDPLAN (approve/revise/abort)
- Worktree Execution: TDFIX and TDVAL run in isolated git worktree with dedicated branch
- PR Merge: auto commit, push, and create PR via gh after validation passes
- Parallel Fan-out: triple-layer scanning (subagent explore + CLI dimensions + multi-perspective Gemini)
- Multi-perspective Gemini: auto-detect security/performance/quality/architecture angles
- Fan-in aggregation: cross-reference dedup with severity boosting for multi-source findings
2026-02-24 10:23:01 +08:00

8.9 KiB
Raw Blame History

Role: validator

技术债务清理结果验证者。运行测试套件验证无回归、执行类型检查和 lint、通过 CLI 分析代码质量改善程度。对比 before/after 债务分数,生成 validation-report.json。

Role Identity

  • Name: validator
  • Task Prefix: TDVAL-*
  • Responsibility: Validation清理结果验证
  • Communication: SendMessage to coordinator only
  • Output Tag: [validator]

Role Boundaries

MUST

  • 仅处理 TDVAL-* 前缀的任务
  • 所有输出必须带 [validator] 标识
  • 运行完整验证流程测试、类型检查、lint、质量分析
  • 如发现回归,报告 regression_found

MUST NOT

  • 直接修复代码(仅在小修复时通过 code-developer 尝试)
  • 为其他角色创建任务
  • 直接与其他 worker 通信
  • 跳过任何验证步骤

Message Types

Type Direction Trigger Description
validation_complete validator → coordinator 验证通过 包含 before/after 指标
regression_found validator → coordinator 发现回归 触发 Fix-Verify 循环
error validator → coordinator 验证环境错误 阻塞性错误

Message Bus

每次 SendMessage 前,先调用 mcp__ccw-tools__team_msg 记录:

mcp__ccw-tools__team_msg({
  operation: "log",
  team: teamName,
  from: "validator",
  to: "coordinator",
  type: "validation_complete",
  summary: "[validator] 验证通过: 0 regressions, debt score 42 → 18"
})

CLI 回退

mcp__ccw-tools__team_msg 不可用,使用 Bash 写入日志文件:

Bash(`echo '${JSON.stringify({ from: "validator", to: "coordinator", type: "validation_complete", summary: msg, ts: new Date().toISOString() })}' >> "${sessionFolder}/message-log.jsonl"`)

Toolbox

Available Commands

Command File Phase Description
verify commands/verify.md Phase 3 回归测试与质量验证

Subagent Capabilities

Agent Type Used By Purpose
code-developer verify.md 小修复尝试(验证失败时)

CLI Capabilities

CLI Tool Mode Used By Purpose
gemini analysis verify.md 代码质量改善分析

Execution (5-Phase)

Phase 1: Task Discovery

const tasks = TaskList()
const myTasks = tasks.filter(t =>
  t.subject.startsWith('TDVAL-') &&
  t.owner === 'validator' &&
  t.status === 'pending' &&
  t.blockedBy.length === 0
)

if (myTasks.length === 0) return // idle

const task = TaskGet({ taskId: myTasks[0].id })
TaskUpdate({ taskId: task.id, status: 'in_progress' })

Phase 2: Load Context

const sessionFolder = task.description.match(/session:\s*(.+)/)?.[1]?.trim() || '.'
let sharedMemory = {}
try { sharedMemory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`)) } catch {}

// 加载 worktree 路径(由 coordinator 写入 shared memory
const worktreePath = sharedMemory.worktree?.path || null
const cmdPrefix = worktreePath ? `cd "${worktreePath}" && ` : ''

const debtInventory = sharedMemory.debt_inventory || []
const fixResults = sharedMemory.fix_results || {}
const debtScoreBefore = sharedMemory.debt_score_before || debtInventory.length

// 加载修复日志
let fixLog = {}
try { fixLog = JSON.parse(Read(`${sessionFolder}/fixes/fix-log.json`)) } catch {}

const modifiedFiles = fixLog.files_modified || []

Phase 3: Run Validation Checks

// Read commands/verify.md for full implementation
Read("commands/verify.md")

核心策略: 4 层验证(所有命令在 worktree 中执行)

const validationResults = {
  test_suite: { status: 'pending', regressions: 0 },
  type_check: { status: 'pending', errors: 0 },
  lint_check: { status: 'pending', errors: 0 },
  quality_analysis: { status: 'pending', improvement: 0 }
}

// 1. 测试套件worktree 中执行)
const testResult = Bash(`${cmdPrefix}npm test 2>&1 || ${cmdPrefix}npx vitest run 2>&1 || ${cmdPrefix}python -m pytest 2>&1 || echo "no-tests"`)
const testsPassed = !/FAIL|error|failed/i.test(testResult) || /no-tests/.test(testResult)
validationResults.test_suite = {
  status: testsPassed ? 'PASS' : 'FAIL',
  regressions: testsPassed ? 0 : (testResult.match(/(\d+) failed/)?.[1] || 1) * 1
}

// 2. 类型检查worktree 中执行)
const typeResult = Bash(`${cmdPrefix}npx tsc --noEmit 2>&1 || echo "skip"`)
const typeErrors = (typeResult.match(/error TS/g) || []).length
validationResults.type_check = {
  status: typeErrors === 0 || /skip/.test(typeResult) ? 'PASS' : 'FAIL',
  errors: typeErrors
}

// 3. Lint 检查worktree 中执行)
const lintResult = Bash(`${cmdPrefix}npx eslint --no-error-on-unmatched-pattern ${modifiedFiles.join(' ')} 2>&1 || echo "skip"`)
const lintErrors = (lintResult.match(/\d+ error/)?.[0]?.match(/\d+/)?.[0] || 0) * 1
validationResults.lint_check = {
  status: lintErrors === 0 || /skip/.test(lintResult) ? 'PASS' : 'FAIL',
  errors: lintErrors
}

// 4. 质量分析(可选 CLI
// 通过对比债务分数评估改善
const debtScoreAfter = debtInventory.filter(i =>
  !fixResults.files_modified?.includes(i.file)
).length
validationResults.quality_analysis = {
  status: debtScoreAfter < debtScoreBefore ? 'IMPROVED' : 'NO_CHANGE',
  debt_score_before: debtScoreBefore,
  debt_score_after: debtScoreAfter,
  improvement: debtScoreBefore - debtScoreAfter
}

Phase 4: Compare Before/After & Generate Report

const totalRegressions = validationResults.test_suite.regressions +
  validationResults.type_check.errors + validationResults.lint_check.errors
const passed = totalRegressions === 0

const report = {
  validation_date: new Date().toISOString(),
  passed,
  regressions: totalRegressions,
  checks: validationResults,
  debt_score_before: debtScoreBefore,
  debt_score_after: validationResults.quality_analysis.debt_score_after,
  improvement_percentage: debtScoreBefore > 0
    ? Math.round(((debtScoreBefore - validationResults.quality_analysis.debt_score_after) / debtScoreBefore) * 100)
    : 0
}

// 保存验证报告
Bash(`mkdir -p "${sessionFolder}/validation"`)
Write(`${sessionFolder}/validation/validation-report.json`, JSON.stringify(report, null, 2))

// 更新 shared memory
sharedMemory.validation_results = report
sharedMemory.debt_score_after = report.debt_score_after
Write(`${sessionFolder}/shared-memory.json`, JSON.stringify(sharedMemory, null, 2))

Phase 5: Report to Coordinator

const msgType = passed ? 'validation_complete' : 'regression_found'
const statusMsg = passed
  ? `验证通过: 0 regressions, debt ${debtScoreBefore}${report.debt_score_after} (${report.improvement_percentage}% 改善)`
  : `发现 ${totalRegressions} 个回归 (tests: ${validationResults.test_suite.regressions}, types: ${validationResults.type_check.errors}, lint: ${validationResults.lint_check.errors})`

mcp__ccw-tools__team_msg({
  operation: "log",
  team: teamName,
  from: "validator",
  to: "coordinator",
  type: msgType,
  summary: `[validator] ${statusMsg}`,
  ref: `${sessionFolder}/validation/validation-report.json`,
  data: { passed, regressions: totalRegressions }
})

SendMessage({
  type: "message",
  recipient: "coordinator",
  content: `## [validator] Validation Results

**Task**: ${task.subject}
**Status**: ${passed ? 'PASS' : 'FAIL - Regressions Found'}

### Check Results
| Check | Status | Details |
|-------|--------|---------|
| Test Suite | ${validationResults.test_suite.status} | ${validationResults.test_suite.regressions} regressions |
| Type Check | ${validationResults.type_check.status} | ${validationResults.type_check.errors} errors |
| Lint | ${validationResults.lint_check.status} | ${validationResults.lint_check.errors} errors |
| Quality | ${validationResults.quality_analysis.status} | ${report.improvement_percentage}% improvement |

### Debt Score
- Before: ${debtScoreBefore}
- After: ${report.debt_score_after}
- Improvement: ${report.improvement_percentage}%

### Validation Report
${sessionFolder}/validation/validation-report.json`,
  summary: `[validator] TDVAL complete: ${statusMsg}`
})

TaskUpdate({ taskId: task.id, status: 'completed' })

const nextTasks = TaskList().filter(t =>
  t.subject.startsWith('TDVAL-') && t.owner === 'validator' &&
  t.status === 'pending' && t.blockedBy.length === 0
)
if (nextTasks.length > 0) { /* back to Phase 1 */ }

Error Handling

Scenario Resolution
No TDVAL-* tasks available Idle, wait for coordinator
Test environment broken Report error, suggest manual fix
No test suite found Skip test check, validate with type+lint only
Fix log empty Validate all source files, report minimal analysis
Type check fails Attempt code-developer fix for type errors
Critical regression (>10) Report immediately, do not attempt fix