auto-sync: 2026-06-03 00:42:29

This commit is contained in:
cfdaily
2026-06-03 00:42:29 +08:00
parent e7208dda1c
commit cda205763a
+23 -12
View File
@@ -1,11 +1,11 @@
# #06 PM2 Crash 恢复设计
> 版本: v1.1
> 日期: 2026-06-01
> 版本: v1.2
> 日期: 2026-06-03
> 作者: 庞统(副军师)
> 状态: 二次评审中
> 状态: 待评审(v1.2
> 前置: spawner-monitor-design.md §5 A0Agent crash 恢复)
> 变更: v1.1 纳入司马懿评审意见(Blocking #1 reviewing 状态 + Blocking #3 虚拟项目 + 建议 #2 审计事件)
> 变更: v1.2 两个关键改进:(1) working→pending 保留 current_agent 让同一 agent 接手;(2) reviewing 精确恢复到前置状态而非硬推 done
---
@@ -127,15 +127,19 @@ PM2 启动 moziplus v2
```
working + last_attempt.completed?
├─ No → pending
├─ No → pending(保留 current_agent
└─ Yes + has_output?
├─ No → pending
├─ No → pending(保留 current_agent
└─ Yes + has_handoff?
├─ No → pending可能标了 working 就 timeout 退出了,产出残留
├─ No → pending保留 current_agent
└─ Yes → reviewagent 已完成工作并交接)
```
**注意**`pending` 推回后 assignee 被清空,ticker 自然重新 broadcast 或 dispatch。如果原来有 assigneeagent 会看到之前的 outputs 和 comments(黑板数据不丢失),可以选择继续或重新认领。
**保留 current_agent 原则**推回 pending 时不清空 `current_agent`,让同一 agent 重新接手。原因:
1. 该 agent 之前有对话上下文(现已丢失),但黑板上的 outputs/comments 是它写的,它最了解上下文
2. Dispatcher 路由时如果 current_agent 仍在,直接复用,省去重新路由
3. Agent 被 bootstrap 注入完整任务上下文(含之前的产出),自行决定继续还是重来
4. 这是冗余操作,但保证状态一致
#### review 状态
@@ -168,13 +172,20 @@ working + last_attempt.completed?
**含义**parent task 进入庞统 round review 的中间状态(`done/failed → reviewing`)。
**恢复逻辑**推回 `working`,让 ticker 重新触发 `_check_round_complete`
**恢复逻辑**查 events 表找到转入 reviewing 之前的状态(done 或 failed),精确推回该状态
**原因**reviewing 状态依赖 `_spawn_pangtong_review` 的回调 `_handle_review_conclusion` 来推进。PM2 crash 后回调丢失,`_handle_review_conclusion` 永不触发,parent 永久卡死。推回 working 后,下个 tick 的 `_check_round_complete` 检查 sub task 全部终态 + parent 状态非 done/failed → 跳过。但 `_check_round_complete` 只在 `parent_status in (done, failed)` 时触发,所以需要推回 working 后手动触发一次,或者直接推回 done(让 `_check_round_complete` 自然重新触发 review spawn)。
**决策树**
**最终策略**:推回 `done`(恢复到 reviewing 之前的状态),`_check_round_complete` 会自然重新触发庞统 review。
```
reviewing → 查 events 表最后一条 task_status_changed 到 reviewing 的记录
├─ 找到前置状态 done → 推回 done
├─ 找到前置状态 failed → 推回 failed
└─ 找不到 → 兜底推 donedone/failed→reviewing 是唯一合法路径,大概率是 done)
```
> reviewing 状态是从 done/failed 转入的(`_set_parent_reviewing`),所以推回 done 是合法的(reviewing → done 在 VALID_TRANSITIONS 中)。但更安全的做法是查 events 表看 reviewing 之前是什么状态。简化起见直接推 done
**原因**reviewing 状态依赖 `_spawn_pangtong_review` 的回调 `_handle_review_conclusion` 来推进。PM2 crash 后回调丢失,`_handle_review_conclusion` 永不触发,parent 永久卡死。推回 done/failed 后,`_check_round_complete` 会在下个 tick 自然重新触发庞统 review spawn
**精确恢复优于硬推 done**:因为 parent 可能是从 failed 转入 reviewing 的(子任务失败触发 round review),推回 done 语义错误。查 events 表是确定性操作,成本可忽略(单条 SQL)。
#### escalated / waiting_human / paused 状态