Commit 8b57a024c99c4b71131afa806bcea97ee1a2d244

Authored by yibo
1 parent e870611f

docs: archive docs/ into done/todo/todo-future, add index; land P2 Org Graph spec

- New docs/README.md indexes the tree: done/ (shipped features + reference manuals),
  todo/ (current focus — Graph Agent architecture), todo/future/ (deprioritized
  roadmaps: FDE pipeline todo list, stale v1.1 milestones, harness engineering
  proposal — orthogonal to the Graph Agent work, not blocking it)
- Move completed/reference docs into docs/done/ (LEMONBOSS-SYSTEM-DESIGN, architecture-v5,
  claude-code-cron, open-api-manual, qa_judge_req, task_timeline_design, user-guides/,
  system-design/01-26 minus the three moved to todo/future/) — verified against actual
  code (qa-judge template, Task Timeline route/service/view) before filing as done
- Fix the two TOC links in LEMONBOSS-SYSTEM-DESIGN.md that would otherwise point at the
  old paths after the move
- docs/todo/system-design/27-graph-agent-architecture.md: add the P2 Org Graph doc link
  in the roadmap table and 关联文档 section
- Add docs/todo/system-design/27-p2-org-graph.md (P2 requirements & design, drafted in
  parallel while P0/P1 landed)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Showing 38 changed files with 493 additions and 4 deletions
docs/README.md 0 → 100644
  1 +# docs 索引
  2 +
  3 +文档按状态分为三个目录:
  4 +
  5 +- **`done/`** — 描述已实现 / 当前有效的架构与功能的文档(含长期参考手册)。
  6 +- **`todo/`** — 当前正在推进的路线图/设计草案。
  7 +- **`todo/future/`** — 尚未实现、但**不是当前重心**的待办(暂缓,等主线腾出手再回来处理)。
  8 +
  9 +判断依据:文档正文的显式「状态」标记(✅ 已完成 / 已实现 vs 📝 设计中 / 未实现)、未勾选的 checklist,以及与代码库实际实现的交叉核对(见各条目备注)。
  10 +
  11 +> **当前主线**:Graph Agent 架构重构([27-graph-agent-architecture.md](./todo/system-design/27-graph-agent-architecture.md))。`todo/` 下只保留这一份,其余待办已移入 `todo/future/`,避免和主线抢注意力。
  12 +
  13 +## done/
  14 +
  15 +| 文件 | 说明 |
  16 +|------|------|
  17 +| [LEMONBOSS-SYSTEM-DESIGN.md](./done/LEMONBOSS-SYSTEM-DESIGN.md) | 系统设计主索引 v2.0,含 27 章 `system-design/` 的总目录 |
  18 +| [architecture-v5.md](./done/architecture-v5.md) | v5.3 架构方案,Phase 1-6 已完成(Phase 7 认知架构条目单独见 todo/) |
  19 +| [claude-code-cron.md](./done/claude-code-cron.md) | Claude Code 原生 Cron 调度功能参考手册 |
  20 +| [open-api-manual.md](./done/open-api-manual.md) | ArenaSK Open API 外部调用手册 |
  21 +| [qa_judge_req.md](./done/qa_judge_req.md) | QA Judge Agent 需求文档 — 已在 `system/templates/qa-judge/` 落地 |
  22 +| [task_timeline_design.md](./done/task_timeline_design.md) | Task Timeline View 设计文档 — 已实现(`server/routes/tasks.js`、`server/services/task-service.js`、`web/src/views/TaskTimeline.vue`) |
  23 +| [user-guides/08-base-agent-4-phase-guide.md](./done/user-guides/08-base-agent-4-phase-guide.md) | Base Agent 四阶段使用指南 |
  24 +| [system-design/01-26](./done/system-design/) | 系统设计正文 01~26 章(14、25-harness-engineering-improvements 例外,见 todo/future/;27 例外,见 todo/),各章节状态见文内「状态」标记 |
  25 +
  26 +## todo/(当前主线)
  27 +
  28 +| 文件 | 说明 |
  29 +|------|------|
  30 +| [system-design/27-graph-agent-architecture.md](./todo/system-design/27-graph-agent-architecture.md) | Graph Agent 架构,状态:📝 设计中,未实现。P0-P6 分阶段路线图,当前唯一在推进的重构 |
  31 +| [system-design/27-p1-virtual-reference.md](./todo/system-design/27-p1-virtual-reference.md) | P1(虚拟引用)细化需求与设计文档:`getAgentConfig()`/`PromptBuilder.build()`/`hire()` 的具体改法、验收标准、blast radius、未决问题 |
  32 +
  33 +## todo/future/(暂缓,非当前重心)
  34 +
  35 +| 文件 | 说明 |
  36 +|------|------|
  37 +| [architecture_todo_list.md](./todo/future/architecture_todo_list.md) | FDE Pipeline 架构待办清单(Judge 系统 / 反馈闭环等五大维度)。与 Graph Agent 架构基本正交,其中第 4 点「版本回滚」与 27 号文档 P5 阶段的 git 版本化 `memory.md` 有部分重叠,P5 落地后可回来划掉 |
  38 +| [system-design/14-milestones.md](./todo/future/system-design/14-milestones.md) | 早期里程碑规划(v1.1,checklist 未勾选)。已被后续实际实现大幅绕过,主要留作历史存档,不建议优先处理 |
  39 +| [system-design/25-harness-engineering-improvements.md](./todo/future/system-design/25-harness-engineering-improvements.md) | Harness Engineering 改进提案(单 Agent 上下文管理),Phase 3-5 未落地。与 Graph Agent 架构(多 Agent 组织/图执行)维度不同,互不阻塞 |
  40 +
  41 +## 未纳入整理的目录
  42 +
  43 +以下目录本身是**活跃系统的一部分**(不是静态文档),保持原位不动:
  44 +
  45 +- **`prd/`** — DevLoop 的 PRD/SDD 规格站点源文件。`prd/newfunction/*.html` 由 `npm run spec:extract` 读取生成 `prd/newfunction/_spec/*.md`,是代码依赖的机器可读规格,不是待归档的说明文档。
  46 +- **`create-drama/`** — 独立的 Skill 工具子项目(含自身 `package.json` / `node_modules`),不是设计文档。
  47 +
  48 +## 维护说明
  49 +
  50 +新增文档时,先判断它描述的是**已实现的能力**(放 `done/`)、**当前正在推进的重心**(放 `todo/`),还是**尚未开始且非当前重心**(放 `todo/future/`)。功能落地后,将对应文档从 `todo/`(或 `todo/future/`)移到 `done/` 并更新本索引与 `LEMONBOSS-SYSTEM-DESIGN.md` 中的链接;当主线切换时(比如 Graph Agent 架构完成后),把 `todo/future/` 里优先级提升的条目挪回 `todo/`。
... ...
docs/LEMONBOSS-SYSTEM-DESIGN.md renamed to docs/done/LEMONBOSS-SYSTEM-DESIGN.md
... ... @@ -71,7 +71,7 @@
71 71 | 11 | **目录结构** | [11-directory-structure.md](./system-design/11-directory-structure.md) | packages / server / web / data 全貌 |
72 72 | 12 | **数据模型** | [12-data-model.md](./system-design/12-data-model.md) | 5 张核心表(agent type: master/cxo/role/skill) |
73 73 | 13 | **API 设计** | [13-api-design.md](./system-design/13-api-design.md) | Agent + Company + Goals + Innovator REST API |
74   -| 14 | **里程碑与附录** | [14-milestones.md](./system-design/14-milestones.md) | 迭代计划 + 决策表 + 术语表 |
  74 +| 14 | **里程碑与附录** | [14-milestones.md](../todo/future/system-design/14-milestones.md) | 迭代计划 + 决策表 + 术语表(📦 已过时存档,见 docs/todo/future/) |
75 75  
76 76 ### 进阶架构
77 77  
... ... @@ -89,6 +89,7 @@
89 89 | 24 | **公司层架构** | [24-company-layer-architecture.md](./system-design/24-company-layer-architecture.md) | Multi-Tenant 公司实例化 + 招聘系统 + Bootstrap (已实现) |
90 90 | 25 | **Bootstrap 自举机制** | [25-bootstrap-mechanism.md](./system-design/25-bootstrap-mechanism.md) | 公司创建时自动部署核心骨干团队 |
91 91 | 26 | **全自动招聘编排** | [26-automated-hiring-orchestration.md](./system-design/26-automated-hiring-orchestration.md) | Creator → Skills → Innovator 训练流水线 |
  92 +| 27 | **Graph Agent 架构** | [27-graph-agent-architecture.md](../todo/system-design/27-graph-agent-architecture.md) | Org Graph / Work Graph + System Agent 统一寻址,取代 Template 拷贝模型(⏳ 设计中,见 docs/todo/) |
