27-requirement.md 51 KB

27-REQ · 原始需求

所属: 27 Graph Agent 架构 的需求源头文档。 版本: v0.1 日期: 2026-08-15 定位: 用户提出的需求原话照搬,再做结构化解析。本页是 27 系列所有设计决策的「源头」。 格式与定位对齐仓库既有惯例 docs/prd/newfunction/_spec/requirement.md(DevLoop 的原始需求页)。


为什么需要这一页

27 系列其余文档(E2E / P2 / P3-P4 / EXAMPLE / NAMING)全部是对下面这些原话的转述与结构化解读,包括 27-example-dev-company-walkthrough.md 里那个「配图工厂」场景——那是为了走查而虚构的例子,不是用户给的。

转述会漂移。当出现「当初到底是怎么说的」这类争议、或者需要判断某个设计决策是不是过度解读时,以本页为准。

照搬原则:原文一字不改,含笔误(validtor / syste agent / intergration / fin in / object-key result 等)与不完整的句子,一律保留。笔误本身有时是理解意图的线索。


R-1 · 起点:P2 对 P1 的依赖排查

你看一下todo 的 需求文档,p2 的部分有多少依赖于 p1 的实现

落点:无独立文档,结论并入 27-P2 §九。


R-2 · 要一份 P2 详细设计

那你现在写一个新的 p2 的需求设计文档,来对 p2 的需求进行详细设计,任务划分

落点:27-P2(初版 v0.1,后经 R-3 / R-10 两次重写)


R-3 · Org Graph 由第一个 agent 动态生成

org graph 生成,应该由 company 的第一个 agent: org graph creator agent 来实现,根据这个公司的目标,描述,类型,来生成,比如要生成开发,还是运营,还是内容生成,会有多个不同的 org graph的模板,然后根据需求+agent list 动态来生成 org graph

落点:27-P2 §4.1(orggraph-planning agent)、§4.6(system/org-graph-templates/) 后续变更:其中 org graph creator 这个名字在 R-10 的命名统一中改为 orggraph-planning。


R-4 · 要一个执行控制台页面

我们需要一个新的页面,展示公司的 org graph 和每一个 org node 运行的 work graph,这个需求也需要设计一下,这个界面还需要设计一下 MVCP,数据库设计,界面设计,有启动,下一步,暂停,停止,重试这样的操作按钮,还需要展示每一个节点的运行日志,边的输入输出,loop 的划线,这些展示,还有主流程如何处理,异常流程如何处理,下钻的 sub agent 的流程如何处理和展示。

落点:27-P3/P4 全文(§四 按 MVCP 四象限组织) 关键澄清:此处的 "MVCP" 经确认是 Model-View-Control-Process,即仓库既有 SDD 的四象限文档格式(docs/prd/newfunction/_spec/sdd-{model,view,control,process}.md),不是 MVP(最小可行范围)。


R-5 · 手动 / 自动两种执行模式

对,而且运行有自动化和手动化两个选择,如果是手动,则 org graph,work graph 的执行是需要在界面上点击下一步下一步来完成,如果是自动则是授权自动从头到尾自动执行,一个节点完成则自动跳转到下一个节点执行

落点:27-P3/P4 §四.C(execution_mode ∈ {manual, auto},两者共用同一个 advanceOne() 原语,区别只在谁触发下一次调用)


R-6 · 完整的七阶段流程(核心需求)

我说一下我理解的 process, 1, 用户新建一个 company 写入 company 的目标和描述2. company 默认有一个 org graph creator,根据用户描述,生成基础的 org graph,每一个 org graph node 可以从 system agent 中引用实现,也可以新建一个 system agent 来实现,比如开发 company,需要有 planner,code,validator 三个基础的 org graph 3. 用户输入一个具体的开发task, 4. org planner agent 作为执行 orggraph 的第一个节点,首先调用 planning work graph subagent,来规划执行 planning work graph 的这个任务,生成针对 planner agent 这个节点的 work graph,比如 brd->prd->sdd->benchmark->testdata->planner validtor->judge-loop-jump 来完成开发的第一个阶段需求planner的工作,这里面的每一个 work graph 节点都是一个 system agent 的引用,并且完成第一个 loop 闭环的跳转,如果成功则完成,如果有 bug 则跳转到对应的节点,让其只针对某一个部分开始修改。5 完成当前 org graph 节点工作,进入下一个 code graph node agent 的工作 6 code agent 也需要先调用 planning-work graph subagent 来设计 code work graph,可能是可以 fan out 并行多个 phase 的 code subagent->unit test 的开发,如果 unittest 有问题则loop 到 code subagent 来持续修改,全部并行完成后 fin in 节点到一个整合,->intergration test 来完成测试,如果有 bug 则判断是重新 planning 一个新的 work graph ,还是跳转到原有某个 work graph 节点来完成 7 codeagent 完成则进入全局的 validetor agent 来进行整体的判断,测试,审计,benchmark 的测试,test data 的测试等等,成功后完成,不成功则需要判断为什么会报错,是不是需要迭代某一个 syste agent 的 skill memory data llm 才能完成,先迭代 system agent ,再 loop 某个 work graph workflow ,再跑到 validator 验证,直至最后满足这个任务的 benchmark 或者 test data。 这个流程你整理成为一个文档,并且跟我们的 p2 设计比较,更新文档。 还有哪些没有考虑到的地方,这个流程是否是这样实现的?

落点:27-E2E 全文(§三 七阶段逐段还原、§四 与既有设计的差异、§七 未考虑到的地方)

由此产生的三条核心结论(27-E2E §二):

  1. 这套流程 70-80% 已在 docs/prd/newfunction/_spec/ 被完整设计过(DevLoop 的 L1/L2/L3)
  2. DevLoop 是这套架构的一个硬编码实例
  3. 第七步「迭代 system agent」是真正全新的一层(后定名 L4)

R-7 · 更正:benchmark / test data 是 work graph 的节点,不是基础设施

