状态机
触发渠道
① REST
POST /api/devloop/projects/:pid/requirement
JSON body 走 CLAUDE.md 推荐的 -d @/tmp/req.json 方式。
② Web UI
DevLoopDashboard 右上角 + NEW REQUIREMENT,弹出 textarea。
③ 自动信号
L1 blocked 或 L2 exhausted 时,LoopController 主动发 SSE,由前端弹「请补充信息」对话框。
增量 Unit 算法
Architect 对比新旧 units.json,标记三种变化:
| 变化类型 | 判断 | 处置 |
|---|---|---|
| added | 新 unit.id 不在旧 list | status = pending,加入 L1 队列 |
| changed | 同 id,contract_hash 变化 | status 回退到 pending,加入 L1 队列(旧代码归档到 history/) |
| removed | 旧 id 不在新 list | 整个 unit 目录归档到 history/removed/,从 DAG 摘除 |
| unchanged | id 在且 hash 不变 | 保持 passed,无须重跑。这是增量化的关键 |
PRD 增量合并示例
PM Agent 不重写整个 PRD,只追加 <section data-rev=N>,并维护 doc 级 data-rev 自增。这样人类能直观看到「这一轮反馈引入了什么」。
<article data-doc="prd" data-rev="2"> <section data-rev="1"> 用户名密码登录,会话 7 天有效 </section> <section data-rev="2"> 个人主页:显示用户名 / 邮箱 </section> </article>
<article data-doc="prd" data-rev="3"> <section data-rev="1">...</section> <section data-rev="2">...</section> <section data-rev="3" data-origin="yibo@2026-05-12T10:31"> + 新增:支持 GitHub OAuth 登录 + NFR:3rd-party token 刷新 ≤ 5s </section> </article>
什么时候算「项目结束」
L3 没有自动退出条件。结束信号来自人类的显式动作:
- 显式 sign-off:
POST /api/devloop/projects/:pid/sign-off→ 项目 status 置shipped-final,停止接收新需求。 - 归档:30 天无人类反馈,自动归档但保留所有产物。
- 放弃:
POST .../abandon,整个项目目录加.abandoned标记,从 Dashboard 列表移除。