prd-feature-tree.html 11.5 KB
<!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/agents/devloop-*/prompt.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>