我描述的 benchmark 和 test data 是 workgraph 的两个 subagent 节点,例如在code planner agent,他的 work graph里包含了要规划当前 goal task 的 benchmark 或者 test data 或者 test script 来完成最终对这个 goal 的验收,所以 work graph 里 就需要调用 code-planner-benchmark code-planner-test-data code-planner-test-script 这三个 system agent ,动态选择是否需要在 work graph 中加入这三个节点,还是只需要其中某一个,来完成 code planner。

落点:27-E2E §十一(验收产出节点设计)

这条更正推翻了什么:此前我把 benchmark / test data 理解成系统级基础设施,因而去核实 benchmark-runner.js 并判定「是假的、test data 不存在」。该判断与本需求无关——本流程根本不使用 benchmark-runner.js。

后续变更:文中的 code-planner-benchmark / code-planner-test-data / code-planner-test-script 三个名字,经 R-10 与 R-12 两轮,最终定为 goal-benchmark / goal-test-data / goal-test-script(作用域从"父 org node"改为"goal")。


R-8 · 是否需要独立的 example 文档

是否将我的描述的这个用户流程,更新迭代在文档里,并且作为一个 example 文档?

落点:27-EXAMPLE ⚠️ 注意:该文档用的是虚构的「配图工厂」场景,不是本页 R-6 的原文。R-6 的原文只在本页。


R-9 · 四个关键决策(回答确认问题)

以下四条是针对具体设计分叉的定案回答,逐条照搬。

R-9.1 · Org Graph 的定位(最大的架构分叉)

org graph 是由 company 级别生成的 workflow ,work graph 是由 org graph node 级别生成的 workflow 我不知道这个解释清楚了么?

落点:27-E2E §五定案、27-P2 v0.4 §一、27 号总纲 v0.3 §二术语表 + §3.3

推翻了什么:P2 v0.1-v0.3 把 Org Graph 建模为静态汇报结构(边是 reports_to / collaborates_with),以及我提出的 A/B/C 三个折中方案,全部作废。新模型下两层图同构,共用一套 schema、引擎与 UI。

R-9.2 · 元 Agent 继承

我们所有的org graph work graph 的 subagent 的 node agent,都是由一个元 agent 架构来继承生成的,统一有全局通用+公司/角色记忆分区

落点:27-E2E §八bis

关联发现:元 agent 在仓库里已有实物 —— system/templates/base/("标准基座员工 Base Agent"),已强制 RESEARCH → PLAN → EXECUTE → VERIFY 四段式 + 阶段间 context flush + 换装元技能 + 失败写 _lessons.md 打回上一阶段。它本身就是一个最小 work graph。

R-9.3 · 验收产物由谁生成、由谁执行

验收产物在 org graph 中是由 planner 生成,由 validator 执行,每一个 node agent 的 benchmark 是由自身的 work graph 的 validator/test script/test benchmark/test script /节点来运行,

落点:27-E2E §11.3

要点:验收是逐层递归的——不是最外层一次总检,每一层图收尾都跑自己那层的验收;且执行由 agent 节点承担,不由引擎硬编码。

R-9.4 · L4 拆成 company / general 两条通道

迭代 system agent 本体,也是分为 company 还是 general 的部分,company 的部分在运行过程中就需要自动迭代,general 的部分需要 system agent 的管理者 master agent 或者人工来驱动执行,比如每日定时或者手工执行agent dream流程来自我更新,根据今天所有的 company 执行的成功 失败 经验,来更新 general 的本体部分

落点:27-E2E §八(L4-company / L4-general 对照表)、§8.1(agent dream 流程)

解决了什么:此前我提出的「为修一个任务而改坏十家公司共用 agent」这一跨公司污染风险(原 §7.2),以及我给的三个缓解方案(fork 副本 / 只改私有 / 人工确认),因这条分层而全部不再需要——在线自动迭代永远只碰 company 分区,general 本体的更新被移出任务循环。


R-10 · P2 重写 + 统一命名前缀

把 p2 文档按新的执行流边模型重写,仓库里的 benchmark 是 单 agent-benchmark 或者是 skill-benchmark ,给他们改个名字 ,我们这次聊的是goal-benchmark 或者 task-benchmark,我们在前面都统一加上前缀,包括 planner validator 也要加上 code-planner code-validator ,planning 是 workgraph-planning brd-planning,prd-planning orggraph-planning 这样起名,你可以统一排查一下

落点:27-P2 v0.4 全文重写、27-NAMING 全文

取舍过程:原话给了 goal- 与 task- 两个选项。我初次选了 task-,理由是"goal 已被 OKR 体系占用";R-11 把 OKR 正名后该理由失效,我改用"验收标准跟着一次 task 执行走"作为理由继续保留 task-。这个理由在 R-12 被推翻,最终定为 goal-。


R-11 · OKR 正名

okr 树应该叫做 object-key result ,可以修改一下,不要叫做 goal 了

落点:27-NAMING §六

要点:体系整体从 goal 改为 okr;且当前第 1 层节点也叫 "Goal" 是一处自我遮蔽,建议正名为 Objective(O-001),成为标准的 Objective → Key Result → Sub-Task 三层。代码层已于 commit 74ea1ff 实施完毕(okr-service.js/routes/okr.js、/api/okr + 旧路径别名、scripts/migrate-goals-to-okr.js 迁移脚本、7 例单测)。


R-12 · 验收产物定名 goal-,并给出 goal 与 task 的层级区分

改回 goal-benchmark,因为 task 可能有很多个,task 是 sub agent 或者并行的层次,但是 goal 对于一个人类的需求描述只有一个,task 在 graph 中可能会有多个

落点:27-NAMING §四(含 goal / task / okr 三者的层级定义)

这条推翻了什么:推翻了 R-10 阶段"验收标准跟着一次 task 执行走"这个理由。关键区分是基数:

概念 基数 说明
goal 一个人类需求描述 = 1 个 验收的边界。"这次交付到底算不算满足了人的要求"
task 一个 goal 分解出 N 个 图中的执行单元,可并行、可下钻 sub agent
okr 跨多个 goal 的长周期度量树 Objective / Key Result(见 R-11)

