data-layout.html 10.1 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="data-layout.html">
<div class="shell">
  <aside id="sidebar"></aside>
  <main class="page">
    <header class="page-head">
      <div class="crumb"><span class="pill">05 · DATA</span><span class="sep">/</span><span>文件空间布局</span></div>
      <h1>文件空间布局</h1>
      <p class="deck">沿用 LemonBoss 现有「company-scoped 文件根」。所有 DevLoop 项目落在 <code>data/companies/{cid}/projects/{pid}/</code> 下,与已有 <code>conversations/</code> / <code>memory/</code> 并列。</p>
    </header>
    <article class="body">

      <section>
        <h2>全景目录树</h2>
<pre class="tree">
data/
└── companies/
    └── <span class="reuse">{cid}/</span>
        ├── <span class="reuse">agents/{agentId}/</span>             <span class="com"># 复用:现有 agent 沙箱</span>
        ├── <span class="reuse">conversations/</span>                <span class="com"># 复用</span>
        ├── <span class="reuse">memory/</span>                       <span class="com"># 复用根</span>
        │   └── <span class="new">devloop/</span>                  <span class="com"># NEW · DevLoop Agent 跨项目长期记忆 (M-11)</span>
        │       ├── pm/{topic}.md
        │       ├── architect/{topic}.md
        │       ├── coder/{topic}.md
        │       └── ...
        └── <span class="new">projects/</span>                     <span class="com"># NEW · LoopController 根</span>
            └── <span class="new">{pid}/</span>
                ├── project.json              <span class="com"># 项目元数据 (M-1)</span>
                ├── <span class="new">prd/</span>                      <span class="com"># NEW · PM 写的多页 PRD 站点 (M-3)</span>
                │   ├── index.html
                │   ├── reading-guide.html
                │   ├── assets/{shell.css, shell.js, search-index.json}
                │   ├── product/{background, personas, original-req, scope, success-metrics, glossary}.html
                │   ├── feature/feature-tree.html
                │   ├── flow/user-flows.html
                │   └── prototype/proto-{viewName}.html
                ├── <span class="new">sdd/</span>                      <span class="com"># NEW · Architect 写的多页 SDD 站点 (M-4) · 待 Phase 3 详定</span>
                │   ├── index.html
                │   ├── assets/{shell.css, shell.js, search-index.json}
                │   └── mvcp/{model, view, control, process}.html
                ├── units.json                <span class="com"># Architect 字段 + UnitRegistry status (M-2)</span>
                ├── timeline.ndjson           <span class="com"># 全流程统一日志 append-only (M-13)</span>
                ├── bugs.ndjson               <span class="com"># NEW · 跨 run bug 台账 (M-14)</span>
                ├── changelog.ndjson          <span class="com"># NEW · 版本变更流 (M-15)</span>
                ├── agent-state/              <span class="com"># NEW · Agent 持久化运行态</span>
                │   ├── pm.json               <span class="com"># M-10 AgentRuntimeState</span>
                │   ├── pm-todo.json          <span class="com"># M-12 AgentTodolist</span>
                │   ├── architect.json
                │   ├── architect-todo.json
                │   ├── coder.json            <span class="com"># 单 agent 同时只跑一个 unit</span>
                │   ├── coder-todo.json
                │   ├── ... (tester, integrator, bug-triager)
                │   └── snapshots/            <span class="com"># 输入/输出快照,call_id 索引</span>
                │       ├── {call_id}-in.json
                │       └── {call_id}-out.json
                ├── history/                  <span class="com"># 全部 rev 归档</span>
                │   ├── prd-rev-001.html
                │   ├── prd-rev-002.html
                │   ├── sdd-rev-001.html
                │   └── units-rev-001.json
                ├── units/
                │   ├── auth-be/
                │   │   ├── spec.json
                │   │   ├── code/             <span class="com"># Coder 输出</span>
                │   │   │   ├── server.js
                │   │   │   ├── auth-service.js
                │   │   │   └── ...
                │   │   ├── tests/            <span class="com"># Tester 输出</span>
                │   │   │   └── login.spec.ts
                │   │   ├── contract.json     <span class="com"># Coder 写</span>
                │   │   ├── coder.log         <span class="com"># Coder 自己的决策日志</span>
                │   │   └── runs/
                │   │       └── {runId}/
                │   │           ├── result.json
                │   │           └── stdout.txt
                │   ├── auth-fe/...
                │   └── profile-be/...
                ├── integration/
                │   ├── spec.json             <span class="com"># Architect 写</span>
                │   └── runs/
                │       └── {runId}/
                │           ├── result.json   <span class="com"># Integrator 写</span>
                │           ├── triage.json   <span class="com"># BugTriager 写</span>
                │           └── process.log
                └── stream.log                <span class="com"># SSE 客户端视角日志 (7 天滚动)</span>
