prd-feature-tree.html
11.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" />
<title>功能树 · LemonBoss PRD</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,300;9..144,500;9..144,700&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="assets/shell.css" />
</head>
<body data-page="prd-feature-tree.html">
<div class="shell">
<aside id="sidebar"></aside>
<main class="page">
<header class="page-head">
<div class="crumb"><span class="pill">01 · PRD</span><span class="sep">/</span><span>功能树</span></div>
<h1>功能树</h1>
<p class="deck">把 DevLoop 系统所有功能拆成 4 层树。每个叶子节点对应一个或一组 <b>Unit</b>,将被 Architect Agent 翻译成 units.json 的 DAG 节点。这是 Claude Code 复现整个项目时的第一份「清单」。</p>
</header>
<article class="body">
<section>
<h2>全景树</h2>
<pre class="tree">
DevLoop System
├── <span class="new">F1 · 项目生命周期</span>
│ ├── F1.1 创建项目 (POST /projects)
│ │ └── Unit: <span class="new">devloop-be-projects</span>
│ ├── F1.2 启动 / 续跑 (POST /run)
│ │ └── Unit: <span class="new">devloop-be-run</span>
│ ├── F1.3 查询状态 (GET /state)
│ │ └── Unit: <span class="new">devloop-be-state</span>
│ ├── F1.4 Sign-off / Abandon
│ │ └── Unit: <span class="new">devloop-be-finalize</span>
│ └── F1.5 项目元数据持久化
│ └── Unit: <span class="new">devloop-be-projectmeta</span>
│
├── <span class="new">F2 · 文档管理 (DocStore)</span>
│ ├── F2.1 PRD CRUD + 归档
│ │ └── Unit: <span class="new">docstore-prd</span>
│ ├── F2.2 SDD CRUD + 归档
│ │ └── Unit: <span class="new">docstore-sdd</span>
│ ├── F2.3 units.json schema 校验
│ │ └── Unit: <span class="new">docstore-units-schema</span>
│ ├── F2.4 HTML 解析与校验 (cheerio)
│ │ └── Unit: <span class="new">docstore-html-validator</span>
│ └── F2.5 contract_hash 计算
│ └── Unit: <span class="new">docstore-contract-hash</span>
│
├── <span class="new">F3 · Unit 状态机 (UnitRegistry)</span>
│ ├── F3.1 状态转换合法性
│ │ └── Unit: <span class="new">registry-fsm</span>
│ ├── F3.2 L2 gate 判定
│ │ └── Unit: <span class="new">registry-l2gate</span>
│ ├── F3.3 增量 diff (added/changed/removed)
│ │ └── Unit: <span class="new">registry-diff</span>
│ └── F3.4 retry 预算管理
│ └── Unit: <span class="new">registry-budget</span>
│
├── <span class="new">F4 · 三层 Loop 编排 (LoopController)</span>
│ ├── F4.1 L1 单 Unit 跑通
│ │ └── Unit: <span class="new">loop-l1-runner</span>
│ ├── F4.2 L1 retryWithReflection
│ │ └── Unit: <span class="new">loop-retry</span>
│ ├── F4.3 L1 并行调度 (scheduler 复用)
│ │ └── Unit: <span class="new">loop-parallel</span>
│ ├── F4.4 L2 集成 gate + run
│ │ └── Unit: <span class="new">loop-l2-runner</span>
│ ├── F4.5 L2 修复回写 (triage → patch SDD → reset)
│ │ └── Unit: <span class="new">loop-l2-repair</span>
│ ├── F4.6 L3 增量需求并入
│ │ └── Unit: <span class="new">loop-l3-merge</span>
│ └── F4.7 全局预算 + 终止条件
│ └── Unit: <span class="new">loop-guard</span>
│
├── <span class="new">F5 · Agent 模板 + 调用</span>
│ ├── F5.1 PM Agent
│ │ └── Unit: <span class="new">agent-pm</span>
│ ├── F5.2 Architect Agent (generate + patch 两模式)
│ │ └── Unit: <span class="new">agent-architect</span>
│ ├── F5.3 Coder Agent
│ │ └── Unit: <span class="new">agent-coder</span>
│ ├── F5.4 Tester Agent
│ │ └── Unit: <span class="new">agent-tester</span>
│ ├── F5.5 Integrator Agent
│ │ └── Unit: <span class="new">agent-integrator</span>
│ └── F5.6 BugTriager Agent
│ └── Unit: <span class="new">agent-triager</span>
│
├── <span class="new">F6 · 事件推送 (SSE)</span>
│ ├── F6.1 SSEBroker 订阅 / 退订
│ │ └── Unit: <span class="new">sse-broker</span>
│ ├── F6.2 9 类事件序列化
│ │ └── Unit: <span class="new">sse-events</span>
│ └── F6.3 断线重连 + replay
│ └── Unit: <span class="new">sse-replay</span>
│
├── <span class="new">F7 · 前端 Dashboard</span>
│ ├── F7.1 主页面 DevLoopDashboard.vue
│ │ └── Unit: <span class="new">fe-dashboard</span>
│ ├── F7.2 DashboardHeader (含 + NEW REQUIREMENT)
│ │ └── Unit: <span class="new">fe-header</span>
│ ├── F7.3 LoopStatusBar (3 张状态卡)
│ │ └── Unit: <span class="new">fe-loopbar</span>
│ ├── F7.4 UnitsDAG (复用 PipelineEditor 渲染)
│ │ └── Unit: <span class="new">fe-dag</span>
│ ├── F7.5 LiveAgentStream (终端样式 SSE)
│ │ └── Unit: <span class="new">fe-stream</span>
│ ├── F7.6 PrdDiffPanel (section 级 diff)
│ │ └── Unit: <span class="new">fe-prddiff</span>
│ ├── F7.7 FeedbackModal (反馈输入)
│ │ └── Unit: <span class="new">fe-modal</span>
│ ├── F7.8 UnitDrawer (Unit 详情侧栏)
│ │ └── Unit: <span class="new">fe-drawer</span>
│ └── F7.9 路由 + i18n keys
│ └── Unit: <span class="new">fe-router-i18n</span>
│
└── <span class="new">F8 · 复现 / 可执行性</span>
├── F8.1 PRD/SDD data-* 锚点协议
│ └── (无 Unit,文档约定)
├── F8.2 build-manifest 提取脚本
│ └── Unit: <span class="new">tool-manifest-extract</span>
└── F8.3 Reproducibility prompt 模板
└── (无 Unit,prompt 文件)
</pre>
<p class="sig">绿色 = 一个 Unit。共 <b>34 个 Unit</b>。Architect Agent 在 P1 演示时会从这棵树派生 units.json。</p>
</section>
<section>
<h2>按层级统计</h2>
<table class="dense">
<thead><tr><th>L1 功能群</th><th>L2 功能</th><th>Unit 数</th><th>类型构成</th></tr></thead>
<tbody>
<tr><td>F1 项目生命周期</td><td>5</td><td>5</td><td>be × 5</td></tr>
<tr><td>F2 文档管理</td><td>5</td><td>5</td><td>be × 5</td></tr>
<tr><td>F3 Unit 状态机</td><td>4</td><td>4</td><td>be × 4</td></tr>
<tr><td>F4 Loop 编排</td><td>7</td><td>7</td><td>be × 7</td></tr>
<tr><td>F5 Agent 模板</td><td>6</td><td>6</td><td>config × 6(Agent prompt + 注册)</td></tr>
<tr><td>F6 SSE</td><td>3</td><td>3</td><td>be × 3</td></tr>
<tr><td>F7 前端</td><td>9</td><td>9</td><td>fe × 9</td></tr>
<tr><td>F8 复现</td><td>3</td><td>1</td><td>tool × 1</td></tr>
<tr><td><b>合计</b></td><td><b>42</b></td><td><b>34</b></td><td>be × 24 / fe × 9 / tool × 1</td></tr>
</tbody>
</table>
</section>
<section>
<h2>依赖拓扑(粗)</h2>
<p>箭头 = 「下游 Unit 需要上游 contract」。LoopController.scheduler 据此分波并行。</p>
<svg viewBox="0 0 1100 360" width="100%" role="img">
<defs><marker id="arrFT" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto"><path d="M0,0 L10,5 L0,10 Z" fill="#0E0E10"/></marker></defs>
<g font-family="JetBrains Mono" font-size="11">
<rect x="40" y="40" width="180" height="50" rx="6" fill="#fff" stroke="#0E0E10"/><text x="130" y="70" text-anchor="middle">F2 DocStore</text>
<rect x="40" y="120" width="180" height="50" rx="6" fill="#fff" stroke="#0E0E10"/><text x="130" y="150" text-anchor="middle">F3 UnitRegistry</text>
<rect x="40" y="200" width="180" height="50" rx="6" fill="#fff" stroke="#0E0E10"/><text x="130" y="230" text-anchor="middle">F5 Agent 模板</text>
<rect x="280" y="120" width="200" height="50" rx="6" fill="#E2F2EA" stroke="#0E8C5A"/><text x="380" y="150" text-anchor="middle">F4 LoopController</text>
<rect x="540" y="40" width="200" height="50" rx="6" fill="#F7E8D2" stroke="#C77C2C"/><text x="640" y="70" text-anchor="middle">F1 项目生命周期 API</text>
<rect x="540" y="120" width="200" height="50" rx="6" fill="#F7E8D2" stroke="#C77C2C"/><text x="640" y="150" text-anchor="middle">F6 SSE Broker</text>
<rect x="540" y="200" width="200" height="50" rx="6" fill="#F7E8D2" stroke="#C77C2C"/><text x="640" y="230" text-anchor="middle">F8 manifest tool</text>
<rect x="800" y="120" width="220" height="50" rx="6" fill="#ECE4FB" stroke="#6E48C3"/><text x="910" y="150" text-anchor="middle">F7 前端 Dashboard</text>
<g stroke="#0E0E10" fill="none" marker-end="url(#arrFT)">
<line x1="220" y1="65" x2="275" y2="135"/>
<line x1="220" y1="145" x2="275" y2="145"/>
<line x1="220" y1="225" x2="275" y2="155"/>
<line x1="480" y1="145" x2="535" y2="65"/>
<line x1="480" y1="145" x2="535" y2="145"/>
<line x1="220" y1="65" x2="535" y2="65"/>
<line x1="740" y1="65" x2="795" y2="135"/>
<line x1="740" y1="145" x2="795" y2="145"/>
<line x1="220" y1="225" x2="535" y2="225"/>
</g>
</g>
</svg>
<p class="sig">P1 优先做 F2 + F5 (PM + Architect);P2 加 F3 + F4.1~4.3;P3 加 F4.4~4.7 + F1 + F6;P4 加 F7。</p>
</section>
<section>
<h2>Unit id 命名约定</h2>
<p>本树里的 Unit id 全部遵循 <a href="agents-architect.html">Architect 拆解策略</a>:</p>
<table class="dense">
<thead><tr><th>前缀</th><th>层</th><th>预计 cwd</th></tr></thead>
<tbody>
<tr><td><code>devloop-be-*</code></td><td>F1</td><td>server/routes/devloop.js · server/services/</td></tr>
<tr><td><code>docstore-*</code></td><td>F2</td><td>server/services/doc-store.js</td></tr>
<tr><td><code>registry-*</code></td><td>F3</td><td>server/services/unit-registry.js</td></tr>
<tr><td><code>loop-*</code></td><td>F4</td><td>server/src/core/loop-controller.js</td></tr>
<tr><td><code>agent-*</code></td><td>F5</td><td>system/templates/devloop-*.md</td></tr>
<tr><td><code>sse-*</code></td><td>F6</td><td>server/services/sse-broker.js</td></tr>
<tr><td><code>fe-*</code></td><td>F7</td><td>web/src/views/ · web/src/components/devloop/</td></tr>
<tr><td><code>tool-*</code></td><td>F8</td><td>scripts/</td></tr>
</tbody>
</table>
</section>
</article>
<nav class="prev-next"></nav>
<footer class="site"><div><b>Section</b>01 · PRD</div><div><b>Page</b>prd-feature-tree.html</div></footer>
</main>
</div>
<script src="assets/shell.js"></script>
</body>
</html>