验收标准回答的是"人类想要的东西做到了没有",这是 goal 级的判定;task 只是达成它的执行分支,一个 goal 下有很多个,把验收挂在 task 上会导致"到底以哪个 task 的验收为准"无法回答。


R-13 · P2 需求审计中的四个定案

针对「P2 是否兑现原话」的逐条比对,四个分叉的定案回答,逐条照搬。

R-13.1 · goal 分三层

公司的目标是公司的 goal 叫做 company-goal ,任务的目标叫做 task-goal ,还有每一个子任务的目标叫做 subagent-goal,应该这么叫吧?

落点:27-NAMING §四「goal 是三层递归的」、27-P2 §4.1 第 1 步

澄清了什么:R-12 说的「一个人类需求描述只有一个 goal」,指的其实是三层里的 task-goal。三个验收 agent(goal-benchmark / goal-test-data / goal-test-script)保持通用,不按层级拆分——在哪一层调用就为那一层的 goal 产出标准,与 R-9.2 元 agent 继承一致。

后续变更(R-14):subagent-goal 按执行者命名,与另两个的作用域命名轴不一致,已定名为 subtask-goal。上方原话保留提出时的用词,不随之改写。

R-13.2 · 公司类型由 agent 推断

完全由 orggraph-planning 推断

落点:27-P2 §4.6(模板是起点集合,不是代码里的 switch(type))

推翻了什么:审计时我把「不给 company.json 加枚举 type 字段」记为「我擅自偏离了 R-3 原话(原话把类型列为输入)」。本条确认 LLM 推断正是所需,当前设计无需修改,那条自我记过的缺陷不成立。

R-13.3 · 新 agent 从元 agent 继承

从 base 元 agent 继承 + agent-creator 填内容,建成后可以手动或者根据 company 的需求设置自动innovator 培养训练

落点:27-P2 §4.1 第 7 步、§五 T5b

这是 R-9.2 在 P2 的落地点:模板不存在的角色,先从 system/templates/base/ 继承骨架(自动带上 RESEARCH → PLAN → EXECUTE → VERIFY 四段式),再由 agent-creator 填充角色定义——不是直接走现有的 needs_training 全量培养分支。训练是可选后置步骤,可手动触发或按公司需求配置自动。新建 agent 一律 scope='company'。

R-13.4 · org graph 强制单入口

强制单入口(推荐)

落点:27-P2 §3.3 第 2 条(原为 open question,现已定案)


R-14 · 命名轴统一为作用域

改成 subtask-goal

落点:27-NAMING §四

定案:三层 goal 一律按作用域命名 —— company-goal / task-goal / subtask-goal。R-13.1 提出时第三个叫 subagent-goal(按执行者命名,与另两个的轴不一致),本条统一。R-13.1 的原话引用保留提出时的用词,不随之改写。


R-15 · P3 需求规划讨论中的六个定案

针对「27 系列 P3 该做成什么样」的一轮讨论产出。

⚠️ 本节两种来源混排,逐条标注:R-15.1 / R-15.2 / R-15.3 有用户原话(引用块内一字不改,遵循本页照搬原则);R-15.4 / R-15.5 / R-15.6 是选项式确认——选项文本由我拟、用户勾选,不是用户自己的措辞,因此只记为定案,不冒充原话。

📌 恢复记录(2026-08-15):R-15.1 的全文、R-15.4 的后半、R-15.5、R-15.6、以及速查表对应行,曾因一次错误回滚(git checkout --)丢失,后据会话上下文补回。R-15.3 的「节点名 vs 本体名」表未按原始版本还原——它在丢失期间被 27-NAMING §三 的重写取代(命名轴从「业务领域」改为「所在图的层级」),新版更贴合 R-15.3 引用的原话,故保留新版。

R-15.1 · 讨论对象是 org graph 这条线的 P3

有一个进程正在开发p2 我们来看看 p3 的需求的规划

对 我们要讨论 org graph 的 p3

澄清了什么:仓库里有两条互不相干的 P3,容易混。

DevLoop 的 P3 27 系列的 P3
出处 docs/prd/newfunction/_spec/plan-migration.md 27 总纲 §六
内容 L1+L2 联动,跨 Unit runProject Work Graph 最小闭环
状态 runProject 已实现(loop-controller.js:576) 零代码

本条确认讨论的是后者。下文 R-15.2 起全部属于 27 系列。

落点:27-P3/P4 全文。

R-15.2 · workgraph-planning 是全局通用 agent

① 用全局通用 workgraph-planning

澄清了什么:每个 org node 接到任务时不是各自带一份规划能力,而是都调同一个全局 workgraph-planning 本体,靠记忆分区区分它在不同 org node / 不同公司下的语境。与 R-9.2 元 agent 继承、27-P1 虚拟引用寻址一致——agent 池不随 org node 数量膨胀。

落点:27-NAMING §二(该条目已在表内)、27-P3/P4 阶段 D。

R-15.3 · validator 分两个层级,各有全局本体

② org graph 的 validator 叫做 org-validator work graph 里面生成的 validator 叫做 xx-validator 比如 planner agent 的 validator 叫做 planner-validator ,code agent 内生成的 work graph 的 validator 叫做 code-validator。所以是两个层级的不同的 validator ,每个层级的 validator 在 system agent 里面都有对应的全局 agent ,比如有 planner-validator coder-validator org-validator , org-validator agent 里面也许会调用 benchmark-validator testdata-validator 等等不同的 sub agent 来完成任务。

两级验收的分工:

节点名 验什么 决定什么 失败退到哪
org 层 org-validator 整个任务达成了吗(27-E2E §三 阶段 7 的全局 validator) 整个 org graph run 的收敛 退回某个 org node,整张 work graph 重跑
work 层 {orgNode}-validator 这个 org node 自己的产出合格吗 该 org node 的 success/fail 退回本张 work graph 内的某个节点

