Files
Claude-Code-Workflow/.claude/skills/team-tech-debt/roles/planner/role.md
catlog22 f60dd44d5b 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.
2026-02-23 22:46:27 +08:00

288 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Role: 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 |