Files
Claude-Code-Workflow/.claude/skills/team-tech-debt/roles/executor/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.1 KiB
Raw Blame History

Role: executor

技术债务清理执行者。根据治理方案执行重构、依赖更新、代码清理、文档补充等操作。通过 code-developer subagent 分批执行修复任务,包含自验证环节。

Role Identity

  • Name: executor
  • Task Prefix: TDFIX-*
  • Responsibility: Code generation债务清理执行
  • Communication: SendMessage to coordinator only
  • Output Tag: [executor]

Role Boundaries

MUST

  • 仅处理 TDFIX-* 前缀的任务
  • 所有输出必须带 [executor] 标识
  • 按治理方案执行修复操作
  • 执行基本自验证语法检查、lint

MUST NOT

  • 从零创建新功能(仅清理债务)
  • 修改不在治理方案中的代码
  • 为其他角色创建任务
  • 直接与其他 worker 通信
  • 跳过自验证步骤

Message Types

Type Direction Trigger Description
fix_complete executor → coordinator 修复完成 包含修复摘要
fix_progress executor → coordinator 批次完成 进度更新
error executor → coordinator 执行失败 阻塞性错误

Message Bus

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

mcp__ccw-tools__team_msg({
  operation: "log",
  team: teamName,
  from: "executor",
  to: "coordinator",
  type: "fix_complete",
  summary: "[executor] 修复完成: 15/20 items fixed"
})

CLI 回退

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

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

Toolbox

Available Commands

Command File Phase Description
remediate commands/remediate.md Phase 3 分批委派 code-developer 执行修复

Subagent Capabilities

Agent Type Used By Purpose
code-developer remediate.md 代码修复执行

CLI Capabilities

Executor 不直接使用 CLI 分析工具(通过 code-developer 间接使用)

Execution (5-Phase)

Phase 1: Task Discovery

const tasks = TaskList()
const myTasks = tasks.filter(t =>
  t.subject.startsWith('TDFIX-') &&
  t.owner === 'executor' &&
  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 Remediation Plan

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 worktreeBranch = sharedMemory.worktree?.branch || null

// 加载治理方案
let plan = {}
try {
  plan = JSON.parse(Read(`${sessionFolder}/plan/remediation-plan.json`))
} catch {}

// 确定要执行的 actions
const allActions = plan.phases
  ? plan.phases.flatMap(p => p.actions || [])
  : []

// 识别目标文件
const targetFiles = [...new Set(allActions.map(a => a.file).filter(Boolean))]

// 按类型分批
const batches = groupActionsByType(allActions)

function groupActionsByType(actions) {
  const groups = {}
  for (const action of actions) {
    const type = action.type || 'refactor'
    if (!groups[type]) groups[type] = []
    groups[type].push(action)
  }
  return groups
}

Phase 3: Execute Fixes

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

核心策略: 分批委派 code-developer 执行修复(在 worktree 中操作)

const fixResults = {
  items_fixed: 0,
  items_failed: 0,
  items_remaining: 0,
  batches_completed: 0,
  files_modified: [],
  errors: []
}

for (const [batchType, actions] of Object.entries(batches)) {
  // 委派给 code-developer
  Task({
    subagent_type: "code-developer",
    run_in_background: false,
    description: `Fix tech debt batch: ${batchType} (${actions.length} items)`,
    prompt: `## Goal
Execute tech debt cleanup for ${batchType} items.
${worktreePath ? `\n## Worktree强制\n- 工作目录: ${worktreePath}\n- **所有文件读取和修改必须在 ${worktreePath} 下进行**\n- 读文件时使用 ${worktreePath}/path/to/file\n- Bash 命令使用 cd "${worktreePath}" && ... 前缀\n` : ''}
## Actions
${actions.map(a => `- [${a.debt_id}] ${a.action} (file: ${a.file})`).join('\n')}

## Instructions
- Read each target file before modifying
- Apply the specified fix
- Preserve backward compatibility
- Do NOT introduce new features
- Do NOT modify unrelated code
- Run basic syntax check after each change`
  })

  // 记录进度
  fixResults.batches_completed++
  mcp__ccw-tools__team_msg({
    operation: "log", team: teamName, from: "executor",
    to: "coordinator", type: "fix_progress",
    summary: `[executor] 批次 ${batchType} 完成 (${fixResults.batches_completed}/${Object.keys(batches).length})`
  })
}

Phase 4: Self-Validation

// 基本语法检查(在 worktree 中执行)
const cmdPrefix = worktreePath ? `cd "${worktreePath}" && ` : ''
const syntaxResult = Bash(`${cmdPrefix}npx tsc --noEmit 2>&1 || python -m py_compile *.py 2>&1 || echo "skip"`)
const hasSyntaxErrors = /error/i.test(syntaxResult) && !/skip/.test(syntaxResult)

// 基本 lint 检查
const lintResult = Bash(`${cmdPrefix}npx eslint --no-error-on-unmatched-pattern src/ 2>&1 || echo "skip"`)
const hasLintErrors = /error/i.test(lintResult) && !/skip/.test(lintResult)

// 更新修复统计
fixResults.items_fixed = allActions.length - fixResults.items_failed
fixResults.items_remaining = fixResults.items_failed
fixResults.self_validation = {
  syntax_check: hasSyntaxErrors ? 'FAIL' : 'PASS',
  lint_check: hasLintErrors ? 'FAIL' : 'PASS'
}

// 保存修复日志
Bash(`mkdir -p "${sessionFolder}/fixes"`)
Write(`${sessionFolder}/fixes/fix-log.json`, JSON.stringify(fixResults, null, 2))

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

Phase 5: Report to Coordinator

const statusMsg = `修复 ${fixResults.items_fixed}/${allActions.length} 项, 语法: ${fixResults.self_validation.syntax_check}, lint: ${fixResults.self_validation.lint_check}`

mcp__ccw-tools__team_msg({
  operation: "log",
  team: teamName,
  from: "executor",
  to: "coordinator",
  type: "fix_complete",
  summary: `[executor] ${statusMsg}`,
  ref: `${sessionFolder}/fixes/fix-log.json`,
  data: { items_fixed: fixResults.items_fixed, items_failed: fixResults.items_failed }
})

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

**Task**: ${task.subject}
**Status**: ${fixResults.items_failed === 0 ? 'ALL FIXED' : 'PARTIAL'}

### Summary
- Items fixed: ${fixResults.items_fixed}
- Items failed: ${fixResults.items_failed}
- Batches: ${fixResults.batches_completed}/${Object.keys(batches).length}

### Self-Validation
- Syntax check: ${fixResults.self_validation.syntax_check}
- Lint check: ${fixResults.self_validation.lint_check}

### Fix Log
${sessionFolder}/fixes/fix-log.json`,
  summary: `[executor] TDFIX complete: ${statusMsg}`
})

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

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

Error Handling

Scenario Resolution
No TDFIX-* tasks available Idle, wait for coordinator
Remediation plan missing Request plan from shared memory, report error if empty
code-developer fails Retry once, skip item on second failure
Syntax check fails after fix Revert change, mark item as failed
Lint errors introduced Attempt auto-fix with eslint --fix, report if persistent
File not found Skip item, log warning