节点名 vs 本体名(本条推导出的一条新规则):

例 带前缀?
system agent 本体 planner-validator / coder-validator / org-validator ❌ 不带领域前缀
org graph 节点 org-planner / org-coder / org-validator ✅ 带 org-
work graph 节点 {父 org 节点职能}-{职能} ✅ 带父节点名

禁止裸用 validator 的理由是「一家公司内两个节点不能重名」——该理由针对的是节点,不针对本体。本体若被迫带领域前缀,coder-validator 会复制成多份,与 P1「同一份本体、多处引用、各自私有语境」直接冲突。

三个 validator 是三个独立本体:它们验的东西本质不同——规划产物 / 代码 / 整个任务达成,是不同能力,不是同一能力的不同语境。27-E2E §八bis 的「不特化」原则针对的是同一能力在不同 org node 下,与本条不冲突。

org-validator 调 sub agent 不需要新机制:org-validator 本身是一个 org node,按定义有自己的 work graph,benchmark-validator / testdata-validator 就是这张 work graph 的节点,落在已有的递归模型里,引擎不加分支。

连带影响:R-9.3「planner 生成、validator 执行」的两个角色现在分属两个不同的 org node——goal-benchmark / goal-test-data / goal-test-script 在 org-planner 的 work graph 里产出,由 org-validator 这个 org node 消费。因此需要跨 org node 的产物传递机制,27-P3/P4 现有的 output_ref(节点内产物指针)不够。

落点:27-NAMING §三 + 新增 validator 命名轴、27-P2 §4.6 三个模板、27-P3/P4。

R-15.4 · 引擎泛化,定义层与运行时层分离

选项确认,非原话。给出的三个选项是:引擎泛化接受表名参数(选中)/ org graph 执行时物化成 work_graph 实例 / 先只做 work graph 把 org graph 执行推到 P5。

推翻了什么:27-P3/P4 §四.A 的注释专门为「不拆定义表和实例表」辩护,理由是 work graph「规划完即执行、执行完即归档」,定义即实例。该前提在 org graph 也要被执行之后失效——org graph 是建公司时生成一次、活整个公司生命周期的长期定义,一份定义要被跑很多次(每来一个任务跑一遍)。

定案:定义层保留两套(org_graph_* 长期 / work_graph_* 一次性),运行时层统一为一套 graph_runs + graph_run_nodes,引擎只操作运行时层,定义从哪来由 graph_runs.graph_kind 决定。三层下钻改用 parent_run_id 一条链(取代 parent_node_id);任务级总预算(27-E2E §7.1)挂 root run,子 run 上溯扣同一个池;暂停/停止沿同一条链向下级联(§7.5)。

连带定案:org node 与 work node 的执行语义不同——前者是「起一张子图并等它收敛」(子 run completed → success,blocked → fail),后者是「一次 agent 调用」。引擎需要 agent_call / subgraph 两种 node executor。org 层回退不强制插 loop_validator 节点(会污染「这家公司有哪些角色」的语义),改由引擎对 edge_kind='backward' 的边统一计数 + 硬顶熔断。

落点:27-P3/P4 §四.A / §四.D。

R-15.5 · P3 范围含 workgraph-planning + 任务入口

选项确认,非原话。

推翻了什么:27-P3/P4 §一非目标把 workgraph-planning 排除在外,代价是该文档 §八.5 自己承认「只能用手写测试数据构造图,不能端到端验证从一句自然语言目标到一张可执行的图这条链路」。且 27 总纲 §六本来就把 workgraph-planning 列为 P3 交付物。任务入口(用户 → 公司)是 27-E2E §四 #7 标注的「完全空白」,没有它图没有来源。

定案:两者都收进 P3,作为最后一个阶段(前面的阶段全部不起 LLM、可独立验收,与 27-P2 §五「三个可独立验收的阶段」同一套切法)。

落点:27-P3/P4 §一非目标(两条作废)、§五任务划分。

R-15.6 · 验收契约提到最前面

选项确认,非原话。

依据:27-E2E §十「整条流程的终止条件(验收)是实现程度最低的一环……先建验收,再建循环——否则会得到一个跑得很顺畅但永远不知道该不该停的系统」。按该节 v0.2 调整,「验收先行」的含义不是建 benchmark 基础设施(那是误解),而是定义验收契约格式 + 建执行器。

定案:P3 新增一个前置阶段,先定 goal-benchmark / goal-test-data / goal-test-script 三种产物的统一契约格式并建执行器,再动引擎。

落点:27-P3/P4 §五任务划分、27-E2E §十一。


R-16 · 失败归因由专职 subagent 做,回退边是多条

org-validator 判定任务未达成时,退回 code-coder(实现有问题)还是 code-planner(规划有问题)? 这个org-validator 会有自己的 work graph 里的 subagent 决定,它首先需要有一个 validator-reflection subagent 来判断当前的 bug 的源头是哪个 agent 的哪个 skill 的问题,还是哪个 agent 的输入约束不够的问题,还是哪个 agent 的执行问题,判断完原因,才知道是先改 skill,还是直接让某个 agent 直接+bug context 描述直接重做。 所以回退的边是多个的,不是一个的,在回放的时候才知道用哪个边实现回退。你觉得如何?

落点:27-P3/P4 §四.D.2.2(选边)、§四.D.0(子 run 回写透传)、§四.D.2.1(熔断)

这条回答了什么:27-P3/P4 v0.3 §八.1 把「一个节点有多条 fail 边时走哪条」列为本版最需要确认的 open question,本条关闭它。

关键结构:归因不是失败节点自己顺手吐一个 reason,而是 org-validator 自己 work graph 里排第一位的一个专职节点 validator-reflection。这与 DevLoop 的既有分工同构——Integrator 判定集成失败、BugTriager 单独归因,是两个不同 agent,理由是同一个 agent 既当裁判又当法医容易把「我判失败」和「我认为该怪谁」混成一次输出。

