tackle-harness 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tackle-harness",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Plugin-based AI Agent Harness framework for Claude Code",
5
5
  "main": "plugins/runtime/harness-build.js",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skill-agent-dispatcher",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "type": "skill",
5
5
  "description": "子代理批量调度 Skill - 基于 Agent Teams 机制的子代理批量任务调度,支持角色赋能、记忆注入、依赖分析和并行执行",
6
6
  "triggers": ["批量执行", "并行执行", "调度子代理", "agent-dispatcher", "batch execute", "parallel execute", "dispatch agents"],
@@ -39,9 +39,9 @@ description: Use when user says "批量执行", "并行执行", "调度子代理
39
39
 
40
40
  | 场景 | 执行方式 |
41
41
  |------|----------|
42
- | 无依赖的多个工作包 | 并行执行 (Teamee 自主认领) |
43
- | 有依赖链的工作包 | blockedBy 自动阻塞 |
44
- | 混合依赖 | TaskList 自动协调 |
42
+ | 无依赖的多个工作包 | 并行执行 (每 WP 一个专用 Teamee) |
43
+ | 有依赖链的工作包 | blockedBy 阻塞 + 依赖解除后按需创建 Teamee |
44
+ | 混合依赖 | 监控循环动态创建 + 即时销毁 |
45
45
 
46
46
  ---
47
47
 
@@ -54,27 +54,30 @@ description: Use when user says "批量执行", "并行执行", "调度子代理
54
54
  │ 1. 解析工作包 → 分析依赖 │
55
55
  │ 2. TeamCreate 创建团队 │
56
56
  │ 3. TaskCreate 创建任务 + 设置 blockedBy │
57
- │ 4. 角色匹配 → 确定需要哪些专家
58
- │ 5. Agent 启动 Teamee (注入角色+记忆)
59
- 6. 监控 TaskList + 接收空闲通知
60
- 7. 全部完成后 TeamDelete
61
- 8. 经验提取 + completion-report
57
+ │ 4. 角色匹配 → 预计算每个 WP 的角色和记忆
58
+ │ 5. 监控循环:
59
+ - 检测 newly-unblocked 任务 → 按需创建专用 Teamee (1:1)
60
+ - 检测已完成的任务 → 即时销毁对应 Teamee
61
+ - 维护映射表 {task_id → teamee_name}
62
+ │ 6. 全部完成后 TeamDelete │
63
+ │ 7. 经验提取 + completion-report │
62
64
  └─────────────────────────────────────────────────────────────┘
63
65
 
64
66
  ┌─────────────────────┼─────────────────────┐
65
67
  ▼ ▼ ▼
66
68
  ┌──────────┐ ┌──────────┐ ┌──────────┐
67
- │ Teamee 1 │ │ Teamee 2 │ │ Teamee 3
68
- 角色专家 │ │ 角色专家 │ │ 角色专家
69
+ │ Teamee A │ │ Teamee B │ │ Teamee C
70
+ WP-037 │ │ WP-038 │ │ WP-039
71
+ │ 专用绑定 │ │ 专用绑定 │ │ 专用绑定 │
69
72
  └────┬─────┘ └────┬─────┘ └────┬─────┘
70
-
71
- └─────────────────────┼─────────────────────┘
72
-
73
+ 已完成 执行中 blockedBy #2
74
+ │ 即时销毁 │ │ 等待创建
75
+ ▼ ▼
73
76
  ┌───────────────────────────────┐
74
77
  │ 共享 Task List │
75
- Task #1: WP-037 (完成)
76
- Task #2: WP-038 (进行中)
77
- Task #3: WP-039 (blockedBy #2)
78
+ │ Task #1: WP-037 (completed)
79
+ │ Task #2: WP-038 (in_progress)│
80
+ │ Task #3: WP-039 (blockedBy #2)│
78
81
  └───────────────────────────────┘
79
82
  ```
80
83
 
@@ -83,7 +86,7 @@ description: Use when user says "批量执行", "并行执行", "调度子代理
83
86
  ## Flow
84
87
 
85
88
  ```dot