</pre>
        <p class="sig"><span style="color:var(--accent);font-weight:700">红</span> = 新增目录 · <span style="color:#6c6c6c">灰</span> = 已存在并复用</p>
      </section>

      <section>
        <h2>命名规则</h2>
        <table class="dense">
          <thead><tr><th>占位符</th><th>格式</th><th>示例</th></tr></thead>
          <tbody>
            <tr><td><code>{cid}</code></td><td>company id (UUID)</td><td><code>c-lemonv-001</code></td></tr>
            <tr><td><code>{pid}</code></td><td><code>p-</code> + 时间戳后 6 位</td><td><code>p-731042</code></td></tr>
            <tr><td><code>{unitId}</code></td><td><code>{feature}-{type}</code></td><td><code>auth-be</code> · <code>profile-fe</code></td></tr>
            <tr><td><code>{runId}</code></td><td><code>run-{YYYYMMDD-HHMM}</code></td><td><code>run-20260513-0731</code></td></tr>
            <tr><td>L2 runId</td><td><code>run-int-{YYYYMMDD-HHMM}</code></td><td><code>run-int-20260513-1031</code></td></tr>
          </tbody>
        </table>
      </section>

      <section>
        <h2>沙箱边界(写白名单)</h2>
        <table class="dense">
          <thead><tr><th>Agent</th><th>cwd</th><th>可写路径</th></tr></thead>
          <tbody>
            <tr><td>PM</td><td><code>projects/{pid}/</code></td><td><code>prd.html</code> · <code>history/prd-*</code></td></tr>
            <tr><td>Architect</td><td><code>projects/{pid}/</code></td><td><code>sdd.html</code> · <code>units.json</code> (字段) · <code>integration/spec.json</code> · <code>history/sdd-* · history/units-*</code></td></tr>
            <tr><td>Coder</td><td><code>projects/{pid}/units/{unitId}/</code></td><td><code>code/**</code> · <code>contract.json</code> · <code>coder.log</code></td></tr>
            <tr><td>Tester</td><td><code>projects/{pid}/units/{unitId}/</code></td><td><code>tests/**</code> · <code>runs/{runId}/**</code></td></tr>
            <tr><td>Integrator</td><td><code>projects/{pid}/</code></td><td><code>integration/runs/{runId}/**</code></td></tr>
            <tr><td>BugTriager</td><td><code>projects/{pid}/</code></td><td><code>integration/runs/{runId}/triage.json</code></td></tr>
          </tbody>
        </table>
        <p class="sig">沙箱由 Claude CLI 的 <code>cli.sandbox.writeAllowList</code> 配置强制执行;越权写直接被工具层拒绝。</p>
      </section>

      <section>
        <h2>磁盘占用估算</h2>
        <table class="dense">
          <thead><tr><th>项目规模</th><th>Unit 数</th><th>典型大小</th></tr></thead>
          <tbody>
            <tr><td>小</td><td>3-5</td><td>~5 MB(含日志)</td></tr>
            <tr><td>中</td><td>10-20</td><td>~30 MB</td></tr>
            <tr><td>大</td><td>50+</td><td>~150 MB</td></tr>
          </tbody>
        </table>
        <p>主要开销在 <code>runs/*/stdout.txt</code>(每次 vitest 完整输出)。如需节省,启用 <code>project.json.compressOldRuns: true</code> 自动 gzip 14 天前的 run 目录。</p>
      </section>

      <section>
        <h2>多项目共享</h2>
        <p>同一 company 下不同项目之间默认<b>隔离</b>。如需共享代码(如公共 utils),约定:</p>
        <ul>
          <li>在 <code>companies/{cid}/shared/</code> 放置共享库</li>
          <li>Unit spec 通过 <code>spec.shared_deps: ["@shared/utils"]</code> 显式声明</li>
          <li>Coder 沙箱里 <code>shared/</code> 是<b>只读</b>挂载,Coder 不能改</li>
        </ul>
        <p class="sig">P1~P4 不实现 shared,留给 P5 视实际需要再加。</p>
      </section>

    </article>
    <nav class="prev-next"></nav>
    <footer class="site"><div><b>Section</b>05 · Data</div><div><b>Page</b>data-layout.html</div></footer>
  </main>
</div>
<script src="assets/shell.js"></script>
</body>
</html>