三分类归因与 DevLoop 四分类的对照:

原话的归因 DevLoop 对应 回退动作
哪个 agent 的执行问题 impl_bug 该 agent 带 bug context 重做
哪个 agent 的输入约束不够 contract_mismatch / spec_ambiguous 退回上游产出约束的那个节点
哪个 agent 的哪个 skill 的问题 无对应 先改 skill —— 这一支即 L4-company
(原话未提)进程超时 / 被杀 infra_flake 直接重跑,不烧预算、不动节点

⚠️ 「skill 问题」这一支落在 P3 的非目标里(L4 是三级恢复中最贵、爆炸半径最大的一级,27-E2E §十 建议最后做)。建议:v1 保留 skill_defect 这个归因取值让 reflection 照常判定(数据先攒着,归因体系一次成型),但动作降级为「挂起等人工」,不自动触发 L4。infra_flake 建议补上——纯引擎逻辑、近乎零成本,不补则超时会被误判成执行问题、白烧一轮预算。

对 schema 的要求:子 run 收敛时不能只回写 success/fail,还要把 fail_reason 和 remediation_note 一起透传回父节点——因为决定走哪条边的是子图里的 reflection 节点,不是失败节点本身。27-P3/P4 §四.D.0 原表只写了「子 run completed → success;blocked/failed → fail」,缺这条透传。

本条带出的一个熔断漏洞:v0.3 §四.D.2.1 按 (run_id, edge_id) 计数、硬顶 3,前提是一个节点只有一条回退边。多条回退边各自计数后,硬顶实际变成 3×N——reflection 只要每次归因到不同 agent、走不同的边,就永远撞不到任何一个计数器的顶。这是 27-E2E §7.1「每级都重置下一级计数器则没有终止条件」的同型变体。修法:双层计数,单边计数(防同一路径死循环)+ graph_runs.backward_count 的 run 级总回退计数(防「换个借口继续退」),任一撞顶即 force_terminated。这与任务级总预算是两回事——预算管花了多少钱,这个管绕了多少圈,两者都要。


R-17 · R-16 遗留两问的定案

R-16 结尾留了两处待确认,本条给出定案。两条都推翻了我当时标注的倾向,其中第一条要求改已经实现的引擎。

R-17.1 · 归因精确到 work graph node 层

归因精确到 work graph node 层

推翻了什么:R-16 结尾我倾向「保持层级封装」——org 层只退到 org node 粒度,remediation_note 跟着传下去,由该 org node 自己的 workgraph-planning 决定是重新规划还是只重跑某节点。本条否决了这个方案,改为允许跨层直接寻址:validator-triager 归因到哪个 work graph node,就退到哪个 node。

代价是明知的(R-16 里已列为该方案的坏处,本条接受):破坏层级封装;控制台「暂停 / 单步」作用于哪一层的语义会变含糊,需要在 UI 上显式表达。

对已有实现的影响:27-P3/P4 v0.3 与首批实现(commit c3abf4a)都是按 org node 粒度做的,本条要求返工:

面 现状(org node 粒度) 定案后(work graph node 粒度)
回退目标 org 边上的 to_node_id,指向一个 org node 需要一个跨层节点地址(org node + 其 work graph 内的具体 node)
重跑范围 该 org node 整张 work graph 重跑(起新子 run) 复用既有 work graph 定义,只重置被点名的 node
下游处理 整张图重来,无所谓 按 contract_hash 的 added/changed/removed/unchanged 四分类决定级联——已有机制,正好复用(27-P3/P4 §四.C 末段)
子 run 每次回退新建一张 复用旧子 run,节点 attempt+1

⚠️ 与已修缺陷的交互,返工时必须复核:第二轮修掉的「subgraph 重跑不起新子 run 导致永久死锁」,修法正是「每次回退都新建子 run 并清空 child_run_id」。改成复用旧子 run 之后,那个死锁的原始成因(幂等守卫读到上一轮终态子 run 而直接返回 pending)会以另一种形式回来。返工时要重新设计幂等判据,并保证 graph-engine.test.js 里那条「回退后 subgraph 节点重跑」的用例仍然成立(可能需要按新语义重写该用例的期望——这是唯一允许改测试期望的情形,因为语义本身变了,且必须在提交信息里写明)。

落点:27-P3/P4 §四.D.2.2 / §四.D.3 / §四.A.2(跨层地址的存储形态)/ §四.B(控制台层级语义)、§八 第 1 条(关闭)。

R-17.2 · validator-reflection 改名 validator-triager

validator-reflection 可以改叫 validator-triager

理由:它做的是归因不是判定,triager 与 DevLoop 已经跑通的 BugTriager 对齐,语义更准。

影响面(纯改名,但铺得较开):system/templates/validator-reflection/ 目录、system/templates/_registry.json 条目、org-validator work graph 骨架里的节点名、graph-engine.js 里读归因产出的相关标识与注释(如 resolveReflectionFile / readNodeProduct 的 node.reflection timeline 事件名)、27-NAMING 的 validator 命名轴说明、27-P3/P4 全文、本文档 R-16。

R-16 正文中的原话引用保留 validator-reflection 的用词不改(照搬原则),本条作为后续变更记录。 上方 R-16 与本节以外的地方读到 validator-reflection,一律按本条理解为 validator-triager 的历史名。

落点:27-NAMING、27-P3/P4、system/templates/。

落地记录(第五轮):引擎外的改名已完成——system/templates/validator-triager/(目录 + 内容自称)、_registry.json 条目、system/templates/org-validator/ 的节点名引用、system/work-graph-templates/validator.json 的 nodeName/systemAgentId/边端点、27-NAMING §3.5(该节标题与「两处待定案」表也一并更新,只剩前缀那一处未定案)、27-P3/P4 全文(含 §八.2 关闭)。引擎内的 ATTRIBUTION_NODE_NAME 常量与 node.reflection timeline 事件名另行改。

