Commit 7b422b52172cb73ae3e2d4ebc4c8c78c21877e93

Authored by yibo
1 parent c312dd9b

docs(27-P3C): 给「实现在、零调用方」立案 —— 本文档三处要求是同一个惯犯

并行会话指出 graph-engine.js 的 indexNodeOutputs 注释里早就写着
「goal-contract 零调用、setPlanWorkGraph 零调用、三值透传只接了读
那一半」。顺着查下去,这个模式在仓库里被记录过至少 7 处,而且证据
本身就是结论:

- graph-engine.js 跨层判据处:「(『实现在、零调用方』的第五次)」
- graph-run-route-io.test.js 文件头:「这一路踩了十几次的
  『实现在、零调用方』换个方向再来一次」
- graph-run.js:243:「等于又一次『实现在、零调用方』」
- 27-goal-contract-format.md:101:「T0 交付后有四轮时间里,全仓库
  唯一提到 goal-contract.js 的是一句注释 —— 实现完整、零调用方、
  零单测,验收 1 从未被执行过」

有人数到第五次,有人写「十几次」,然后它继续复发。这些记录证明的
不是「有这个问题」,而是「发现了也没人回来收」。

本文档的三处要求是同一个惯犯的三个实例:砍掉 goals.budget_json
(§四.1)、report_to 必须落库(§四.7 禁令二)、处理 goal-contract
那个声明了却零使用的 RUNS_ROOT(验收 12c)。写明它们是硬要求,
不是可以留到下一轮的整洁度问题。

批 1 一并加不变式测试「凡是声明了 GRAPH_RUNS_DIR 覆盖的模块,该
覆盖必须真的被用到」,形状照抄 agents-root-single-holder.test.js。
「样本非空」前置断言别省 —— 扫不到文件时会静默全绿,那正是这类
测试自己变成零调用方的方式。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
docs/todo/system-design/27-p3c-goal-task-model.md
... ... @@ -699,6 +699,26 @@ for (const t of queuedTasks) {
699 699 2. **拆分质量决定预算消耗**。拆出 5 条 task 就是 5 份 `DEFAULT_TASK_BUDGET`(各 100 次调用 / 500 万 token)。这是「产出一律 `draft`、必须人确认」的根本理由 —— 那一步是唯一一道成本闸门。界面上要显式提示「N 个任务 ≈ N × 单任务成本」。
700 700 3. **新本体的真正闸门是「毕业」,不是 registry 登记**(§四.9 约束 4/5 已纠正初稿的反向结论)。`agent.md` + `soul.md` 没写满就停在 `draft`,`hire()` 返回 `body_not_ready`;而 `_registry.json` 缺条目只是少个 `benchmark_score`。另外本体正文的相对路径写错**不报错只静默降级**(§四.9 约束 6)—— 这是本文档点名的静默故障家族里最新的一个成员。
701 701  
  702 +### 4quater. 本文档有三处要求属于同一个惯犯模式:「实现在、零调用方」
  703 +
  704 +§四.1 砍掉 `goals.budget_json`、§四.7 禁令二要求 `report_to` 落库、验收 12c 处理 `goal-contract.js` 那个声明了却零使用的 `RUNS_ROOT` —— 三条都是同一件事:**别留下「代码写了、但没有任何活的调用方/消费方」的东西。**
  705 +
  706 +这不是洁癖,仓库里有完整的证据链,而且证据本身就说明问题:
  707 +
  708 +| 出处 | 原话 |
  709 +|---|---|
  710 +| `graph-engine.js`(`indexNodeOutputs` 注释)| 「凡『靠 agent 自觉』的环节几乎全部落空过(**goal-contract 零调用**、`setPlanWorkGraph` 零调用、三值透传只接了读那一半)」|
  711 +| `graph-engine.js`(跨层判据处)| 「(『实现在、零调用方』的**第五次**)」|
  712 +| `graph-run-route-io.test.js` 文件头 | 「就是这一路踩了**十几次**的『实现在、零调用方』换个方向再来一次(这次是前端在、后端没喂)」|
  713 +| `graph-edge-contracts.test.js` 文件头 | 「`declareEdgeContract` **零调用方**」|
  714 +| `graph-run.js:243` | 「契约声明与产物索引都在库里,界面上却看不见,等于**又一次**『实现在、零调用方』」|
  715 +| `27-goal-contract-format.md:101` | 「T0 交付后有四轮时间里,全仓库唯一提到 `goal-contract.js` 的是一句注释 —— 实现完整、零调用方、零单测,§六 验收 1 **从未被执行过**」|
  716 +| 27-P3/P4 §八 已关闭项 6 | `ProcessGuard` 生产代码里从未被实例化、`RunRegistry.add()` 从未被调用、杀进程那条链同样零调用方 |
  717 +
  718 +**这些记录证明的不是「有这个问题」,而是「发现了也没人回来收」** —— 有人数到第五次,有人写「十几次」,然后它继续复发。所以本文档凡是写「必须落库 / 必须接上调用方 / 零调用方就删掉」的地方,都请当成硬要求,而不是可以留到下一轮的整洁度问题。
  719 +
  720 +**批 1 的落点**:验收 12c 就是收其中一个(`resolveRunDir` + 那个死常量)。同时按并行会话的建议加一条不变式测试 —— 「凡是声明了 `GRAPH_RUNS_DIR` 覆盖的模块,该覆盖必须真的被用到」,形状照抄 `server/tests/unit/agents-root-single-holder.test.js`(**「样本非空」前置断言别省** —— 扫不到文件时会静默全绿,那正是这类测试自己变成「零调用方」的方式)。
  721 +
702 722 ### 5. 两套 `T-` id —— 由 §十二 的统一消解,但在那之前是真风险
703 723  
704 724 `agent-chat.js` 的 `/task/dispatch` 也发 `T-` 开头的 id 并写 `system/tasklog/`。**批 1-4 期间两套并存**,长得像但不同源,读日志时别混(本文档的 id 一律带 `-{4hex}` 后缀,肉眼可分)。批 5(§十二)把存储统一到 `tasks` 表之后,这个风险随之消失 —— 那时 `T-` 只有一个来源。
... ...