diff --git a/docs/design/07-spawner-acquire-first.md b/docs/design/07-spawner-acquire-first.md index 8e39df0..ce846e9 100644 --- a/docs/design/07-spawner-acquire-first.md +++ b/docs/design/07-spawner-acquire-first.md @@ -233,21 +233,22 @@ def _revive_session(agent_id: str) -> bool: pass ``` -### 4.5 O5: compact 扫描条件收紧 +### 4.5 O5: compact 扫描条件 — 去掉 status 过滤(2026-06-05 修订) -当前 compact 扫描在 status 非 idle/done/unknown/None 时都触发,范围过宽。 +**原设计**:只在 status=running 时扫描 compact,理由是"其他状态不需要检查"。 -**改后**:只在 status 为 running 或 compacting 相关时扫描: +**Bug 发现**(2026-06-05):done 状态下 compaction 完全可能正在进行(openclaw turn 结束后自动触发 fromHook compaction)。此时 spawner spawn 新 agent → 撞上 compact 中的 session → exit=1 crash。实测 case:mail-1780656469707。 + +**修正方案**:去掉 status 前置条件,对所有状态都检测: ```python -# 只在这些状态下检查 compact -if result["status"] in ("running",) and sf: +# compact 检测:对所有状态都扫描 +# done 状态下 compaction 可能正在进行,不能跳过 +if sf: result["recent_compact"] = AgentSpawner._check_recent_compaction_jsonl(sf) ``` -注:Gateway 的 sessions.json status 实际值主要是 `idle/running/timeout/failed`。 -`running` 时检查 compact 有意义(agent turn 执行中可能触发 compact)。 -其他状态不需要检查。 +代价:每次 _check_session_state 都读 jsonl 末尾 50KB。但 Phase 2 已在 counter 锁内执行,30 秒才一次,I/O 开销可忽略。 ## 五、改动范围