端到端时序图
同一时刻三个 Loop 的并发关系
L1 内部允许并行(多 Unit),但 L2 始终串行(一个项目同时只能有一个 Integrator 跑)。L3 触发会等待当前 L2 跑完再合并 PRD。
| 场景 | 处理 |
|---|---|
| L1 跑了一半,L3 新需求到达 | 当前 L1 跑完再合并(保证状态一致),合并后增量 reset |
| L2 跑了一半,L3 新需求到达 | L2 跑完再合并;若 L2 失败也照常合并(人类可能本来就是为了改这个) |
| L2 跑了一半,又收到一个 L3 反馈 | 队列化,按时间序处理 |
| 多项目并行 | 每项目独立 LoopController 实例,互不干扰 |
SSE 事件清单
Dashboard 通过 GET /api/devloop/projects/:pid/stream 订阅。事件类型:
| event | 触发时机 | payload 关键字段 |
|---|---|---|
prd.updated | PM 写 PRD 完成 | rev, changeSummary |
sdd.updated | Architect 写 SDD 完成 | rev, mode (generate/patch) |
unit.state | UnitRegistry 状态转换 | unit_id, from, to, retries |
agent.stream | Agent stdout/stderr 流式 | agent, unit_id, chunk |
integration.result | Integrator 返回 | ok, failures[] |
triage.result | BugTriager 返回 | category, confidence, affected_units |
human_intervention_needed | confidence < 0.5 或 blocked | reason, suggestion |
project.shipped | L2 通过 | final_rev |
project.exhausted | L2 修复预算耗尽 | last_triage |
错误与中止
LoopController 顶层 try/catch:
- Agent 调用超时(> 10min):kill 进程,retry 一次,再失败置 Unit blocked。
- DocStore 写失败(磁盘满 / 权限):整个项目挂起,SSE 告警人类。
- 未捕获异常:记录到
stream.log,发fatal事件,不自动重启(避免雪崩)。