auto-sync: 2026-05-30 00:41:37
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
| v3.0 | 2026-05-28 | **本版**:PRD 3.0 对齐 + 源码回溯 + 完整现状记录 |
|
||||
| v3.0.1 | 2026-05-28 | 补充6个讨论话题(§6.5/§10.4~10.6)+ 新增§21 T阶段规划(T1~T6) |
|
||||
| v3.0.2 | 2026-05-29 | §12.3 Mail API 防御 + Prompt 约束设计(纳入司马懿评审意见);§6.5 补充 spawn 改造方向 |
|
||||
| v3.0.3 | 2026-05-30 | §6.3.1 Session Lock 实测结论 + L3a/L3b/L3c 有效性分析 + Bug 修复(outcome 白名单 + 详细日志) |
|
||||
|
||||
### 1.2 v3.0 定位
|
||||
|
||||
@@ -509,6 +510,80 @@ Ticker.tick()
|
||||
6. wrapped_on_complete 闭包 → counter.release (try/finally 保证)
|
||||
```
|
||||
|
||||
### 6.3.1 Session Lock 实测结论 (v3.0.3)
|
||||
|
||||
> 2026-05-30 基于实际 Gateway 日志 + daemon 日志的联合分析
|
||||
|
||||
#### 三层防线 (L3a/L3b/L3c)
|
||||
|
||||
spawn 前检查 main session 状态(`_check_session_state`),三层防线:
|
||||
|
||||
```python
|
||||
# spawner.py spawn_full_agent() 内
|
||||
if use_main_session:
|
||||
session_state = self._check_session_state(agent_id)
|
||||
# L3a: lock 文件检查(唯一有效防线)
|
||||
if session_state.get("lock_pid_alive"):
|
||||
raise AgentBusyError(...)
|
||||
# L3b: sessions.json status 检查(实测无效)
|
||||
if session_state.get("status") == "running":
|
||||
raise AgentBusyError(...)
|
||||
# L3c: compact 检查
|
||||
if session_state.get("recent_compact"):
|
||||
raise AgentBusyError(...)
|
||||
```
|
||||
|
||||
#### 实测数据 (2026-05-30 双邮件测试)
|
||||
|
||||
| 时间 | 事件 | status | lock_pid | alive | 拦截者 |
|
||||
|------|------|--------|----------|-------|--------|
|
||||
| 00:25:35 | spawn simayi (测试1) | done | None | False | ✅ 通过 |
|
||||
| 00:26:05 | ticker 重试 simayi (测试2) | **done** | **75279** | **True** | **L3a** |
|
||||
| 00:26:05 | spawn pangtong (处理回复) | done | None | False | ✅ 通过 |
|
||||
| 00:26:36 | ticker 再试 simayi | done | 75279 | True | L3a |
|
||||
| 00:30:38 | ticker 尝试 pangtong | **failed** | **75279** | **True** | **L3a** |
|
||||
| 00:31:09 | spawn pangtong (回复) | done | None | False | ✅ 通过 |
|
||||
|
||||
#### 关键发现
|
||||
|
||||
1. **`sessions.json` 的 `status` 全程未出现 `running`**
|
||||
- Gateway 处理 Agent turn 时,`sessions.json` 的 status 在 daemon 30s 采样间隔内不会变为 `running`
|
||||
- 唯一可靠信号是 lock 文件(L3a)
|
||||
- L3b 的 `status == "running"` 检查在实际场景中**从未触发**
|
||||
|
||||
2. **L3a(lock check)是唯一有效防线**
|
||||
- 所有拦截都是 `lock_pid_alive=True`(L3a)
|
||||
- L3b 修复(`"processing"` → `"running"`)是正确的但实测无效
|
||||
|
||||
3. **Gateway 内部存在二次 lock 竞争**
|
||||
- Gateway 处理 CLI turn 时(持有 session write lock 5+ 分钟),内部会产生另一个请求也想写同一 session
|
||||
- 表现为 `SessionWriteLockTimeoutError: timeout 60000ms`
|
||||
- 这是 Gateway 内部并发问题,daemon 无法解决
|
||||
- 02 架构改造(统一 main session)是根本解法
|
||||
|
||||
4. **status 字段可能出现 `failed`**
|
||||
- 00:30:38 检查 pangtong 时 `status=failed`(上一次 turn lock 超时后 Gateway 写入)
|
||||
- L3b 不检查 `failed`,此时只有 L3a 在守
|
||||
|
||||
#### 已修复的 Bug
|
||||
|
||||
| Bug | 问题 | 修复 | 影响 |
|
||||
|-----|------|------|------|
|
||||
| L3b 枚举值 | `"processing"` 应为 `"running"` | ✅ 已修复 | L3b 形同虚设,现恢复理论作用 |
|
||||
| outcome 白名单 | `process_crash`/`unknown_status` 不在 CHECK 约束中 | ✅ 已映射到 `crashed`/`agent_error` | daemon 崩溃根因 |
|
||||
| 无详细日志 | session state 检查通过时不打日志 | ✅ 已加 INFO 日志 | 下次出问题可追溯 |
|
||||
|
||||
#### TOCTOU 竞态(已知限制)
|
||||
|
||||
L3a 检查和 CLI subprocess 获取 write lock 之间存在时间差:
|
||||
1. daemon 检查 `lock_pid_alive=False` → 通过
|
||||
2. spawn CLI subprocess
|
||||
3. CLI 连接 Gateway 请求 session write lock
|
||||
4. 此时用户通过 webchat 发消息 → Gateway 持有 lock
|
||||
5. CLI 等 60s 超时 → `SessionWriteLockTimeoutError`
|
||||
|
||||
这不是 daemon 能解决的问题,需要 02 架构改造(不再用 CLI spawn,统一投递到 main session)。
|
||||
|
||||
### 6.4 关键差异: 设计 vs 实现
|
||||
|
||||
| 设计文档 | 实际代码 | 状态 |
|
||||
@@ -1592,6 +1667,8 @@ PRAGMA busy_timeout=5000 # 写锁等待 5s
|
||||
| C4 | §17.1 #5 | **工具链集成** | PRD 差距 | P3 |
|
||||
| C5 | §17.1 #6 | **经验闭环 IMPROVE** | PRD 差距 | P3 |
|
||||
| C6 | §17.2 #16 | **per-provider 冷却** | 设计未落地 | P4 |
|
||||
| C7 | §6.3.1 | **Gateway 内部 session lock 竞争**(已知限制,02 架构改造解决) | 已知限制 | P2 |
|
||||
| C8 | §6.3.1 | **TOCTOU 竞态**(L3a 检查和 CLI 获取 lock 之间的窗口期) | 已知限制 | P2 |
|
||||
| D1 | HEARTBEAT | **v2.8 executor-prompt-design 漏洞**(3 个设计漏洞未修) | 设计暂停 | P3 |
|
||||
| D2 | HEARTBEAT | **Pipeline 架构调研**(暂停,已废弃——不搞 Pipeline 框架) | 设计暂停 | ~~P3~~ 📦 已归档 |
|
||||
| D3 | MEMORY | **M2 进程管理**(同步 vs 异步) | 待讨论 | P2 |
|
||||
@@ -1645,12 +1722,16 @@ PRAGMA busy_timeout=5000 # 写锁等待 5s
|
||||
|
||||
**涉及文件**: `src/daemon/ticker.py`、`src/daemon/dispatcher.py`、`src/daemon/router.py`
|
||||
|
||||
**前置条件**: T1 完成 ✅
|
||||
**前置条件**: T1 完成 ✅ + #02 Main Session Delegation 架构方案确认
|
||||
|
||||
**bug 修复**(T2 前置):
|
||||
- B8: BUG-7 planning 暂停失败 — 需在功能开发前修复
|
||||
- B9: BUG-8 cancel→resume 空图完成 — 需在功能开发前修复
|
||||
|
||||
**已知限制**(T2 需解决):
|
||||
- C7: Gateway 内部 session lock 竞争 — 02 架构改造(统一 main session)根治
|
||||
- C8: TOCTOU 竞态 — 同上,不再用 CLI spawn
|
||||
|
||||
**来源**: v2.8-direction-notes §一~§二 + §17 #2/#3
|
||||
|
||||
#### T3: 主动汇报 + 需求探索触发 📋 待开始
|
||||
@@ -1788,6 +1869,8 @@ PRAGMA busy_timeout=5000 # 写锁等待 5s
|
||||
| C4 | 工具链集成 | T8 | ❌ |
|
||||
| C5 | 经验闭环 IMPROVE | T7 | ❌ |
|
||||
| C6 | per-provider 冷却 | T8 | ❌ |
|
||||
| C7 | Gateway 内部 session lock 竞争 | T2 | ⚠️ 已知限制 |
|
||||
| C8 | TOCTOU 竞态 | T2 | ⚠️ 已知限制 |
|
||||
| D1 | executor-prompt-design 漏洞 | T5 | ❌ |
|
||||
| D2 | Pipeline 架构调研 | — | 📦 已废弃 |
|
||||
| D3 | M2 进程管理 | T6 | ❌ |
|
||||
@@ -1812,3 +1895,5 @@ PRAGMA busy_timeout=5000 # 写锁等待 5s
|
||||
| 14 | prompt_templates 角色模板 | B6 | T5 |
|
||||
| 15 | CLI Schema 校验 | B7 | T5 |
|
||||
| 16 | per-provider 冷却 | C6 | T8 |
|
||||
| — | Gateway 内部 session lock 竞争 | C7 | T2 (02 架构改造) |
|
||||
| — | TOCTOU 竞态 | C8 | T2 (02 架构改造) |
|
||||
|
||||
Reference in New Issue
Block a user