最小改造路径
五个阶段递进,每阶段独立可演示。P0 把 79 个工具实现 + ACP 桥接搭好;P1 不动核心,让 PM+Architect 跑出文档;P2 先单 Unit;P3 才把 L1 + L2 接起来;P4 加 L3 反馈 + UI。每阶段对应一个 PR。
第一天 Quick-Start · 从零起步
「我装好仓库 cd 进去,第一行命令该是什么」—— 答案:
# 1. 拉仓库 + 装依赖
git clone gitlab-wuwei.hexpm.com:yibo/lemonboss.git
cd lemonboss
pnpm install # LemonBoss 用 pnpm workspace
# 2. 配 .env
cp .env.example .env
# 编辑设置 PORT=3010 等;v1 不需要 OPEN_API_KEYS
# 3. 浏览本 PRD (推荐先扫一遍 index → reading-guide)
open docs/prd/newfunction/index.html # macOS
# 或: python3 -m http.server -d docs/prd/newfunction 8000 → open localhost:8000
# 4. 验证文档侧 tooling 已经就绪
node scripts/extract-manifest.js # 期望: 54 MVCP defs 100%
node scripts/build-search-index.js # 期望: 51 pages 195KB
# 5. 从 P0.0 开始动代码 (按 §五阶段总览 P0 表格顺序)
mkdir -p server/services
# 第一个文件: server/services/path-resolver.js (所有人都依赖它)
# 第二个文件: server/services/doc-store.js
# ...按 §P0 子任务速览 P0.0 行的服务清单顺次实现
# 6. P0.B 启用 Mock Claude CLI 模式 (一旦工具骨架在)
# 详见 arch-acp-bridge.html · Mock Mode 章节
MOCK_CLAUDE=1 node scripts/phase0-verify.js # 工具流跑通,不烧 token
# 7. 真跑 P0 验证 (P0.J 完成后)
node scripts/phase0-verify.js # ✓ All 79 tools + 1 mock PM call
node scripts/phase0-test-call.js # ✓ todolist 落盘 + SSE 触发
# 8. 进 P1: 准备启动真实 Agent
PORT=3010 node server/index.js & # server 起来
node scripts/devloop-new.js \
--name "Auto TODO" \
--requirement "做一个 TODO API + Vue 前端" # sandbox 模式
# 期望: 30-60s 内 data/.../projects/p-XXXXXX/prd/ 完整生成
第一天能 100% 跑通到第 4 步(文档侧验证);P0.0 实施开始后第 5 步以下才有意义。
五阶段总览
| 阶段 | 目标 | 新增 / 修改 | 可演示场景 |
|---|---|---|---|
| P0 · Bootstrap 3.5 周 |
服务层 7 件套(pathResolver/docStore/unitRegistry/bugTracker/timelineLogger/sseBroker/GitVault)+ 79 工具实现 + Mock Claude CLI 模式 + ACP 桥接 + 系统提示提取 + git 集成 | 7 个 server/services/*.js、tool-registry(34 工具)、acp-bridge + Mock 模式、git-versioning、scripts/extract-agent-prompts.js、scripts/phase0-verify.js |
MOCK_CLAUDE=1 phase0-verify 通过 → 真跑 phase0-verify 通过 → 一个 mock PM call 落 todolist + .git 初始化 + 首个 prd commit |
| P1 · Docs MVP | 能由 PM + Architect 把一段需求转成多页 PRD 站点 + 多页 SDD 站点 + units.json + integration/spec.json |
DocStore、PM / Architect 模板、POST /api/devloop/projects |
curl 一段中文需求 → 文件系统里看到 PRD/SDD 多页站点 + units.json + integration/spec.json + agent-state/ |
| P2 · L1 单 Unit | 对单个 Unit 跑 Coder→Tester 重试到通过 | Coder / Tester 模板、UnitRegistry、retryWithReflection(新写在 loop-controller.js 内,不抽公共) |
故意挖一个 bug 让 Tester 红,看 Coder 反思后绿 |
| P3 · L1 + L2 联动 | 多 Unit 并行 + 集成测试 + 失败回写 | LoopController、Integrator / BugTriager 模板,复用 scheduler |
故意写 contract mismatch,看 SDD 自动 patch + 受影响 Unit reset → 重跑 L1 |
| P4 · L3 + UI | 人类反馈触发增量;前端实时看板 | DevLoopDashboard.vue、SSE 流、PRD diff 渲染 |
页面上发新需求 → 看到 PRD 新增 section + 新 Unit 自动入队 |
P0 · Bootstrap(~2.5 周 / 11.5 天)
这是 P1 的前置条件。没有 P0,PM/Architect 的 79 个工具签名都是空中楼阁。详细工时分解 + 工具组织见 arch-tool-registry §⑪。
P0 子任务速览
| 子阶段 | 内容 | 工时 | 难度 |
|---|---|---|---|
| P0.0 服务层 7 件套 所有其他都依赖它 |
server/services/ 顺次实现:① path-resolver.js(~80 行;第一个写,其余都依赖它)② doc-store.js(~140 行;prd/sdd/units IO + cheerio 校验)③ unit-registry.js(~120 行;Unit FSM + l2GateOpen)④ bug-tracker.js(~110 行;bugs.ndjson CRUD + dedupKey)⑤ timeline-logger.js + changelog-writer.js(~80 行合计)⑥ sse-broker.js(~80 行;订阅 + 心跳 + replay)⑦ git-vault.js(~150 行;spawn git wrapper + per-pid mutex) |
4.5 天 | 低中(独立实现 · 每个文件可单测) |
| P0.A 工具实现 需 P0.0 完成 |
server/src/tools/devloop/ 下 7 个文件,34 个独立函数 (~1700 行)。每个工具 wrapper 通过 ctx 引用 P0.0 的服务 |
5 天 | 中(cheerio 多) |
| P0.A2 Mock Claude CLI 模式 开发期省 token |
给 ClaudeCliProtocol 加 MOCK_CLAUDE=1 分支,读 system/mock-responses/{agent}/*.json 当 stub 回复。详见 acp-bridge · Mock Mode |
0.5 天 | 低 |
| P0.B 提示提取 | scripts/extract-agent-prompts.js 从 6 个 agent HTML §2.2 抽 prompt |
0.5 天 | 低(正则) |
| P0.C 模板注册 | system/agents/_registry.json 加 6 条 devloop-* + toolPolicy |
0.5 天 | 低 |
| P0.D CLI tools 注入 | packages/acp-core/protocol/ClaudeCliProtocol.js 改 ~10 行,按 toolPolicy 生成 --tools json |
1 天 | 中 |
| P0.E agent-manager 透传 | 加 toolRegistry / toolCtx / onChunk 三个可选参数,~10 行 | 0.5 天 | 低 |
| P0.F jsonGuard 挂 Bash | Bash 工具 preExecute 钩子拦截 inline JSON | 0.5 天 | 低 |
| P0.G 验证脚本 | scripts/phase0-verify.js + phase0-test-call.js |
1 天 | 低 |
| P0.H 联调 | 跑一个 mock PM 调用 → 看 todolist 落盘 + SSE 触发 | 2 天 | — |
| P0.I git 集成到 LoopController | createProject 时 git init + .gitignore 模板;callAgentWithPersistence success 分支加 commitAfterAgent;recoverOnBoot 加 git status 检查(GitVault 已在 P0.0 ⑦ 落盘) | 1 天 | 中 |
| P0.J git 验证 | phase0-verify 加:项目初始化后 .git 存在 + 一次 mock commit + tag · listTags | 0.5 天 | 低 |
| P0 合计 | — | 17 天 ≈ 3.5 周 | — |
验收
node scripts/phase0-verify.js
# ✓ All 79 tools registered (34 unique impl)
# ✓ 6 system prompts extracted to system/agents/devloop-*/prompt.md
# ✓ _registry.json contains all 6 devloop-* entries
node scripts/phase0-test-call.js
# ✓ Mock PM call → write_todolist tool invoked
# ✓ data/companies/c-test/projects/p-mock/agent-state/pm-todo.json written
# ✓ SSE agent.todolist event emitted
# ✓ No sandbox violations
关键决策:P0 期间 agent-manager 改动 ≤ 20 行,全是追加可选参数。老调用方(Master Agent / Innovator)不受影响。
P1 · Docs MVP(~1 周 / 5 天)
建议的 demo 需求:「一个 TODO 列表 API + 前端」。比登录系统更小、不涉及 auth/JWT/bcrypt 等坑、30 分钟能端到端跑通。
预期 Architect 拆出 3 个 Unit:todo-be(POST/GET /todos)· todo-fe(Vue 列表)· 可选 todo-db(SQLite schema)。
登录系统留到 P3 当 contract_mismatch 演示用。
新增文件
server/
├── services/
│ └── doc-store.js # ~140 行
├── routes/
│ └── devloop.js # 只挂 POST /projects · GET /state,~80 行
└── src/core/
└── (LoopController 阶段性 stub)
system/agents/
├── devloop-pm.md # PM system prompt
├── devloop-architect.md # Architect system prompt
└── _registry.json # 追加 6 条(先用 PM + Architect 两条)
验收
curl -X POST http://localhost:3010/api/devloop/projects -d @/tmp/req.json
# /tmp/req.json: {"company_id":"c-001","name":"todo-demo","requirement":"做一个 TODO 列表:能新增、列表、Vue 前端"}
# 期望产物(与 data-layout.html 对齐)
data/companies/c-001/projects/p-XXXXXX/
├── project.json ✓ # M-1 项目元数据
├── prd/ ✓ # M-3 多页 PRD 站点
│ ├── index.html
│ ├── reading-guide.html
│ ├── product/{background,personas,...}.html
│ ├── feature/feature-tree.html
│ ├── flow/user-flows.html
│ └── prototype/proto-*.html
├── sdd/ ✓ # M-4 多页 SDD 站点
│ ├── index.html
│ └── mvcp/{model,view,control,process}.html
├── units.json ✓ # M-2 含 l2_rounds / l2_budget 初值
├── integration/spec.json ✓ # Architect 写
├── agent-state/ ✓ # M-10 / M-12 Agent 持久化运行态
│ ├── pm.json · pm-todo.json
│ └── architect.json · architect-todo.json
└── history/ ✓ # 全部 rev 归档
├── prd-rev-001.html
└── sdd-rev-001.html
P2 · L1 单 Unit(~1.5 周 / 8 天)
新增文件
server/
├── services/
│ └── unit-registry.js # ~120 行
└── src/core/
└── loop-controller.js # runUnit() 单 unit 循环 + retryWithReflection() 内置,~140 行
system/agents/
├── devloop-coder.md
└── devloop-tester.md
关于反思重试:直接在 loop-controller.js 内写一份 retryWithReflection()。不从 evolution-loop.js 抽公共。原因见 arch-mapping · 为什么 P1~P4 不抽公共 retry 函数。
修改文件
server/routes/devloop.js· 加POST /api/devloop/projects/:pid/run(即 sdd-control · C-3);P2 阶段 handler 临时支持 query?only=<unitId>调用loopController.runUnit(pid, unitId)让单 unit 可测,P3 改造runProject()后即移除only参数,与 C-3 完全等价server/services/evolution-loop.js· 不动
验收
跑命令后看到:
- Unit 状态从
pending → coding → testing → failed → coding → testing → passed coder.log第二条决策明显引用了第一条的失败原因(说明反思生效)- 沙箱越权(试图改其他 unit code)被工具层拒绝
P3 · L1 + L2 联动(~3 周 / 15 天)
新增 / 完善
server/src/core/loop-controller.js # 完整 runProject() 主循环(去掉 P2 的 ?only= 临时入口)
system/agents/
├── devloop-integrator.md
└── devloop-triager.md
server/services/
├── sse-broker.js # SSE 订阅管理 + stream.log replay,~80 行
└── bug-tracker.js # 写 bugs.ndjson + GET /bugs 端点支持,~80 行
server/routes/devloop.js # 加 C-5 GET /api/devloop/projects/:pid/stream + GET /:pid/bugs
# 同步生成的 append-only 产物(与 data-layout.html 对齐)
projects/{pid}/
├── timeline.ndjson # M-13 全流程统一日志(loop-controller / agent-bridge 写)
├── bugs.ndjson # M-14 跨 run bug 台账(bug-tracker 写)
├── changelog.ndjson # M-15 PRD/SDD/units rev 变更流(DocStore 写)
└── stream.log # SSE 客户端视角日志(sse-broker 写,7 天滚动)
验收
P3 必须在 4 类 L2 分支(参见 sdd-process · P-2)下都跑通:
① contract_mismatch · 自动 patch SDD
- 需求 = 「一个登录系统:邮箱密码 + token,前端展示」
- 在 Architect 生成的 SDD 中故意插入矛盾(auth-be 写 401,auth-fe 假设 403)
- L1 全部 passed → L2 集成失败
- BugTriager 给出
contract_mismatch,confidence ≥ 0.5 - Architect 自动 patch SDD(mode=patch)→
sdd.updated事件 - auth-be + auth-fe reset → 重跑 L1(计 1 个 l2_round)
- 第二次 L2 通过 →
project.shipped
② impl_bug · 不改 SDD,仅 reset
- SDD 正确,故意把 auth-be 实现写成 password 字段名打错
- BugTriager 归因
impl_bug→ SDD 不动 → 仅 auth-be reset → 重跑 L1(不烧 l2_round 预算)
③ spec_ambiguous / confidence
- 需求中故意留模糊点(如「token 续期策略」未定)
- Triager 给出
spec_ambiguous或 confidence - SSE 收到
human_intervention_needed(reason=low_confidence_triage)→ LoopController 进入l2_blocked,不自动 patch
④ infra_flake · 直接重跑
- 模拟 Integrator 进程超时(kill -9)→ 归因
infra_flake→ 直接runL2()重跑,不烧预算、不动 Unit
⑤ 可观测性产物校验(4 类分支跑完后统一检查)
bugs.ndjson含上述每次 triage 结果(open → fixing → fixed → verified 状态机轨迹)changelog.ndjson至少 1 条 sdd-rev 变更(来自分支 ①)timeline.ndjson含完整事件链路(unit.state / integration.result / triage.result / sdd.updated)- SSE
GET /api/devloop/projects/:pid/stream用 Last-Event-ID 重连后能 replay 缺失事件
桥梁:极简 Status Page
P3 末尾顺手做一个 ~100 行的纯静态 HTML status page(不上 Vue 路由,单文件放 server/public/devloop-status.html),轮询 GET /api/devloop/projects/:pid/state 渲染 DAG 与 loop 状态条。作用:
- 给 P3 后期调试时一个可视化窗口(眼看 unit 状态翻飞比 tail 文件直观)
- 作为 P4 完整 Dashboard 的功能预演 — 提前发现交互问题
- ~100 行,不算进 P4 工作量
P4 · L3 + UI(~2 周 / 10 天)
新增
web/src/views/
├── DevLoopDashboard.vue # ~400 行
└── DevLoopOps.vue # Ops 容器(4 个 tab:Bugs / Loops / Changelog / Progress)
web/src/components/devloop/ # Dashboard 子组件
├── DashboardHeader.vue
├── LoopStatusBar.vue
├── UnitsDAG.vue # 复用 PipelineEditor 渲染层
├── LiveAgentStream.vue
├── PrdDiffPanel.vue
└── FeedbackModal.vue
web/src/components/devloop/ops/ # Ops 子页(与 ops-*.html wireframe 对齐)
├── BuglistView.vue # 渲染 bugs.ndjson(M-14)
├── LoopLogView.vue # 按 L1/L2/L3 分组 timeline.ndjson
├── ChangelogView.vue # 渲染 changelog.ndjson(M-15)
└── ProgressView.vue # 项目实时进度聚合
web/src/router/index.js # 加 /devloop/:pid 主路由 + /devloop/:pid/ops/{bugs,loops,changelog,progress} 4 个子路由
server/routes/devloop.js # 加 C-6 POST /:pid/sign-off + C-7 POST /:pid/abandon(参见 sdd-control)
验收
- 打开
http://localhost:5173/devloop/p-XXXXXX看到 wireframe 描述的全部 4 个区域 - 点 「+ NEW REQUIREMENT」发新需求 → PRD diff 区出现新 section(触发 PM incremental 模式)
- Live 流实时滚动 Agent 输出(断网 5s 后自动重连,用 Last-Event-ID replay)
- DAG 节点点击展开抽屉,看 unit 的最近 3 次 run
- 4 个 Ops 子页都能打开:
/ops/bugs·/ops/loops·/ops/changelog·/ops/progress - 项目交付后点 「Sign Off」按钮 →
POST /api/devloop/projects/:pid/sign-off→ 状态变shipped-final,前端拒绝再发新反馈 - 异常项目点 「Abandon」按钮 →
POST /api/devloop/projects/:pid/abandon→ 状态变abandoned,SSE 发 close 帧
成本估算
| 类型 | 文件数 | 预估行数 | 难度 |
|---|---|---|---|
| 新增 JS(后端) | 6 (doc-store · devloop route · unit-registry · loop-controller · sse-broker · bug-tracker) |
~800 | 中 |
| 新增 Agent 模板 | 6 (PM · Architect · Coder · Tester · Integrator · Triager) | ~900 | 中(参考 agents-pm / agents-architect,单模板 ~150 行 + 多个 few-shot 例子) |
| 新增 Vue 组件 | 12 (Dashboard 1 + Ops 容器 1 + dashboard 子组件 6 + ops 子页 4) | ~1650 | 中 |
| 修改既有 | 3 (server/index.js 挂路由 · _registry.json 加 6 条 · web/src/router/index.js 加 5 条路由) |
~50 | 低 |
| 新增包依赖 | 1 (cheerio) |
— | — |
| 合计 | 27 | ~3400 行 | — |
较早前版本(20 文件 / ~1580 行)低估了:① Agent 模板单文件实际 prompt 长度(PM/Architect 当前 PRD 已揭示需 200-300 行 prompt + 数个 few-shot);② Dashboard 子组件粒度(DAG / 抽屉 / diff 渲染单组件就 100+ 行);③ Ops 4 个子页此前未计入。
时间预算
单人 Claude Code 协同开发:P0(17 天) → P1(5 天)→ P2(8 天)→ P3(18 天)→ P4(15 天)= 约 10.5 周。每阶段末 1 天用于演示 + 写迭代 PR 描述。
- P0(17 天):P0.0 服务层 7 件套(4.5 天,第一个写)+ 工具 + Mock Claude + ACP 桥接 + 提示提取 + GitVault 集成 + 验证脚本。详见上方 P0 表 + tool-registry + acp-bridge + git-versioning
- P3 +3 天:增加 4 类 L2 分支演示(contract_mismatch / impl_bug / spec_ambiguous / infra_flake)+ 可观测性产物(bugs/changelog/timeline.ndjson)
- P4 +5 天:Ops 4 个子页(Bugs / Loops / Changelog / Progress)+ sign-off / abandon 端点联调
原估 4 周 → 6 周 → 7 周 → 9.5 周 → 10 周 → 10.5 周(含 P0.0 服务层 + Mock 模式)。每次都是补缺,不是膨胀。参考 成本预算。
「自举」乐趣
P4 完成后,你可以让 LemonBoss DevLoop 系统去开发 LemonBoss 自己的下一个 feature。换句话说:用 v1 的 DevLoop 写 v1.1 的代码。这是验证三层 Loop 是否真的「能自我迭代」的最朴素方式。