92 93  
93 94 ---
94 95  
... ...
docs/architecture-v5.md renamed to docs/done/architecture-v5.md
... ... @@ -530,4 +530,4 @@ Task 进入 → 海马体检索 → 命中? → 小脑快速执行
530 530 | `data/goals/` | 全局 OKR 目标数据 |
531 531 | `docs/system-design/21-fde-pipeline-architecture.md` | FDE 流水线架构文档 |
532 532 | `docs/system-design/24-company-layer-architecture.md` | 公司层架构文档 |
533   -| `docs/claude-code-cron.md` | Claude Code 定时调度文档 |
  533 +| `docs/done/claude-code-cron.md` | Claude Code 定时调度文档 |
... ...
docs/claude-code-cron.md renamed to docs/done/claude-code-cron.md
... ... @@ -74,7 +74,7 @@ Claude Code 原生支持定时调度,通过 `CronCreate` / `CronList` / `CronD
74 74  
75 75 ### 文件位置
76 76  
77   -- 文档: `docs/claude-code-cron.md` (本文件)
  77 +- 文档: `docs/done/claude-code-cron.md` (本文件)
78 78 - 模板: `packages/agent-core/AgentScaffold.js` (_defaultCronJson)
79 79 - 注入点: `server/routes/agent-chat.js` (buildPrompt)
80 80 - Agent 配置: `data/agents/{agent-id}/cron.json`
... ...
docs/open-api-manual.md renamed to docs/done/open-api-manual.md
docs/qa_judge_req.md renamed to docs/done/qa_judge_req.md
docs/system-design/01-vision.md renamed to docs/done/system-design/01-vision.md
docs/system-design/02-agent-architecture.md renamed to docs/done/system-design/02-agent-architecture.md
docs/system-design/03-agent-model.md renamed to docs/done/system-design/03-agent-model.md
docs/system-design/04-agentic-loop.md renamed to docs/done/system-design/04-agentic-loop.md
docs/system-design/05-boss-meta-capabilities.md renamed to docs/done/system-design/05-boss-meta-capabilities.md
docs/system-design/06-sandbox-autonomy.md renamed to docs/done/system-design/06-sandbox-autonomy.md
docs/system-design/07-task-handover.md renamed to docs/done/system-design/07-task-handover.md
docs/system-design/08-differentiated-reflection.md renamed to docs/done/system-design/08-differentiated-reflection.md
docs/system-design/09-usage-flow.md renamed to docs/done/system-design/09-usage-flow.md
docs/system-design/10-runtime-architecture.md renamed to docs/done/system-design/10-runtime-architecture.md
docs/system-design/11-directory-structure.md renamed to docs/done/system-design/11-directory-structure.md
docs/system-design/12-data-model.md renamed to docs/done/system-design/12-data-model.md
docs/system-design/13-api-design.md renamed to docs/done/system-design/13-api-design.md
docs/system-design/15-innovator-meta-agent.md renamed to docs/done/system-design/15-innovator-meta-agent.md
docs/system-design/16-agent-conversation-architecture.md renamed to docs/done/system-design/16-agent-conversation-architecture.md
docs/system-design/17-skill-orchestration-and-concurrency.md renamed to docs/done/system-design/17-skill-orchestration-and-concurrency.md
docs/system-design/18-local-filesystem-first-agent-encapsulation.md renamed to docs/done/system-design/18-local-filesystem-first-agent-encapsulation.md
docs/system-design/19-orchestrator-tool-isolation.md renamed to docs/done/system-design/19-orchestrator-tool-isolation.md
docs/system-design/20-scaffold-first-agent-creation.md renamed to docs/done/system-design/20-scaffold-first-agent-creation.md
docs/system-design/21-fde-pipeline-architecture.md renamed to docs/done/system-design/21-fde-pipeline-architecture.md
docs/system-design/22-agent-memory-system.md renamed to docs/done/system-design/22-agent-memory-system.md
docs/system-design/23-agent-active-heartbeat.md renamed to docs/done/system-design/23-agent-active-heartbeat.md
docs/system-design/24-company-layer-architecture.md renamed to docs/done/system-design/24-company-layer-architecture.md
docs/system-design/25-bootstrap-mechanism.md renamed to docs/done/system-design/25-bootstrap-mechanism.md
docs/system-design/26-automated-hiring-orchestration.md renamed to docs/done/system-design/26-automated-hiring-orchestration.md
docs/task_timeline_design.md renamed to docs/done/task_timeline_design.md
docs/user-guides/08-base-agent-4-phase-guide.md renamed to docs/done/user-guides/08-base-agent-4-phase-guide.md
docs/architecture_todo_list.md renamed to docs/todo/future/architecture_todo_list.md
docs/system-design/14-milestones.md renamed to docs/todo/future/system-design/14-milestones.md
docs/system-design/25-harness-engineering-improvements.md renamed to docs/todo/future/system-design/25-harness-engineering-improvements.md
docs/todo/system-design/27-graph-agent-architecture.md
... ... @@ -212,7 +212,7 @@ CREATE TABLE work_graph_edges (
212 212 |-------|------|--------|----------|
213 213 | **P0 地基** ✅ | 建表 + 现有数据迁移,不改变任何现有执行路径 | `system_agents`/`org_graph_*` 表;把现有 `system/agents/` + `system/templates/` 目录扫描导入为种子数据(`system_agents` 行,`scope` 按当前所属推断) | 迁移脚本跑完,`system_agents` 表行数与现有 agent+模板目录数一致(**实际行数与本文档最初估计不同,见第七节**);现有 `company-service.js` 行为不变(并行只读验证,已确认零改动) |
214 214 | **P1 虚拟引用** | 停止文件拷贝,改为引用 | 改造 `AgentManager.getAgentConfig()` + `PromptBuilder.build()` 支持 `(agentId, companyId)` 寻址;`company-service.hire()` 改为创建 org_graph 引用节点而非 `_copyTemplate()`。细化需求与设计见 [27-P1 虚拟引用寻址](./27-p1-virtual-reference.md) | 新雇佣的 agent 不再产生文件拷贝,调用时能正确拼装公共+私有上下文;旧公司(仍是拷贝模式)继续可跑,不强制迁移存量数据 |
215   -| **P2 Org Graph** | `company.json.agents[]` 迁移为图结构 | `org_graph_nodes`/`edges` 落地;HR/CEO 招聘走新表 | 现有 Company Dashboard 前端能正确读出 org graph 并渲染(哪怕暂时按列表展示) |
  215 +| **P2 Org Graph** | `company.json.agents[]` 迁移为图结构 | `org_graph_nodes`/`edges` 落地;HR/CEO 招聘走新表。细化需求与设计见 [27-P2 Org Graph 落地](./27-p2-org-graph.md) | 现有 Company Dashboard 前端能正确读出 org graph 并渲染(哪怕暂时按列表展示) |
216 216 | **P3 Work Graph 最小闭环** | 单向执行,先不做回退 | work-graph-planning agent(system agent,新建);`work_graphs`/`nodes`/`edges` 表;顺序执行器(success → next,fail → 停止/标记 blocked,暂不回退) | 一个 goal 能被规划成 2-3 节点的图并顺序跑完,状态正确落库 |
217 217 | **P4 回退 + Loop-Validator** | 引入死循环防护 | loop-validator system agent + 内置熔断 skill;`edge_kind=backward` 支持;3.4 第 5 点的执行前结构校验 | 人为构造一个"总是失败"的节点,验证第 4 次回退被 loop-validator 强制终止,且校验能拒绝"回退边未经过 validator"的非法图 |
218 218 | **P5 自我进化** | 公共记忆蒸馏机制 | 公共 `memory.md` 写入走自省校验 + git 版本化;company-scoped → public 的升级门槛复用现有 benchmark ≥95 链路 | 同一 public agent 被两家公司调用后,`memory.md` 有可观察的增量更新,且能 git revert 到升级前版本 |
... ... @@ -245,3 +245,4 @@ P0 阶段的处理方式是**迁移脚本层面的临时保护**:`system_agent
245 245 ### 关联文档
246 246  
247 247 P1(虚拟引用寻址)的详细需求与设计已有独立草稿:[27-P1 虚拟引用寻址](./27-p1-virtual-reference.md)。
  248 +P2(Org Graph 落地)的详细需求与设计见:[27-P2 Org Graph 落地](./27-p2-org-graph.md)。