86
- digraph dispatcher_v2 {
89
+ digraph dispatcher_v3 {
87
90
  rankdir=TB;
88
91
 
89
92
  // 准备阶段
@@ -97,19 +100,27 @@ digraph dispatcher_v2 {
97
100
  "设置 blockedBy 依赖" [shape=box];
98
101
 
99
102
  // 角色匹配
100
- "角色匹配" [shape=box, style=filled, fillcolor=lightyellow];
103
+ "角色匹配 (预计算)" [shape=box, style=filled, fillcolor=lightyellow];
101
104
  "读取角色定义" [shape=box];
102
105
  "注入专属记忆" [shape=box];
103
106
 
104
- // Teamee 启动
105
- "Agent 启动 Teamee" [shape=box, style=filled, fillcolor=orange];
106
- "Teamee 认领任务" [shape=box];
107
- "Teamee 执行任务" [shape=box];
108
- "TaskUpdate 更新状态" [shape=box];
107
+ // 监控循环
108
+ "监控循环: TaskList" [shape=diamond, style=filled, fillcolor=orange];
109
+ "检测 newly-unblocked 任务" [shape=box];
110
+ "为可用任务创建专用 Teamee" [shape=box, style=filled, fillcolor=orange];
111
+ "预分配 owner (TaskUpdate)" [shape=box];
112
+ "Teamee 执行单一任务" [shape=box];
113
+ "TaskUpdate 标记 completed" [shape=box];
109
114
 
110
- // 协调
111
- "检查 TaskList" [shape=diamond];
112
- "还有待处理任务?" [shape=diamond];
115
+ // 即时销毁
116
+ "检测已完成任务" [shape=box];
117
+ "发送 shutdown_request" [shape=box, style=filled, fillcolor=red];
118
+ "等待 shutdown_response" [shape=box];
119
+ "从映射表移除" [shape=box];
120
+
121
+ // 循环判断
122
+ "所有任务 completed?" [shape=diamond];
123
+ "超时?" [shape=diamond];
113
124
 
114
125
  // 收尾
115
126
  "TeamDelete 清理团队" [shape=box];
@@ -124,20 +135,29 @@ digraph dispatcher_v2 {
124
135
 
125
136
  "TeamCreate 创建团队" -> "TaskCreate 创建任务";
126
137
  "TaskCreate 创建任务" -> "设置 blockedBy 依赖";
127
- "设置 blockedBy 依赖" -> "角色匹配";
128
- "角色匹配" -> "读取角色定义";
138
+ "设置 blockedBy 依赖" -> "角色匹配 (预计算)";
139
+
140
+ "角色匹配 (预计算)" -> "读取角色定义";
129
141
  "读取角色定义" -> "注入专属记忆";
130
- "注入专属记忆" -> "Agent 启动 Teamee";
142
+ "注入专属记忆" -> "监控循环: TaskList";
143
+
144
+ "监控循环: TaskList" -> "检测 newly-unblocked 任务";
145
+ "检测 newly-unblocked 任务" -> "为可用任务创建专用 Teamee" [label="有可用任务"];
146
+ "为可用任务创建专用 Teamee" -> "预分配 owner (TaskUpdate)";
147
+ "预分配 owner (TaskUpdate)" -> "Teamee 执行单一任务";
148
+ "Teamee 执行单一任务" -> "TaskUpdate 标记 completed";
131
149
 
132
- "Agent 启动 Teamee" -> "Teamee 认领任务";
133
- "Teamee 认领任务" -> "Teamee 执行任务";
134
- "Teamee 执行任务" -> "TaskUpdate 更新状态";
135
- "TaskUpdate 更新状态" -> "检查 TaskList";
136
- "检查 TaskList" -> "还有待处理任务?";
137
- "还有待处理任务?" -> "Teamee 认领任务" [label="是"];
138
- "还有待处理任务?" -> "发送空闲通知" [label=""];
150
+ "监控循环: TaskList" -> "检测已完成任务";
151
+ "检测已完成任务" -> "发送 shutdown_request" [label="有新完成"];
152
+ "发送 shutdown_request" -> "等待 shutdown_response";
153
+ "等待 shutdown_response" -> "从映射表移除";
154
+
155
+ "监控循环: TaskList" -> "所有任务 completed?";
156
+ "所有任务 completed?" -> "TeamDelete 清理团队" [label=""];
157
+ "所有任务 completed?" -> "超时?" [label="否"];
158
+ "超时?" -> "监控循环: TaskList" [label="否"];
159
+ "超时?" -> "TeamDelete 清理团队" [label="是"];
139
160
 
140
- "发送空闲通知" -> "TeamDelete 清理团队";
141
161
  "TeamDelete 清理团队" -> "经验提取";
142
162
  "经验提取" -> "生成执行报告";
143
163
  }
@@ -230,94 +250,214 @@ def match_role(work_package):
230
250
  return max(scores, key=scores.get)
231
251
  ```
232
252
 
233
- ### Step 5: 启动 Teamee
253
+ ### Step 5: 预计算角色 + 记忆准备
254
+
255
+ **⚠️ 重要**: 角色匹配和记忆注入在监控循环之前完成(预计算),为每个工作包准备好角色 Prompt。
256
+
257
+ ```
258
+ # 预计算所有工作包的角色匹配结果和记忆
259
+
260
+ wp_assignments = {} # {task_id: {role_id, role_prompt, memories, wp_doc_path}}
261
+
262
+ for task in tasks:
263
+ wp = extract_work_package(task)
264
+ role = match_role(wp)
265
+ memories = load_memories(role.id)
266
+ wp_assignments[task.id] = {
267
+ "role_id": role.id,
268
+ "role_prompt": role.prompt_template,
269
+ "memories": memories,
270
+ "wp_doc_path": wp.doc_path
271
+ }
272
+ ```
273
+
274
+ **为什么预计算**:
275
+ - 监控循环中按需创建 Teamee 时,直接使用预计算结果构建 Prompt
276
+ - 避免在监控循环中重复执行角色匹配逻辑
277
+ - 角色匹配算法不变(仍使用 Step 4 中的算法)
278
+
279
+ ### Step 6: 初始创建 Teamee(首次可用任务)
280
+
281
+ <HARD-GATE>
282
+ Step 5 完成后,立即检查有哪些任务的 blockedBy 已满足。
283
+ 为每个 initially-unblocked 的任务创建专用 Teamee。
284
+ 不可跳过此步骤!
285
+ </HARD-GATE>
234
286
 
235
287
  **⚠️ 重要**: 必须使用 `general-purpose` subagent_type!
236
288
 
237
289
  不要使用 `Explore` 或其他只读 agent 类型,因为它们没有 SendMessage 工具,
238
- 无法响应 shutdown_request,会导致 TeamDelete 卡死。
290
+ 无法响应 shutdown_request,会导致即时销毁流程失败。
239
291
 
240
292
  ```
241
- Agent:
242
- name: "{role_id}" # "godot-scene-expert"
243
- team_name: "batch-20260314-WP073-075"
244
- subagent_type: "general-purpose" # ✅ 必须使用 general-purpose
245
- prompt: |
246
- {Teamee Prompt 模板}
293
+ # 初始化映射表
294
+ teamee_map = {} # {task_id: teamee_name}
295
+
296
+ # 检查哪些任务在初始时就没有阻塞
297
+ tasks = TaskList()
298
+ for task in tasks:
299
+ if task.status == "pending" and is_unblocked(task):
300
+ # 从预计算结果获取角色信息
301
+ assignment = wp_assignments[task.id]
302
+
303
+ # 生成唯一的 Teamee 名称(包含 task_id 和 role)
304
+ teamee_name = f"{assignment.role_id}-t{task.id}"
305
+
306
+ # 预分配 owner
307
+ TaskUpdate(taskId=task.id, owner=teamee_name)
308
+
309
+ # 创建专用 Teamee
310
+ Agent(
311
+ name=teamee_name,
312
+ team_name="{team_name}",
313
+ subagent_type="general-purpose", # 必须使用 general-purpose
314
+ prompt=build_single_task_prompt(
315
+ teamee_name=teamee_name,
316
+ task_id=task.id,
317
+ role_prompt=assignment.role_prompt,
318
+ memories=assignment.memories,
319
+ wp_doc_path=assignment.wp_doc_path
320
+ )
321
+ )
322
+
323
+ # 记录映射关系
324
+ teamee_map[task.id] = teamee_name
247
325
  ```
248
326
 
249
327
  **为什么不能用 Explore agent**:
250
328
  - Explore agent 的工具集: `All tools except Agent, ExitPlanMode, Edit, Write, NotebookEdit`
251
329
  - 没有 Agent 工具 = 没有 SendMessage
252
- - 无法发送 `shutdown_response` = TeamDelete 永远等待 = 清理死锁
330
+ - 无法发送 `shutdown_response` = 即时销毁失败 = 资源泄漏
253
331
 
254
- ### Step 6: Teamee 自主执行
255
-
256
- Teamee 收到 prompt 后,按以下流程工作:
257
-
258
- ```
259
- 1. TaskList 查看可用任务
260
- 2. 找到: status=pending + owner=空 + blockedBy 已满足
261
- 3. TaskUpdate 认领任务 (设置 owner)
262
- 4. 执行任务
263
- 5. TaskUpdate 标记完成 (status=completed)
264
- 6. 重复步骤 1-5 直到无可用任务
265
- 7. 等待 Lead 的 shutdown_request(不要主动退出)
266
- ```
267
-
268
- ### Step 6.5: 监控任务完成状态 (🔴 关键步骤)
332
+ ### Step 6.5: 监控循环 (🔴 关键步骤 — 动态创建 + 即时销毁)
269
333
 
270
334
  <HARD-GATE>
271
335
  Lead Agent 必须进入监控循环,不可跳过!
272
- 这是保证 TeamDelete 执行的核心机制。
336
+ 此循环负责:
337
+ 1. 检测 newly-unblocked 任务 → 按需创建专用 Teamee
338
+ 2. 检测已完成任务 → 即时销毁对应 Teamee
339
+ 3. 判断全部完成 → 退出循环
340
+ 这是保证资源及时释放和依赖正确解析的核心机制。
273
341
  </HARD-GATE>
274
342
 
275
343
  ```
276
344
  # Lead Agent 监控循环
277
345
  loop_interval = 30 # 秒
278
346
  max_wait_time = 7200 # 2 小时
347
+ shutdown_timeout = 15 # 等待 Teamee shutdown 响应的超时
279
348
 
280
349
  start_time = now()
281
350
  while (now() - start_time) < max_wait_time:
282
- # 1. 获取任务状态
351
+ # ---- Phase A: 获取任务状态 ----
283
352
  tasks = TaskList()
284
353
 
285
- # 2. 统计状态
354
+ # ---- Phase B: 即时销毁已完成的 Teamee ----
355
+ for task in tasks:
356
+ if task.status == "completed" and task.id in teamee_map:
357
+ teamee_name = teamee_map[task.id]
358
+ print(f"任务 {task.id} 已完成,即时销毁 Teamee: {teamee_name}")
359
+
360
+ # B1. 发送 shutdown_request
361
+ SendMessage(to=teamee_name, message={
362
+ "type": "shutdown_request",
363
+ "reason": f"任务 {task.id} 已完成,释放资源",
364
+ "request_id": f"shutdown-{task.id}-{timestamp()}"
365
+ })
366
+
367
+ # B2. 等待 shutdown_response(最多 shutdown_timeout 秒)
368
+ # Teamee 收到后应回复 {"type":"shutdown_response","approve":true}
369
+ # 如果超时未响应,继续执行(不阻塞循环)
370
+
371
+ # B3. 从映射表移除
372
+ del teamee_map[task.id]
373
+ print(f"Teamee {teamee_name} 已销毁并从映射表移除")
374
+
375
+ # ---- Phase C: 按需创建 Teamee 处理 newly-unblocked 任务 ----
376
+ for task in tasks:
377
+ if task.status == "pending" and task.owner == "" and is_unblocked(task):
378
+ # C1. 检查是否已有映射(防止重复创建)
379
+ if task.id in teamee_map:
380
+ continue
381
+
382
+ # C2. 从预计算结果获取角色信息
383
+ assignment = wp_assignments[task.id]
384
+ teamee_name = f"{assignment.role_id}-t{task.id}"
385
+
386
+ # C3. 预分配 owner
387
+ TaskUpdate(taskId=task.id, owner=teamee_name)
388
+
389
+ # C4. 创建专用 Teamee
390
+ Agent(
391
+ name=teamee_name,
392
+ team_name="{team_name}",
393
+ subagent_type="general-purpose",
394
+ prompt=build_single_task_prompt(
395
+ teamee_name=teamee_name,
396
+ task_id=task.id,
397
+ role_prompt=assignment.role_prompt,
398
+ memories=assignment.memories,
399
+ wp_doc_path=assignment.wp_doc_path
400
+ )
401
+ )
402
+
403
+ # C5. 记录映射关系
404
+ teamee_map[task.id] = teamee_name
405
+ print(f"为任务 {task.id} 创建专用 Teamee: {teamee_name}")
406
+
407
+ # ---- Phase D: 判断退出条件 ----
286
408
  completed = count(status == "completed")
287
- in_progress = count(status == "in_progress")
288
- pending = count(status == "pending")
289
409
  total = len(tasks)
290
410
 
291
- # 3. 输出状态(可选)
292
- print(f"📊 任务状态: 完成={completed}/{total}, 进行中={in_progress}, 待处理={pending}")
293
-
294
- # 4. 判断清理条件
295
411
  if completed == total:
296
- print("✅ 所有任务完成,准备清理")
297
- break # 退出循环,执行 Step 7
298
-
299
- if in_progress > 0:
300
- # 有任务正在执行,继续等待
301
- sleep(loop_interval)
302
- continue
412
+ print("所有任务完成,退出监控循环")
413
+ break
303
414
 
304
- if pending > 0 and in_progress == 0:
305
- # 有待处理任务但无活跃 Teamee(可能异常)
306
- print("⚠️ 检测到异常:有待处理任务但无活跃执行者")
307
- break # 退出循环,执行异常清理
415
+ # Phase D2: 异常检测
416
+ in_progress = count(status == "in_progress")
417
+ pending = count(status == "pending")
418
+ if pending > 0 and in_progress == 0 and len(teamee_map) == 0:
419
+ print("异常: 有待处理任务但无活跃 Teamee 且无映射")
420
+ break
308
421
 
309
422
  sleep(loop_interval)
310
423
 
311
424
  # 超时处理
312
425
  if (now() - start_time) >= max_wait_time:
313
- print("⚠️ 监控超时,强制执行清理")
426
+ print("监控超时,强制执行清理")
427
+ # 销毁所有剩余的 Teamee
428
+ for task_id, teamee_name in teamee_map.items():
429
+ SendMessage(to=teamee_name, message={
430
+ "type": "shutdown_request",
431
+ "reason": "监控超时,强制清理",
432
+ "request_id": f"force-shutdown-{task_id}-{timestamp()}"
433
+ })
314
434
  ```
315
435
 
436
+ **辅助函数 — 判断任务是否已解除阻塞**:
437
+ ```
438
+ def is_unblocked(task):
439
+ """检查任务的所有 blockedBy 依赖是否都已满足"""
440
+ if not task.blockedBy:
441
+ return True
442
+ all_tasks = TaskList()
443
+ for blocker_id in task.blockedBy:
444
+ blocker = find_by_id(all_tasks, blocker_id)
445
+ if blocker.status != "completed":
446
+ return False
447
+ return True
448
+ ```
449
+
450
+ **监控循环关键特性**:
451
+ - **Phase B (即时销毁)** 在 Phase C (创建) 之前执行,确保资源先释放再分配
452
+ - 每次循环都检查 `teamee_map` 防止重复创建/重复销毁
453
+ - 异常检测同时检查 `teamee_map` 是否为空,避免误判
454
+
316
455
  ### Step 7: 清理团队 (🔴 强制执行 + 验证)
317
456
 
318
457
  <HARD-GATE>
319
458
  TeamDelete 必须执行,且必须验证结果!
320
- 无论任务成功、失败还是超时,都必须清理并验证。
459
+ 注意:大部分 Teamee 已在 Step 6.5 监控循环中即时销毁。
460
+ 此步骤负责最终的 TeamDelete 调用和验证。
321
461
  不信任 TeamDelete 返回值,必须检查目录是否真的被删除!
322
462
  以下步骤必须按顺序逐一执行,不可跳过!
323
463
  </HARD-GATE>
@@ -344,19 +484,32 @@ TeamDelete 必须执行,且必须验证结果!
344
484
 
345
485
  ---
346
486
 
347
- #### Step 7b: 发送 shutdown_request
487
+ #### Step 7b: 发送 shutdown_request (清理残留 Teamee)
348
488
 
349
- 读取团队配置获取活跃 Teamee 列表:
350
- - 读取 `~/.claude/teams/$team_name/config.json`
351
- - 提取 `members` 中 `name != "team-lead"` 的成员
352
-
353
- 向每个 Teamee 发送:
489
+ 检查 `teamee_map` 中是否还有未销毁的 Teamee:
354
490
  ```
355
- SendMessage(to=teamee.name, message={
356
- "type": "shutdown_request",
357
- "reason": "所有任务已完成/超时,准备清理团队",
358
- "request_id": "<生成唯一 ID>"
359
- })
491
+ # 检查映射表中是否还有残留 Teamee
492
+ if teamee_map is not empty:
493
+ print(f"⚠️ 发现 {len(teamee_map)} 个未销毁的 Teamee,发送 shutdown_request")
494
+ for task_id, teamee_name in teamee_map.items():
495
+ SendMessage(to=teamee_name, message={
496
+ "type": "shutdown_request",
497
+ "reason": "最终清理阶段,准备 TeamDelete",
498
+ "request_id": f"final-shutdown-{task_id}-{timestamp()}"
499
+ })
500
+ else:
501
+ print("所有 Teamee 已在监控循环中即时销毁,无需额外 shutdown")
502
+
503
+ # 额外安全网: 读取团队配置检查是否有遗漏的成员
504
+ # (防止映射表不一致的情况)
505
+ config = Read("~/.claude/teams/$team_name/config.json")
506
+ for member in config.members:
507
+ if member.name != "team-lead" and member.name not in teamee_map.values():
508
+ SendMessage(to=member.name, message={
509
+ "type": "shutdown_request",
510
+ "reason": "最终清理阶段,发现未在映射表中的成员",
511
+ "request_id": f"orphan-shutdown-{member.name}-{timestamp()}"
512
+ })
360
513
  ```
361
514
 
362
515
  ---
@@ -441,7 +594,7 @@ test -d "$HOME/.claude/tasks/$team_name" && echo "STILL_EXISTS" || echo "CLEAN"
441
594
  ## Teamee Prompt 模板
442
595
 
443
596
  ```markdown
444
- # [角色名称] - 团队任务执行
597
+ # [角色名称] - 单一任务专用执行
445
598
 
446
599
  ## 你的身份
447
600
  {角色 prompt_template}
@@ -450,12 +603,22 @@ test -d "$HOME/.claude/tasks/$team_name" && echo "STILL_EXISTS" || echo "CLEAN"
450
603
  - 团队名称: {team_name}
451
604
  - 你的角色: {role_id}
452
605
 
606
+ ## 任务绑定 (1:1 专用)
607
+
608
+ **⚠️ 重要:你只负责处理一个任务,不可认领其他任务!**
609
+
610
+ - 分配给你的任务 ID: {task_id}
611
+ - 任务主题: {task_subject}
612
+ - 完成此任务后,你将被立即销毁释放资源
613
+ - **禁止** 认领或执行其他任务
614
+ - 可以调用 TaskList 查看全局进度,但仅限查看,不可对其他任务执行 TaskUpdate
615
+
453
616
  ## 📖 首要任务:阅读工作包文档
454
617
 
455
618
  **执行任何任务前,必须先读取工作包文档!**
456
619
 
457
620
  ```
458
- 1. 认领任务后,立即读取任务 description 中指定的工作包文档
621
+ 1. 确认任务后,立即读取任务 description 中指定的工作包文档
459
622
  2. 工作包文档路径格式: `docs/wp/WP-XXX.md` 或 `docs/wp/WP-XXX-N-type.md`
460
623
  3. 从文档中获取:
461
624
  - 问题分析/上下文
@@ -466,36 +629,28 @@ test -d "$HOME/.claude/tasks/$team_name" && echo "STILL_EXISTS" || echo "CLEAN"
466
629
 
467
630
  ## 工作流程 (必须严格遵守)
468
631
 
469
- ### 1. 认领任务
632
+ ### 1. 确认任务分配
470
633
  ```
471
- # 查看所有任务
472
- result = TaskList()
473
-
474
- # 找可用任务:
475
- # - status = "pending"
476
- # - owner = 空 (无人认领)
477
- # - blockedBy 列表中的任务都已 completed
478
-
479
- # 认领任务
480
- TaskUpdate(taskId="{任务ID}", owner="{你的role_id}")
634
+ # 你的任务已由 Lead 预分配,直接确认
635
+ TaskGet(taskId="{task_id}")
636
+ # 验证 owner 是你、status 是 pending 或 in_progress
481
637
  ```
482
638
 
483
- ### 2. 执行任务
484
- - 认领后立即将 status 改为 "in_progress"
639
+ ### 2. 开始执行
640
+ - 立即将 status 改为 "in_progress"
641
+ - TaskUpdate(taskId="{task_id}", status="in_progress")
642
+ - 读取工作包文档获取完整上下文
485
643
  - 按任务描述执行
486
644
  - 完成验收标准
487
645
 
488
646
  ### 3. 完成任务
489
647
  ```
490
- TaskUpdate(taskId="{任务ID}", status="completed")
648
+ TaskUpdate(taskId="{task_id}", status="completed")
491
649
  ```
492
650
 
493
- ### 4. 继续下一个任务
494
- - 再次调用 TaskList 查看可用任务
495
- - 如有可用任务,重复步骤 1-3
496
- - 如无可用任务,**等待 Lead 的 shutdown_request**(不要主动退出)
651
+ ### 4. 等待关闭 (🔴 必须响应)
497
652
 
498
- ### 5. 接收关闭请求 (🔴 必须响应)
653
+ **完成任务后,不要查找其他任务!直接等待 Lead shutdown_request。**
499
654
 
500
655
  当收到 `shutdown_request` 消息时,**必须**发送响应:
501
656
 
@@ -515,7 +670,10 @@ SendMessage(
515
670
 
516
671
  发送响应后,你的工作结束,可以退出。
517
672
 
518
- **⚠️ 重要**: 不要主动退出!必须等待 Lead 的 shutdown_request。
673
+ **⚠️ 禁止事项**:
674
+ - 不要认领或执行其他任务(可以查看 TaskList 了解进度,但不可对其他任务执行 TaskUpdate)
675
+ - 不要在完成后继续工作
676
+ - 必须等待 Lead 的 shutdown_request,不要主动退出
519
677
 
520
678
  ## 相关经验(从历史中学习)
521
679
 
@@ -557,11 +715,12 @@ SendMessage(
557
715
  ⚠️ 如果不执行状态同步,工作包将被视为未完成!
558
716
 
559
717
  ## 重要提醒
560
- - **优先认领低 ID 任务** (如 Task #1 优先于 Task #2)
718
+ - **你只处理一个任务** 完成后等待 shutdown,不要查找其他任务
561
719
  - 完成后必须执行测试验证
562
720
  - 如遇阻塞问题,在任务描述中说明阻塞原因
563
721
  - 不要跳过任何验收标准
564
- - 任务完成后立即更新状态,方便其他 Teamee 认领依赖任务
722
+ - 任务完成后立即更新状态为 completed,方便 Lead 检测并解锁依赖任务
723
+ - 收到 shutdown_request 后立即响应,不要延迟
565
724
  ```
566
725
 
567
726
  ---
@@ -630,9 +789,10 @@ SendMessage(
630
789
  ┌─────────────────────────────────────────────────┐
631
790
  │ Task List (共享状态) │
632
791
  │ │
633
- │ Task #1: 状态=completed, Owner=scene-expert
634
- │ Task #2: 状态=in_progress, Owner=script-expert │
635
- │ Task #3: 状态=pending, blockedBy=[#2]
792
+ │ Task #1: 状态=completed, Owner=scene-expert-t1
793
+ │ Task #2: 状态=in_progress, Owner=script-expert-t2
794
+ │ Task #3: 状态=pending, blockedBy=[#2], Owner=""
795
+ │ (Task #3 等待 #2 完成后 Lead 创建专用 Teamee) │
636
796
  └─────────────────────────────────────────────────┘
637
797
  ```
638
798
 
@@ -832,10 +992,11 @@ docs/reports/2026-03-14_WP-073-075_execution_report.md
832
992
  ### Teamee 执行失败
833
993
  ```
834
994
  ⚠️ Task #2 执行失败
835
- Owner: godot-script-expert
995
+ Owner: godot-script-expert-t2
836
996
  状态: in_progress (卡住)
837
- 处理: Lead 发送 shutdown_request 关闭 Teamee
838
- 创建新任务重试或人工介入
997
+ 处理: Lead 发送 shutdown_request 即时销毁该 Teamee
998
+ 从 teamee_map 移除映射
999
+ 创建新 Teamee 重试 或 人工介入
839
1000
  ```
840
1001
 
841
1002
  ### 部分任务超时
@@ -866,12 +1027,13 @@ Owner: godot-script-expert
866
1027
 
867
1028
  1. **TeamCreate 是必须的** - 没有团队就没有共享 Task List
868
1029
  2. **blockedBy 自动阻塞** - 依赖机制由 Task List 自动处理
869
- 3. **Teamee 自主认领** - Lead 不需要手动分配任务
870
- 4. **角色匹配提升质量** - 专业角色比通用代理更高效
871
- 5. **记忆注入避免踩坑** - 从历史经验中学习
872
- 6. **经验沉淀形成闭环** - 每次执行都让角色更聪明
873
- 7. **🔴 TeamDelete 是强制的** - 无论成功/失败/超时,都必须执行清理!
874
- 8. **🔴 监控循环不可跳过** - Lead 必须进入 Step 6.5 监控循环
1030
+ 3. **Lead 按需分配 (1:1)** - 每个 WP 由 Lead 创建专用 Teamee 并预分配,禁止一个 Teamee 处理多个 WP
1031
+ 4. **即时销毁** - Teamee 完成任务后立即销毁释放资源,不等到全部完成
1032
+ 5. **角色匹配提升质量** - 专业角色比通用代理更高效
1033
+ 6. **记忆注入避免踩坑** - 从历史经验中学习
1034
+ 7. **经验沉淀形成闭环** - 每次执行都让角色更聪明
1035
+ 8. **🔴 TeamDelete 是强制的** - 无论成功/失败/超时,都必须执行清理!
1036
+ 9. **🔴 监控循环不可跳过** - Lead 必须进入 Step 6.5 监控循环,负责动态创建和即时销毁
875
1037
 
876
1038
  ## Cleanup Guarantee (清理保障)
877
1039
 
@@ -879,10 +1041,10 @@ Owner: godot-script-expert
879
1041
  ┌─────────────────────────────────────────────────────────────┐
880
1042
  │ 强制清理检查点 │
881
1043
  │ │
882
- │ ✅ 正常完成 → Step 6.5 检测 → Step 7 清理 → TeamDelete
883
- │ ✅ 部分失败 → Step 6.5 检测 → Step 7 清理 → TeamDelete
884
- │ ✅ 超时 → Step 6.5 超时 → Step 7 强制清理 → TeamDelete
885
- │ ✅ 异常中断 → 捕获中断 → Step 7 强制清理 → TeamDelete
1044
+ │ ✅ 正常完成 → Step 6.5 即时销毁 → Step 7 最终清理 → TeamDelete
1045
+ │ ✅ 部分失败 → Step 6.5 即时销毁 → Step 7 最终清理 → TeamDelete
1046
+ │ ✅ 超时 → Step 6.5 超时销毁 → Step 7 强制清理 → TeamDelete
1047
+ │ ✅ 异常中断 → 捕获中断 → Step 7 强制销毁残留 → TeamDelete
886
1048
  │ │
887
1049
  │ ❌ 无任何情况可以跳过 TeamDelete! │
888
1050
  └─────────────────────────────────────────────────────────────┘
@@ -899,8 +1061,9 @@ Owner: godot-script-expert
899
1061
  | 创建协调 | 无 | TeamCreate |
900
1062
  | 任务管理 | 主 Agent 手动 | TaskCreate + TaskList |
901
1063
  | 依赖处理 | 主 Agent 分析 | blockedBy 自动阻塞 |
902
- | 任务分配 | 主 Agent 指定 | Teamee 自主认领 |
1064
+ | 任务分配 | 主 Agent 指定 | Lead 按需创建 + 预分配 (1:1 绑定) |
903
1065
  | 状态同步 | 无 | TaskList 实时 |
1066
+ | Teamee 生命周期 | 无管理 | 按需创建 / 即时销毁 |
904
1067
  | 清理 | 无 | TeamDelete |
905
1068
 
906
1069
  ### 保留的功能