⚠️ 改名是「节点名 / systemAgentId / 引擎常量」三点同步才成立的:任一处留在旧名,deriveChildOutcome 就匹配不到归因节点,三值透传静默降级成「没有 fail_reason」,落到兜底边——正是 27-P3/P4 §十 那个「产生 → 传递 → 落库 → 读回漏一环」的缺陷模式。改完必须 grep -rn validator-reflection 复核一遍(R-16 正文的原话引用是唯一允许的命中)。


R-18 · 招聘归 workgraph-planning,且改用真实 Claude CLI

本条起于一次界面走查:为了在控制台上手工跑通流程,我写了一个 scripts/p3-demo-setup.js 帮用户雇人、写 org graph、起 run。用户指出这个脚本本身就是错的。

R-18.1 · 人工操作不该是跑脚本

我们要讨论一下,我手工新建一个公司,人工的操作不应该是跑脚本,而是我点击 org graph planning ,让他来真实运行,并且 plan 出来需要雇佣哪几个 agent 到 company。

指出了什么:p3-demo-setup.js 代劳的前两步(雇人、写 org graph),本来就是 orggraph-planning 的活——27-P2 §4.1 的八步工作流第 7 步就是「执行招聘」,system/templates/orggraph-planning/agent.md Step 7 与 tools.md §4 都已写好,后端也有 POST /api/company/:companyId/org-graph/replan(company.js:1159)。设计完整、代码半成,缺的是接线与一个 UI 入口。

脚本作为调试夹具可以留,但不能是产品流程。

R-18.2 · work 层本体由 workgraph-planning 自己雇(方案 a)

我选择 a ,让workgraph-planning 自己雇

背景:招聘实际是两层,而第二层此前没有任何执行者——

层 谁决定雇谁 谁执行 定案前状态
org 节点(org-planner / org-coder / org-validator) orggraph-planning,建公司时 它自己(Step 7) 已设计已实现
work graph 节点(prd-planning / coder-validator …) workgraph-planning,每次接到任务时 没有人 空白

workgraph-planning 现有 tools.md 明写「你不招人也不辞人」;它规划出的图引用哪些本体是任务来了才知道的,建公司时 orggraph-planning 无法预知。这是第七轮定为 blocker 的「供给环缺失」。

定案:选 (a)——workgraph-planning 规划完图后,自己把引用到的本体雇进本公司,再提交图。否决的两个备选:(b) 引擎在 createWorkGraph 时按需雇(与 resolvePlanningAgentName 同构、工作量更小,但招聘变成引擎副作用、用户看不到是谁决定的);(c) 只许在已雇本体里选(最保守,但新公司什么都规划不出来)。

(a) 相对 (b) 多出来的成本,必须一并处理:company-service.hire() 会把任何被雇的 agent upsert 成一行 org_graph_nodes。(a) 下每次任务规划都要雇几个人,org graph 会被 work 层本体越塞越满(界面走查时已实际撞到:雇了 prd-planning 后左栏 org graph 立刻混入该节点)。所以选 (a) 就必须同时决定 work 层招聘不写 org 节点,或写了但打标区分。

R-18.3 · 停用 mock,改用真实 Claude CLI

另外我们需要开始真的起 Claude CLI 规划,不再 mock 数据来跑

推翻了什么:前六轮的「端到端生产成立」结论建立在 mock 之上,而 ClaudeCliProtocol._sendMockPrompt 完全不读提示词,只按 agent 名回放 fixture。第七轮换真 CLI 后,链路在第一个 work 节点就断。本条要求彻底改用真实调用来验证。

落点:27-P3B 真实运行前置(本条派生出的工作项文档)。


R-19 · 产物统一路径与「边即输入输出」

起于第四次真跑:自动模式下 org-planner-prd 失败,它自己的归因写得很准 —— 「不是上游没产出,是它的产出结构上到不了我手上」。上游 brd.md / contract.json 落在节点私有目录,而 prd 的提示词只给了它自己的私有目录 + 只读 artifacts/, 那条 brd --success--> prd 的边不携带任何文件引用。同一张 work graph 内部 上游到下游没有数据通路 —— 这不是引擎 bug,是这条路从来没建。

R-19.1 · 统一产物路径 + 索引(原话)

我记得之前说过这个,要所有的 agent 把自己的产出都放在 data/company/company-id/workspace 下,你可以约束一下所有的 agent subagent graph agent,统一一下输出和输入的共享路径。这个路径下有一个 json 文件描述节点,边(输入,输出文件),时间,作为所有文件的索引。

核实结果:这条在 27-REQ 里没有记录(本页此前 0 处提 workspace), 但设计确实存在 —— 27-P4 §4.6「产物统一目录 + files.json」, 文中自己标着「用户要求的第 3 项,P3 未实现」。所以是设计在、需求源头漏记、实现未做。

R-19.2 · 建表而不是 JSON 文件(原话)

所以我们应该在 sqlite 库里增加一个表 files ,再增加 edges-files 对应关系表,关联每一个边和每一个文件的对应关系,边代表着节点的输入输出,这样节点就能找到输入的文件都在哪里,输出的文件存哪里,真实存储目录则有全局的 workspace 指定,可以存在 company 表的定义里

改掉 §4.6 的 files.json,改为建表。 理由不是抽象的:本轮刚被 _registry.json 咬过 —— 它既是人工维护清单又被 _updateTemplateUsedCount() 每次招聘原地改写,任何一次真跑都产生 git diff,最后 W13 只能把计数挪去另一个被 ignore 的文件。files.json 会是同一形状 (并发追加、整文件重写、和 git 打架)。表没有这些问题,还带外键与可查询性。

R-19.3 · 三处定案

两类都要,workspace 根用代码推导,路径走 tasks/{taskId}/

① 两类数据流都要。 纯 edges_files 有硬伤:边是 (from, to) 二元关系,只能表达 相邻节点间的传递,而 R-9.3 定的「验收产物由 planner 生成、由 validator 执行」是 非相邻依赖 —— org graph 是 org-planner → org-coder → org-validator, acceptance.json 从 planner 流到 validator 跳过 coder,这两个节点之间没有边。 所以分两类:

沿边传递 任务级共享
例 brd.md → 紧邻的 prd 节点 acceptance.json → 任意下游 validator
绑定 边上声明契约(kind) 挂在 task 上,按 kind 检索
不受限于 —— 拓扑相邻性

② workspace 根用代码推导,不入库。 库里存路径会烂:W13 清掉的那 10 条 legacy_path 悬空行就是这个病(指向早已删除的目录)。files 表只存相对公司根的路径, 根由代码推导(与 runRootDir / nodeArtifactDir 现有做法一致,需要覆盖时给环境变量)。 另核实:库里没有 companies 表 —— 公司是 company.json 文件 + 目录扫描, 所以原话里「存在 company 表的定义里」这个落点不存在。

③ 路径走 tasks/{taskId}/,不是 workspace/。两个理由:§4.6 原文的「同一家公司会跑 很多 task,平铺的话第二个 task 的 prd.md 会覆盖第一个」;以及 workspace/ 现有语义是 06-沙盒自治 定的「Agent 自治领地, 框架不干预」,把框架管着的索引塞进去会混淆两种所有权。

R-19.4 · 由此带来的一个设计收益(本条是我提出、用户定案的部分之外的推论)

边上声明的是契约(kind)、files 表记的是实例(path),两者是规划时 / 运行时两阶段: workgraph-planning 画图时不可能知道文件名,但能声明「这条边传一份 brd」。

于是引擎能在节点跑之前就校验「你声明要吃 brd,但上游没有任何节点产 brd」—— 这类图结构错误现在完全查不出来,只能等跑到那一步 agent 说「我拿不到输入」 (第四次真跑就是这么发现的)。这比事后归因强得多。

落点:27-P4 §4.6 重写。


R-20 · 公司任务是 goal / task 两级,可排队可并行

起于执行控制台走查。用户原话:

我们看一下,一个 company 在控制台下达任务只能有一个?应该有一个任务列表,能够对任务的增删改查,然后点击任务后看到任务对应的 org graph,work graph 以及执行情况。所以需要在 /:id/graph-console 的最左侧再增加一列任务列表,新增任务即可。

第一版设计把「任务」直接等同于 root graph_run(理由是库里 parent_run_id IS NULL 的每一行本来就是一次任务,只是界面没入口),被用户否掉,改为下面四条。

R-20.1 · 建 goal 表与 task 表,不复用 root run(原话)

还是新建一个任务表吧,company 层面人类下达的任务应该是 goal 表,goal 可以分解为多个 task,让 lemonboss 执行。

这不是新增概念,是补上一张缺席的表。 27-NAMING §四 早就定义了 goal 1 : task N 的基数(goal = 一个人类需求描述 = 验收边界;task = 图中的执行单元,可并行),graph_runs 里 goal_id / task_id 两列也早就在,company.js 的注释还写着「三者基数不同不可混用」——但全仓库没有任何写入方,goal_id 是一个悬空外键。

顺带确认两处历史包袱已清干净,新概念可以直接用回这两个名字:G- 前缀已被 R-11 的 OKR 正名释放(G-001 → O-001,迁移已执行);/api/goals 与 /api/company/:cid/goals 目前是 OKR 的向后兼容别名,但全仓库零调用方,本次连带退役。

R-20.2 · 两级结构之上做排队与并行(原话)

有个 goal 表,task 表结构后,可以形成排队,或者并行

这一条推翻了 P3 当初「拒绝而不排队」的定案。 原定案的理由写在 company.js 的注释里 ——「仓库里没有任何出队/唤醒的 worker,排进去的任务不会被自动消费,那是一条会静默丢任务的路」。这个判断本身今天仍然成立,所以 R-20.2 的实质内容不是「加两张表」,而是必须同时交付调度器:入队时 / run 收敛时 / 服务启动时 / 60s 兜底,四个触发点少接一个,任务就会静默躺在队里,而界面上它长得跟「正在排队」一模一样。

并行是最后一批:max_parallel_tasks > 1 要 DROP idx_graph_runs_one_active_root,等于删掉最后一道 DB 兜底,守卫改成事务内 count + admit(SQLite 单写者天然序列化),单独排期单独验。

R-20.3 · 已下达的描述不可改(原话)

已下达的 goal 不给改描述,task 已下达也不给改。

理由不是保守,是数据一致性的硬要求:task 的描述在入队那一刻就写进 runs/{runId}/artifacts/task-goal.json,而 describeTask 等 agent 侧链路读的是 artifact。改库不改 artifact 会让两份记录对不上;两份都改则等于篡改已被 agent 消费过的审计输入。要改就取消后新建。title / priority 仍可改 —— 它们不进任何 agent 的上下文。

R-20.4 · 新增一个 run status(原话)

新增一个 run status

定为 queued。有了 tasks 表之后它仍然必要,唯一理由是把出队的并发临界区交给既有唯一索引兜底:idx_graph_runs_one_active_root 的 WHERE 覆盖 ready/running/paused 而不覆盖 queued,于是「入队时建 queued 行(不占坑,可有任意多条)→ 出队时 UPDATE ... SET run_status='ready' WHERE id=? AND run_status='queued'」这一步,超发的那条会被唯一索引直接拒绝,不需要应用层的「先查后插」(那中间永远有竞态窗口)。

顺带三个收益:入队即有稳定 run_id(可分享的控制台链接)、task-goal.json 的落盘路径在入队时就确定(描述冻结点与 artifact 落盘点重合,正是 R-20.3 要的)、timeline 上记得下「何时入队」这条审计事实。

R-20.5 · 四条实现口径定案(2026-08-18,文档复核后确认)

初稿复核完成后就四个「会实质改变要建的东西」的选择征询,用户逐条定案:

# 问题 定案 影响
1 goal 拆成多个 task 由谁来拆? task-planning agent 进 v1(原设计留到 v2 人手拆)。产出一律是 draft 清单,人确认/编辑后才下达 批 2 多一个 agent 本体 + 拆分链路 + 两步表单,工作量约翻倍
2 并行是这次就要还是先只排队? 先只排队,max_parallel_tasks = 1。唯一索引 idx_graph_runs_one_active_root 不动,DB 层兜底保留 并行仍是批 4,单独排期单独验收
3 manual 任务在队列里怎么处理? 不参与自动出队,人在控制台点「开始」才占坑 startRun(manual) 只点亮入口节点就停下等 /next,而 run 已经是 running 占着坑;自动拉起会让一个没人管的 manual 任务无限期堵死队头
4 上游 task 失败时下游怎么办? 自动转 blocked 并在界面标红,给「重跑上游」与「强制放行」两个出路 depends_on 只认 completed,不处理的话下游会静默躺在队里,与「正在正常排队」无从区分 —— 正是本次要消灭的那类症状

定案 1 连带牵出一处新缺陷:task-planning 跑在 goal 层、任何 run 存在之前,它烧的 token 没有预算池可扣。这正是 graph-engine.defaultPlanWorkGraph 注释里点过名的那个病——「规划调用也是真花钱的一次 agent 调用,token 必须计入同一个 root run 预算池,否则『一层规划 + 一层执行』里有一半的花费是隐形的」——在 goal 层的新实例。复核第二轮刚以「零消费方」为由砍掉的 goal 级预算字段,因此以记账字段 planning_tokens 的形式回来(闸门仍不做,见 P3C §十一.6)。

落点:27-P3C goal / task 两级模型(本条派生出的工作项文档)。


附 · 需求 → 设计落点 速查

需求 一句话 主要落点
R-3 org graph 由第一个 agent 按公司描述动态生成 P2 §4.1 / §4.6
R-4 执行控制台页面(MVCP + 五个控制按钮 + 日志 + loop 划线 + 下钻) P3/P4 全文
R-5 手动 / 自动两种执行模式 P3/P4 §四.C
R-6 七阶段端到端流程 E2E §三
R-7 验收产物是 work graph 的动态可选节点 E2E §十一
R-9.1 org graph = company 级 workflow;work graph = org node 级 workflow E2E §五 / P2 §一 / 总纲 §3.3
R-9.2 所有 node agent 由元 agent 继承生成 E2E §八bis
R-9.3 验收逐层递归,planner 生成、validator 执行 E2E §11.3
R-9.4 L4 拆 company(自动)/ general(dream,人工或 master 驱动) E2E §八 / §8.1
R-10 统一命名前缀 NAMING 全文
R-11 OKR 正名,不叫 goal NAMING §六
R-12 验收产物定名 goal-;goal 唯一、task 多个 NAMING §四
R-13 goal 三层;类型由 agent 推断;新 agent 从 base 继承;强制单入口 NAMING §四 / P2 §3.3 §4.1 §五
R-14 命名轴统一为作用域:subagent-goal → subtask-goal NAMING §四
R-15.1 讨论的是 27 系列的 P3,不是 DevLoop 的 P3 P3/P4 全文
R-15.2 workgraph-planning 是全局通用 agent,不按 org node 特化 NAMING §二 / P3/P4 阶段 D
R-15.3 validator 分 org / work 两层;本体名不带领域前缀 NAMING §三 / P2 §4.6 / P3/P4
R-15.4 引擎泛化,定义层(org/work 两套)与运行时层(graph_runs 一套)分离 P3/P4 §四.A / §四.D
R-15.5 P3 范围含 workgraph-planning + 任务入口,两条非目标作废 P3/P4 §一 / §五
R-15.6 验收契约格式 + 执行器提到最前面,作为 P3 的前置阶段 P3/P4 §五 / E2E §十一
R-16 归因由专职节点做;回退边多条,运行时选边;熔断需双层计数 P3/P4 §四.D.0 / §四.D.2.1 / §四.D.2.2
R-17.1 归因精确到 work graph node 层(跨层寻址,推翻 org node 粒度封装,需返工) P3/P4 §四.D.2.2 / §四.D.3 / §四.A.2
R-17.2 validator-reflection → validator-triager(做的是归因不是判定,对齐 BugTriager) NAMING / P3/P4 / system/templates/
R-18.1 人工操作不该是跑脚本;点一下让 orggraph-planning 真跑并自行招聘 P3B §四 W8 / P2 §4.1
R-18.2 work 层本体由 workgraph-planning 自己雇(方案 a);须同时解决 org graph 被污染 P3B §四 W5-W7
R-18.3 停用 mock,改真实 Claude CLI 验证(mock 不读提示词,此前结论只验到引擎层) P3B 全文
R-19.1 统一产物路径 + 索引(原话此前未记录在源头文档,但 27-P4 §4.6 有设计、未实现) P4 §4.6
R-19.2 建 sqlite 表而不是 files.json(JSON 会重演 _registry.json 的并发重写与 git 冲突) P4 §4.6
R-19.3 两类数据流都要(沿边传递 + 任务级共享);workspace 根代码推导不入库;路径走 tasks/{taskId}/ P4 §4.6
R-19.4 边存契约(kind)、files 表存实例(path),规划/运行两阶段 → 引擎可在跑之前校验「声明要吃的输入没人产」 P4 §4.6
R-20.1 公司任务拆 goal / task 两级,落地 NAMING §四 早已定义、代码里一直没有载体的 goal 1 : task N P3C §三 / §四
R-20.2 两级结构之上做排队与并行;推翻 P3「拒绝而不排队」,必须同时交付调度器(四个触发点) P3C §五
R-20.3 goal / task 描述一经下达不可改(artifact 已被 agent 消费,改库等于篡改审计输入) P3C §四.4
R-20.4 新增 run status queued,出队原子性靠既有唯一索引兜底 P3C §四.3
R-20.5 四条口径:task-planning 进 v1 / 并行留批 4 / manual 不自动出队 / 上游失败下游自动 blocked P3C §四.9 / §五.1.2 / §五.2bis