... ...
docs/todo/system-design/27-p2-org-graph.md 0 → 100644
  1 +# 27-P2. Org Graph 落地 — 需求与设计文档
  2 +
  3 +> **所属**: [27 Graph Agent 架构](./27-graph-agent-architecture.md) 的 Phase P2("Org Graph")
  4 +> **版本**: v0.2(设计阶段,未实现;相比 v0.1 的核心变化见 §二末尾"为什么从『招聘时可选传 reportsTo』升级为『org-graph-creator 自动生成』")
  5 +> **日期**: 2026-08-15
  6 +> **前置**: P0 地基已完工并提交(commit `8421f55`,`server/services/graph-db.js` + `graph-seed-service.js`)。**P1(虚拟引用寻址)目前仍是设计稿,未实现**——`server/services/graph-service.js` 尚不存在。§九说明 P2 为什么不需要等 P1 落地即可开工。
  7 +
  8 +---
  9 +
  10 +## 一、目标与非目标
  11 +
  12 +### 目标(本阶段要交付什么)
  13 +
  14 +按 27 号文档 P2 行的原始定义(27-graph-agent-architecture.md:215):
  15 +
  16 +> `company.json.agents[]` 迁移为图结构。`org_graph_nodes`/`edges` 落地;HR/CEO 招聘走新表。验收标准:现有 Company Dashboard 前端能正确读出 org graph 并渲染(哪怕暂时按列表展示)。
  17 +
  18 +结合最新明确的方向——**org graph 不再是招聘过程中零散声明出来的副产品,而是由公司的第一个 agent「org-graph-creator」在公司创建之初,根据公司目标/描述 + 一套按公司类型区分的 org graph 模板 + 当前可招聘的 agent 模板库,一次性规划并执行出来的**——展开为四件具体的事:
  19 +
  20 +1. **补全边(edges)+ 提供写入机制**:P0 只回填了节点(来自 `company.json.agents[]` 的扁平角色名),`org_graph_edges` 表建了但从未写入过一行。P2 要让 `hire()` 支持声明 `reportsTo`,这是所有汇报关系(不管谁写的)最终落地的**唯一通道**。
  21 +2. **org-graph-creator agent**:新增一个系统级 agent 模板,作为每家新公司创建后自动"入职"的第一个 agent。它读公司目标/描述、读 `system/org-graph-templates/*.json` 里的候选组织结构模板、读当前 `system/templates/*` 实际能招到的角色,综合判断出一套具体的组织结构,再按拓扑序(先上级后下级)依次调用 `hire()` 把这套结构真正建出来。
  22 +3. **组织结构模板库**:新增 `system/org-graph-templates/`,用一组按"公司类型"归类的 JSON 骨架文件(开发型/内容型/运营型……)表达"这类公司通常长什么样",供 org-graph-creator 参考、裁剪、组合——不是每家公司都严格照抄某一个模板,模板只是起点。
  23 +4. **提供一个可读的视图**:新增只读 REST 端点把 `(nodes, edges)` 拼成组织架构数据,Company Dashboard 至少能按"谁向谁汇报"分层列表展示。
  24 +
  25 +### 非目标(本阶段明确不做)
  26 +
  27 +- **不做**图形化组织架构图(连线画布、拖拽调整层级)——验收标准原文写明"哪怕暂时按列表展示"即可。
  28 +- **不做** `company.json.agents[]` 的废弃或只读化——很多现有代码(`listAgents()`、心跳、Dashboard 概览卡)仍在直接读它,P2 阶段 `org_graph_nodes`/`edges` 是**追加写入**,不是替换现有读取路径。
  29 +- **不做**存量公司历史雇佣关系的"猜测式"补边——见 §四.12。
  30 +- **不做**已经跑过一次 org-graph-creator 的公司的"重新规划/推倒重来"——org-graph-creator 在 P2 阶段是**一次性的公司创建时动作**,不是可以随时对着一家已经有员工的公司重跑的东西。公司后续想调整组织结构(加人、换汇报对象),走的是 HR agent 走既有 `hire()`/`reportsTo` 机制做增量调整(§四.4),不是重新触发 org-graph-creator。重新规划一家运行中公司的组织结构涉及"已有节点怎么办、正在跑的任务怎么办",复杂度明显更高,留作 Open Question(§八.5)。
  31 +- **不做**给 `company.json` 加一个枚举型的 `type` 字段——公司类型的判断是 org-graph-creator(LLM)基于目标/描述做的一次性推理,不是一个需要长期维护、需要建校验逻辑的结构化字段。org-graph-creator 执行完可以顺手把自己判断出的类型写成一段说明文字存档(§四.9),但那是审计用的自由文本,不是可枚举、可用于 if-else 分支的字段。
  32 +- **不做** Work Graph(P3)、Loop-Validator(P4)——P2 只处理静态协作结构。
  33 +- **不做** `system/agents/` 与 `system/templates/` 之间 6 个同名 id 的冲突解决——这是 27 号文档 §七遗留给"实现阶段之前"的产品决策,P1 §九 Q4 建议在排 P2 之前解决掉,本文档在 §八重申但不阻塞技术交付。
  34 +
  35 +---
  36 +
  37 +## 二、背景:为什么"边"是空的,不是"没扫描到"
  38 +
  39 +27 号文档 §四数据模型草稿把 `org_graph_edges` 定义为"公司静态协作结构"的关系边,`relation_type` 取 `reports_to` / `collaborates_with`(27-graph-agent-architecture.md:154-160)。但走查现有代码后发现:**这不是"数据源里有汇报关系、只是没写代码去读",而是系统里从来没有任何地方产生过"谁向谁汇报"这条信息**:
  40 +
  41 +- `company.json` 的 schema(`company-service.js:50-69`)里 `agents` 是纯字符串数组,没有汇报关系字段。
  42 +- HR Agent 的招聘 SOP(`system/templates/hr/agent.md:18-32`)里,CTO 给 HR 发的"招聘需求单"是一句自然语言,HR 执行的命令是 `node bin/lemon.js company hire --id <公司ID> --role <角色名> --type executor --name "岗位名称"`——**没有 `--reportsTo` / `--manager` 这类参数**,`bin/lemon.js` 的 `parseArgs` 选项列表(`bin/lemon.js:63-67`)里也确实没有。
  43 +- `config.json` 里唯一带层级意味的字段是 `parentId`(`packages/agent-core/AgentScaffold.js:63`「上级 Agent ID」),但它**只在 `scaffoldNewAgent()`(培养路径,company-service.js:241-283)里被写入**——走模板复制的 `hire()`(招聘路径,绝大多数场景)压根不 touch `parentId`。
  44 +- 各模板 `config.json` 的 `type` 字段本身就不构成一致的层级体系:实际扫描结果是 `cxo` / `specialist` / `executor` / `devloop` / `meta` / `quality_assurance` / `skill` 混杂(见 §三.3),`ceo` 模板目录甚至**没有 `config.json`**,导致 `hire()` 里"`type==='cxo'` 才设置 `company.ceo`"的逻辑(company-service.js:211-213)对字面意义上的 "ceo" 角色从不生效,反而任何被标 `type: 'cxo'` 的角色(`cto`/`coo`/`innovator`)招聘时会覆盖 `company.ceo`——这是一个和 P2 无关、但 org-graph-creator 大概率会踩到的既有 bug,见 §八.6。
  45 +
  46 +**结论一**(v0.1 就已确立,本次不变):没有任何历史数据可以无损映射成 `reports_to` 边,`type` 字段也不能作为可靠的层级推导依据。存量数据只补节点(P0 已完成),不自动猜边。
  47 +
  48 +### 为什么从"招聘时可选传 reportsTo"升级为"org-graph-creator 自动生成"
  49 +
  50 +v0.1 的方案是把 `reportsTo` 做成 `hire()` 的一个可选参数,指望 HR/CEO agent 在招聘时"顺手"传一下。这个方案本身没有错——它仍然是本版本的**底层写入机制**(§四.4 完整保留)——但作为唯一的产生边的路径,有一个结构性弱点:HR 是**被动响应**式地一个一个招人("CTO 说招三个人,HR 就招三个人"),从来不会有一个时刻"通盘看一眼这家公司应该长成什么样"。用户指出的改进方向是补上这个缺失的环节:公司创建时先有一个专职的 agent 站在全局视角,根据这家公司**要做什么**(目标/描述)参考"这类公司通常怎么搭"(模板库),一次性把骨架定下来,之后 HR 的增量招聘只是在这个骨架上加叶子节点。这不是推翻 v0.1,而是在它之上加一层"谁来负责最开始把 reportsTo 填对"的机制。
  51 +
  52 +---
  53 +
  54 +## 三、现状代码走查(决定设计边界的关键证据)
  55 +
  56 +### 3.1 `org_graph_edges` 表已建但从未被写入
  57 +
  58 +`server/services/graph-db.js:54-60` 定义了表结构(`id` 是 `INTEGER PRIMARY KEY AUTOINCREMENT`,不是 27 号文档草稿里写的 `TEXT PRIMARY KEY`——P0 实现时改了主键类型,P2 沿用实际实现)。`server/services/graph-seed-service.js:202` 的注释明确写着"`org_graph_edges` 本阶段留空——company.json 目前没有汇报关系数据,是预期状态,不是 bug"。
  59 +
  60 +### 3.2 真正被前端调用的招聘/辞退路径,和 `CompanyService` 里同名方法不是一回事
  61 +
  62 +- **招聘**:`POST /:companyId/hire`(`server/routes/company.js:908`)调用的是 `companyService.hireWithTraining()`(`company-service.js:381-383`,内部转调 `this.hire()`),`opts` 会从 route 的 `req.body` 一路传到 `hire()`。
  63 +- **辞退**:`POST /:companyId/fire`(`server/routes/company.js:1009-1055`)**没有调用 `companyService.fire()`**。它在路由 handler 里直接重新实现了一遍逻辑:停心跳 → 按 `archive` 参数决定归档还是删除 → 直接改 `company.agents` 数组。`CompanyService.fire()`(company-service.js:411-433)**唯一的调用方是测试脚本 `server/scripts/test-company-e2e.js:227`,是死代码路径**。
  64 +- **公司创建**:`POST /create`(`server/routes/company.js:22-38`),目前只创建一个"没有员工的空壳公司",响应里写着"请通知 MasterBot 从 Template 库中雇佣 Agent"——**创建流程本身不会自动招任何 agent**,这是 P2 要打破的现状(见 §四.10)。
  65 +
  66 +给"辞退"加清理逻辑必须改 `/fire` 路由 handler 本体;给"创建"接上 org-graph-creator 必须改 `/create` 路由 handler 本体——两者是同一类问题:真正生效的代码在路由层,不在 service 层的对应方法里。
  67 +
  68 +### 3.3 `type` 字段现状扫描
  69 +
  70 +对 `system/templates/*/config.json` 逐个读取 `type` 字段(39 个模板目录,2026-08-15 现场扫描):
  71 +
  72 +| type 取值 | 数量 | 代表角色 |
  73 +|---|---|---|
  74 +| `specialist` | 22 | hr, digester, hunter, content-selector, ... |
  75 +| `cxo` | 3 | cto, coo, innovator |
  76 +| `devloop` | 6 | devloop-pm/architect/coder/tester/integrator/triager |
  77 +| `executor` | 2 | evolver, scrapling_crawler |
  78 +| `meta` | 1 | evolver-youtube-crawler |
  79 +| `quality_assurance` | 1 | qa-judge |
  80 +| `skill` | 1 | claude-youtube-skills |
  81 +| 无 `config.json` | 1 | **ceo** |
  82 +
  83 +没有任何字段能区分层级,`type` 只是粗粒度的职能分类。
  84 +
  85 +### 3.4 `listTemplates()` 已经提供了 org-graph-creator 需要的"可招聘角色清单"
  86 +
  87 +`company-service.js:480-` 的 `listTemplates()`(`GET /api/company/templates`,HR 已经在用,`system/templates/hr/agent.md:17` 的 `node bin/lemon.js company templates`)对每个模板目录返回 `{id, name, type, description, benchmarkScore, ...}`。这正是 org-graph-creator 判断"模板里写的这个角色,现实里有没有对应的可招模板"所需要的原始数据——**不需要为 org-graph-creator 新开一个查询接口**,复用现成的 CLI 命令即可(见 §四.9)。
  88 +
  89 +### 3.5 Company Dashboard 现状:纯扁平列表,无层级渲染
  90 +
  91 +`web/src/views/CompanyDashboard.vue:212-229`("团队成员" tab)用 `companyAgents` 渲染一个 `agents-grid`,卡片之间没有连线也没有分组。P2 加"至少列表展示"是**新增**一块 UI。
  92 +
  93 +---
  94 +
  95 +## 四、设计方案
  96 +
  97 +### 4.1 总体架构与触发时机
  98 +
  99 +```
  100 +POST /api/company/create
  101 + │
  102 + ├─ companyService.create():建空壳公司(company.json.agents=[],不变)
  103 + │
  104 + ├─ 【新】companyService.hire(companyId, 'org-graph-creator', {})
  105 + │ org-graph-creator 是系统模板,招聘流程与其他角色完全一致(走 §3.2 已有的 hire() 路径)
  106 + │ 不传 reportsTo —— 它是基础设施角色,不挂在业务汇报树里(见 §4.9 末尾)
  107 + │
  108 + └─ 【新】fire-and-forget 触发首轮对话(复用 /hire 路由里已有的
  109 + fetch(`/api/agent/{agentId}/chat`) 异步模式,company.js:917-940)
  110 + 消息内容:公司 id/name/description(见 §4.10)
  111 + │
  112 + ▼
  113 + org-graph-creator(LLM agent,system/templates/org-graph-creator/)
  114 + 1. 读 system/org-graph-templates/*.json(结构骨架候选集,见 §4.8)
  115 + 2. 读 `node bin/lemon.js company templates`(现实里能招到的角色,见 §3.4)
  116 + 3. 综合公司 description + 上面两份数据,判断/裁剪出一套具体组织结构
  117 + 4. 把这套结构写成一份规划记录(workspace/org-plan.md,见 §4.9)
  118 + 5. 按拓扑序(先上级、后下级)依次执行:
  119 + node bin/lemon.js company hire --id <公司ID> --role <角色> --reportsTo <上级角色>
  120 + 6. 全部招完后关闭自己的心跳,转入休眠(一次性任务,见 §4.9 末尾)
  121 +```
  122 +
  123 +`hire()`/`org_graph_nodes`/`org_graph_edges`/`reportsTo` 校验规则(§4.4)是这套流程的**底层机制**,org-graph-creator 只是这套机制目前最重要的调用方——HR agent 后续做增量招聘时,走的是同一条 `hire()` + `reportsTo` 路径,不是另一套。
  124 +
  125 +### 4.2 数据模型改动(在 P0 schema 上追加,不改已有列)
  126 +
  127 +```sql
  128 +-- org_graph_nodes:追加"是否仍在职"标记,供 fire() 软删除用
  129 +ALTER TABLE org_graph_nodes ADD COLUMN status TEXT NOT NULL DEFAULT 'active';
  130 +-- status: 'active' | 'removed'
  131 +
  132 +CREATE UNIQUE INDEX IF NOT EXISTS idx_org_graph_nodes_company_role_active
  133 + ON org_graph_nodes(company_id, role_name)
  134 + WHERE status = 'active';
  135 +
  136 +CREATE TABLE IF NOT EXISTS org_graph_edges (
  137 + id INTEGER PRIMARY KEY AUTOINCREMENT,
  138 + company_id TEXT NOT NULL,
  139 + from_node_id INTEGER NOT NULL REFERENCES org_graph_nodes(id),
  140 + to_node_id INTEGER NOT NULL REFERENCES org_graph_nodes(id),
  141 + relation_type TEXT NOT NULL CHECK (relation_type IN ('reports_to','collaborates_with')),
  142 + status TEXT NOT NULL DEFAULT 'active',
  143 + created_at TEXT NOT NULL
  144 +);
  145 +CREATE UNIQUE INDEX IF NOT EXISTS idx_org_graph_edges_dedupe_active
  146 + ON org_graph_edges(company_id, from_node_id, to_node_id, relation_type)
  147 + WHERE status = 'active';
  148 +```
  149 +
  150 +放进 `server/services/graph-db.js` 的 `getDb()` 里,用 `CREATE ... IF NOT EXISTS` / 探测后 `ALTER TABLE ... ADD COLUMN`,跟 P0 一贯的"只加不改"风格一致。**为什么软删除**:`org_graph_nodes`/`edges` 是审计轨迹的一部分(类比 DevLoop `timeline.ndjson` 的 append-only 原则),物理删除会让"这家公司 3 个月前的组织架构长什么样"无法回答。
  151 +
  152 +### 4.3 新模块 `server/services/org-graph-service.js`(不复用/不等待 P1 的 `graph-service.js`)
  153 +
  154 +```js
  155 +// server/services/org-graph-service.js
  156 +// 职责:org_graph_nodes/edges 的读写,供 company-service.js 和 routes/company.js 调用。
  157 +// 与假想中 P1 的 graph-service.js(管 agent.md 从哪读)职责不同、文件不同,都基于 graph-db.js 的
  158 +// getDb(),若 P1 之后落地,两个文件共存,org_graph_nodes 表 schema(含本文档新加的 status 列)
  159 +// 双方共享,实现前需互相 diff 一次 graph-db.js。
  160 +
  161 +function upsertNode(companyId, roleName, systemAgentId = roleName) { /* INSERT ... ON CONFLICT ... */ }
  162 +function removeNode(companyId, roleName) { /* UPDATE status='removed',级联失效相关边 */ }
  163 +function addEdge(companyId, fromRoleName, toRoleName, relationType) { /* 见 4.4 校验规则 */ }
  164 +function getOrgGraph(companyId) { /* JOIN nodes + edges + system_agents */ }
  165 +
  166 +module.exports = { upsertNode, removeNode, addEdge, getOrgGraph };
  167 +```
  168 +
  169 +### 4.4 `hire()` / `hireWithTraining()` 改动 —— 新增可选 `reportsTo`(org-graph-creator 与 HR 共用的机制)
  170 +
  171 +`company-service.js:189` 的 `hire(companyId, roleName, opts = {})`:`opts` 新增可选字段 `reportsTo`(角色名字符串,指向同一家公司里另一个已存在的角色)。模板命中分支末尾追加:
  172 +
  173 +```js
  174 +try {
  175 + orgGraphService.upsertNode(companyId, roleName);
  176 + if (opts.reportsTo) {
  177 + orgGraphService.addEdge(companyId, roleName, opts.reportsTo, 'reports_to');
  178 + }
  179 +} catch (e) {
  180 + console.warn(`[Company] org_graph 写入失败(不影响招聘结果): ${e.message}`);
  181 +}
  182 +```
  183 +
  184 +try/catch-not-fail:`org_graph_nodes`/`edges` 在 P2 阶段仍然是 `company.json.agents[]` 的旁路记录,写失败不能让招聘这个更重要的操作跟着失败——**这一点对 org-graph-creator 尤其重要**:它会在几十秒内连续调用 `hire()` 十几次,任何一次的 org-graph 旁路写入失败都不该让整个批量招聘链路中断。
  185 +
  186 +**`reportsTo` 校验规则**:
  187 +
  188 +1. `reportsTo` 指向的角色必须已经是该公司 `org_graph_nodes` 里一条 `status='active'` 的节点——否则报错拒绝这次 `hire()`。**这一条对 org-graph-creator 是硬约束**:它必须按拓扑序(先招上级、后招下级)执行,见 §4.11。
  189 +2. `reportsTo === roleName` 直接拒绝。
  190 +3. 不做环检测——留到 P4 Loop-Validator 上线、或后续 Work Graph 需要拓扑排序时再补,刻意简化。
  191 +
  192 +`hireWithTraining()`(company-service.js:381-383)本身只是 `hire()` 的一层包装,`opts` 透传。**Route 层需要同步改**:`server/routes/company.js:908-914` 的 `/hire` handler 目前从 `req.body` 解构时没有 `reportsTo` 字段,需要加上。
  193 +
  194 +### 4.5 `/fire` 路由改动(不是 `CompanyService.fire()`——见 §3.2)
  195 +
  196 +`server/routes/company.js:1009-1055`,"从公司 agents 列表中移除"之后追加:
  197 +
  198 +```js
  199 +try {
  200 + orgGraphService.removeNode(companyId, role);
  201 +} catch (e) {
  202 + console.warn(`[Fire] org_graph 清理失败(不影响辞退结果): ${e.message}`);
  203 +}
  204 +```
  205 +
  206 +`removeNode()` 把该节点 `status` 置为 `removed`,同时把所有以它为 `from_node_id`/`to_node_id` 的 active 边一并置为 `removed`。`CompanyService.fire()` 同步做一样的改动(仅为不让测试脚本继续验证一个跟线上不一致的假实现)。
  207 +
  208 +### 4.6 只读 REST 端点:`GET /api/company/:companyId/org-graph`
  209 +
  210 +```js
  211 +router.get('/:companyId/org-graph', (req, res) => {
  212 + res.json(orgGraphService.getOrgGraph(req.params.companyId));
  213 +});
  214 +```
  215 +
  216 +返回形状:
  217 +
  218 +```json
  219 +{
  220 + "nodes": [
  221 + { "id": 12, "roleName": "cto", "systemAgentId": "cto", "status": "active" },
  222 + { "id": 15, "roleName": "hr", "systemAgentId": "hr", "status": "active" }
  223 + ],
  224 + "edges": [
  225 + { "fromRoleName": "hr", "toRoleName": "cto", "relationType": "reports_to" }
  226 + ]
  227 +}
  228 +```
  229 +
  230 +不在这一层拼装 `name`/`type`/心跳状态——那些字段权威来源始终是 `companyService.listAgents()`,前端按 `roleName` 去 join 已经在加载的 `companyAgents` 列表。
  231 +
  232 +### 4.7 前端:Company Dashboard 新增"组织架构"渲染
  233 +
  234 +不新增 tab。在"团队成员" tab 的 `agents-grid` 上方插入按 `reports_to` 边分层的缩进列表;没有边数据的节点退化成当前的平铺 grid(保证存量公司 Dashboard 展示效果不变);不引入图形库依赖。
  235 +
  236 +### 4.8 `system/org-graph-templates/`:组织结构模板库
  237 +
  238 +新增目录,每个文件是一种"公司类型"的组织结构骨架,供 org-graph-creator 参考:
  239 +
  240 +```json
  241 +// system/org-graph-templates/dev.json
  242 +{
  243 + "id": "dev",
  244 + "label": "开发型公司(持续构建/维护软件产品)",
  245 + "whenToUse": "公司目标包含实现某个产品/功能、需要跑代码开发-测试循环时优先参考",
  246 + "roles": [
  247 + { "role": "ceo", "reportsTo": null, "note": "公司负责人,制定目标" },
  248 + { "role": "cto", "reportsTo": "ceo", "note": "技术负责人" },
  249 + { "role": "hr", "reportsTo": "ceo", "note": "负责后续增量招聘" },
  250 + { "role": "devloop-pm", "reportsTo": "cto" },
  251 + { "role": "devloop-architect", "reportsTo": "devloop-pm" },
  252 + { "role": "devloop-coder", "reportsTo": "devloop-architect" },
  253 + { "role": "devloop-tester", "reportsTo": "devloop-coder" }
  254 + ]
  255 +}
  256 +```
  257 +
  258 +```json
  259 +// system/org-graph-templates/content.json
  260 +{
  261 + "id": "content",
  262 + "label": "内容型公司(持续产出/发布内容)",
  263 + "whenToUse": "公司目标是短视频/文章/直播等内容的选题-生产-发布流水线",
  264 + "roles": [
  265 + { "role": "ceo", "reportsTo": null },
  266 + { "role": "coo", "reportsTo": "ceo", "note": "内容运营负责人" },
  267 + { "role": "hr", "reportsTo": "ceo" },
  268 + { "role": "trend-scout-cn", "reportsTo": "coo" },
  269 + { "role": "story-architect", "reportsTo": "coo" },
  270 + { "role": "hook-editor", "reportsTo": "story-architect" },
  271 + { "role": "auto-publisher", "reportsTo": "coo" }
  272 + ]
  273 +}
  274 +```
  275 +
  276 +```json
  277 +// system/org-graph-templates/ops.json
  278 +{
  279 + "id": "ops",
  280 + "label": "运营型公司(监控/增长/客户运营为主)",
  281 + "whenToUse": "公司目标偏向数据监控、增长实验、社群/客户运营,不以持续研发或内容生产为主",
  282 + "roles": [
  283 + { "role": "ceo", "reportsTo": null },
  284 + { "role": "coo", "reportsTo": "ceo" },
  285 + { "role": "hr", "reportsTo": "ceo" },
  286 + { "role": "community-manager", "reportsTo": "coo" },
  287 + { "role": "strategy-reflector", "reportsTo": "coo" }
  288 + ]
  289 +}
  290 +```
  291 +
  292 +设计要点:
  293 +
  294 +- **这是起点集合,不是穷举枚举**——目录里有几个 `.json` 就有几种候选,新增一种公司类型只需要加一个新文件,不需要改任何代码(对应用户选定的"固定模板文件 + LLM 选型"方案:org-graph-creator 在 prompt 里被告知"`ls system/org-graph-templates/` 看看有哪些候选,都读一遍,选最贴近或组合出一个新的",不是在代码里写死一个 `switch(type)`)。
  295 +- `roles[].role` 里写的角色名是**建议**,不是强制——org-graph-creator 必须对照 §3.4 的 `company templates` 结果核实这个角色是否真的存在可用模板;如果没有,`hire()` 会走既有的 `needs_training` 分支(自动触发 agent-creator + innovator 培养,company.js:917-940 已有),org-graph-creator 不需要对此做特殊处理,只需要接受 `hire()` 的返回结果继续往下走。
  296 +- 模板之间允许被"揉合":比如一家公司同时要做内容生产和一个配套小工具的开发,org-graph-creator 的 prompt 里应该允许它同时参考 `content.json` 和 `dev.json`、合并出一套结构,而不是只能二选一。这是把"选型"这个判断交给 LLM 的直接后果——好处是不需要穷举组合,代价见 §八.1。
  297 +- P2 阶段先提供以上 3 个模板作为示例/起点(dev/content/ops),覆盖当前 `system/templates/*` 里能看到的三类角色画像(devloop-* 系列、trend-scout/story-architect/hook-editor 系列、community-manager/strategy-reflector),不追求一次性穷尽所有可能的公司类型。
  298 +
  299 +### 4.9 `system/templates/org-graph-creator/`:org-graph-creator agent 本体
  300 +
  301 +新增一个系统模板(和 `hr`/`ceo` 同级),字段沿用现有模板骨架(`agent.md`/`soul.md`/`identity.md`/`tools.md`/`config.json`,`config.json.type` 取一个新值 `meta-bootstrap`,与其余"业务角色"的 `type` 区分开)。`agent.md` 的核心工作流大纲(不是完整文案,实现时按仓库现有模板的写作风格——参照 `system/templates/hr/agent.md` 的"招·留·管·退"体例——展开):
  302 +
  303 +1. **读取输入**:公司 `id`/`name`/`description`(由 §4.10 的首轮消息带入)。
  304 +2. **读候选骨架**:`ls system/org-graph-templates/`,逐个读取,理解每个模板的 `whenToUse`。
  305 +3. **读可招角色清单**:`node bin/lemon.js company templates`,拿到当前系统里真实存在的模板列表(id/name/type/description)。
  306 +4. **规划**:综合 1/2/3,判断这家公司最贴近哪个(或哪几个)模板,裁剪/替换/新增角色,产出一份具体的"角色 + reportsTo"清单。**必须包含一个不挂靠任何模板、始终存在的 `hr` 节点**(如果模板里没有就补上)——它是这套结构未来能否被增量维护的前提,org-graph-creator 自己不会长期存在(见第 6 步)。
  307 +5. **落盘规划记录**:把第 4 步的结果写成 `workspace/org-plan.md`(角色列表 + 汇报关系 + 为什么这么选的简短理由),供事后审计/调试——这不是给代码读的结构化数据(结构化数据是 DB 里的 `org_graph_nodes`/`edges`),是给人看的"这次规划是怎么想的"。
  308 +6. **按拓扑序执行招聘**:从没有 `reportsTo` 的根节点开始,逐层往下,每个角色调用 `node bin/lemon.js company hire --id <公司ID> --role <角色> --reportsTo <上级角色(根节点省略)>`。见 §4.11 关于失败重试的约定。
  309 +7. **收尾**:全部招聘执行完(或明确判断某些角色因为需要培养而转入异步流程后),把自己的 `heartbeat.enabled` 设为 `false`(复用现有心跳开关机制,`server/routes/company.js:774` 一带的 `/heartbeat` 端点),不主动退出/不被 fire——它是这家公司组织架构决策的历史记录持有者,保留在 `company.agents[]`/`org_graph_nodes` 里,但不再被心跳唤醒、不参与后续任何招聘(后续增量招聘是 HR 的职责)。
  310 +
  311 +**org-graph-creator 自己在组织图里的位置**:不产生 `reportsTo` 出边(不属于它规划出来的业务汇报树),`getOrgGraph()` 会把它渲染成一个独立的"根"(和 CEO 一样是无入边——不,无出边——的顶层节点,§4.7 的前端渲染本来就允许多个顶层节点并存)。它是基础设施角色,类比 `agent-creator`/`innovator` 这些不出现在业务组织架构里、但确实活跃在系统里的 meta 角色。
  312 +
  313 +### 4.10 公司创建流程改动
  314 +
  315 +`server/routes/company.js:22-38` 的 `POST /create`:`companyService.create()` 成功后,追加:
  316 +
  317 +```js
  318 +// 1. 同步招聘 org-graph-creator(跟其他角色一样走模板复制,很快)
  319 +const bootstrapResult = companyService.hire(id, 'org-graph-creator', {});
  320 +
  321 +// 2. fire-and-forget 触发它的第一轮对话——复用 /hire 路由里已有的
  322 +// fetch(`/api/agent/{agentId}/chat`, ...) 异步模式(company.js:917-940)
  323 +if (bootstrapResult.status === 'hired_from_template') {
  324 + fetch(`http://127.0.0.1:${PORT}/api/agent/org-graph-creator/chat`, {
  325 + method: 'POST',
  326 + headers: { 'Content-Type': 'application/json' },
  327 + body: JSON.stringify({
  328 + message: `公司 ${id}(${name})已创建。公司描述:${description || '(未填写)'}\n请你按照 org-graph-creator 的工作流规划并执行这家公司的初始组织结构。`,
  329 + conversationId: `org-graph-bootstrap-${id}-${Date.now().toString(36)}`,
  330 + }),
  331 + }).catch(e => console.error('[Create] org-graph-creator 触发失败:', e.message));
  332 +}
  333 +```
  334 +
  335 +响应文案同步调整:不再是"请通知 MasterBot 从 Template 库中雇佣 Agent",改成"公司已创建,正在由 org-graph-creator 自动规划组织结构(异步进行中)"。
  336 +
  337 +**为什么是路由层而不是 `companyService.create()` 内部**:跟 §3.2/§4.5 同一个理由——`fetch` 调用自己的 HTTP 服务、依赖 `PORT` 等运行时上下文的代码,现有代码库的既有约定是放在路由层(`/hire` 的训练触发逻辑就是这么做的),`CompanyService` 保持不依赖 HTTP 层。
  338 +
  339 +**失败降级**:如果 `hire(id, 'org-graph-creator', {})` 本身失败(比如模板目录被误删),`create()` 的返回结果仍然是成功的空壳公司——这一步失败不应该让公司创建本身失败,跟现有的"招聘失败不影响主流程"原则一致。降级后的行为等同于 P2 上线前的现状:一个没有 org graph、需要人工手动招聘的空壳公司。
  340 +
  341 +### 4.11 拓扑序执行失败与重试
  342 +
  343 +§4.4 的校验规则 1 要求 `reportsTo` 目标必须已经是 active 节点——这对一个由 LLM 驱动、顺序执行十几次 `hire()` 调用的 agent 来说,存在"记错顺序、先招了子节点"的现实风险。设计上不在 `hire()` 侧放宽这条校验(放宽会让"脏数据"更容易产生,参见 v0.1 §4.4 校验规则 1 的论证),而是让失败可恢复:
  344 +
  345 +- `hire()` 对这种情况返回的错误信息要明确指出"角色 `<reportsTo>` 尚不存在于该公司,请先招聘它"(不是一个笼统的 500)——org-graph-creator 的 prompt 里要求它读到这类错误后,转去招那个缺失的上级角色,成功后再重试当前角色。
  346 +- 每个角色的 `hire()` 调用天然幂等(`already_exists` 短路,company-service.js:194-196),所以"招错顺序 → 报错 → 补招上级 → 重试子节点"这个循环不会因为重复调用产生副作用。
  347 +- 不引入一个专门的"依赖排序引擎"帮 org-graph-creator 提前算好正确顺序——§4.9 第 4 步产出的规划记录本身就是一份树状结构,从根遍历下去自然就是拓扑序,只要 org-graph-creator 老老实实按自己写的 `org-plan.md` 从上往下执行,这个问题不常发生;真发生时靠上面的重试机制兜底,不值得为小概率场景builds额外基础设施。
  348 +
  349 +### 4.12 存量数据 & 已建公司:明确不做的两件事
  350 +
  351 +沿用 v0.1 的结论并扩展一条:
  352 +
  353 +| 场景 | 决定 | 理由 |
  354 +|---|---|---|
  355 +| P2 上线前已存在的公司(P0 只回填了节点,没有边) | 不补边,`org_graph_edges` 就是空的,前端退化展示 | 没有可靠数据源支撑(见 §二),按 `type`/`parentId` 反推都已被证伪,见 v0.1 版本 §四.7 的完整方案对比表 |
  356 +| P2 上线后,一家已经跑过 org-graph-creator(或已经手动搭好组织架构)的公司,业务发生变化想要"重新规划" | 不支持——org-graph-creator 只在 §4.10 的创建时触发点运行一次 | 对一家已有员工、可能正在跑任务的公司做"推倒重来"式重新规划,涉及已有节点保留/替换、进行中任务归属等问题,复杂度显著高于"对着空壳公司规划一次",留 Open Question(§八.5),不在 P2 范围内 |
  357 +
  358 +---
  359 +
  360 +## 五、任务划分(Task Breakdown)
  361 +
  362 +| # | 任务 | 涉及文件 | 依赖 | 验收方式 |
  363 +|---|------|----------|------|----------|
  364 +| **T1** | schema 追加:`org_graph_nodes.status` 列、两个唯一索引、`org_graph_edges.status`/`created_at` | `server/services/graph-db.js` | 无 | 单测:`PRAGMA table_info` 能看到新列;重复插入同 `(company,role)` 的 active 节点报唯一索引冲突 |
  365 +| **T2** | 新建 `org-graph-service.js`:`upsertNode`/`removeNode`/`addEdge`/`getOrgGraph`,含 `reportsTo` 校验规则(§4.4) | `server/services/org-graph-service.js`(新增) | T1 | 单测覆盖幂等写入、非法 `reportsTo`(不存在/自环)报错且报错信息包含缺失的角色名(供 §4.11 重试逻辑解析)、`removeNode` 级联失效边 |
  366 +| **T3** | `hire()` 接入:写 node + 可选 edge,try/catch 不阻断主流程 | `server/services/company-service.js` | T2 | 单测:`hire()` 传 `reportsTo` 后 DB 各新增一行;`org-graph-service` 内部抛错时 `hire()` 仍返回 `hired_from_template` |
  367 +| **T4** | `/hire` 路由透传 `reportsTo`;`/fire` 路由接入 `removeNode()`;`CompanyService.fire()` 同步改 | `server/routes/company.js`、`server/services/company-service.js` | T2 | 集成测试:`POST /hire` body 带 `reportsTo` → 查 DB 有边;`POST /fire` 后节点与相关边均 `removed` |
  368 +| **T5** | 新增只读端点 `GET /:companyId/org-graph` | `server/routes/company.js` | T2 | 路由测试:返回形状符合 §4.6 契约;不存在的公司返回空数组而非 500 |
  369 +| **T6** | CLI:`bin/lemon.js company hire` 新增 `--reportsTo` 参数 | `bin/lemon.js` | T4 | 手工跑一次带 `--reportsTo` 的 hire,核对返回值与 DB |
  370 +| **T7** | 新增 `system/org-graph-templates/`:至少 `dev.json`/`content.json`/`ops.json` 三个骨架 | `system/org-graph-templates/*.json`(新增) | 无(可与 T1-T6 并行) | 人工 review:每个文件的 `roles[].role` 都能在 `system/templates/*` 或 `system/agents/*` 里找到同名目录(避免规划出一个连培养都无从谈起的角色名) |
  371 +| **T8** | 新增 `system/templates/org-graph-creator/`:agent.md/soul.md/identity.md/tools.md/config.json,落地 §4.9 工作流 | `system/templates/org-graph-creator/*`(新增) | T6, T7 | 人工 review + 手动跑一次完整对话,核对生成的 `org-plan.md` 与实际 `hire()` 调用序列一致 |
  372 +| **T9** | `/create` 路由接入自动招聘 + fire-and-forget 触发首轮对话 | `server/routes/company.js` | T4, T8 | 集成测试:`POST /create` 后立即查 `company.agents` 含 `org-graph-creator`;等待异步对话完成后查 `org_graph_nodes`/`edges` 有业务角色数据 |
  373 +| **T10** | HR agent 模板更新:明确"公司初建时的组织结构由 org-graph-creator 负责,HR 只做后续增量招聘"的职责边界 + `reportsTo` 用法 | `system/templates/hr/agent.md` | T6 | 人工 review,确认新增段落不与现有"强制工作流"章节冲突 |
  374 +| **T11** | 前端:Dashboard 团队成员 tab 加分层列表渲染,退化态验证 | `web/src/views/CompanyDashboard.vue` | T5 | 手动验证:有 `reportsTo` 边的测试公司显示缩进层级;存量公司展示效果与改动前一致 |
  375 +| **T12** | 回归测试 + 端到端测试:新建 `server/tests/unit/org-graph-service.test.js`;扩展 `server/scripts/test-company-e2e.js` 覆盖"建公司 → org-graph-creator 自动跑完 → 查 org-graph"全链路 | `server/tests/unit/org-graph-service.test.js`(新增)、`server/scripts/test-company-e2e.js` | T3, T4, T9 | `npm run test:unit` 全绿;e2e 脚本能跑通全链路(org-graph-creator 这一步用 mock 模式,参考 DevLoop 的 `ClaudeCliProtocol({mock:true})` 思路,不在自动化测试里真的起 Claude CLI 子进程) |
  376 +
  377 +**顺序建议**:T1→T2 是地基。T3/T4/T5 可在 T2 后并行。T7(组织结构模板库)不依赖任何代码改动,可以最早开工、和 T1-T6 并行写。T8(org-graph-creator agent 本体)依赖 T6(CLI 参数)和 T7(有模板可读)。T9(接入创建流程)依赖 T8。T10/T11 分别依赖 T6/T5。T12 贯穿全程,全链路部分要等 T9 完成。
  378 +
  379 +---
  380 +
  381 +## 六、验收标准
  382 +
  383 +沿用 27 号文档给出的 P2 验收标准(27-graph-agent-architecture.md:215),细化为可直接验证的检查项:
  384 +
  385 +1. **端到端场景(核心)**:`POST /api/company/create` 创建一家 `description` 明确写"我们要做一个短视频内容自动化生产的公司"的测试公司,不做任何手动干预:
  386 + - 几秒内 `company.agents` 出现 `org-graph-creator`
  387 + - org-graph-creator 完成一轮对话后,`GET /:companyId/org-graph` 能看到至少 `ceo`/`hr` 加若干与内容生产相关的角色(不强制要求跟 `content.json` 模板逐字一致,因为允许 LLM 裁剪),且存在至少一条 `reports_to` 边
  388 + - `workspace/org-plan.md`(org-graph-creator 私有目录下)存在且内容与实际 `hire()` 调用结果一致
  389 +2. 对一家新建测试公司依次 `hire(companyId, 'cto', {})` → `hire(companyId, 'hr', {reportsTo: 'cto'})`:`org_graph_nodes` 新增两行,`org_graph_edges` 新增一行 `(hr → cto, reports_to, active)`。
  390 +3. `hire(companyId, roleName, {reportsTo: 'nonexistent-role'})`:报错拒绝,不产生半成品数据,且错误信息包含缺失角色名(供 §4.11 重试逻辑验证)。
  391 +4. `POST /:companyId/hire` 的 HTTP body 带 `reportsTo` 字段:验证请求确实透传到了 `hireWithTraining()`。
  392 +5. `POST /:companyId/fire` 辞退某角色后:该节点与其相关边均 `status='removed'`,`GET /:companyId/org-graph` 不再返回它们。
  393 +6. `GET /:companyId/org-graph` 对一家 P0 迁移进来、从未走过新流程的存量公司:返回 `edges: []`,`nodes` 数量与 `company.json.agents.length` 一致。
  394 +7. Company Dashboard:有 `reportsTo` 数据的测试公司按层级缩进展示;存量公司展示效果与 P2 上线前一致。
  395 +8. `npm run test:unit` 全绿,含新增的 `org-graph-service.test.js`。
  396 +
  397 +---
  398 +
  399 +## 七、影响面 / Blast Radius
  400 +
  401 +| 文件 | 改动类型 |
  402 +|------|----------|
  403 +| `server/services/graph-db.js` | 修改:追加 `status` 列 + 两个唯一索引 |
  404 +| `server/services/org-graph-service.js` | 新增:`upsertNode`/`removeNode`/`addEdge`/`getOrgGraph` |
  405 +| `server/services/company-service.js` | 修改:`hire()` 接入 org-graph 写入;`fire()` 同步加 `removeNode()` |
  406 +| `server/routes/company.js` | 修改:`/create` 接入自动招聘 org-graph-creator + 异步触发对话;`/hire` 透传 `reportsTo`;`/fire` 接入 `removeNode()`;新增 `GET /:companyId/org-graph` |
  407 +| `bin/lemon.js` | 修改:`company hire` 命令新增 `--reportsTo` 选项 |
  408 +| `system/org-graph-templates/*.json` | 新增:组织结构模板库(至少 dev/content/ops 三份) |
  409 +| `system/templates/org-graph-creator/*` | 新增:新的系统模板(agent.md/soul.md/identity.md/tools.md/config.json) |
  410 +| `system/templates/hr/agent.md` | 修改:明确与 org-graph-creator 的职责边界 |
  411 +| `web/src/views/CompanyDashboard.vue` | 修改:团队成员 tab 加分层渲染逻辑 |
  412 +
  413 +**明确不改**:`company.json` 的 schema(`agents` 数组继续是唯一真相源)、`AgentManager`/`PromptBuilder`(P2 不碰运行时寻址)、`CompanyService.listAgents()`。
  414 +
  415 +---
  416 +
  417 +## 八、风险 / Open Questions
  418 +
  419 +1. **LLM 选型/裁剪质量没有硬性校验**:org-graph-creator 选模板、裁剪角色、判断 `reportsTo` 全靠一次 LLM 推理,没有像 `hire()` 校验规则那样的确定性把关(只保证"图结构合法",不保证"这套结构适合这家公司")。缓解:§4.9 第 5 步的 `org-plan.md` 提供了事后可读的决策记录,公司创建者发现规划不合理时,可以走现有 `fire()`/`hire()` 手动调整——**这也是为什么 §一非目标里明确不支持自动重新规划**:与其让 org-graph-creator 自己判断"要不要推倒重来",不如交给人看着 `org-plan.md` 做增量修正。
  420 +2. **一次公司创建多一轮 LLM 对话的成本与延迟**:以前建公司是纯本地文件操作(毫秒级),现在多了一次真实的 Claude CLI 子进程对话(几十秒到几分钟,还有 token 成本)。`POST /create` 保持同步返回(不等 org-graph-creator 跑完,走 fire-and-forget,见 §4.10),前端体验上公司创建本身不受影响,但"什么时候能看到组织结构"变成异步——Dashboard 需要一个"组织结构规划中"的过渡态提示(T11 范围内可以顺手加,不需要单独立项)。
  421 +3. **模板揉合没有边界**:§4.8 允许 org-graph-creator 同时参考多个模板文件自由组合,理论上可能拼出一个奇怪的结构(比如把三个模板的角色全招一遍)。P2 阶段不加约束(不限制招聘角色数量上限),如果上线后观察到滥招问题,可以在 org-graph-creator 的 prompt 里加"单次规划角色数不超过 N 个"这类软性约束,不需要代码层面的强制校验。
  422 +4. **6 个命名冲突 id 对 org-graph-creator 选型的影响**:P1 §九 Q4 指出的 `agent-creator`/`digester`/`evolver`/`evolver-youtube-crawler`/`hunter`/`innovator` 命名空间冲突问题,现在从"HR 偶尔招到"变成"org-graph-creator 系统性地对照 `company templates` 列表做选型,遇到这批 id 的概率显著提高"。不阻塞 P2 技术交付(`hire()` 本身对这批 id 的处理逻辑不受影响),但建议在 P2 上线前,至少把这 6 个 id 从 `system/org-graph-templates/*.json` 的候选角色名单里排除(在模板文件里就不引用它们),避免规划阶段就把歧义引进来。
  423 +5. **已有公司的组织结构再规划**:§4.12 明确列为非目标,但这是一个真实存在的后续需求(公司业务转型、组织结构随规模变化)。留待后续阶段设计——可能的方向是"org-graph-creator 支持增量模式:读现有 org graph + 新目标,只补差集",但这需要先观察 P2 上线后 HR 的增量招聘(§4.4 机制)能不能覆盖大部分场景,不值得在还没有真实使用数据时就设计。
  424 +6. **`hire()` 里 `company.ceo` 判定逻辑本身有既有 bug**(§二已指出:`ceo` 模板没有 `config.json`,`type==='cxo'` 判定命中的其实是最后一个被雇的 cxo 类型角色)——org-graph-creator 大概率会招一个字面意义的 `ceo` 角色,这个 bug 会被更频繁地触发(`company.ceo` 显示的可能是 `cto`/`coo` 而不是真正的 `ceo`)。这是 P2 之外的既有缺陷,本文档记录下来供后续排期,不在 P2 任务列表里顺带修(避免这次改动的 diff 范围扩大到不相关的既有逻辑)。
  425 +
  426 +---
  427 +
  428 +## 九、与 P1 的关系(现状澄清)
  429 +
  430 +P1(`27-p1-virtual-reference.md`)**目前仍处于设计阶段,代码未落地**(`server/services/graph-service.js` 不存在,`company-service.js` 里也没有任何 `systemAgentRef`/`companyContextPath` 相关代码)。27 号文档 §六的强顺序声明(27-graph-agent-architecture.md:221)只显式要求 P3 依赖 P1,没有把 P2 排进这条链:
  431 +
  432 +- P2 直接基于 P0 的 `graph-db.js`/`org_graph_nodes` 表施工,不需要 P1 的虚拟引用寻址先行。
  433 +- P2 新建的 `org-graph-service.js` 与 P1 设计稿里的 `graph-service.js` 是两个独立文件、不同职责。
  434 +- 唯一需要协调的是**共享的 `org_graph_nodes` 表 schema**:本文档 §4.2 给这张表加了 `status` 列。如果 P1 之后落地,P1 §4.4 里 `upsertOrgGraphNode()` 的实现需要感知这个新列(默认 `status='active'` 即可)。
  435 +- org-graph-creator 本身招聘自己所需要的所有角色时,走的是**当前**(P1 未落地时)的 `hire()` 实现——也就是说 org-graph-creator 招出来的每个角色,`agent.md` 仍然是物理拷贝,不是 P1 设想的虚拟引用。这一点不影响 P2 的正确性,只是意味着 P1 一旦落地,"批量自动招聘"这个新增的调用模式会让"同一个模板被拷贝 N 份"的问题(P1 §二要解决的问题)被更快地放大——这是支持"P1 应该尽早提上日程"的一个新论据,但不是 P2 必须等 P1 的理由。
  436 +
  437 +如果团队希望先补上 P1 再做 P2,也完全可以调换顺序——本文档在设计上不依赖那个决定。
... ...