From f60dd44d5b5eb77fd56dd85b79e3de8af61515d0 Mon Sep 17 00:00:00 2001 From: catlog22 Date: Mon, 23 Feb 2026 22:46:27 +0800 Subject: [PATCH] feat: add team-tech-debt skill for tech debt identification and cleanup 6-role team (coordinator, scanner, assessor, planner, executor, validator) with 3 pipeline modes (scan, remediate, targeted) and fix-verify loop. Scanner performs 5-dimension analysis (code, architecture, testing, dependency, documentation) via CLI fan-out. Follows team-skill-designer patterns with self-contained role.md and command.md files. --- .claude/skills/team-tech-debt/SKILL.md | 404 ++++++++++++++++++ .../roles/assessor/commands/evaluate.md | 164 +++++++ .../team-tech-debt/roles/assessor/role.md | 262 ++++++++++++ .../roles/coordinator/commands/dispatch.md | 157 +++++++ .../roles/coordinator/commands/monitor.md | 255 +++++++++++ .../team-tech-debt/roles/coordinator/role.md | 264 ++++++++++++ .../roles/executor/commands/remediate.md | 176 ++++++++ .../team-tech-debt/roles/executor/role.md | 267 ++++++++++++ .../roles/planner/commands/create-plan.md | 165 +++++++ .../team-tech-debt/roles/planner/role.md | 287 +++++++++++++ .../roles/scanner/commands/scan-debt.md | 198 +++++++++ .../team-tech-debt/roles/scanner/role.md | 258 +++++++++++ .../roles/validator/commands/verify.md | 199 +++++++++ .../team-tech-debt/roles/validator/role.md | 263 ++++++++++++ .../team-tech-debt/specs/team-config.json | 132 ++++++ 15 files changed, 3451 insertions(+) create mode 100644 .claude/skills/team-tech-debt/SKILL.md create mode 100644 .claude/skills/team-tech-debt/roles/assessor/commands/evaluate.md create mode 100644 .claude/skills/team-tech-debt/roles/assessor/role.md create mode 100644 .claude/skills/team-tech-debt/roles/coordinator/commands/dispatch.md create mode 100644 .claude/skills/team-tech-debt/roles/coordinator/commands/monitor.md create mode 100644 .claude/skills/team-tech-debt/roles/coordinator/role.md create mode 100644 .claude/skills/team-tech-debt/roles/executor/commands/remediate.md create mode 100644 .claude/skills/team-tech-debt/roles/executor/role.md create mode 100644 .claude/skills/team-tech-debt/roles/planner/commands/create-plan.md create mode 100644 .claude/skills/team-tech-debt/roles/planner/role.md create mode 100644 .claude/skills/team-tech-debt/roles/scanner/commands/scan-debt.md create mode 100644 .claude/skills/team-tech-debt/roles/scanner/role.md create mode 100644 .claude/skills/team-tech-debt/roles/validator/commands/verify.md create mode 100644 .claude/skills/team-tech-debt/roles/validator/role.md create mode 100644 .claude/skills/team-tech-debt/specs/team-config.json diff --git a/.claude/skills/team-tech-debt/SKILL.md b/.claude/skills/team-tech-debt/SKILL.md new file mode 100644 index 00000000..0c60681e --- /dev/null +++ b/.claude/skills/team-tech-debt/SKILL.md @@ -0,0 +1,404 @@ +--- +name: team-tech-debt +description: Unified team skill for tech debt identification and cleanup. All roles invoke this skill with --role arg for role-specific execution. Triggers on "team tech-debt", "tech debt cleanup", "技术债务". +allowed-tools: TeamCreate(*), TeamDelete(*), SendMessage(*), TaskCreate(*), TaskUpdate(*), TaskList(*), TaskGet(*), Task(*), AskUserQuestion(*), Read(*), Write(*), Edit(*), Bash(*), Glob(*), Grep(*) +--- + +# Team Tech Debt + +技术债务识别与清理团队。融合"债务扫描"、"量化评估"、"治理规划"、"清理执行"、"验证回归"五大能力域,形成"扫描→评估→规划→清理→验证"闭环。通过 Scanner 多维度扫描、Executor-Validator 修复验证循环、共享债务清单数据库,实现渐进式技术债务治理。所有成员通过 `--role=xxx` 路由到角色执行逻辑。 + +## Architecture Overview + +``` +┌──────────────────────────────────────────────────────────┐ +│ Skill(skill="team-tech-debt", args="--role=xxx") │ +└────────────────────────┬─────────────────────────────────┘ + │ Role Router + ┌────────┬───────────┼───────────┬──────────┬──────────┐ + ↓ ↓ ↓ ↓ ↓ ↓ +┌────────┐┌────────┐┌──────────┐┌─────────┐┌────────┐┌─────────┐ +│coordi- ││scanner ││assessor ││planner ││executor││validator│ +│nator ││TDSCAN-*││TDEVAL-* ││TDPLAN-* ││TDFIX-* ││TDVAL-* │ +│ roles/ ││ roles/ ││ roles/ ││ roles/ ││ roles/ ││ roles/ │ +└────────┘└────────┘└──────────┘└─────────┘└────────┘└─────────┘ +``` + +## Command Architecture + +``` +roles/ +├── coordinator/ +│ ├── role.md # Pipeline 编排(模式选择、任务分发、监控) +│ └── commands/ +│ ├── dispatch.md # 任务链创建 +│ └── monitor.md # 进度监控 +├── scanner/ +│ ├── role.md # 多维度技术债务扫描 +│ └── commands/ +│ └── scan-debt.md # 多维度 CLI Fan-out 扫描 +├── assessor/ +│ ├── role.md # 量化评估与优先级排序 +│ └── commands/ +│ └── evaluate.md # 影响/成本矩阵评估 +├── planner/ +│ ├── role.md # 治理方案规划 +│ └── commands/ +│ └── create-plan.md # 分阶段治理方案生成 +├── executor/ +│ ├── role.md # 债务清理执行 +│ └── commands/ +│ └── remediate.md # 重构/清理/更新执行 +└── validator/ + ├── role.md # 清理结果验证 + └── commands/ + └── verify.md # 回归测试与质量验证 +``` + +**设计原则**: role.md 保留 Phase 1(Task Discovery)和 Phase 5(Report)内联。Phase 2-4 根据复杂度决定内联或委派到 `commands/*.md`。 + +## Role Router + +### Input Parsing + +Parse `$ARGUMENTS` to extract `--role` and optional `--agent-name`: + +```javascript +const args = "$ARGUMENTS" +const roleMatch = args.match(/--role[=\s]+(\w+)/) +const teamName = args.match(/--team[=\s]+([\w-]+)/)?.[1] || "tech-debt" + +if (!roleMatch) { + // No --role: Orchestration Mode → auto route to coordinator + // See "Orchestration Mode" section below +} + +const role = roleMatch ? roleMatch[1] : "coordinator" +const agentName = args.match(/--agent-name[=\s]+([\w-]+)/)?.[1] || role +``` + +### Role Dispatch + +```javascript +const VALID_ROLES = { + "coordinator": { file: "roles/coordinator/role.md", prefix: null }, + "scanner": { file: "roles/scanner/role.md", prefix: "TDSCAN" }, + "assessor": { file: "roles/assessor/role.md", prefix: "TDEVAL" }, + "planner": { file: "roles/planner/role.md", prefix: "TDPLAN" }, + "executor": { file: "roles/executor/role.md", prefix: "TDFIX" }, + "validator": { file: "roles/validator/role.md", prefix: "TDVAL" } +} + +if (!VALID_ROLES[role]) { + throw new Error(`Unknown role: ${role}. Available: ${Object.keys(VALID_ROLES).join(', ')}`) +} + +// Read and execute role-specific logic +Read(VALID_ROLES[role].file) +// → Execute the 5-phase process defined in that file +``` + +### Orchestration Mode(无参数触发) + +当不带 `--role` 调用时,自动进入 coordinator 编排模式。 + +**触发方式**: + +```javascript +// 用户调用(无 --role)— 自动路由到 coordinator +Skill(skill="team-tech-debt", args="扫描并清理项目中的技术债务") + +// 等价于 +Skill(skill="team-tech-debt", args="--role=coordinator 扫描并清理项目中的技术债务") +``` + +**完整调用链**: + +``` +用户: Skill(args="任务描述") + │ + ├─ SKILL.md: 无 --role → Orchestration Mode → 读取 coordinator role.md + │ + ├─ coordinator Phase 2: TeamCreate + spawn workers + │ 每个 worker prompt 中包含 Skill(args="--role=xxx") 回调 + │ + ├─ coordinator Phase 3: dispatch 任务链 + │ + ├─ worker 收到任务 → Skill(args="--role=xxx") → SKILL.md Role Router → role.md + │ 每个 worker 自动获取: + │ ├─ 角色定义 (role.md: identity, boundaries, message types) + │ ├─ 可用命令 (commands/*.md) + │ └─ 执行逻辑 (5-phase process) + │ + └─ coordinator Phase 4-5: 监控 → 结果汇报 +``` + +### Available Roles + +| Role | Task Prefix | Responsibility | Role File | +|------|-------------|----------------|-----------| +| `coordinator` | N/A | Pipeline 编排、模式选择、质量门控 | [roles/coordinator/role.md](roles/coordinator/role.md) | +| `scanner` | TDSCAN-* | 多维度技术债务扫描 | [roles/scanner/role.md](roles/scanner/role.md) | +| `assessor` | TDEVAL-* | 量化评估与优先级排序 | [roles/assessor/role.md](roles/assessor/role.md) | +| `planner` | TDPLAN-* | 分阶段治理方案规划 | [roles/planner/role.md](roles/planner/role.md) | +| `executor` | TDFIX-* | 重构/清理/更新执行 | [roles/executor/role.md](roles/executor/role.md) | +| `validator` | TDVAL-* | 回归测试与质量验证 | [roles/validator/role.md](roles/validator/role.md) | + +## Shared Infrastructure + +> 以下为编排级概览。具体实现代码(Message Bus、Task Lifecycle、工具方法)在各 role.md 中自包含。 + +### Team Configuration + +```javascript +const TEAM_CONFIG = { + name: "tech-debt", + sessionDir: ".workflow/.team/TD-{slug}-{date}/", + sharedMemory: "shared-memory.json", + debtDimensions: ["code", "architecture", "testing", "dependency", "documentation"], + priorityMatrix: { + highImpact_lowCost: "立即修复 (Quick Win)", + highImpact_highCost: "战略规划 (Strategic)", + lowImpact_lowCost: "待办处理 (Backlog)", + lowImpact_highCost: "暂缓接受 (Defer)" + } +} +``` + +### Role Isolation Rules + +**核心原则**: 每个角色仅能执行自己职责范围内的工作。 + +#### Output Tagging(强制) + +所有角色的输出必须带 `[role_name]` 标识前缀。 + +#### Coordinator 隔离 + +| 允许 | 禁止 | +|------|------| +| 需求澄清 (AskUserQuestion) | ❌ 直接扫描代码 | +| 创建任务链 (TaskCreate) | ❌ 直接执行重构或清理 | +| 模式选择 + 质量门控 | ❌ 直接评估或规划 | +| 监控进度 (消息总线) | ❌ 绕过 worker 自行完成 | + +#### Worker 隔离 + +| 允许 | 禁止 | +|------|------| +| 处理自己前缀的任务 | ❌ 处理其他角色前缀的任务 | +| 读写 shared-memory.json (自己的字段) | ❌ 为其他角色创建任务 | +| SendMessage 给 coordinator | ❌ 直接与其他 worker 通信 | + +## Three-Mode Pipeline Architecture + +``` +Scan Mode (仅扫描评估): + TDSCAN-001(多维度扫描) → TDEVAL-001(量化评估) → 报告 + +Remediate Mode (完整闭环): + TDSCAN-001(扫描) → TDEVAL-001(评估) → TDPLAN-001(规划) → TDFIX-001(修复) → TDVAL-001(验证) + +Targeted Mode (定向修复): + TDPLAN-001(规划) → TDFIX-001(修复) → TDVAL-001(验证) +``` + +### Mode Auto-Detection + +```javascript +function detectMode(args, taskDescription) { + if (/--mode[=\s]+(scan|remediate|targeted)/.test(args)) { + return args.match(/--mode[=\s]+(\w+)/)[1] + } + if (/扫描|scan|审计|audit|评估|assess/.test(taskDescription)) return 'scan' + if (/定向|targeted|指定|specific|修复.*已知/.test(taskDescription)) return 'targeted' + return 'remediate' +} +``` + +### Fix-Verify Loop + +``` +TDFIX → TDVAL → (if regression or quality drop) → TDFIX-fix → TDVAL-2 + (if all pass) → report +``` + +## Unified Session Directory + +``` +.workflow/.team/TD-{slug}-{YYYY-MM-DD}/ +├── team-session.json +├── shared-memory.json # 债务清单 / 评估矩阵 / 治理方案 / 修复结果 / 验证结果 +├── scan/ # Scanner output +│ └── debt-inventory.json +├── assessment/ # Assessor output +│ └── priority-matrix.json +├── plan/ # Planner output +│ └── remediation-plan.md +├── fixes/ # Executor output +│ └── fix-log.json +└── validation/ # Validator output + └── validation-report.json +``` + +## Coordinator Spawn Template + +```javascript +TeamCreate({ team_name: teamName }) + +// Scanner +Task({ + subagent_type: "general-purpose", + team_name: teamName, + name: "scanner", + prompt: `你是 team "${teamName}" 的 SCANNER。 + +## ⚠️ 首要指令(MUST) +你的所有工作必须通过调用 Skill 获取角色定义后执行,禁止自行发挥: +Skill(skill="team-tech-debt", args="--role=scanner") +此调用会加载你的角色定义(role.md)、可用命令(commands/*.md)和完整执行逻辑。 + +当前需求: ${taskDescription} +约束: ${constraints} + +## 角色准则(强制) +- 你只能处理 TDSCAN-* 前缀的任务,不得执行其他角色的工作 +- 所有输出(SendMessage、team_msg)必须带 [scanner] 标识前缀 +- 仅与 coordinator 通信,不得直接联系其他 worker +- 不得使用 TaskCreate 为其他角色创建任务 + +## 消息总线(必须) +每次 SendMessage 前,先调用 mcp__ccw-tools__team_msg 记录。 + +## 工作流程(严格按顺序) +1. 调用 Skill(skill="team-tech-debt", args="--role=scanner") 获取角色定义和执行逻辑 +2. 按 role.md 中的 5-Phase 流程执行(TaskList → 找到 TDSCAN-* 任务 → 执行 → 汇报) +3. team_msg log + SendMessage 结果给 coordinator(带 [scanner] 标识) +4. TaskUpdate completed → 检查下一个任务 → 回到步骤 1` +}) + +// Assessor +Task({ + subagent_type: "general-purpose", + team_name: teamName, + name: "assessor", + prompt: `你是 team "${teamName}" 的 ASSESSOR。 + +## ⚠️ 首要指令(MUST) +Skill(skill="team-tech-debt", args="--role=assessor") + +当前需求: ${taskDescription} +约束: ${constraints} + +## 角色准则(强制) +- 你只能处理 TDEVAL-* 前缀的任务 +- 所有输出必须带 [assessor] 标识前缀 +- 仅与 coordinator 通信 + +## 消息总线(必须) +每次 SendMessage 前,先调用 mcp__ccw-tools__team_msg 记录。 + +## 工作流程 +1. Skill(skill="team-tech-debt", args="--role=assessor") 获取角色定义 +2. TaskList → 找到 TDEVAL-* 任务 → 执行 → 汇报 +3. team_msg log + SendMessage 结果给 coordinator +4. TaskUpdate completed → 检查下一个任务` +}) + +// Planner +Task({ + subagent_type: "general-purpose", + team_name: teamName, + name: "planner", + prompt: `你是 team "${teamName}" 的 PLANNER。 + +## ⚠️ 首要指令(MUST) +Skill(skill="team-tech-debt", args="--role=planner") + +当前需求: ${taskDescription} +约束: ${constraints} + +## 角色准则(强制) +- 你只能处理 TDPLAN-* 前缀的任务 +- 所有输出必须带 [planner] 标识前缀 +- 仅与 coordinator 通信 + +## 消息总线(必须) +每次 SendMessage 前,先调用 mcp__ccw-tools__team_msg 记录。 + +## 工作流程 +1. Skill(skill="team-tech-debt", args="--role=planner") 获取角色定义 +2. TaskList → 找到 TDPLAN-* 任务 → 执行 → 汇报 +3. team_msg log + SendMessage 结果给 coordinator +4. TaskUpdate completed → 检查下一个任务` +}) + +// Executor +Task({ + subagent_type: "general-purpose", + team_name: teamName, + name: "executor", + prompt: `你是 team "${teamName}" 的 EXECUTOR。 + +## ⚠️ 首要指令(MUST) +Skill(skill="team-tech-debt", args="--role=executor") + +当前需求: ${taskDescription} +约束: ${constraints} + +## 角色准则(强制) +- 你只能处理 TDFIX-* 前缀的任务 +- 所有输出必须带 [executor] 标识前缀 +- 仅与 coordinator 通信 + +## 消息总线(必须) +每次 SendMessage 前,先调用 mcp__ccw-tools__team_msg 记录。 + +## 工作流程 +1. Skill(skill="team-tech-debt", args="--role=executor") 获取角色定义 +2. TaskList → 找到 TDFIX-* 任务 → 执行 → 汇报 +3. team_msg log + SendMessage 结果给 coordinator +4. TaskUpdate completed → 检查下一个任务` +}) + +// Validator +Task({ + subagent_type: "general-purpose", + team_name: teamName, + name: "validator", + prompt: `你是 team "${teamName}" 的 VALIDATOR。 + +## ⚠️ 首要指令(MUST) +Skill(skill="team-tech-debt", args="--role=validator") + +当前需求: ${taskDescription} +约束: ${constraints} + +## 角色准则(强制) +- 你只能处理 TDVAL-* 前缀的任务 +- 所有输出必须带 [validator] 标识前缀 +- 仅与 coordinator 通信 + +## 消息总线(必须) +每次 SendMessage 前,先调用 mcp__ccw-tools__team_msg 记录。 + +## 工作流程 +1. Skill(skill="team-tech-debt", args="--role=validator") 获取角色定义 +2. TaskList → 找到 TDVAL-* 任务 → 执行 → 汇报 +3. team_msg log + SendMessage 结果给 coordinator +4. TaskUpdate completed → 检查下一个任务` +}) +``` + +## Error Handling + +| Scenario | Resolution | +|----------|------------| +| Unknown --role value | Error with available role list | +| Missing --role arg | Orchestration Mode → auto route to coordinator | +| Role file not found | Error with expected path (roles/{name}/role.md) | +| Command file not found | Fall back to inline execution in role.md | +| Task prefix conflict | Log warning, proceed | +| Scanner finds no debt | Report clean codebase, skip to summary | +| Fix introduces regression | Trigger Fix-Verify loop (max 3 iterations) | +| Validation repeatedly fails | Escalate to user with diagnosis | diff --git a/.claude/skills/team-tech-debt/roles/assessor/commands/evaluate.md b/.claude/skills/team-tech-debt/roles/assessor/commands/evaluate.md new file mode 100644 index 00000000..965e45e2 --- /dev/null +++ b/.claude/skills/team-tech-debt/roles/assessor/commands/evaluate.md @@ -0,0 +1,164 @@ +# Command: evaluate + +> CLI 分析评估债务项。对每项债务评估业务影响(1-5)、修复成本(1-5)、未修复风险,产出优先级象限分配。 + +## When to Use + +- Phase 3 of Assessor +- 需要对债务清单中的项目进行量化评估 +- 债务项数量较多需要 CLI 辅助分析 + +**Trigger conditions**: +- TDEVAL-* 任务进入 Phase 3 +- 债务清单包含 >10 项需要评估的条目 +- 需要上下文理解来评估影响和成本 + +## Strategy + +### Delegation Mode + +**Mode**: CLI Batch Analysis +**CLI Tool**: `gemini` (primary) +**CLI Mode**: `analysis` + +### Decision Logic + +```javascript +// 评估策略选择 +if (debtInventory.length <= 10) { + // 少量项目:内联评估(基于严重性和工作量启发式) + mode = 'heuristic' +} else if (debtInventory.length <= 50) { + // 中等规模:单次 CLI 批量评估 + mode = 'cli-batch' +} else { + // 大规模:分批 CLI 评估 + mode = 'cli-chunked' + chunkSize = 25 +} +``` + +## Execution Steps + +### Step 1: Context Preparation + +```javascript +// 准备评估上下文 +const debtSummary = debtInventory.map(item => + `[${item.id}] [${item.dimension}] [${item.severity}] ${item.file}:${item.line} - ${item.description}` +).join('\n') + +// 读取项目元信息用于上下文 +const projectContext = [] +try { + const pkg = JSON.parse(Read('package.json')) + projectContext.push(`Project: ${pkg.name}, Dependencies: ${Object.keys(pkg.dependencies || {}).length}`) +} catch {} +``` + +### Step 2: Execute Strategy + +```javascript +if (mode === 'heuristic') { + // 内联启发式评估 + for (const item of debtInventory) { + const severityImpact = { critical: 5, high: 4, medium: 3, low: 1 } + const effortCost = { small: 1, medium: 3, large: 5 } + item.impact_score = severityImpact[item.severity] || 3 + item.cost_score = effortCost[item.estimated_effort] || 3 + item.risk_if_unfixed = getRiskDescription(item) + item.priority_quadrant = assignQuadrant(item.impact_score, item.cost_score) + } +} else { + // CLI 批量评估 + const prompt = `PURPOSE: Evaluate technical debt items for business impact and fix cost to create a priority matrix +TASK: • For each debt item, assess business impact (1-5 scale: 1=negligible, 5=critical) • Assess fix complexity/cost (1-5 scale: 1=trivial, 5=major refactor) • Describe risk if unfixed • Assign priority quadrant: quick-win (high impact + low cost), strategic (high impact + high cost), backlog (low impact + low cost), defer (low impact + high cost) +MODE: analysis +CONTEXT: ${projectContext.join(' | ')} +EXPECTED: JSON array with: [{id, impact_score, cost_score, risk_if_unfixed, priority_quadrant}] for each item +CONSTRAINTS: Be realistic about costs, consider dependencies between items + +## Debt Items to Evaluate +${debtSummary}` + + Bash(`ccw cli -p "${prompt}" --tool gemini --mode analysis --rule analysis-analyze-code-patterns`, { + run_in_background: true + }) + + // 等待 CLI 完成,解析结果,合并回 debtInventory +} + +function assignQuadrant(impact, cost) { + if (impact >= 4 && cost <= 2) return 'quick-win' + if (impact >= 4 && cost >= 3) return 'strategic' + if (impact <= 3 && cost <= 2) return 'backlog' + return 'defer' +} + +function getRiskDescription(item) { + const risks = { + 'code': 'Increased maintenance cost and bug probability', + 'architecture': 'Growing coupling makes changes harder and riskier', + 'testing': 'Reduced confidence in changes, higher regression risk', + 'dependency': 'Security vulnerabilities and compatibility issues', + 'documentation': 'Onboarding friction and knowledge loss' + } + return risks[item.dimension] || 'Technical quality degradation over time' +} +``` + +### Step 3: Result Processing + +```javascript +// 验证评估结果完整性 +const evaluated = debtInventory.filter(i => i.priority_quadrant) +const unevaluated = debtInventory.filter(i => !i.priority_quadrant) + +if (unevaluated.length > 0) { + // 未评估的项目使用启发式兜底 + for (const item of unevaluated) { + item.impact_score = item.impact_score || 3 + item.cost_score = item.cost_score || 3 + item.priority_quadrant = assignQuadrant(item.impact_score, item.cost_score) + item.risk_if_unfixed = item.risk_if_unfixed || getRiskDescription(item) + } +} + +// 生成统计 +const stats = { + total: debtInventory.length, + evaluated_by_cli: evaluated.length, + evaluated_by_heuristic: unevaluated.length, + avg_impact: (debtInventory.reduce((s, i) => s + i.impact_score, 0) / debtInventory.length).toFixed(1), + avg_cost: (debtInventory.reduce((s, i) => s + i.cost_score, 0) / debtInventory.length).toFixed(1) +} +``` + +## Output Format + +``` +## Evaluation Results + +### Method: [heuristic|cli-batch|cli-chunked] +### Total Items: [count] +### Average Impact: [score]/5 +### Average Cost: [score]/5 + +### Priority Distribution +| Quadrant | Count | % | +|----------|-------|---| +| Quick-Win | [n] | [%] | +| Strategic | [n] | [%] | +| Backlog | [n] | [%] | +| Defer | [n] | [%] | +``` + +## Error Handling + +| Scenario | Resolution | +|----------|------------| +| CLI returns invalid JSON | Fall back to heuristic scoring | +| CLI timeout | Evaluate processed items, heuristic for rest | +| Debt inventory too large (>200) | Chunk into batches of 25 | +| Missing severity/effort data | Use dimension-based defaults | +| All items same quadrant | Re-evaluate with adjusted thresholds | diff --git a/.claude/skills/team-tech-debt/roles/assessor/role.md b/.claude/skills/team-tech-debt/roles/assessor/role.md new file mode 100644 index 00000000..d642c806 --- /dev/null +++ b/.claude/skills/team-tech-debt/roles/assessor/role.md @@ -0,0 +1,262 @@ +# Role: assessor + +技术债务量化评估师。对扫描发现的每项债务进行影响评分(1-5)和修复成本评分(1-5),划分优先级象限,生成 priority-matrix.json。 + +## Role Identity + +- **Name**: `assessor` +- **Task Prefix**: `TDEVAL-*` +- **Responsibility**: Read-only analysis(量化评估) +- **Communication**: SendMessage to coordinator only +- **Output Tag**: `[assessor]` + +## Role Boundaries + +### MUST + +- 仅处理 `TDEVAL-*` 前缀的任务 +- 所有输出必须带 `[assessor]` 标识 +- 基于数据量化评估债务优先级 +- 更新 shared memory 中的 priority_matrix + +### MUST NOT + +- 修改源代码或测试代码 +- 执行修复操作 +- 为其他角色创建任务 +- 直接与其他 worker 通信 + +## Message Types + +| Type | Direction | Trigger | Description | +|------|-----------|---------|-------------| +| `assessment_complete` | assessor → coordinator | 评估完成 | 包含优先级矩阵摘要 | +| `error` | assessor → coordinator | 评估失败 | 阻塞性错误 | + +## Message Bus + +每次 SendMessage 前,先调用 `mcp__ccw-tools__team_msg` 记录: + +```javascript +mcp__ccw-tools__team_msg({ + operation: "log", + team: teamName, + from: "assessor", + to: "coordinator", + type: "assessment_complete", + summary: "[assessor] 评估完成: 12 quick-wins, 8 strategic, 15 backlog, 7 defer" +}) +``` + +### CLI 回退 + +若 `mcp__ccw-tools__team_msg` 不可用,使用 Bash 写入日志文件: + +```javascript +Bash(`echo '${JSON.stringify({ from: "assessor", to: "coordinator", type: "assessment_complete", summary: msg, ts: new Date().toISOString() })}' >> "${sessionFolder}/message-log.jsonl"`) +``` + +## Toolbox + +### Available Commands + +| Command | File | Phase | Description | +|---------|------|-------|-------------| +| `evaluate` | [commands/evaluate.md](commands/evaluate.md) | Phase 3 | 影响/成本矩阵评估 | + +### Subagent Capabilities + +> Assessor 不直接使用 subagent + +### CLI Capabilities + +| CLI Tool | Mode | Used By | Purpose | +|----------|------|---------|---------| +| `gemini` | analysis | evaluate.md | 债务影响与修复成本评估 | + +## Execution (5-Phase) + +### Phase 1: Task Discovery + +```javascript +const tasks = TaskList() +const myTasks = tasks.filter(t => + t.subject.startsWith('TDEVAL-') && + t.owner === 'assessor' && + 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 Debt Inventory + +```javascript +const sessionFolder = task.description.match(/session:\s*(.+)/)?.[1]?.trim() || '.' +let sharedMemory = {} +try { sharedMemory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`)) } catch {} + +const debtInventory = sharedMemory.debt_inventory || [] +if (debtInventory.length === 0) { + // 尝试从文件加载 + try { + const inventoryFile = JSON.parse(Read(`${sessionFolder}/scan/debt-inventory.json`)) + debtInventory.push(...(inventoryFile.items || [])) + } catch {} +} + +if (debtInventory.length === 0) { + // 无债务项,直接报告 + mcp__ccw-tools__team_msg({ + operation: "log", team: teamName, from: "assessor", + to: "coordinator", type: "assessment_complete", + summary: `[assessor] 无债务项需要评估` + }) + TaskUpdate({ taskId: task.id, status: 'completed' }) + return +} +``` + +### Phase 3: Evaluate Each Item + +```javascript +// Read commands/evaluate.md for full CLI evaluation implementation +Read("commands/evaluate.md") +``` + +**核心策略**: 对每项债务评估 impact(1-5) + cost(1-5) + priority quadrant + +```javascript +const evaluatedItems = [] + +for (const item of debtInventory) { + // CLI 分析评估(批量处理以节约 API 调用) + const evaluation = { + ...item, + impact_score: 0, // 1-5, 业务影响 + cost_score: 0, // 1-5, 修复成本 + risk_if_unfixed: '', // 风险描述 + priority_quadrant: '' // quick-win / strategic / backlog / defer + } + + // 基于严重性预评估 + const severityImpact = { critical: 5, high: 4, medium: 3, low: 1 } + evaluation.impact_score = severityImpact[item.severity] || 3 + + // 基于预估工作量预评估 + const effortCost = { small: 1, medium: 3, large: 5 } + evaluation.cost_score = effortCost[item.estimated_effort] || 3 + + // 象限划分 + if (evaluation.impact_score >= 4 && evaluation.cost_score <= 2) { + evaluation.priority_quadrant = 'quick-win' + } else if (evaluation.impact_score >= 4 && evaluation.cost_score >= 3) { + evaluation.priority_quadrant = 'strategic' + } else if (evaluation.impact_score <= 3 && evaluation.cost_score <= 2) { + evaluation.priority_quadrant = 'backlog' + } else { + evaluation.priority_quadrant = 'defer' + } + + evaluatedItems.push(evaluation) +} +``` + +### Phase 4: Generate Priority Matrix + +```javascript +const priorityMatrix = { + evaluation_date: new Date().toISOString(), + total_items: evaluatedItems.length, + by_quadrant: { + 'quick-win': evaluatedItems.filter(i => i.priority_quadrant === 'quick-win'), + 'strategic': evaluatedItems.filter(i => i.priority_quadrant === 'strategic'), + 'backlog': evaluatedItems.filter(i => i.priority_quadrant === 'backlog'), + 'defer': evaluatedItems.filter(i => i.priority_quadrant === 'defer') + }, + summary: { + 'quick-win': evaluatedItems.filter(i => i.priority_quadrant === 'quick-win').length, + 'strategic': evaluatedItems.filter(i => i.priority_quadrant === 'strategic').length, + 'backlog': evaluatedItems.filter(i => i.priority_quadrant === 'backlog').length, + 'defer': evaluatedItems.filter(i => i.priority_quadrant === 'defer').length + } +} + +// 排序:每个象限内按 impact_score 降序 +for (const quadrant of Object.keys(priorityMatrix.by_quadrant)) { + priorityMatrix.by_quadrant[quadrant].sort((a, b) => b.impact_score - a.impact_score) +} + +// 保存评估结果 +Bash(`mkdir -p "${sessionFolder}/assessment"`) +Write(`${sessionFolder}/assessment/priority-matrix.json`, JSON.stringify(priorityMatrix, null, 2)) + +// 更新 shared memory +sharedMemory.priority_matrix = priorityMatrix.summary +sharedMemory.debt_inventory = evaluatedItems +Write(`${sessionFolder}/shared-memory.json`, JSON.stringify(sharedMemory, null, 2)) +``` + +### Phase 5: Report to Coordinator + +```javascript +const summaryText = Object.entries(priorityMatrix.summary) + .map(([q, c]) => `${q}: ${c}`) + .join(', ') + +mcp__ccw-tools__team_msg({ + operation: "log", + team: teamName, + from: "assessor", + to: "coordinator", + type: "assessment_complete", + summary: `[assessor] 评估完成: ${summaryText}`, + ref: `${sessionFolder}/assessment/priority-matrix.json` +}) + +SendMessage({ + type: "message", + recipient: "coordinator", + content: `## [assessor] Assessment Results + +**Task**: ${task.subject} +**Total Items**: ${evaluatedItems.length} + +### Priority Matrix +| Quadrant | Count | Description | +|----------|-------|-------------| +| Quick-Win | ${priorityMatrix.summary['quick-win']} | High impact, low cost | +| Strategic | ${priorityMatrix.summary['strategic']} | High impact, high cost | +| Backlog | ${priorityMatrix.summary['backlog']} | Low impact, low cost | +| Defer | ${priorityMatrix.summary['defer']} | Low impact, high cost | + +### Top Quick-Wins +${priorityMatrix.by_quadrant['quick-win'].slice(0, 5).map(i => `- **[${i.dimension}]** ${i.file} - ${i.description} (impact: ${i.impact_score}, cost: ${i.cost_score})`).join('\n')} + +### Priority Matrix +${sessionFolder}/assessment/priority-matrix.json`, + summary: `[assessor] TDEVAL complete: ${summaryText}` +}) + +TaskUpdate({ taskId: task.id, status: 'completed' }) + +const nextTasks = TaskList().filter(t => + t.subject.startsWith('TDEVAL-') && t.owner === 'assessor' && + t.status === 'pending' && t.blockedBy.length === 0 +) +if (nextTasks.length > 0) { /* back to Phase 1 */ } +``` + +## Error Handling + +| Scenario | Resolution | +|----------|------------| +| No TDEVAL-* tasks available | Idle, wait for coordinator | +| Debt inventory empty | Report empty assessment, notify coordinator | +| Shared memory corrupted | Re-read from debt-inventory.json file | +| CLI analysis fails | Fall back to severity-based heuristic scoring | +| Too many items (>200) | Batch-evaluate top 50 critical/high first | diff --git a/.claude/skills/team-tech-debt/roles/coordinator/commands/dispatch.md b/.claude/skills/team-tech-debt/roles/coordinator/commands/dispatch.md new file mode 100644 index 00000000..ab2f6eec --- /dev/null +++ b/.claude/skills/team-tech-debt/roles/coordinator/commands/dispatch.md @@ -0,0 +1,157 @@ +# Command: dispatch + +> 任务链创建与依赖管理。根据 pipeline 模式创建技术债务治理任务链并分配给 worker 角色。 + +## When to Use + +- Phase 3 of Coordinator +- Pipeline 模式已确定,需要创建任务链 +- 团队已创建,worker 已 spawn + +**Trigger conditions**: +- Coordinator Phase 2 完成后 +- 模式切换需要重建任务链 +- Fix-Verify 循环需要创建修复任务 + +## Strategy + +### Delegation Mode + +**Mode**: Direct(coordinator 直接操作 TaskCreate/TaskUpdate) + +### Decision Logic + +```javascript +// 根据 pipelineMode 选择 pipeline +function buildPipeline(pipelineMode, sessionFolder, taskDescription) { + const pipelines = { + 'scan': [ + { prefix: 'TDSCAN', owner: 'scanner', desc: '多维度技术债务扫描', blockedBy: [] }, + { prefix: 'TDEVAL', owner: 'assessor', desc: '量化评估与优先级排序', blockedBy: ['TDSCAN'] } + ], + 'remediate': [ + { prefix: 'TDSCAN', owner: 'scanner', desc: '多维度技术债务扫描', blockedBy: [] }, + { prefix: 'TDEVAL', owner: 'assessor', desc: '量化评估与优先级排序', blockedBy: ['TDSCAN'] }, + { prefix: 'TDPLAN', owner: 'planner', desc: '分阶段治理方案规划', blockedBy: ['TDEVAL'] }, + { prefix: 'TDFIX', owner: 'executor', desc: '债务清理执行', blockedBy: ['TDPLAN'] }, + { prefix: 'TDVAL', owner: 'validator', desc: '清理结果验证', blockedBy: ['TDFIX'] } + ], + 'targeted': [ + { prefix: 'TDPLAN', owner: 'planner', desc: '定向修复方案规划', blockedBy: [] }, + { prefix: 'TDFIX', owner: 'executor', desc: '债务清理执行', blockedBy: ['TDPLAN'] }, + { prefix: 'TDVAL', owner: 'validator', desc: '清理结果验证', blockedBy: ['TDFIX'] } + ] + } + return pipelines[pipelineMode] || pipelines['scan'] +} +``` + +## Execution Steps + +### Step 1: Context Preparation + +```javascript +const pipeline = buildPipeline(pipelineMode, sessionFolder, taskDescription) +``` + +### Step 2: Execute Strategy + +```javascript +const taskIds = {} + +for (const stage of pipeline) { + // 构建任务描述(包含 session 和上下文信息) + const fullDesc = [ + stage.desc, + `\nsession: ${sessionFolder}`, + `\n\n目标: ${taskDescription}` + ].join('') + + // 创建任务 + TaskCreate({ + subject: `${stage.prefix}-001: ${stage.desc}`, + description: fullDesc, + activeForm: `${stage.desc}进行中` + }) + + // 记录任务 ID + const allTasks = TaskList() + const newTask = allTasks.find(t => t.subject.startsWith(`${stage.prefix}-001`)) + taskIds[stage.prefix] = newTask.id + + // 设置 owner 和依赖 + const blockedByIds = stage.blockedBy + .map(dep => taskIds[dep]) + .filter(Boolean) + + TaskUpdate({ + taskId: newTask.id, + owner: stage.owner, + addBlockedBy: blockedByIds + }) +} +``` + +### Step 3: Result Processing + +```javascript +// 验证任务链 +const allTasks = TaskList() +const chainTasks = pipeline.map(s => taskIds[s.prefix]).filter(Boolean) +const chainValid = chainTasks.length === pipeline.length + +if (!chainValid) { + mcp__ccw-tools__team_msg({ + operation: "log", team: teamName, from: "coordinator", + to: "user", type: "error", + summary: `[coordinator] 任务链创建不完整: ${chainTasks.length}/${pipeline.length}` + }) +} +``` + +## Fix-Verify Loop Task Creation + +当 validator 报告回归问题时,coordinator 调用此逻辑追加任务: + +```javascript +function createFixVerifyTasks(fixVerifyIteration, sessionFolder) { + // 创建修复任务 + TaskCreate({ + subject: `TDFIX-fix-${fixVerifyIteration}: 修复回归问题 (Fix-Verify #${fixVerifyIteration})`, + description: `修复验证发现的回归问题\nsession: ${sessionFolder}\ntype: fix-verify`, + activeForm: `Fix-Verify #${fixVerifyIteration} 修复中` + }) + + // 创建重新验证任务 + TaskCreate({ + subject: `TDVAL-verify-${fixVerifyIteration}: 重新验证 (Fix-Verify #${fixVerifyIteration})`, + description: `重新验证修复结果\nsession: ${sessionFolder}`, + activeForm: `Fix-Verify #${fixVerifyIteration} 验证中` + }) + + // 设置依赖: TDVAL-verify 依赖 TDFIX-fix + // ... TaskUpdate addBlockedBy +} +``` + +## Output Format + +``` +## Task Chain Created + +### Mode: [scan|remediate|targeted] +### Pipeline Stages: [count] +- [prefix]-001: [description] (owner: [role], blocked by: [deps]) + +### Verification: PASS/FAIL +``` + +## Error Handling + +| Scenario | Resolution | +|----------|------------| +| Task creation fails | Retry once, then report to user | +| Dependency cycle detected | Flatten dependencies, warn coordinator | +| Invalid pipelineMode | Default to 'scan' mode | +| Agent/CLI failure | Retry once, then fallback to inline execution | +| Timeout (>5 min) | Report partial results, notify coordinator | diff --git a/.claude/skills/team-tech-debt/roles/coordinator/commands/monitor.md b/.claude/skills/team-tech-debt/roles/coordinator/commands/monitor.md new file mode 100644 index 00000000..4edc8f9a --- /dev/null +++ b/.claude/skills/team-tech-debt/roles/coordinator/commands/monitor.md @@ -0,0 +1,255 @@ +# Command: monitor + +> 阶段驱动的协调循环。按 pipeline 阶段顺序等待 worker 完成,路由消息,处理 Fix-Verify 循环,检测完成。 + +## When to Use + +- Phase 4 of Coordinator +- 任务链已创建并分发 +- 需要持续监控直到所有任务完成 + +**Trigger conditions**: +- dispatch 完成后立即启动 +- Fix-Verify 循环创建新任务后重新进入 + +## Strategy + +### Delegation Mode + +**Mode**: Stage-driven(按阶段顺序等待,非轮询) + +### 设计原则 + +> **模型执行没有时间概念**。禁止空转 while 循环检查状态。 +> 使用固定 sleep 间隔 + 最大轮询次数,避免无意义的 API 调用浪费。 + +### Decision Logic + +```javascript +// 消息路由表 +const routingTable = { + // Scanner 完成 + 'scan_complete': { action: 'Mark TDSCAN complete, unblock TDEVAL' }, + 'debt_items_found': { action: 'Mark TDSCAN complete with items, unblock TDEVAL' }, + // Assessor 完成 + 'assessment_complete': { action: 'Mark TDEVAL complete, unblock TDPLAN' }, + // Planner 完成 + 'plan_ready': { action: 'Mark TDPLAN complete, unblock TDFIX' }, + 'plan_revision': { action: 'Plan revised, re-evaluate dependencies' }, + // Executor 完成 + 'fix_complete': { action: 'Mark TDFIX complete, unblock TDVAL' }, + 'fix_progress': { action: 'Log progress, continue waiting' }, + // Validator 完成 + 'validation_complete': { action: 'Mark TDVAL complete, evaluate quality gate', special: 'quality_gate' }, + 'regression_found': { action: 'Evaluate regression, decide Fix-Verify loop', special: 'fix_verify_decision' }, + // 错误 + 'error': { action: 'Assess severity, retry or escalate', special: 'error_handler' } +} +``` + +### 等待策略常量 + +```javascript +const POLL_INTERVAL_SEC = 300 // 每次检查间隔 5 分钟 +const MAX_POLLS_PER_STAGE = 6 // 单阶段最多等待 6 次(~30 分钟) +const SLEEP_CMD = process.platform === 'win32' + ? `timeout /t ${POLL_INTERVAL_SEC} /nobreak >nul 2>&1` + : `sleep ${POLL_INTERVAL_SEC}` + +// 统一 auto mode 检测 +const autoYes = /\b(-y|--yes)\b/.test(args) +``` + +## Execution Steps + +### Step 1: Context Preparation + +```javascript +// 从 shared memory 获取上下文 +const sharedMemory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`)) + +let fixVerifyIteration = 0 +const MAX_FIX_VERIFY_ITERATIONS = 3 + +// 获取 pipeline 阶段列表 +const allTasks = TaskList() +const pipelineTasks = allTasks + .filter(t => t.owner && t.owner !== 'coordinator') + .sort((a, b) => Number(a.id) - Number(b.id)) +``` + +### Step 2: Stage-Driven Execution + +> **核心**: 按 pipeline 阶段顺序,逐阶段等待完成。 +> 每个阶段:sleep → 检查消息 → 确认任务状态 → 处理结果 → 下一阶段。 + +```javascript +for (const stageTask of pipelineTasks) { + let stageComplete = false + let pollCount = 0 + + while (!stageComplete && pollCount < MAX_POLLS_PER_STAGE) { + Bash(SLEEP_CMD) + pollCount++ + + // 1. 检查消息总线 + const messages = mcp__ccw-tools__team_msg({ + operation: "list", + team: teamName, + last: 5 + }) + + // 2. 路由消息 + for (const msg of messages) { + const handler = routingTable[msg.type] + if (!handler) continue + processMessage(msg, handler) + } + + // 3. 确认任务状态 + const currentTask = TaskGet({ taskId: stageTask.id }) + stageComplete = currentTask.status === 'completed' || currentTask.status === 'deleted' + } + + // 阶段超时处理 + if (!stageComplete) { + const elapsedMin = Math.round(pollCount * POLL_INTERVAL_SEC / 60) + + if (autoYes) { + mcp__ccw-tools__team_msg({ + operation: "log", team: teamName, from: "coordinator", + to: "user", type: "error", + summary: `[coordinator] [auto] 阶段 ${stageTask.subject} 超时 (${elapsedMin}min),自动跳过` + }) + TaskUpdate({ taskId: stageTask.id, status: 'deleted' }) + continue + } + + const decision = AskUserQuestion({ + questions: [{ + question: `阶段 "${stageTask.subject}" 已等待 ${elapsedMin} 分钟仍未完成。如何处理?`, + header: "Stage Wait", + multiSelect: false, + options: [ + { label: "继续等待", description: `再等 ${MAX_POLLS_PER_STAGE} 轮` }, + { label: "跳过此阶段", description: "标记为跳过,继续后续流水线" }, + { label: "终止流水线", description: "停止整个流程,汇报当前结果" } + ] + }] + }) + + const answer = decision["Stage Wait"] + if (answer === "跳过此阶段") { + TaskUpdate({ taskId: stageTask.id, status: 'deleted' }) + continue + } else if (answer === "终止流水线") { + mcp__ccw-tools__team_msg({ + operation: "log", team: teamName, from: "coordinator", + to: "user", type: "shutdown", + summary: `[coordinator] 用户终止流水线,当前阶段: ${stageTask.subject}` + }) + break + } + } +} +``` + +### Step 2.1: Message Processing (processMessage) + +```javascript +function processMessage(msg, handler) { + switch (handler.special) { + case 'quality_gate': { + const latestMemory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`)) + const debtBefore = latestMemory.debt_score_before || 0 + const debtAfter = latestMemory.debt_score_after || 0 + const improved = debtAfter < debtBefore + + let status = 'PASS' + if (!improved && latestMemory.validation_results?.regressions > 0) status = 'FAIL' + else if (!improved) status = 'CONDITIONAL' + + mcp__ccw-tools__team_msg({ + operation: "log", team: teamName, from: "coordinator", + to: "user", type: "quality_gate", + summary: `[coordinator] 质量门控: ${status} (债务分 ${debtBefore} → ${debtAfter})` + }) + break + } + + case 'fix_verify_decision': { + const regressions = msg.data?.regressions || 0 + if (regressions > 0 && fixVerifyIteration < MAX_FIX_VERIFY_ITERATIONS) { + fixVerifyIteration++ + mcp__ccw-tools__team_msg({ + operation: "log", team: teamName, from: "coordinator", + to: "executor", type: "task_unblocked", + summary: `[coordinator] Fix-Verify #${fixVerifyIteration}: 发现 ${regressions} 个回归,请修复`, + data: { iteration: fixVerifyIteration, regressions } + }) + // 创建 Fix-Verify 修复任务(参见 dispatch.md createFixVerifyTasks) + } else { + mcp__ccw-tools__team_msg({ + operation: "log", team: teamName, from: "coordinator", + to: "user", type: "quality_gate", + summary: `[coordinator] Fix-Verify 循环已达上限(${MAX_FIX_VERIFY_ITERATIONS}),接受当前结果` + }) + } + break + } + + case 'error_handler': { + const severity = msg.data?.severity || 'medium' + if (severity === 'critical') { + SendMessage({ + content: `## [coordinator] Critical Error from ${msg.from}\n\n${msg.summary}`, + summary: `[coordinator] Critical error: ${msg.summary}` + }) + } + break + } + } +} +``` + +### Step 3: Result Processing + +```javascript +// 汇总所有结果 +const finalSharedMemory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`)) +const allFinalTasks = TaskList() +const workerTasks = allFinalTasks.filter(t => t.owner && t.owner !== 'coordinator') +const summary = { + total_tasks: workerTasks.length, + completed_tasks: workerTasks.filter(t => t.status === 'completed').length, + fix_verify_iterations: fixVerifyIteration, + debt_score_before: finalSharedMemory.debt_score_before, + debt_score_after: finalSharedMemory.debt_score_after +} +``` + +## Output Format + +``` +## Coordination Summary + +### Pipeline Status: COMPLETE +### Tasks: [completed]/[total] +### Fix-Verify Iterations: [count] +### Debt Score: [before] → [after] + +### Message Log (last 10) +- [timestamp] [from] → [to]: [type] - [summary] +``` + +## Error Handling + +| Scenario | Resolution | +|----------|------------| +| Message bus unavailable | Fall back to TaskList polling only | +| Stage timeout (交互模式) | AskUserQuestion: 继续等待 / 跳过 / 终止 | +| Stage timeout (自动模式 `-y`/`--yes`) | 自动跳过,记录日志 | +| Teammate unresponsive (2x no response) | Respawn teammate with same task | +| Deadlock detected | Identify cycle, manually unblock | +| Quality gate FAIL | Report to user, suggest targeted re-run | +| Fix-Verify loop stuck >3 iterations | Accept current state, continue pipeline | diff --git a/.claude/skills/team-tech-debt/roles/coordinator/role.md b/.claude/skills/team-tech-debt/roles/coordinator/role.md new file mode 100644 index 00000000..3e9fe499 --- /dev/null +++ b/.claude/skills/team-tech-debt/roles/coordinator/role.md @@ -0,0 +1,264 @@ +# Role: coordinator + +技术债务治理团队协调者。编排 pipeline:需求澄清 → 模式选择(scan/remediate/targeted) → 团队创建 → 任务分发 → 监控协调 → Fix-Verify 循环 → 债务消减报告。 + +## Role Identity + +- **Name**: `coordinator` +- **Task Prefix**: N/A (coordinator creates tasks, doesn't receive them) +- **Responsibility**: Orchestration +- **Communication**: SendMessage to all teammates +- **Output Tag**: `[coordinator]` + +## Role Boundaries + +### MUST + +- 所有输出(SendMessage、team_msg、日志)必须带 `[coordinator]` 标识 +- 仅负责需求澄清、模式选择、任务创建/分发、进度监控、质量门控、结果汇报 +- 通过 TaskCreate 创建任务并分配给 worker 角色 +- 通过消息总线监控 worker 进度并路由消息 + +### MUST NOT + +- 直接执行任何业务任务(扫描、评估、规划、修复、验证等) +- 直接调用 cli-explore-agent、code-developer 等实现类 subagent +- 直接修改源代码或生成产物文件 +- 绕过 worker 角色自行完成应委派的工作 +- 在输出中省略 `[coordinator]` 标识 + +> **核心原则**: coordinator 是指挥者,不是执行者。所有实际工作必须通过 TaskCreate 委派给 worker 角色。 + +## Message Types + +| Type | Direction | Trigger | Description | +|------|-----------|---------|-------------| +| `mode_selected` | coordinator → all | 模式确定 | scan/remediate/targeted | +| `quality_gate` | coordinator → user | 质量评估 | 通过/不通过/有条件通过 | +| `task_unblocked` | coordinator → worker | 依赖解除 | 任务可执行 | +| `error` | coordinator → user | 协调错误 | 阻塞性问题 | +| `shutdown` | coordinator → all | 团队关闭 | 清理资源 | + +## Message Bus + +每次 SendMessage 前,先调用 `mcp__ccw-tools__team_msg` 记录: + +```javascript +mcp__ccw-tools__team_msg({ + operation: "log", + team: teamName, + from: "coordinator", + to: "user", + type: "mode_selected", + summary: "[coordinator] 模式已选择: remediate" +}) +``` + +### CLI 回退 + +若 `mcp__ccw-tools__team_msg` 不可用,使用 Bash 写入日志文件: + +```javascript +Bash(`echo '${JSON.stringify({ from: "coordinator", to: "user", type: "mode_selected", summary: msg, ts: new Date().toISOString() })}' >> "${sessionFolder}/message-log.jsonl"`) +``` + +## Toolbox + +### Available Commands + +| Command | File | Phase | Description | +|---------|------|-------|-------------| +| `dispatch` | [commands/dispatch.md](commands/dispatch.md) | Phase 3 | 任务链创建与依赖管理 | +| `monitor` | [commands/monitor.md](commands/monitor.md) | Phase 4 | 消息总线轮询与协调循环 | + +### Subagent Capabilities + +> Coordinator 不直接使用 subagent(通过 worker 角色间接使用) + +### CLI Capabilities + +> Coordinator 不直接使用 CLI 分析工具 + +## Execution (5-Phase) + +### Phase 1: Parse Arguments & Mode Detection + +```javascript +const args = "$ARGUMENTS" + +// 提取任务描述 +const taskDescription = args.replace(/--role[=\s]+\w+/, '').replace(/--team[=\s]+[\w-]+/, '').replace(/--mode[=\s]+\w+/, '').trim() + +// Three-Mode 检测 +function detectMode(args, desc) { + const modeMatch = args.match(/--mode[=\s]+(scan|remediate|targeted)/) + if (modeMatch) return modeMatch[1] + if (/扫描|scan|审计|audit|评估|assess/.test(desc)) return 'scan' + if (/定向|targeted|指定|specific|修复.*已知/.test(desc)) return 'targeted' + return 'remediate' +} + +let pipelineMode = detectMode(args, taskDescription) + +// 统一 auto mode 检测 +const autoYes = /\b(-y|--yes)\b/.test(args) + +// 简单任务可跳过确认(auto 模式跳过) +if (!autoYes && (!taskDescription || taskDescription.length < 10)) { + const clarification = AskUserQuestion({ + questions: [{ + question: "请描述技术债务治理目标(哪些模块?关注哪些维度?)", + header: "Tech Debt Target", + multiSelect: false, + options: [ + { label: "自定义", description: "输入具体描述" }, + { label: "全项目扫描", description: "多维度扫描并评估技术债务" }, + { label: "完整治理", description: "扫描+评估+规划+修复+验证闭环" }, + { label: "定向修复", description: "针对已知债务项进行修复" } + ] + }] + }) +} +``` + +### Phase 2: Create Team + Spawn Teammates + +```javascript +const teamName = "tech-debt" +const sessionSlug = taskDescription.slice(0, 30).replace(/[^a-zA-Z0-9\u4e00-\u9fa5]/g, '-') +const sessionDate = new Date().toISOString().slice(0, 10) +const sessionFolder = `.workflow/.team/TD-${sessionSlug}-${sessionDate}` +Bash(`mkdir -p "${sessionFolder}/scan" "${sessionFolder}/assessment" "${sessionFolder}/plan" "${sessionFolder}/fixes" "${sessionFolder}/validation"`) + +// 初始化 shared memory +Write(`${sessionFolder}/shared-memory.json`, JSON.stringify({ + debt_inventory: [], + priority_matrix: {}, + remediation_plan: {}, + fix_results: {}, + validation_results: {}, + debt_score_before: null, + debt_score_after: null +}, null, 2)) + +TeamCreate({ team_name: teamName }) + +// Spawn teammates (see SKILL.md Coordinator Spawn Template) +// Scanner, Assessor, Planner, Executor, Validator +``` + +### Phase 3: Create Task Chain + +根据 pipelineMode 创建不同的任务链: + +```javascript +// Read commands/dispatch.md for full implementation +Read("commands/dispatch.md") +``` + +**Scan Mode**: +``` +TDSCAN-001(多维度扫描) → TDEVAL-001(量化评估) +``` + +**Remediate Mode**: +``` +TDSCAN-001(扫描) → TDEVAL-001(评估) → TDPLAN-001(规划) → TDFIX-001(修复) → TDVAL-001(验证) +``` + +**Targeted Mode**: +``` +TDPLAN-001(规划) → TDFIX-001(修复) → TDVAL-001(验证) +``` + +### Phase 4: Coordination Loop + +```javascript +// Read commands/monitor.md for full implementation +Read("commands/monitor.md") +``` + +| Received Message | Action | +|-----------------|--------| +| `scan_complete` | 标记 TDSCAN complete → 解锁 TDEVAL | +| `assessment_complete` | 标记 TDEVAL complete → 解锁 TDPLAN | +| `plan_ready` | 标记 TDPLAN complete → 解锁 TDFIX | +| `fix_complete` | 标记 TDFIX complete → 解锁 TDVAL | +| `validation_complete` | 标记 TDVAL complete → 评估质量门控 | +| `regression_found` | 评估回归 → 触发 Fix-Verify 循环(max 3) | +| Worker: `error` | 评估严重性 → 重试或上报用户 | + +**Fix-Verify 循环逻辑**: +```javascript +if (regressionFound && fixVerifyIteration < 3) { + fixVerifyIteration++ + // 创建 TDFIX-fix 任务 → TDVAL 重新验证 +} else if (fixVerifyIteration >= 3) { + // 接受当前状态,继续汇报 + mcp__ccw-tools__team_msg({ + operation: "log", team: teamName, from: "coordinator", + to: "user", type: "quality_gate", + summary: `[coordinator] Fix-Verify 循环已达上限(3次),接受当前结果` + }) +} +``` + +### Phase 5: Report + Debt Reduction Metrics + +```javascript +// 读取 shared memory 汇总结果 +const memory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`)) + +const report = { + mode: pipelineMode, + debt_items_found: memory.debt_inventory?.length || 0, + debt_score_before: memory.debt_score_before || 'N/A', + debt_score_after: memory.debt_score_after || 'N/A', + items_fixed: memory.fix_results?.items_fixed || 0, + items_remaining: memory.fix_results?.items_remaining || 0, + validation_passed: memory.validation_results?.passed || false, + regressions: memory.validation_results?.regressions || 0 +} + +// 计算债务消减率 +const reductionRate = report.debt_items_found > 0 + ? Math.round((report.items_fixed / report.debt_items_found) * 100) + : 0 + +mcp__ccw-tools__team_msg({ + operation: "log", team: teamName, from: "coordinator", + to: "user", type: "quality_gate", + summary: `[coordinator] 技术债务治理完成: ${report.debt_items_found}项债务, 修复${report.items_fixed}项, 消减率${reductionRate}%` +}) + +SendMessage({ + content: `## [coordinator] Tech Debt Report\n\n${JSON.stringify(report, null, 2)}`, + summary: `[coordinator] Debt reduction: ${reductionRate}%` +}) + +// 询问下一步(auto 模式跳过,默认关闭团队) +if (!autoYes) { + AskUserQuestion({ + questions: [{ + question: "技术债务治理流程已完成。下一步:", + header: "Next", + multiSelect: false, + options: [ + { label: "新目标", description: "对新模块/维度执行债务治理" }, + { label: "深度修复", description: "对剩余高优先级债务继续修复" }, + { label: "关闭团队", description: "关闭所有 teammate 并清理" } + ] + }] + }) +} +``` + +## Error Handling + +| Scenario | Resolution | +|----------|------------| +| Teammate unresponsive | Send follow-up, 2x → respawn | +| Scanner finds no debt | Report clean codebase, skip to summary | +| Fix-Verify loop stuck >3 iterations | Accept current state, continue pipeline | +| Build/test environment broken | Notify user, suggest manual fix | +| All tasks completed but debt_score_after > debt_score_before | Report with WARNING, suggest re-run | diff --git a/.claude/skills/team-tech-debt/roles/executor/commands/remediate.md b/.claude/skills/team-tech-debt/roles/executor/commands/remediate.md new file mode 100644 index 00000000..f8a6dad8 --- /dev/null +++ b/.claude/skills/team-tech-debt/roles/executor/commands/remediate.md @@ -0,0 +1,176 @@ +# Command: remediate + +> 分批委派 code-developer 执行债务清理。按修复类型分组(重构、死代码移除、依赖更新、文档补充),每批委派给 code-developer。 + +## When to Use + +- Phase 3 of Executor +- 治理方案已加载,修复 actions 已分批 +- 需要通过 code-developer 执行代码修改 + +**Trigger conditions**: +- TDFIX-* 任务进入 Phase 3 +- 修复 actions 列表非空 +- 目标文件可访问 + +## Strategy + +### Delegation Mode + +**Mode**: Sequential Batch Delegation +**Subagent**: `code-developer` +**Batch Strategy**: 按修复类型分组,每组一个委派 + +### Decision Logic + +```javascript +// 分批策略 +const batchOrder = ['refactor', 'update-deps', 'add-tests', 'add-docs', 'restructure'] + +// 按优先级排序批次 +function sortBatches(batches) { + const sorted = {} + for (const type of batchOrder) { + if (batches[type]) sorted[type] = batches[type] + } + // 追加未知类型 + for (const [type, actions] of Object.entries(batches)) { + if (!sorted[type]) sorted[type] = actions + } + return sorted +} +``` + +## Execution Steps + +### Step 1: Context Preparation + +```javascript +// 按类型分组并排序 +const sortedBatches = sortBatches(batches) + +// 每批最大 items 数 +const MAX_ITEMS_PER_BATCH = 10 + +// 如果单批过大,进一步拆分 +function splitLargeBatches(batches) { + const result = {} + for (const [type, actions] of Object.entries(batches)) { + if (actions.length <= MAX_ITEMS_PER_BATCH) { + result[type] = actions + } else { + for (let i = 0; i < actions.length; i += MAX_ITEMS_PER_BATCH) { + const chunk = actions.slice(i, i + MAX_ITEMS_PER_BATCH) + result[`${type}-${Math.floor(i / MAX_ITEMS_PER_BATCH) + 1}`] = chunk + } + } + } + return result +} + +const finalBatches = splitLargeBatches(sortedBatches) +``` + +### Step 2: Execute Strategy + +```javascript +for (const [batchName, actions] of Object.entries(finalBatches)) { + // 构建修复上下文 + const batchType = batchName.replace(/-\d+$/, '') + const fileList = actions.map(a => a.file).filter(Boolean) + + // 根据类型选择修复提示 + const typePrompts = { + 'refactor': `Refactor the following code to reduce complexity and improve readability. Preserve all existing behavior.`, + 'update-deps': `Update the specified dependencies. Check for breaking changes in changelogs.`, + 'add-tests': `Add missing test coverage for the specified modules. Follow existing test patterns.`, + 'add-docs': `Add documentation (JSDoc/docstrings) for the specified public APIs. Follow existing doc style.`, + 'restructure': `Restructure module boundaries to reduce coupling. Move code to appropriate locations.` + } + + const prompt = typePrompts[batchType] || 'Apply the specified fix to resolve technical debt.' + + // 委派给 code-developer + Task({ + subagent_type: "code-developer", + run_in_background: false, + description: `Tech debt cleanup: ${batchName} (${actions.length} items)`, + prompt: `## Goal +${prompt} + +## Items to Fix +${actions.map(a => `### ${a.debt_id}: ${a.action} +- File: ${a.file || 'N/A'} +- Type: ${a.type} +${a.steps ? '- Steps:\n' + a.steps.map(s => ` 1. ${s}`).join('\n') : ''}`).join('\n\n')} + +## Constraints +- Read each file BEFORE modifying +- Make minimal changes - fix only the specified debt item +- Preserve backward compatibility +- Do NOT skip tests or add @ts-ignore +- Do NOT introduce new dependencies unless explicitly required +- Run syntax check after modifications + +## Files to Read First +${fileList.map(f => `- ${f}`).join('\n')}` + }) + + // 验证批次结果 + const batchResult = { + batch: batchName, + items: actions.length, + status: 'completed' + } + + // 检查文件是否被修改 + for (const file of fileList) { + const modified = Bash(`git diff --name-only -- "${file}" 2>/dev/null`).trim() + if (modified) { + fixResults.files_modified.push(file) + } + } +} +``` + +### Step 3: Result Processing + +```javascript +// 统计修复结果 +const totalActions = Object.values(finalBatches).flat().length +fixResults.items_fixed = fixResults.files_modified.length +fixResults.items_failed = totalActions - fixResults.items_fixed +fixResults.items_remaining = fixResults.items_failed + +// 生成修复摘要 +const batchSummaries = Object.entries(finalBatches).map(([name, actions]) => + `- ${name}: ${actions.length} items` +).join('\n') +``` + +## Output Format + +``` +## Remediation Results + +### Batches Executed: [count] +### Items Fixed: [count]/[total] +### Files Modified: [count] + +### Batch Details +- [batch-name]: [count] items - [status] + +### Modified Files +- [file-path] +``` + +## Error Handling + +| Scenario | Resolution | +|----------|------------| +| code-developer fails on a batch | Retry once, mark failed items | +| File locked or read-only | Skip file, log error | +| Syntax error after fix | Revert with git checkout, mark as failed | +| New import/dependency needed | Add minimally, document in fix log | +| Batch too large (>10 items) | Auto-split into sub-batches | +| Agent timeout | Use partial results, continue next batch | diff --git a/.claude/skills/team-tech-debt/roles/executor/role.md b/.claude/skills/team-tech-debt/roles/executor/role.md new file mode 100644 index 00000000..7793f9cb --- /dev/null +++ b/.claude/skills/team-tech-debt/roles/executor/role.md @@ -0,0 +1,267 @@ +# 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` 记录: + +```javascript +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 写入日志文件: + +```javascript +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](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 + +```javascript +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 + +```javascript +const sessionFolder = task.description.match(/session:\s*(.+)/)?.[1]?.trim() || '.' +let sharedMemory = {} +try { sharedMemory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`)) } catch {} + +// 加载治理方案 +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 + +```javascript +// Read commands/remediate.md for full implementation +Read("commands/remediate.md") +``` + +**核心策略**: 分批委派 code-developer 执行修复 + +```javascript +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. + +## 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 + +```javascript +// 基本语法检查 +const syntaxResult = Bash(`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(`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 + +```javascript +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 | diff --git a/.claude/skills/team-tech-debt/roles/planner/commands/create-plan.md b/.claude/skills/team-tech-debt/roles/planner/commands/create-plan.md new file mode 100644 index 00000000..cb44f732 --- /dev/null +++ b/.claude/skills/team-tech-debt/roles/planner/commands/create-plan.md @@ -0,0 +1,165 @@ +# Command: create-plan + +> 使用 gemini CLI 创建结构化治理方案。将 quick-wins 归为立即执行,systematic 归为中期治理,识别预防机制用于长期改善。输出 remediation-plan.md。 + +## When to Use + +- Phase 3 of Planner +- 评估矩阵已就绪,需要创建治理方案 +- 债务项已按优先级象限分组 + +**Trigger conditions**: +- TDPLAN-* 任务进入 Phase 3 +- 评估数据可用(priority-matrix.json) +- 需要 CLI 辅助生成详细修复建议 + +## Strategy + +### Delegation Mode + +**Mode**: CLI Analysis + Template Generation +**CLI Tool**: `gemini` (primary) +**CLI Mode**: `analysis` + +### Decision Logic + +```javascript +// 方案生成策略 +if (quickWins.length + strategic.length <= 5) { + // 少量项目:内联生成方案 + mode = 'inline' +} else { + // 较多项目:CLI 辅助生成详细修复步骤 + mode = 'cli-assisted' +} +``` + +## Execution Steps + +### Step 1: Context Preparation + +```javascript +// 准备债务摘要供 CLI 分析 +const debtSummary = debtInventory + .filter(i => i.priority_quadrant === 'quick-win' || i.priority_quadrant === 'strategic') + .map(i => `[${i.id}] [${i.priority_quadrant}] [${i.dimension}] ${i.file}:${i.line} - ${i.description} (impact: ${i.impact_score}, cost: ${i.cost_score})`) + .join('\n') + +// 读取相关源文件获取上下文 +const affectedFiles = [...new Set(debtInventory.map(i => i.file).filter(Boolean))] +const fileContext = affectedFiles.slice(0, 20).map(f => `@${f}`).join(' ') +``` + +### Step 2: Execute Strategy + +```javascript +if (mode === 'inline') { + // 内联生成方案 + for (const item of quickWins) { + item.remediation_steps = [ + `Read ${item.file}`, + `Apply fix: ${item.suggestion || 'Resolve ' + item.description}`, + `Verify fix with relevant tests` + ] + } + for (const item of strategic) { + item.remediation_steps = [ + `Analyze impact scope of ${item.file}`, + `Plan refactoring: ${item.suggestion || 'Address ' + item.description}`, + `Implement changes incrementally`, + `Run full test suite to verify` + ] + } +} else { + // CLI 辅助生成修复方案 + const prompt = `PURPOSE: Create detailed remediation steps for each technical debt item, grouped into actionable phases +TASK: • For each quick-win item, generate specific fix steps (1-3 steps) • For each strategic item, generate a refactoring plan (3-5 steps) • Identify prevention mechanisms based on recurring patterns • Group related items that should be fixed together +MODE: analysis +CONTEXT: ${fileContext} +EXPECTED: Structured remediation plan with: phase name, items, steps per item, dependencies between fixes, estimated time per phase +CONSTRAINTS: Focus on backward-compatible changes, prefer incremental fixes over big-bang refactoring + +## Debt Items to Plan +${debtSummary} + +## Recurring Patterns +${[...new Set(debtInventory.map(i => i.dimension))].map(d => { + const count = debtInventory.filter(i => i.dimension === d).length + return `- ${d}: ${count} items` +}).join('\n')}` + + Bash(`ccw cli -p "${prompt}" --tool gemini --mode analysis --rule planning-breakdown-task-steps`, { + run_in_background: true + }) + + // 等待 CLI 完成,解析结果 +} +``` + +### Step 3: Result Processing + +```javascript +// 生成 Markdown 治理方案 +function generatePlanMarkdown(plan, validation) { + return `# Tech Debt Remediation Plan + +## Overview +- **Total Actions**: ${validation.total_actions} +- **Files Affected**: ${validation.files_affected.length} +- **Total Estimated Effort**: ${validation.total_effort} points + +## Phase 1: Quick Wins (Immediate) +> High impact, low cost items for immediate action. + +${plan.phases[0].actions.map((a, i) => `### ${i + 1}. ${a.debt_id}: ${a.action} +- **File**: ${a.file || 'N/A'} +- **Type**: ${a.type} +${a.steps ? a.steps.map(s => `- [ ] ${s}`).join('\n') : ''}`).join('\n\n')} + +## Phase 2: Systematic (Medium-term) +> High impact items requiring structured refactoring. + +${plan.phases[1].actions.map((a, i) => `### ${i + 1}. ${a.debt_id}: ${a.action} +- **File**: ${a.file || 'N/A'} +- **Type**: ${a.type} +${a.steps ? a.steps.map(s => `- [ ] ${s}`).join('\n') : ''}`).join('\n\n')} + +## Phase 3: Prevention (Long-term) +> Mechanisms to prevent future debt accumulation. + +${plan.phases[2].actions.map((a, i) => `### ${i + 1}. ${a.action} +- **Dimension**: ${a.dimension || 'general'} +- **Type**: ${a.type}`).join('\n\n')} + +## Execution Notes +- Execute Phase 1 first for maximum ROI +- Phase 2 items may require feature branches +- Phase 3 should be integrated into CI/CD pipeline +` +} +``` + +## Output Format + +``` +## Remediation Plan Created + +### Phases: 3 +### Quick Wins: [count] actions +### Systematic: [count] actions +### Prevention: [count] actions +### Files Affected: [count] + +### Output: [sessionFolder]/plan/remediation-plan.md +``` + +## Error Handling + +| Scenario | Resolution | +|----------|------------| +| CLI returns unstructured text | Parse manually, extract action items | +| No quick-wins available | Focus plan on systematic and prevention | +| File references invalid | Verify with Glob, skip non-existent files | +| CLI timeout | Generate plan from heuristic data only | +| Agent/CLI failure | Retry once, then inline generation | +| Timeout (>5 min) | Report partial plan, notify planner | diff --git a/.claude/skills/team-tech-debt/roles/planner/role.md b/.claude/skills/team-tech-debt/roles/planner/role.md new file mode 100644 index 00000000..5fd1e64c --- /dev/null +++ b/.claude/skills/team-tech-debt/roles/planner/role.md @@ -0,0 +1,287 @@ +# Role: planner + +技术债务治理方案规划师。基于评估矩阵创建分阶段治理方案:quick-wins 立即执行、systematic 中期系统治理、prevention 长期预防机制。产出 remediation-plan.md。 + +## Role Identity + +- **Name**: `planner` +- **Task Prefix**: `TDPLAN-*` +- **Responsibility**: Orchestration(治理规划) +- **Communication**: SendMessage to coordinator only +- **Output Tag**: `[planner]` + +## Role Boundaries + +### MUST + +- 仅处理 `TDPLAN-*` 前缀的任务 +- 所有输出必须带 `[planner]` 标识 +- 基于评估数据制定可行的治理方案 +- 更新 shared memory 中的 remediation_plan + +### MUST NOT + +- 修改源代码或测试代码 +- 执行修复操作 +- 为其他角色创建任务 +- 直接与其他 worker 通信 + +## Message Types + +| Type | Direction | Trigger | Description | +|------|-----------|---------|-------------| +| `plan_ready` | planner → coordinator | 方案完成 | 包含分阶段治理方案 | +| `plan_revision` | planner → coordinator | 方案修订 | 根据反馈调整方案 | +| `error` | planner → coordinator | 规划失败 | 阻塞性错误 | + +## Message Bus + +每次 SendMessage 前,先调用 `mcp__ccw-tools__team_msg` 记录: + +```javascript +mcp__ccw-tools__team_msg({ + operation: "log", + team: teamName, + from: "planner", + to: "coordinator", + type: "plan_ready", + summary: "[planner] 治理方案就绪: 3 phases, 12 quick-wins, 8 systematic" +}) +``` + +### CLI 回退 + +若 `mcp__ccw-tools__team_msg` 不可用,使用 Bash 写入日志文件: + +```javascript +Bash(`echo '${JSON.stringify({ from: "planner", to: "coordinator", type: "plan_ready", summary: msg, ts: new Date().toISOString() })}' >> "${sessionFolder}/message-log.jsonl"`) +``` + +## Toolbox + +### Available Commands + +| Command | File | Phase | Description | +|---------|------|-------|-------------| +| `create-plan` | [commands/create-plan.md](commands/create-plan.md) | Phase 3 | 分阶段治理方案生成 | + +### Subagent Capabilities + +| Agent Type | Used By | Purpose | +|------------|---------|---------| +| `cli-explore-agent` | create-plan.md | 代码库探索验证方案可行性 | + +### CLI Capabilities + +| CLI Tool | Mode | Used By | Purpose | +|----------|------|---------|---------| +| `gemini` | analysis | create-plan.md | 治理方案生成 | + +## Execution (5-Phase) + +### Phase 1: Task Discovery + +```javascript +const tasks = TaskList() +const myTasks = tasks.filter(t => + t.subject.startsWith('TDPLAN-') && + t.owner === 'planner' && + 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 Assessment Data + +```javascript +const sessionFolder = task.description.match(/session:\s*(.+)/)?.[1]?.trim() || '.' +let sharedMemory = {} +try { sharedMemory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`)) } catch {} + +const debtInventory = sharedMemory.debt_inventory || [] + +// 加载优先级矩阵 +let priorityMatrix = {} +try { + priorityMatrix = JSON.parse(Read(`${sessionFolder}/assessment/priority-matrix.json`)) +} catch {} + +// 分组 +const quickWins = debtInventory.filter(i => i.priority_quadrant === 'quick-win') +const strategic = debtInventory.filter(i => i.priority_quadrant === 'strategic') +const backlog = debtInventory.filter(i => i.priority_quadrant === 'backlog') +const deferred = debtInventory.filter(i => i.priority_quadrant === 'defer') +``` + +### Phase 3: Create Remediation Plan + +```javascript +// Read commands/create-plan.md for full implementation +Read("commands/create-plan.md") +``` + +**核心策略**: 3 阶段治理方案 + +```javascript +const plan = { + phases: [ + { + name: 'Quick Wins', + description: '高影响低成本项,立即执行', + items: quickWins, + estimated_effort: quickWins.reduce((s, i) => s + i.cost_score, 0), + actions: quickWins.map(i => ({ + debt_id: i.id, + action: i.suggestion || `Fix ${i.description}`, + file: i.file, + type: determineActionType(i) + })) + }, + { + name: 'Systematic', + description: '高影响高成本项,需系统规划', + items: strategic, + estimated_effort: strategic.reduce((s, i) => s + i.cost_score, 0), + actions: strategic.map(i => ({ + debt_id: i.id, + action: i.suggestion || `Refactor ${i.description}`, + file: i.file, + type: determineActionType(i) + })) + }, + { + name: 'Prevention', + description: '预防机制建设,长期生效', + items: [], + estimated_effort: 0, + actions: generatePreventionActions(debtInventory) + } + ] +} + +function determineActionType(item) { + const typeMap = { + 'code': 'refactor', + 'architecture': 'restructure', + 'testing': 'add-tests', + 'dependency': 'update-deps', + 'documentation': 'add-docs' + } + return typeMap[item.dimension] || 'refactor' +} + +function generatePreventionActions(inventory) { + const actions = [] + const dimensions = [...new Set(inventory.map(i => i.dimension))] + for (const dim of dimensions) { + const count = inventory.filter(i => i.dimension === dim).length + if (count >= 3) { + actions.push({ + action: getPreventionAction(dim), + type: 'prevention', + dimension: dim + }) + } + } + return actions +} + +function getPreventionAction(dimension) { + const prevention = { + 'code': 'Add linting rules for complexity thresholds and code smell detection', + 'architecture': 'Introduce module boundary checks in CI pipeline', + 'testing': 'Set minimum coverage thresholds in CI and add pre-commit test hooks', + 'dependency': 'Configure automated dependency update bot (Renovate/Dependabot)', + 'documentation': 'Add JSDoc/docstring enforcement in linting rules' + } + return prevention[dimension] || 'Add automated checks for this category' +} +``` + +### Phase 4: Validate Plan Feasibility + +```javascript +// 验证方案可行性 +const validation = { + total_actions: plan.phases.reduce((s, p) => s + p.actions.length, 0), + total_effort: plan.phases.reduce((s, p) => s + p.estimated_effort, 0), + files_affected: [...new Set(plan.phases.flatMap(p => p.actions.map(a => a.file)).filter(Boolean))], + has_quick_wins: quickWins.length > 0, + has_prevention: plan.phases[2].actions.length > 0 +} + +// 保存治理方案 +Bash(`mkdir -p "${sessionFolder}/plan"`) +Write(`${sessionFolder}/plan/remediation-plan.md`, generatePlanMarkdown(plan, validation)) +Write(`${sessionFolder}/plan/remediation-plan.json`, JSON.stringify(plan, null, 2)) + +// 更新 shared memory +sharedMemory.remediation_plan = { + phases: plan.phases.map(p => ({ name: p.name, action_count: p.actions.length, effort: p.estimated_effort })), + total_actions: validation.total_actions, + files_affected: validation.files_affected.length +} +Write(`${sessionFolder}/shared-memory.json`, JSON.stringify(sharedMemory, null, 2)) +``` + +### Phase 5: Report to Coordinator + +```javascript +const planSummary = plan.phases.map(p => `${p.name}: ${p.actions.length} actions`).join(', ') + +mcp__ccw-tools__team_msg({ + operation: "log", + team: teamName, + from: "planner", + to: "coordinator", + type: "plan_ready", + summary: `[planner] 治理方案就绪: ${planSummary}`, + ref: `${sessionFolder}/plan/remediation-plan.md` +}) + +SendMessage({ + type: "message", + recipient: "coordinator", + content: `## [planner] Remediation Plan + +**Task**: ${task.subject} +**Total Actions**: ${validation.total_actions} +**Files Affected**: ${validation.files_affected.length} + +### Phase 1: Quick Wins (${quickWins.length} items) +${quickWins.slice(0, 5).map(i => `- ${i.file} - ${i.description}`).join('\n')} + +### Phase 2: Systematic (${strategic.length} items) +${strategic.slice(0, 3).map(i => `- ${i.file} - ${i.description}`).join('\n')} + +### Phase 3: Prevention (${plan.phases[2].actions.length} items) +${plan.phases[2].actions.slice(0, 3).map(a => `- ${a.action}`).join('\n')} + +### Plan Document +${sessionFolder}/plan/remediation-plan.md`, + summary: `[planner] TDPLAN complete: ${planSummary}` +}) + +TaskUpdate({ taskId: task.id, status: 'completed' }) + +const nextTasks = TaskList().filter(t => + t.subject.startsWith('TDPLAN-') && t.owner === 'planner' && + t.status === 'pending' && t.blockedBy.length === 0 +) +if (nextTasks.length > 0) { /* back to Phase 1 */ } +``` + +## Error Handling + +| Scenario | Resolution | +|----------|------------| +| No TDPLAN-* tasks available | Idle, wait for coordinator | +| Assessment data empty | Create minimal plan based on debt inventory | +| No quick-wins found | Skip Phase 1, focus on systematic | +| CLI analysis fails | Fall back to heuristic plan generation | +| Too many items for single plan | Split into multiple phases with priorities | diff --git a/.claude/skills/team-tech-debt/roles/scanner/commands/scan-debt.md b/.claude/skills/team-tech-debt/roles/scanner/commands/scan-debt.md new file mode 100644 index 00000000..89770fa1 --- /dev/null +++ b/.claude/skills/team-tech-debt/roles/scanner/commands/scan-debt.md @@ -0,0 +1,198 @@ +# Command: scan-debt + +> 多维度 CLI Fan-out 技术债务扫描。从代码质量、架构、测试、依赖、文档 5 个维度并行分析代码,发现技术债务。 + +## When to Use + +- Phase 3 of Scanner +- 需要对代码库进行多维度技术债务扫描 +- 复杂度为 Medium 或 High 时使用 CLI Fan-out + +**Trigger conditions**: +- TDSCAN-* 任务进入 Phase 3 +- 复杂度评估为 Medium/High +- 需要深度分析超出 ACE 搜索能力 + +## Strategy + +### Delegation Mode + +**Mode**: CLI Fan-out +**CLI Tool**: `gemini` (primary) +**CLI Mode**: `analysis` +**Parallel Dimensions**: 3-5(根据复杂度) + +### Decision Logic + +```javascript +// 复杂度决定扫描策略 +if (complexity === 'Low') { + // ACE 搜索 + Grep 内联分析(不使用 CLI) + mode = 'inline' +} else if (complexity === 'Medium') { + // CLI Fan-out: 3 个核心维度 + mode = 'cli-fanout' + activeDimensions = ['code', 'testing', 'dependency'] +} else { + // CLI Fan-out: 所有 5 个维度 + mode = 'cli-fanout' + activeDimensions = dimensions +} +``` + +## Execution Steps + +### Step 1: Context Preparation + +```javascript +// 确定扫描范围 +const projectRoot = Bash(`git rev-parse --show-toplevel 2>/dev/null || pwd`).trim() +const scanScope = task.description.match(/scope:\s*(.+)/)?.[1] || '**/*' + +// 获取变更文件用于聚焦扫描 +const changedFiles = Bash(`git diff --name-only HEAD~10 2>/dev/null || echo ""`) + .split('\n').filter(Boolean) + +// 构建文件上下文 +const fileContext = changedFiles.length > 0 + ? changedFiles.map(f => `@${f}`).join(' ') + : `@${scanScope}` +``` + +### Step 2: Execute Strategy + +```javascript +if (mode === 'inline') { + // 快速内联扫描 + const aceResults = mcp__ace-tool__search_context({ + project_root_path: projectRoot, + query: "code smells, TODO/FIXME, deprecated APIs, complex functions, dead code, missing tests, circular imports" + }) + // 解析 ACE 结果并分类到维度 +} else { + // CLI Fan-out: 每个维度一个 CLI 调用 + const dimensionPrompts = { + 'code': `PURPOSE: Identify code quality debt - complexity, duplication, code smells +TASK: • Find functions with cyclomatic complexity > 10 • Detect code duplication (>20 lines) • Identify code smells (God class, long method, feature envy) • Find TODO/FIXME/HACK comments • Detect dead code and unused exports +MODE: analysis +CONTEXT: ${fileContext} +EXPECTED: List of findings with severity (critical/high/medium/low), file:line, description, estimated fix effort (small/medium/large) +CONSTRAINTS: Focus on actionable items, skip generated code`, + + 'architecture': `PURPOSE: Identify architecture debt - coupling, circular dependencies, layering violations +TASK: • Detect circular dependencies between modules • Find tight coupling between components • Identify layering violations (e.g., UI importing DB) • Check for God modules with too many responsibilities • Find missing abstraction layers +MODE: analysis +CONTEXT: ${fileContext} +EXPECTED: Architecture debt findings with severity, affected modules, dependency graph issues +CONSTRAINTS: Focus on structural issues, not style`, + + 'testing': `PURPOSE: Identify testing debt - coverage gaps, test quality, missing test types +TASK: • Find modules without any test files • Identify complex logic without test coverage • Check for test anti-patterns (flaky tests, hardcoded values) • Find missing edge case tests • Detect test files that import from test utilities incorrectly +MODE: analysis +CONTEXT: ${fileContext} +EXPECTED: Testing debt findings with severity, affected files, missing test type (unit/integration/e2e) +CONSTRAINTS: Focus on high-risk untested code paths`, + + 'dependency': `PURPOSE: Identify dependency debt - outdated packages, vulnerabilities, unnecessary deps +TASK: • Find outdated major-version dependencies • Identify known vulnerability packages • Detect unused dependencies • Find duplicate functionality from different packages • Check for pinned vs range versions +MODE: analysis +CONTEXT: @package.json @package-lock.json @requirements.txt @go.mod @pom.xml +EXPECTED: Dependency debt with severity, package name, current vs latest version, CVE references +CONSTRAINTS: Focus on security and compatibility risks`, + + 'documentation': `PURPOSE: Identify documentation debt - missing docs, stale docs, undocumented APIs +TASK: • Find public APIs without JSDoc/docstrings • Identify README files that are outdated • Check for missing architecture documentation • Find configuration options without documentation • Detect stale comments that don't match code +MODE: analysis +CONTEXT: ${fileContext} +EXPECTED: Documentation debt with severity, file:line, type (missing/stale/incomplete) +CONSTRAINTS: Focus on public interfaces and critical paths` + } + + for (const dimension of activeDimensions) { + const prompt = dimensionPrompts[dimension] + if (!prompt) continue + + Bash(`ccw cli -p "${prompt}" --tool gemini --mode analysis --rule analysis-analyze-code-patterns`, { + run_in_background: true + }) + } + + // 等待所有 CLI 完成(hook 回调通知) +} +``` + +### Step 3: Result Processing + +```javascript +// 聚合所有维度的结果 +const allFindings = [] + +// 从 CLI 输出解析结果 +for (const dimension of activeDimensions) { + const findings = parseCliOutput(cliResults[dimension]) + for (const finding of findings) { + finding.dimension = dimension + allFindings.push(finding) + } +} + +// 去重:相同 file:line 的发现合并 +function deduplicateFindings(findings) { + const seen = new Set() + const unique = [] + for (const f of findings) { + const key = `${f.file}:${f.line}:${f.dimension}` + if (!seen.has(key)) { + seen.add(key) + unique.push(f) + } + } + return unique +} + +const deduped = deduplicateFindings(allFindings) + +// 按严重性排序 +deduped.sort((a, b) => { + const order = { critical: 0, high: 1, medium: 2, low: 3 } + return (order[a.severity] || 3) - (order[b.severity] || 3) +}) +``` + +## Output Format + +``` +## Debt Scan Results + +### Dimensions Scanned: [list] +### Complexity: [Low|Medium|High] + +### Findings by Dimension +#### Code Quality ([count]) +- [file:line] [severity] - [description] + +#### Architecture ([count]) +- [module] [severity] - [description] + +#### Testing ([count]) +- [file:line] [severity] - [description] + +#### Dependency ([count]) +- [package] [severity] - [description] + +#### Documentation ([count]) +- [file:line] [severity] - [description] + +### Total Debt Items: [count] +``` + +## Error Handling + +| Scenario | Resolution | +|----------|------------| +| CLI tool unavailable | Fall back to ACE search + Grep inline analysis | +| CLI returns empty for a dimension | Note incomplete dimension, continue others | +| Too many findings (>100) | Prioritize critical/high, summarize medium/low | +| Timeout on CLI call | Use partial results, note incomplete dimensions | +| Agent/CLI failure | Retry once, then fallback to inline execution | +| Timeout (>5 min per dimension) | Report partial results, notify scanner | diff --git a/.claude/skills/team-tech-debt/roles/scanner/role.md b/.claude/skills/team-tech-debt/roles/scanner/role.md new file mode 100644 index 00000000..62589e0f --- /dev/null +++ b/.claude/skills/team-tech-debt/roles/scanner/role.md @@ -0,0 +1,258 @@ +# Role: scanner + +多维度技术债务扫描器。扫描代码库的 5 个维度:代码质量、架构、测试、依赖、文档,生成结构化债务清单。通过 CLI Fan-out 并行分析,产出 debt-inventory.json。 + +## Role Identity + +- **Name**: `scanner` +- **Task Prefix**: `TDSCAN-*` +- **Responsibility**: Orchestration(多维度扫描编排) +- **Communication**: SendMessage to coordinator only +- **Output Tag**: `[scanner]` + +## Role Boundaries + +### MUST + +- 仅处理 `TDSCAN-*` 前缀的任务 +- 所有输出必须带 `[scanner]` 标识 +- 仅通过 SendMessage 与 coordinator 通信 +- 严格在债务扫描职责范围内工作 + +### MUST NOT + +- 编写或修改代码 +- 执行修复操作 +- 为其他角色创建任务 +- 直接与其他 worker 通信 + +## Message Types + +| Type | Direction | Trigger | Description | +|------|-----------|---------|-------------| +| `scan_complete` | scanner → coordinator | 扫描完成 | 包含债务清单摘要 | +| `debt_items_found` | scanner → coordinator | 发现高优先级债务 | 需要关注的关键发现 | +| `error` | scanner → coordinator | 扫描失败 | 阻塞性错误 | + +## Message Bus + +每次 SendMessage 前,先调用 `mcp__ccw-tools__team_msg` 记录: + +```javascript +mcp__ccw-tools__team_msg({ + operation: "log", + team: teamName, + from: "scanner", + to: "coordinator", + type: "scan_complete", + summary: "[scanner] 多维度扫描完成: 42 项债务" +}) +``` + +### CLI 回退 + +若 `mcp__ccw-tools__team_msg` 不可用,使用 Bash 写入日志文件: + +```javascript +Bash(`echo '${JSON.stringify({ from: "scanner", to: "coordinator", type: "scan_complete", summary: msg, ts: new Date().toISOString() })}' >> "${sessionFolder}/message-log.jsonl"`) +``` + +## Toolbox + +### Available Commands + +| Command | File | Phase | Description | +|---------|------|-------|-------------| +| `scan-debt` | [commands/scan-debt.md](commands/scan-debt.md) | Phase 3 | 多维度 CLI Fan-out 扫描 | + +### Subagent Capabilities + +| Agent Type | Used By | Purpose | +|------------|---------|---------| +| `cli-explore-agent` | scan-debt.md | 代码库结构探索 | + +### CLI Capabilities + +| CLI Tool | Mode | Used By | Purpose | +|----------|------|---------|---------| +| `gemini` | analysis | scan-debt.md | 多维度代码分析 | + +## Execution (5-Phase) + +### Phase 1: Task Discovery + +```javascript +const tasks = TaskList() +const myTasks = tasks.filter(t => + t.subject.startsWith('TDSCAN-') && + t.owner === 'scanner' && + 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: Context Loading + +```javascript +// 确定扫描范围 +const scanScope = task.description.match(/scope:\s*(.+)/)?.[1] || '**/*' +const sessionFolder = task.description.match(/session:\s*(.+)/)?.[1]?.trim() || '.' + +// 读取 shared memory +let sharedMemory = {} +try { sharedMemory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`)) } catch {} + +// 检测项目类型和框架 +const projectRoot = Bash(`git rev-parse --show-toplevel 2>/dev/null || pwd`).trim() +const hasPackageJson = Bash(`test -f package.json && echo "yes" || echo "no"`).trim() === 'yes' +const hasPyProject = Bash(`test -f pyproject.toml -o -f requirements.txt && echo "yes" || echo "no"`).trim() === 'yes' +const hasGoMod = Bash(`test -f go.mod && echo "yes" || echo "no"`).trim() === 'yes' + +// 5 个扫描维度 +const dimensions = ["code", "architecture", "testing", "dependency", "documentation"] + +// 评估复杂度 +function assessComplexity(desc) { + let score = 0 + if (/全项目|全量|comprehensive|full/.test(desc)) score += 3 + if (/architecture|架构/.test(desc)) score += 1 + if (/multiple|across|cross|多模块/.test(desc)) score += 2 + return score >= 4 ? 'High' : score >= 2 ? 'Medium' : 'Low' +} +const complexity = assessComplexity(task.description) +``` + +### Phase 3: Multi-Dimension Scan + +```javascript +// Read commands/scan-debt.md for full CLI Fan-out implementation +Read("commands/scan-debt.md") +``` + +**核心策略**: 按维度并行执行 CLI 分析 + +```javascript +if (complexity === 'Low') { + // 直接使用 ACE 搜索 + Grep 进行快速扫描 + const aceResults = mcp__ace-tool__search_context({ + project_root_path: projectRoot, + query: "code smells, TODO/FIXME, deprecated APIs, complex functions, missing tests" + }) +} else { + // CLI Fan-out: 每个维度一个 CLI 调用 + for (const dimension of dimensions) { + Bash(`ccw cli -p "..." --tool gemini --mode analysis`, { run_in_background: true }) + } + // 等待所有 CLI 完成 +} +``` + +### Phase 4: Aggregate into Debt Inventory + +```javascript +// 聚合所有维度的发现 +const debtInventory = [] + +// 为每个发现项创建标准化条目 +for (const item of allFindings) { + debtInventory.push({ + id: `TD-${String(debtInventory.length + 1).padStart(3, '0')}`, + dimension: item.dimension, + severity: item.severity, + file: item.file, + line: item.line, + description: item.description, + suggestion: item.suggestion, + estimated_effort: item.effort || 'unknown' + }) +} + +// 更新 shared memory +sharedMemory.debt_inventory = debtInventory +sharedMemory.debt_score_before = debtInventory.length +Write(`${sessionFolder}/shared-memory.json`, JSON.stringify(sharedMemory, null, 2)) + +// 保存债务清单 +Write(`${sessionFolder}/scan/debt-inventory.json`, JSON.stringify({ + scan_date: new Date().toISOString(), + dimensions: dimensions, + total_items: debtInventory.length, + by_dimension: dimensions.reduce((acc, d) => { + acc[d] = debtInventory.filter(i => i.dimension === d).length + return acc + }, {}), + by_severity: { + critical: debtInventory.filter(i => i.severity === 'critical').length, + high: debtInventory.filter(i => i.severity === 'high').length, + medium: debtInventory.filter(i => i.severity === 'medium').length, + low: debtInventory.filter(i => i.severity === 'low').length + }, + items: debtInventory +}, null, 2)) +``` + +### Phase 5: Report to Coordinator + +```javascript +const resultSummary = `发现 ${debtInventory.length} 项技术债务(${dimensions.map(d => `${d}: ${debtInventory.filter(i => i.dimension === d).length}`).join(', ')})` + +mcp__ccw-tools__team_msg({ + operation: "log", + team: teamName, + from: "scanner", + to: "coordinator", + type: debtInventory.length > 0 ? "debt_items_found" : "scan_complete", + summary: `[scanner] ${resultSummary}`, + ref: `${sessionFolder}/scan/debt-inventory.json` +}) + +SendMessage({ + type: "message", + recipient: "coordinator", + content: `## [scanner] Debt Scan Results + +**Task**: ${task.subject} +**Dimensions**: ${dimensions.join(', ')} +**Status**: ${debtInventory.length > 0 ? 'Debt Found' : 'Clean'} + +### Summary +${resultSummary} + +### Top Debt Items +${debtInventory.filter(i => i.severity === 'critical' || i.severity === 'high').slice(0, 5).map(i => `- **[${i.severity}]** [${i.dimension}] ${i.file}:${i.line} - ${i.description}`).join('\n')} + +### Debt Inventory +${sessionFolder}/scan/debt-inventory.json`, + summary: `[scanner] TDSCAN complete: ${resultSummary}` +}) + +TaskUpdate({ taskId: task.id, status: 'completed' }) + +// Check for next task +const nextTasks = TaskList().filter(t => + t.subject.startsWith('TDSCAN-') && + t.owner === 'scanner' && + t.status === 'pending' && + t.blockedBy.length === 0 +) + +if (nextTasks.length > 0) { + // Continue with next task → back to Phase 1 +} +``` + +## Error Handling + +| Scenario | Resolution | +|----------|------------| +| No TDSCAN-* tasks available | Idle, wait for coordinator assignment | +| CLI tool unavailable | Fall back to ACE search + Grep inline analysis | +| Scan scope too broad | Narrow to src/ directory, report partial results | +| All dimensions return empty | Report clean scan, notify coordinator | +| CLI timeout | Use partial results, note incomplete dimensions | +| Critical issue beyond scope | SendMessage debt_items_found to coordinator | diff --git a/.claude/skills/team-tech-debt/roles/validator/commands/verify.md b/.claude/skills/team-tech-debt/roles/validator/commands/verify.md new file mode 100644 index 00000000..c068bd8e --- /dev/null +++ b/.claude/skills/team-tech-debt/roles/validator/commands/verify.md @@ -0,0 +1,199 @@ +# Command: verify + +> 回归测试与质量验证。运行测试套件、类型检查、lint、可选 CLI 质量分析。对比 debt_score_before vs debt_score_after 评估改善程度。 + +## When to Use + +- Phase 3 of Validator +- 修复操作已完成,需要验证结果 +- Fix-Verify 循环中的验证阶段 + +**Trigger conditions**: +- TDVAL-* 任务进入 Phase 3 +- 修复日志可用(fix-log.json) +- 需要对比 before/after 指标 + +## Strategy + +### Delegation Mode + +**Mode**: Sequential Checks + Optional CLI Analysis +**CLI Tool**: `gemini` (for quality comparison) +**CLI Mode**: `analysis` + +### Decision Logic + +```javascript +// 验证策略选择 +const checks = ['test_suite', 'type_check', 'lint_check'] + +// 可选:CLI 质量分析(仅当修改文件较多时) +if (modifiedFiles.length > 5) { + checks.push('cli_quality_analysis') +} + +// Fix-Verify 循环中的验证:聚焦于回归文件 +const isFixVerify = task.description.includes('fix-verify') +if (isFixVerify) { + // 仅验证上次回归的文件 + targetScope = 'regression_files_only' +} +``` + +## Execution Steps + +### Step 1: Context Preparation + +```javascript +// 获取修改文件列表 +const modifiedFiles = fixLog.files_modified || [] + +// 获取原始债务分数 +const debtScoreBefore = sharedMemory.debt_score_before || 0 + +// 检测可用的验证工具 +const hasNpm = Bash(`which npm 2>/dev/null && echo "yes" || echo "no"`).trim() === 'yes' +const hasTsc = Bash(`which npx 2>/dev/null && npx tsc --version 2>/dev/null && echo "yes" || echo "no"`).includes('yes') +const hasEslint = Bash(`npx eslint --version 2>/dev/null && echo "yes" || echo "no"`).includes('yes') +const hasPytest = Bash(`which pytest 2>/dev/null && echo "yes" || echo "no"`).trim() === 'yes' +``` + +### Step 2: Execute Strategy + +```javascript +// === Check 1: Test Suite === +let testOutput = '' +let testsPassed = true +let testRegressions = 0 + +if (hasNpm) { + testOutput = Bash(`npm test 2>&1 || true`) +} else if (hasPytest) { + testOutput = Bash(`python -m pytest 2>&1 || true`) +} else { + testOutput = 'no-test-runner' +} + +if (testOutput !== 'no-test-runner') { + testsPassed = !/FAIL|error|failed/i.test(testOutput) + testRegressions = testsPassed ? 0 : (testOutput.match(/(\d+) failed/)?.[1] || 1) * 1 +} + +// === Check 2: Type Checking === +let typeErrors = 0 +if (hasTsc) { + const tscOutput = Bash(`npx tsc --noEmit 2>&1 || true`) + typeErrors = (tscOutput.match(/error TS/g) || []).length +} + +// === Check 3: Linting === +let lintErrors = 0 +if (hasEslint && modifiedFiles.length > 0) { + const lintOutput = Bash(`npx eslint --no-error-on-unmatched-pattern ${modifiedFiles.join(' ')} 2>&1 || true`) + lintErrors = (lintOutput.match(/(\d+) error/)?.[0]?.match(/\d+/)?.[0] || 0) * 1 +} + +// === Check 4: Optional CLI Quality Analysis === +let qualityImprovement = 0 +if (checks.includes('cli_quality_analysis')) { + const prompt = `PURPOSE: Compare code quality before and after tech debt cleanup to measure improvement +TASK: • Analyze the modified files for quality metrics • Compare complexity, duplication, naming quality • Assess if the changes actually reduced debt • Identify any new issues introduced +MODE: analysis +CONTEXT: ${modifiedFiles.map(f => `@${f}`).join(' ')} +EXPECTED: Quality comparison with: metrics_before, metrics_after, improvement_score (0-100), new_issues_found +CONSTRAINTS: Focus on the specific changes, not overall project quality` + + Bash(`ccw cli -p "${prompt}" --tool gemini --mode analysis --rule analysis-review-code-quality`, { + run_in_background: true + }) + // 等待 CLI 完成,解析质量改善分数 +} + +// === 计算债务分数 === +// 已修复的项不计入 after 分数 +const fixedDebtIds = new Set( + (sharedMemory.fix_results?.files_modified || []) + .flatMap(f => debtInventory.filter(i => i.file === f).map(i => i.id)) +) +const debtScoreAfter = debtInventory.filter(i => !fixedDebtIds.has(i.id)).length +``` + +### Step 3: Result Processing + +```javascript +const totalRegressions = testRegressions + typeErrors + lintErrors +const passed = totalRegressions === 0 + +// 如果有少量回归,尝试通过 code-developer 修复 +if (totalRegressions > 0 && totalRegressions <= 3) { + const regressionDetails = [] + if (testRegressions > 0) regressionDetails.push(`${testRegressions} test failures`) + if (typeErrors > 0) regressionDetails.push(`${typeErrors} type errors`) + if (lintErrors > 0) regressionDetails.push(`${lintErrors} lint errors`) + + Task({ + subagent_type: "code-developer", + run_in_background: false, + description: `Fix ${totalRegressions} regressions from debt cleanup`, + prompt: `## Goal +Fix regressions introduced by tech debt cleanup. + +## Regressions +${regressionDetails.join('\n')} + +## Modified Files +${modifiedFiles.map(f => `- ${f}`).join('\n')} + +## Test Output (if failed) +${testOutput.split('\n').filter(l => /FAIL|Error|error/i.test(l)).slice(0, 20).join('\n')} + +## Constraints +- Fix ONLY the regressions, do not undo the debt fixes +- Preserve the debt cleanup changes +- Do NOT skip tests or add suppressions` + }) + + // Re-run checks after fix attempt + // ... (simplified: re-check test suite) +} + +// 生成最终验证结果 +const validationReport = { + passed, + regressions: totalRegressions, + debt_score_before: debtScoreBefore, + debt_score_after: debtScoreAfter, + improvement_percentage: debtScoreBefore > 0 + ? Math.round(((debtScoreBefore - debtScoreAfter) / debtScoreBefore) * 100) + : 0 +} +``` + +## Output Format + +``` +## Validation Results + +### Status: [PASS|FAIL] +### Regressions: [count] +- Test Suite: [PASS|FAIL] ([n] regressions) +- Type Check: [PASS|FAIL] ([n] errors) +- Lint: [PASS|FAIL] ([n] errors) +- Quality: [IMPROVED|NO_CHANGE] + +### Debt Score +- Before: [score] +- After: [score] +- Improvement: [%]% +``` + +## Error Handling + +| Scenario | Resolution | +|----------|------------| +| No test runner available | Skip test check, rely on type+lint | +| tsc not available | Skip type check, rely on test+lint | +| eslint not available | Skip lint check, rely on test+type | +| All checks unavailable | Report minimal validation, warn coordinator | +| Fix attempt introduces new regressions | Revert fix, report original regressions | +| CLI quality analysis times out | Skip quality analysis, use debt score comparison only | diff --git a/.claude/skills/team-tech-debt/roles/validator/role.md b/.claude/skills/team-tech-debt/roles/validator/role.md new file mode 100644 index 00000000..ca952d19 --- /dev/null +++ b/.claude/skills/team-tech-debt/roles/validator/role.md @@ -0,0 +1,263 @@ +# 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` 记录: + +```javascript +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 写入日志文件: + +```javascript +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](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 + +```javascript +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 + +```javascript +const sessionFolder = task.description.match(/session:\s*(.+)/)?.[1]?.trim() || '.' +let sharedMemory = {} +try { sharedMemory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`)) } catch {} + +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 + +```javascript +// Read commands/verify.md for full implementation +Read("commands/verify.md") +``` + +**核心策略**: 4 层验证 + +```javascript +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. 测试套件 +const testResult = Bash(`npm test 2>&1 || npx vitest run 2>&1 || 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. 类型检查 +const typeResult = Bash(`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 检查 +const lintResult = Bash(`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 + +```javascript +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 + +```javascript +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 | diff --git a/.claude/skills/team-tech-debt/specs/team-config.json b/.claude/skills/team-tech-debt/specs/team-config.json new file mode 100644 index 00000000..abffe69d --- /dev/null +++ b/.claude/skills/team-tech-debt/specs/team-config.json @@ -0,0 +1,132 @@ +{ + "team_name": "tech-debt", + "version": "1.0.0", + "description": "技术债务识别与清理团队 - 融合\"债务扫描\"、\"量化评估\"、\"治理规划\"、\"清理执行\"、\"验证回归\"五大能力域,形成扫描→评估→规划→清理→验证的闭环", + "skill_entry": "team-tech-debt", + "invocation": "Skill(skill=\"team-tech-debt\", args=\"--role=coordinator ...\")", + + "roles": { + "coordinator": { + "name": "coordinator", + "responsibility": "Orchestration", + "task_prefix": null, + "description": "技术债务治理协调者。编排 pipeline:需求澄清 → 模式选择 → 团队创建 → 任务分发 → 监控协调 → 质量门控 → 结果汇报", + "message_types_sent": ["mode_selected", "quality_gate", "task_unblocked", "error", "shutdown"], + "message_types_received": ["scan_complete", "assessment_complete", "plan_ready", "fix_complete", "validation_complete", "regression_found", "error"], + "commands": ["dispatch", "monitor"] + }, + "scanner": { + "name": "scanner", + "responsibility": "Orchestration (多维度债务扫描)", + "task_prefix": "TDSCAN", + "description": "技术债务扫描员。多维度扫描代码库:代码债务、架构债务、测试债务、依赖债务、文档债务,生成债务清单", + "message_types_sent": ["scan_complete", "debt_items_found", "error"], + "message_types_received": [], + "commands": ["scan-debt"], + "cli_tools": ["gemini"], + "subagents": ["cli-explore-agent"] + }, + "assessor": { + "name": "assessor", + "responsibility": "Read-only analysis (量化评估)", + "task_prefix": "TDEVAL", + "description": "技术债务评估师。量化评估债务项的影响和修复成本,按优先级矩阵排序,生成评估报告", + "message_types_sent": ["assessment_complete", "error"], + "message_types_received": [], + "commands": ["evaluate"], + "cli_tools": ["gemini"] + }, + "planner": { + "name": "planner", + "responsibility": "Orchestration (治理规划)", + "task_prefix": "TDPLAN", + "description": "技术债务治理规划师。制定分阶段治理方案:短期速赢、中期系统性治理、长期预防机制", + "message_types_sent": ["plan_ready", "plan_revision", "error"], + "message_types_received": [], + "commands": ["create-plan"], + "cli_tools": ["gemini"], + "subagents": ["cli-explore-agent"] + }, + "executor": { + "name": "executor", + "responsibility": "Code generation (债务清理执行)", + "task_prefix": "TDFIX", + "description": "技术债务清理执行者。按优先级执行重构、依赖更新、代码清理、测试补充等治理动作", + "message_types_sent": ["fix_complete", "fix_progress", "error"], + "message_types_received": [], + "commands": ["remediate"], + "subagents": ["code-developer"] + }, + "validator": { + "name": "validator", + "responsibility": "Validation (清理验证)", + "task_prefix": "TDVAL", + "description": "技术债务清理验证者。验证清理后无回归、质量指标提升、债务确实消除", + "message_types_sent": ["validation_complete", "regression_found", "error"], + "message_types_received": [], + "commands": ["verify"], + "subagents": ["code-developer"], + "cli_tools": ["gemini"] + } + }, + + "pipeline_modes": { + "scan": { + "description": "仅扫描评估,不执行修复(审计模式)", + "stages": ["TDSCAN", "TDEVAL"], + "entry_role": "scanner" + }, + "remediate": { + "description": "完整闭环:扫描 → 评估 → 规划 → 修复 → 验证", + "stages": ["TDSCAN", "TDEVAL", "TDPLAN", "TDFIX", "TDVAL"], + "entry_role": "scanner" + }, + "targeted": { + "description": "定向修复:用户已知债务项,直接规划执行", + "stages": ["TDPLAN", "TDFIX", "TDVAL"], + "entry_role": "planner" + } + }, + + "fix_verify_loop": { + "max_iterations": 3, + "trigger": "validation fails or regression found", + "participants": ["executor", "validator"], + "flow": "TDFIX-fix → TDVAL-verify → evaluate" + }, + + "shared_memory": { + "file": "shared-memory.json", + "fields": { + "debt_inventory": { "owner": "scanner", "type": "array" }, + "assessment_matrix": { "owner": "assessor", "type": "object" }, + "remediation_plan": { "owner": "planner", "type": "object" }, + "fix_results": { "owner": "executor", "type": "object" }, + "validation_results": { "owner": "validator", "type": "object" }, + "debt_score_before": { "owner": "assessor", "type": "number" }, + "debt_score_after": { "owner": "validator", "type": "number" } + } + }, + + "collaboration_patterns": [ + "CP-1: Linear Pipeline (scan/remediate/targeted mode)", + "CP-2: Review-Fix Cycle (Executor ↔ Validator loop)", + "CP-3: Fan-out (Scanner multi-dimension scan)", + "CP-5: Escalation (Worker → Coordinator → User)", + "CP-6: Incremental Delivery (batch remediation)", + "CP-10: Post-Mortem (debt reduction report)" + ], + + "debt_dimensions": { + "code": { "name": "代码债务", "tools": ["static-analysis", "complexity-metrics"] }, + "architecture": { "name": "架构债务", "tools": ["dependency-graph", "coupling-analysis"] }, + "testing": { "name": "测试债务", "tools": ["coverage-analysis", "test-quality"] }, + "dependency": { "name": "依赖债务", "tools": ["outdated-check", "vulnerability-scan"] }, + "documentation": { "name": "文档债务", "tools": ["doc-coverage", "api-doc-check"] } + }, + + "session_directory": { + "pattern": ".workflow/.team/TD-{slug}-{date}", + "subdirectories": ["scan", "assessment", "plan", "fixes", "validation"] + } +}