mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-27 09:13:07 +08:00
feat(team-iterdev): add Phase 1-3 workflow optimizations
Add 7 missing scenarios for real-world iterative development: - Phase 1 (P1): Conflict handling, concurrency control, rollback strategy - Phase 2 (P2): External dependency management, state recovery - Phase 3 (P3): User feedback loop, tech debt tracking Changes: - Extend task-ledger.json with conflict_info, rollback_info, external_dependencies - Extend shared-memory.json with resource_locks, task_checkpoints, user_feedback_items, tech_debt_items - Add 14 new message types for all scenarios - Update coordinator role with new responsibilities and error handling - Upgrade team-config.json to version 1.2.0
This commit is contained in:
@@ -101,7 +101,6 @@ mcp__ccw-tools__team_msg({ summary: `[${role}] ...` })
|
||||
const TEAM_CONFIG = {
|
||||
name: "iterdev",
|
||||
sessionDir: ".workflow/.team/IDS-{slug}-{date}/",
|
||||
msgDir: ".workflow/.team-msg/iterdev/",
|
||||
sharedMemory: "shared-memory.json",
|
||||
taskLedger: "task-ledger.json"
|
||||
}
|
||||
@@ -126,7 +125,29 @@ const TEAM_CONFIG = {
|
||||
"completed_at": "...",
|
||||
"gc_rounds": 0, // Generator-Critic iterations
|
||||
"review_score": null, // reviewer 评分
|
||||
"test_pass_rate": null // tester 通过率
|
||||
"test_pass_rate": null, // tester 通过率
|
||||
// === Phase 1 扩展字段 ===
|
||||
"conflict_info": { // 冲突处理
|
||||
"status": "none", // none | detected | resolved
|
||||
"conflicting_files": [], // 冲突文件列表
|
||||
"resolution_strategy": null, // manual | auto_merge | abort
|
||||
"resolved_by_task_id": null // 解决此冲突的任务ID
|
||||
},
|
||||
"rollback_info": { // 回滚策略
|
||||
"snapshot_id": null, // 可回滚的快照ID
|
||||
"rollback_procedure": null, // 回滚操作说明或脚本路径
|
||||
"last_successful_state_id": null // 上一个成功状态ID
|
||||
},
|
||||
// === Phase 2 扩展字段 ===
|
||||
"external_dependencies": [ // 外部依赖管理
|
||||
{
|
||||
"name": "string", // 依赖名称
|
||||
"version_range": "string", // 期望版本范围
|
||||
"actual_version": "string", // 实际使用的版本
|
||||
"source": "string", // 来源 (npm, maven, git)
|
||||
"status": "ok" // ok | mismatch | missing
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"metrics": {
|
||||
@@ -165,7 +186,94 @@ function updateLedger(sessionFolder, taskId, updates) {
|
||||
],
|
||||
"architecture_decisions": [],
|
||||
"implementation_context": [],
|
||||
"review_feedback_trends": []
|
||||
"review_feedback_trends": [],
|
||||
// === Phase 1 扩展字段 ===
|
||||
"resource_locks": { // 并发控制:资源锁定状态
|
||||
// "{resource_id}": {
|
||||
// "locked_by_task_id": "DEV-001",
|
||||
// "timestamp": "2026-02-23T10:00:00Z",
|
||||
// "holder_role": "developer"
|
||||
// }
|
||||
},
|
||||
// === Phase 2 扩展字段 ===
|
||||
"task_checkpoints": { // 状态恢复:任务检查点
|
||||
// "{task_id}": [
|
||||
// { "timestamp": "...", "state_data_pointer": "..." }
|
||||
// ]
|
||||
},
|
||||
// === Phase 3 扩展字段 ===
|
||||
"user_feedback_items": [ // 用户反馈循环
|
||||
// {
|
||||
// "feedback_id": "FB-xxx",
|
||||
// "source_task_id": "DEV-001",
|
||||
// "description": "string",
|
||||
// "severity": "medium", // low | medium | high | critical
|
||||
// "status": "new", // new | reviewed | addressed | closed
|
||||
// "timestamp": "...",
|
||||
// "category": "general" // general | ux | performance | bug | feature
|
||||
// }
|
||||
],
|
||||
"tech_debt_items": [ // 技术债务追踪
|
||||
// {
|
||||
// "debt_id": "TD-xxx",
|
||||
// "category": "code", // code | design | test | documentation
|
||||
// "source_task_id": "DEV-001",
|
||||
// "description": "string",
|
||||
// "severity": "medium",
|
||||
// "detection_date": "...",
|
||||
// "owner": "developer",
|
||||
// "resolution_plan": "string",
|
||||
// "estimated_effort": "medium", // small | medium | large
|
||||
// "priority": "medium",
|
||||
// "status": "open", // open | in_progress | resolved | deferred
|
||||
// "related_files": []
|
||||
// }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### Resource Lock Protocol (并发控制)
|
||||
|
||||
```javascript
|
||||
// Coordinator 资源锁定服务
|
||||
function acquireLock(sessionFolder, resourceId, taskId, role) {
|
||||
const memory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`))
|
||||
const lock = memory.resource_locks[resourceId]
|
||||
|
||||
if (lock && lock.locked_by_task_id !== taskId) {
|
||||
// 资源已被锁定
|
||||
return { success: false, lockedBy: lock.locked_by_task_id }
|
||||
}
|
||||
|
||||
// 获取锁
|
||||
memory.resource_locks[resourceId] = {
|
||||
locked_by_task_id: taskId,
|
||||
timestamp: new Date().toISOString(),
|
||||
holder_role: role
|
||||
}
|
||||
Write(`${sessionFolder}/shared-memory.json`, JSON.stringify(memory, null, 2))
|
||||
|
||||
// 发送锁定消息
|
||||
mcp__ccw-tools__team_msg({
|
||||
operation: "log", team: teamName, from: role, to: "coordinator",
|
||||
type: "resource_locked", summary: `[${role}] Resource locked: ${resourceId}`, ref: taskId
|
||||
})
|
||||
return { success: true }
|
||||
}
|
||||
|
||||
function releaseLock(sessionFolder, resourceId, taskId) {
|
||||
const memory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`))
|
||||
const lock = memory.resource_locks[resourceId]
|
||||
|
||||
if (lock && lock.locked_by_task_id === taskId) {
|
||||
delete memory.resource_locks[resourceId]
|
||||
Write(`${sessionFolder}/shared-memory.json`, JSON.stringify(memory, null, 2))
|
||||
|
||||
mcp__ccw-tools__team_msg({
|
||||
operation: "log", team: teamName, from: "coordinator", to: "all",
|
||||
type: "resource_unlocked", summary: `[coordinator] Resource unlocked: ${resourceId}`, ref: taskId
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -180,12 +288,32 @@ mcp__ccw-tools__team_msg({
|
||||
|
||||
| Role | Types |
|
||||
|------|-------|
|
||||
| coordinator | `sprint_started`, `gc_loop_trigger`, `sprint_complete`, `task_unblocked`, `error`, `shutdown` |
|
||||
| coordinator | `sprint_started`, `gc_loop_trigger`, `sprint_complete`, `task_unblocked`, `error`, `shutdown`, **`conflict_detected`**, **`conflict_resolved`**, **`resource_locked`**, **`resource_unlocked`**, **`resource_contention`**, **`rollback_initiated`**, **`rollback_completed`**, **`rollback_failed`** |
|
||||
| architect | `design_ready`, `design_revision`, `error` |
|
||||
| developer | `dev_complete`, `dev_progress`, `error` |
|
||||
| tester | `verify_passed`, `verify_failed`, `fix_required`, `error` |
|
||||
| reviewer | `review_passed`, `review_revision`, `review_critical`, `error` |
|
||||
|
||||
**Phase 1 新增消息类型说明**:
|
||||
- `conflict_detected`: 任务间检测到冲突时发送
|
||||
- `conflict_resolved`: 冲突被解决时发送
|
||||
- `resource_locked`: 共享资源被锁定时发送
|
||||
- `resource_unlocked`: 共享资源被释放时发送
|
||||
- `resource_contention`: 任务尝试获取已锁定资源时发送
|
||||
- `rollback_initiated`: 触发回滚操作时发送
|
||||
- `rollback_completed`: 回滚成功完成时发送
|
||||
- `rollback_failed`: 回滚操作失败时发送
|
||||
|
||||
**Phase 2 新增消息类型说明**:
|
||||
- `dependency_mismatch`: 依赖版本不匹配时发送
|
||||
- `dependency_update_needed`: 外部依赖有重要更新时发送
|
||||
- `context_checkpoint_saved`: 任务上下文检查点保存时发送
|
||||
- `context_restored`: 从检查点恢复上下文时发送
|
||||
|
||||
**Phase 3 新增消息类型说明**:
|
||||
- `user_feedback_received`: 接收到用户反馈时发送
|
||||
- `tech_debt_identified`: 识别到技术债务时发送
|
||||
|
||||
### CLI Fallback
|
||||
|
||||
```javascript
|
||||
@@ -370,3 +498,394 @@ Task({
|
||||
| GC loop exceeds 3 rounds | Accept with warning, record in shared memory |
|
||||
| Sprint velocity drops below 50% | Coordinator alerts user, suggests scope reduction |
|
||||
| Task ledger corrupted | Rebuild from TaskList state |
|
||||
| **Phase 1 新增** | |
|
||||
| Conflict detected | Update conflict_info, notify coordinator, create DEV-fix task |
|
||||
| Resource lock timeout | Force release after 5min, notify holder and coordinator |
|
||||
| Rollback requested | Validate snapshot_id, execute rollback_procedure, notify all |
|
||||
| Deadlock detected | Abort youngest task, release its locks, notify coordinator |
|
||||
|
||||
## Phase 1: 冲突处理机制
|
||||
|
||||
### Conflict Detection (Coordinator)
|
||||
|
||||
```javascript
|
||||
// 在 DEV 任务完成时检测冲突
|
||||
function detectConflicts(sessionFolder, taskId, changedFiles) {
|
||||
const ledger = JSON.parse(Read(`${sessionFolder}/task-ledger.json`))
|
||||
const otherTasks = ledger.tasks.filter(t => t.id !== taskId && ['in_progress', 'completed'].includes(t.status))
|
||||
|
||||
const conflicts = []
|
||||
for (const task of otherTasks) {
|
||||
// 检查文件重叠
|
||||
const taskFiles = task.changed_files || []
|
||||
const overlapping = changedFiles.filter(f => taskFiles.includes(f))
|
||||
if (overlapping.length > 0) {
|
||||
conflicts.push({ taskId: task.id, files: overlapping })
|
||||
}
|
||||
}
|
||||
|
||||
if (conflicts.length > 0) {
|
||||
// 更新冲突信息
|
||||
const currentTask = ledger.tasks.find(t => t.id === taskId)
|
||||
currentTask.conflict_info = {
|
||||
status: "detected",
|
||||
conflicting_files: conflicts.flatMap(c => c.files),
|
||||
resolution_strategy: "manual",
|
||||
resolved_by_task_id: null
|
||||
}
|
||||
Write(`${sessionFolder}/task-ledger.json`, JSON.stringify(ledger, null, 2))
|
||||
|
||||
// 发送冲突消息
|
||||
mcp__ccw-tools__team_msg({
|
||||
operation: "log", team: teamName, from: "coordinator", to: "all",
|
||||
type: "conflict_detected",
|
||||
summary: `[coordinator] Conflict detected: ${taskId} conflicts with ${conflicts.map(c => c.taskId).join(', ')}`,
|
||||
ref: taskId
|
||||
})
|
||||
}
|
||||
|
||||
return conflicts
|
||||
}
|
||||
```
|
||||
|
||||
### Conflict Resolution (Coordinator)
|
||||
|
||||
```javascript
|
||||
function resolveConflict(sessionFolder, taskId, strategy = "manual") {
|
||||
const ledger = JSON.parse(Read(`${sessionFolder}/task-ledger.json`))
|
||||
const task = ledger.tasks.find(t => t.id === taskId)
|
||||
|
||||
if (task?.conflict_info?.status === "detected") {
|
||||
task.conflict_info.status = "resolved"
|
||||
task.conflict_info.resolution_strategy = strategy
|
||||
|
||||
// 创建解决冲突的任务
|
||||
const fixTaskId = `${taskId}-fix-conflict`
|
||||
ledger.tasks.push({
|
||||
id: fixTaskId,
|
||||
title: `Resolve conflict for ${taskId}`,
|
||||
owner: "developer",
|
||||
status: "pending",
|
||||
started_at: null,
|
||||
completed_at: null,
|
||||
gc_rounds: 0,
|
||||
conflict_info: { ...task.conflict_info, resolved_by_task_id: fixTaskId }
|
||||
})
|
||||
|
||||
Write(`${sessionFolder}/task-ledger.json`, JSON.stringify(ledger, null, 2))
|
||||
|
||||
mcp__ccw-tools__team_msg({
|
||||
operation: "log", team: teamName, from: "coordinator", to: "developer",
|
||||
type: "conflict_resolved",
|
||||
summary: `[coordinator] Conflict resolution task created: ${fixTaskId}`,
|
||||
ref: fixTaskId
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Phase 1: 回滚策略
|
||||
|
||||
### Rollback Point Management (Coordinator)
|
||||
|
||||
```javascript
|
||||
// 任务成功完成后记录回滚点
|
||||
function createRollbackPoint(sessionFolder, taskId, stateData) {
|
||||
const ledger = JSON.parse(Read(`${sessionFolder}/task-ledger.json`))
|
||||
const task = ledger.tasks.find(t => t.id === taskId)
|
||||
|
||||
if (task) {
|
||||
const snapshotId = `snapshot-${taskId}-${Date.now()}`
|
||||
task.rollback_info = {
|
||||
snapshot_id: snapshotId,
|
||||
rollback_procedure: stateData.procedure || "git revert HEAD",
|
||||
last_successful_state_id: snapshotId
|
||||
}
|
||||
Write(`${sessionFolder}/task-ledger.json`, JSON.stringify(ledger, null, 2))
|
||||
}
|
||||
}
|
||||
|
||||
// 执行回滚
|
||||
function executeRollback(sessionFolder, taskId, reason) {
|
||||
const ledger = JSON.parse(Read(`${sessionFolder}/task-ledger.json`))
|
||||
const task = ledger.tasks.find(t => t.id === taskId)
|
||||
|
||||
if (task?.rollback_info?.snapshot_id) {
|
||||
mcp__ccw-tools__team_msg({
|
||||
operation: "log", team: teamName, from: "coordinator", to: "all",
|
||||
type: "rollback_initiated",
|
||||
summary: `[coordinator] Rollback initiated for ${taskId}: ${reason}`,
|
||||
ref: task.rollback_info.snapshot_id
|
||||
})
|
||||
|
||||
try {
|
||||
// 执行回滚操作
|
||||
Bash(task.rollback_info.rollback_procedure)
|
||||
|
||||
mcp__ccw-tools__team_msg({
|
||||
operation: "log", team: teamName, from: "coordinator", to: "all",
|
||||
type: "rollback_completed",
|
||||
summary: `[coordinator] Rollback completed for ${taskId}`,
|
||||
ref: task.rollback_info.snapshot_id
|
||||
})
|
||||
} catch (error) {
|
||||
mcp__ccw-tools__team_msg({
|
||||
operation: "log", team: teamName, from: "coordinator", to: "all",
|
||||
type: "rollback_failed",
|
||||
summary: `[coordinator] Rollback failed for ${taskId}: ${error.message}`,
|
||||
ref: task.rollback_info.snapshot_id
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Phase 2: 外部依赖管理
|
||||
|
||||
### Dependency Validation (Coordinator)
|
||||
|
||||
```javascript
|
||||
// 任务启动前验证依赖
|
||||
function validateDependencies(sessionFolder, taskId, dependencies) {
|
||||
const ledger = JSON.parse(Read(`${sessionFolder}/task-ledger.json`))
|
||||
const task = ledger.tasks.find(t => t.id === taskId)
|
||||
|
||||
if (!task) return { valid: false, reason: 'Task not found' }
|
||||
|
||||
task.external_dependencies = dependencies.map(dep => ({
|
||||
name: dep.name,
|
||||
version_range: dep.version_range,
|
||||
actual_version: null,
|
||||
source: dep.source || 'unknown',
|
||||
status: 'pending'
|
||||
}))
|
||||
|
||||
const mismatches = []
|
||||
|
||||
for (const dep of task.external_dependencies) {
|
||||
// 获取实际版本(示例:npm list, pip show)
|
||||
const actualVersion = getInstalledVersion(dep.name, dep.source)
|
||||
dep.actual_version = actualVersion
|
||||
|
||||
if (!actualVersion) {
|
||||
dep.status = 'missing'
|
||||
mismatches.push({ name: dep.name, reason: 'Not installed' })
|
||||
} else if (!satisfiesVersion(actualVersion, dep.version_range)) {
|
||||
dep.status = 'mismatch'
|
||||
mismatches.push({ name: dep.name, reason: `Expected ${dep.version_range}, got ${actualVersion}` })
|
||||
} else {
|
||||
dep.status = 'ok'
|
||||
}
|
||||
}
|
||||
|
||||
Write(`${sessionFolder}/task-ledger.json`, JSON.stringify(ledger, null, 2))
|
||||
|
||||
if (mismatches.length > 0) {
|
||||
mcp__ccw-tools__team_msg({
|
||||
operation: "log", team: teamName, from: "coordinator", to: "all",
|
||||
type: "dependency_mismatch",
|
||||
summary: `[coordinator] Dependency mismatch for ${taskId}: ${mismatches.map(m => m.name).join(', ')}`,
|
||||
ref: taskId
|
||||
})
|
||||
}
|
||||
|
||||
return { valid: mismatches.length === 0, mismatches }
|
||||
}
|
||||
```
|
||||
|
||||
## Phase 2: 状态恢复
|
||||
|
||||
### Checkpoint Management (Coordinator)
|
||||
|
||||
```javascript
|
||||
// 保存任务检查点
|
||||
function saveCheckpoint(sessionFolder, taskId, stateData) {
|
||||
const memory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`))
|
||||
|
||||
if (!memory.task_checkpoints) {
|
||||
memory.task_checkpoints = {}
|
||||
}
|
||||
|
||||
if (!memory.task_checkpoints[taskId]) {
|
||||
memory.task_checkpoints[taskId] = []
|
||||
}
|
||||
|
||||
const checkpoint = {
|
||||
timestamp: new Date().toISOString(),
|
||||
state_data_pointer: stateData.pointer || `${sessionFolder}/checkpoints/${taskId}-${Date.now()}.json`
|
||||
}
|
||||
|
||||
memory.task_checkpoints[taskId].unshift(checkpoint)
|
||||
|
||||
// 保留最近 5 个检查点
|
||||
if (memory.task_checkpoints[taskId].length > 5) {
|
||||
memory.task_checkpoints[taskId] = memory.task_checkpoints[taskId].slice(0, 5)
|
||||
}
|
||||
|
||||
Write(`${sessionFolder}/shared-memory.json`, JSON.stringify(memory, null, 2))
|
||||
|
||||
// 保存状态数据
|
||||
if (stateData.data) {
|
||||
Write(checkpoint.state_data_pointer, JSON.stringify(stateData.data, null, 2))
|
||||
}
|
||||
|
||||
mcp__ccw-tools__team_msg({
|
||||
operation: "log", team: teamName, from: "coordinator", to: "all",
|
||||
type: "context_checkpoint_saved",
|
||||
summary: `[coordinator] Checkpoint saved for ${taskId}`,
|
||||
ref: checkpoint.state_data_pointer
|
||||
})
|
||||
|
||||
return checkpoint
|
||||
}
|
||||
|
||||
// 从检查点恢复
|
||||
function restoreFromCheckpoint(sessionFolder, taskId) {
|
||||
const memory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`))
|
||||
|
||||
if (!memory.task_checkpoints?.[taskId]?.length) {
|
||||
return { success: false, reason: 'No checkpoints available' }
|
||||
}
|
||||
|
||||
const latestCheckpoint = memory.task_checkpoints[taskId][0]
|
||||
|
||||
try {
|
||||
const stateData = JSON.parse(Read(latestCheckpoint.state_data_pointer))
|
||||
|
||||
mcp__ccw-tools__team_msg({
|
||||
operation: "log", team: teamName, from: "coordinator", to: "all",
|
||||
type: "context_restored",
|
||||
summary: `[coordinator] Context restored for ${taskId} from ${latestCheckpoint.timestamp}`,
|
||||
ref: latestCheckpoint.state_data_pointer
|
||||
})
|
||||
|
||||
return { success: true, stateData, checkpoint: latestCheckpoint }
|
||||
} catch (error) {
|
||||
return { success: false, reason: error.message }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Phase 3: 用户反馈循环
|
||||
|
||||
### Feedback Collection (Coordinator)
|
||||
|
||||
```javascript
|
||||
// 接收并记录用户反馈
|
||||
function receiveUserFeedback(sessionFolder, feedback) {
|
||||
const memory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`))
|
||||
|
||||
if (!memory.user_feedback_items) {
|
||||
memory.user_feedback_items = []
|
||||
}
|
||||
|
||||
const feedbackItem = {
|
||||
feedback_id: `FB-${Date.now().toString(36)}`,
|
||||
source_task_id: feedback.source_task_id || null,
|
||||
description: feedback.description,
|
||||
severity: feedback.severity || 'medium', // low | medium | high | critical
|
||||
status: 'new', // new | reviewed | addressed | closed
|
||||
timestamp: new Date().toISOString(),
|
||||
category: feedback.category || 'general' // general | ux | performance | bug | feature
|
||||
}
|
||||
|
||||
memory.user_feedback_items.unshift(feedbackItem)
|
||||
|
||||
// 保留最近 50 条反馈
|
||||
if (memory.user_feedback_items.length > 50) {
|
||||
memory.user_feedback_items = memory.user_feedback_items.slice(0, 50)
|
||||
}
|
||||
|
||||
Write(`${sessionFolder}/shared-memory.json`, JSON.stringify(memory, null, 2))
|
||||
|
||||
mcp__ccw-tools__team_msg({
|
||||
operation: "log", team: teamName, from: "coordinator", to: "all",
|
||||
type: "user_feedback_received",
|
||||
summary: `[coordinator] User feedback received: ${feedbackItem.severity} - ${feedbackItem.description.substring(0, 50)}`,
|
||||
ref: feedbackItem.feedback_id
|
||||
})
|
||||
|
||||
return feedbackItem
|
||||
}
|
||||
|
||||
// 关联反馈到任务
|
||||
function linkFeedbackToTask(sessionFolder, feedbackId, taskId) {
|
||||
const memory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`))
|
||||
const feedback = memory.user_feedback_items?.find(f => f.feedback_id === feedbackId)
|
||||
|
||||
if (feedback) {
|
||||
feedback.source_task_id = taskId
|
||||
feedback.status = 'reviewed'
|
||||
Write(`${sessionFolder}/shared-memory.json`, JSON.stringify(memory, null, 2))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Phase 3: 技术债务追踪
|
||||
|
||||
### Tech Debt Management (Coordinator)
|
||||
|
||||
```javascript
|
||||
// 记录技术债务
|
||||
function identifyTechDebt(sessionFolder, debt) {
|
||||
const memory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`))
|
||||
|
||||
if (!memory.tech_debt_items) {
|
||||
memory.tech_debt_items = []
|
||||
}
|
||||
|
||||
const debtItem = {
|
||||
debt_id: `TD-${Date.now().toString(36)}`,
|
||||
category: debt.category || 'code', // code | design | test | documentation
|
||||
source_task_id: debt.source_task_id || null,
|
||||
description: debt.description,
|
||||
severity: debt.severity || 'medium', // low | medium | high | critical
|
||||
detection_date: new Date().toISOString(),
|
||||
owner: debt.owner || null, // 角色或具体负责人
|
||||
resolution_plan: debt.resolution_plan || null,
|
||||
estimated_effort: debt.estimated_effort || null, // small | medium | large
|
||||
priority: debt.priority || 'medium', // low | medium | high
|
||||
status: 'open', // open | in_progress | resolved | deferred
|
||||
related_files: debt.related_files || []
|
||||
}
|
||||
|
||||
memory.tech_debt_items.unshift(debtItem)
|
||||
|
||||
Write(`${sessionFolder}/shared-memory.json`, JSON.stringify(memory, null, 2))
|
||||
|
||||
mcp__ccw-tools__team_msg({
|
||||
operation: "log", team: teamName, from: "coordinator", to: "all",
|
||||
type: "tech_debt_identified",
|
||||
summary: `[coordinator] Tech debt identified: ${debtItem.category} - ${debtItem.description.substring(0, 50)}`,
|
||||
ref: debtItem.debt_id
|
||||
})
|
||||
|
||||
return debtItem
|
||||
}
|
||||
|
||||
// 生成技术债务报告
|
||||
function generateTechDebtReport(sessionFolder) {
|
||||
const memory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`))
|
||||
const debts = memory.tech_debt_items || []
|
||||
|
||||
const report = {
|
||||
total: debts.length,
|
||||
by_severity: {
|
||||
critical: debts.filter(d => d.severity === 'critical').length,
|
||||
high: debts.filter(d => d.severity === 'high').length,
|
||||
medium: debts.filter(d => d.severity === 'medium').length,
|
||||
low: debts.filter(d => d.severity === 'low').length
|
||||
},
|
||||
by_category: {
|
||||
code: debts.filter(d => d.category === 'code').length,
|
||||
design: debts.filter(d => d.category === 'design').length,
|
||||
test: debts.filter(d => d.category === 'test').length,
|
||||
documentation: debts.filter(d => d.category === 'documentation').length
|
||||
},
|
||||
open_items: debts.filter(d => d.status === 'open'),
|
||||
in_progress_items: debts.filter(d => d.status === 'in_progress')
|
||||
}
|
||||
|
||||
return report
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# Role: coordinator
|
||||
|
||||
持续迭代开发团队协调者。负责 Sprint 规划、积压管理、任务账本维护、Generator-Critic 循环控制(developer↔reviewer,最多3轮)和 Sprint 间学习。
|
||||
持续迭代开发团队协调者。负责 Sprint 规划、积压管理、任务账本维护、Generator-Critic 循环控制(developer↔reviewer,最多3轮)、Sprint 间学习、**冲突处理、并发控制、回滚策略**、**用户反馈循环、技术债务追踪**。
|
||||
|
||||
## Role Identity
|
||||
|
||||
- **Name**: `coordinator`
|
||||
- **Task Prefix**: N/A
|
||||
- **Responsibility**: Orchestration
|
||||
- **Responsibility**: Orchestration + **Stability Management** + **Quality Tracking**
|
||||
- **Communication**: SendMessage to all teammates
|
||||
- **Output Tag**: `[coordinator]`
|
||||
|
||||
@@ -18,6 +18,14 @@
|
||||
- 维护 task-ledger.json 实时进度
|
||||
- 管理 developer↔reviewer 的 GC 循环(最多3轮)
|
||||
- Sprint 结束时记录学习到 shared-memory.json
|
||||
- **Phase 1 新增**:
|
||||
- 检测并协调任务间冲突
|
||||
- 管理共享资源锁定(resource_locks)
|
||||
- 记录回滚点并支持紧急回滚
|
||||
- **Phase 3 新增**:
|
||||
- 收集并跟踪用户反馈(user_feedback_items)
|
||||
- 识别并记录技术债务(tech_debt_items)
|
||||
- 生成技术债务报告
|
||||
|
||||
### MUST NOT
|
||||
|
||||
@@ -264,3 +272,12 @@ AskUserQuestion({
|
||||
| 任务账本损坏 | 从 TaskList 重建 |
|
||||
| 设计被拒 3+ 次 | Coordinator 介入简化设计 |
|
||||
| 测试持续失败 | 创建 DEV-fix 给 developer |
|
||||
| **Phase 1 新增** | |
|
||||
| 冲突检测到 | 更新 conflict_info,通知 coordinator,创建 DEV-fix 任务 |
|
||||
| 资源锁超时 (5min) | 强制释放锁,通知持有者和 coordinator |
|
||||
| 回滚请求 | 验证 snapshot_id,执行 rollback_procedure,通知所有角色 |
|
||||
| 死锁检测 | 终止最年轻任务,释放其锁,通知 coordinator |
|
||||
| **Phase 3 新增** | |
|
||||
| 用户反馈 critical | 立即创建修复任务,优先级提升 |
|
||||
| 技术债务累积超过阈值 | 生成债务报告,建议用户安排专项处理 |
|
||||
| 反馈关联任务失败 | 保留反馈条目,标记为 unlinked,人工跟进 |
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
{
|
||||
"team_name": "team-iterdev",
|
||||
"team_display_name": "Team IterDev",
|
||||
"description": "Iterative development team with Generator-Critic loop, task ledger, sprint learning, and dynamic pipeline",
|
||||
"version": "1.0.0",
|
||||
"description": "Iterative development team with Generator-Critic loop, task ledger, sprint learning, dynamic pipeline, conflict handling, concurrency control, rollback strategy, user feedback loop, and tech debt tracking",
|
||||
"version": "1.2.0",
|
||||
|
||||
"roles": {
|
||||
"coordinator": {
|
||||
"task_prefix": null,
|
||||
"responsibility": "Sprint planning, backlog management, task ledger maintenance, GC loop control",
|
||||
"message_types": ["sprint_started", "gc_loop_trigger", "sprint_complete", "task_unblocked", "error", "shutdown"]
|
||||
"responsibility": "Sprint planning, backlog management, task ledger maintenance, GC loop control, Phase 1: conflict handling, concurrency control, rollback strategy, Phase 3: user feedback loop, tech debt tracking",
|
||||
"message_types": [
|
||||
"sprint_started", "gc_loop_trigger", "sprint_complete", "task_unblocked", "error", "shutdown",
|
||||
"conflict_detected", "conflict_resolved", "resource_locked", "resource_unlocked", "resource_contention",
|
||||
"rollback_initiated", "rollback_completed", "rollback_failed",
|
||||
"user_feedback_received", "tech_debt_identified"
|
||||
]
|
||||
},
|
||||
"architect": {
|
||||
"task_prefix": "DESIGN",
|
||||
@@ -62,7 +67,17 @@
|
||||
"task_ledger": {
|
||||
"file": "task-ledger.json",
|
||||
"updated_by": "coordinator",
|
||||
"tracks": ["status", "gc_rounds", "review_score", "test_pass_rate", "velocity"]
|
||||
"tracks": ["status", "gc_rounds", "review_score", "test_pass_rate", "velocity"],
|
||||
"phase1_extensions": {
|
||||
"conflict_info": {
|
||||
"fields": ["status", "conflicting_files", "resolution_strategy", "resolved_by_task_id"],
|
||||
"default": { "status": "none", "conflicting_files": [], "resolution_strategy": null, "resolved_by_task_id": null }
|
||||
},
|
||||
"rollback_info": {
|
||||
"fields": ["snapshot_id", "rollback_procedure", "last_successful_state_id"],
|
||||
"default": { "snapshot_id": null, "rollback_procedure": null, "last_successful_state_id": null }
|
||||
}
|
||||
}
|
||||
},
|
||||
"shared_memory": {
|
||||
"file": "shared-memory.json",
|
||||
@@ -72,7 +87,14 @@
|
||||
"tester": "test_patterns",
|
||||
"reviewer": "review_feedback_trends"
|
||||
},
|
||||
"persistent_fields": ["sprint_history", "what_worked", "what_failed", "patterns_learned"]
|
||||
"persistent_fields": ["sprint_history", "what_worked", "what_failed", "patterns_learned"],
|
||||
"phase1_extensions": {
|
||||
"resource_locks": {
|
||||
"description": "Concurrency control: resource locking state",
|
||||
"lock_timeout_ms": 300000,
|
||||
"deadlock_detection": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"dynamic_pipeline": {
|
||||
"selector": "coordinator",
|
||||
@@ -81,6 +103,62 @@
|
||||
}
|
||||
},
|
||||
|
||||
"phase1_features": {
|
||||
"conflict_handling": {
|
||||
"enabled": true,
|
||||
"detection_strategy": "file_overlap",
|
||||
"resolution_strategies": ["manual", "auto_merge", "abort"]
|
||||
},
|
||||
"concurrency_control": {
|
||||
"enabled": true,
|
||||
"lock_timeout_minutes": 5,
|
||||
"deadlock_detection": true,
|
||||
"resources": ["task-ledger.json", "shared-memory.json"]
|
||||
},
|
||||
"rollback_strategy": {
|
||||
"enabled": true,
|
||||
"snapshot_trigger": "task_complete",
|
||||
"default_procedure": "git revert HEAD"
|
||||
}
|
||||
},
|
||||
|
||||
"phase2_features": {
|
||||
"external_dependency_management": {
|
||||
"enabled": true,
|
||||
"validation_trigger": "task_start",
|
||||
"supported_sources": ["npm", "maven", "pip", "git"],
|
||||
"version_check_command": {
|
||||
"npm": "npm list {name}",
|
||||
"pip": "pip show {name}",
|
||||
"maven": "mvn dependency:tree"
|
||||
}
|
||||
},
|
||||
"state_recovery": {
|
||||
"enabled": true,
|
||||
"checkpoint_trigger": "phase_complete",
|
||||
"max_checkpoints_per_task": 5,
|
||||
"checkpoint_dir": "checkpoints/"
|
||||
}
|
||||
},
|
||||
|
||||
"phase3_features": {
|
||||
"user_feedback_loop": {
|
||||
"enabled": true,
|
||||
"collection_trigger": "sprint_complete",
|
||||
"max_feedback_items": 50,
|
||||
"severity_levels": ["low", "medium", "high", "critical"],
|
||||
"status_flow": ["new", "reviewed", "addressed", "closed"]
|
||||
},
|
||||
"tech_debt_tracking": {
|
||||
"enabled": true,
|
||||
"detection_sources": ["review", "test", "architect"],
|
||||
"categories": ["code", "design", "test", "documentation"],
|
||||
"severity_levels": ["low", "medium", "high", "critical"],
|
||||
"status_flow": ["open", "in_progress", "resolved", "deferred"],
|
||||
"report_trigger": "sprint_retrospective"
|
||||
}
|
||||
},
|
||||
|
||||
"collaboration_patterns": ["CP-1", "CP-3", "CP-5", "CP-6"],
|
||||
|
||||
"session_dirs": {
|
||||
|
||||
Reference in New Issue
Block a user