09 · 发布之后:规则是怎么被改写的¶
前八章看的是一个仓库从零到 12,000 commits 的第一次蒸馏。这一章看接下来的三周:当产品真的发出去、有了外部用户和已发布的数据,那些从事故里长出来的规则会怎样。 答案不是"继续加",而是加、拆、翻转、降级、放宽、推翻同时发生,每一种都留了案。
口径:本章所有增量统计的范围是 99151657..d347e703,即本书快照 commit 到 2026-09-04。这段区间含 merge 共 2,836 个 commit、不含 merge 1,966 个,截至 d347e703 全历史 15,210 个;期间仓库里出现了 11 个 tag,从 dsh-v0.1.0-rc.7 到 dsh-v0.1.3-alpha.1。快照 commit 99151657 是 08-15 clone 时拿到的 HEAD,事后发现它是一条 08-19 才合入 master 的分支提交,所以涉及祖先关系的统计以它和 master 的 merge-base 5bb600f9 为准。另一件事后才弄清的事:一篇 08-21 的 note 提到开发仓库是私有的,另有一个公开镜像只在 release 时推进;本书 clone 的就是这个镜像,它的 HEAD 恰好是 0.1.3-alpha.1 的 tag 提交,PR 和 issue 面板都关闭,所以本章引用的 PR 号只能在 commit 历史里看到。
先看基本盘变了什么¶
- 节奏正常化。 20 天 2,836 个 commit,日均 142,低于第 01 章的"日均约 200"。按 author date 算,周末提交占比从 20% 降到 14%,0 到 6 点的深夜提交从 16% 降到 11%(第 01 章给的是 0 到 2 点的绝对数,窗口不同)。
- 创始人退到第四。 Tianyi Cui 的作者占比从快照前的 42%(第 01 章按旧总数算是 43%,同一个数)降到这三周的 13%,提交量由 imccyu、Yichen Jiang、Chinesezjc、pku-xht 等分担。前 20 位作者仍覆盖 99% 的提交,参与者全受控这一点没变。
- AI 参与的"明牌"退场。 第 01 章列的两条证据都没了:
codex/*分支的合并从快照前的 204 次降到 26 次,最后一次在 08-28;提交信息里提到 Codex review 的从 65 条降到 0。合并记录里剩下的几乎全是本来就占多数的worktree/*、worktree-*分支(三周 122 次,快照前已有 309 次)和fix(scope): address … review这类不带工具名的修复提交(47 条)。agent 还在写代码,只是不再自报家门。 - 一个统计陷阱。 08-31 按 committer date 有 303 个 commit,是三周最高;按 author date 只有 98 个。差额来自一条存活 30 天的 CPython 后端分支(PR #1148,200 个 commit)在当天被整体 rebase、次日合入。按日统计 commit 数时要同时给两个日期口径,否则一次 rebase 就是一个假高峰。
发布:人管发布,机器只打包¶
仓库里现存的 11 个 tag 全部指向快照之后的提交,最早的是 08-17 的 rc.7。快照前 npm 上已有 6 个版本,按当时的工作流也需要 tag 才能发布,那些 tag 已经不在仓库里。19 天 11 个 tag,其中 9 个真正发到了 npm(0.1.2-alpha.1 和 09-04 的 0.1.3-alpha.1 截至 09-07 未出现在 registry)。发布流程的每一步都能追到一篇 note 或一次事故。
1. 发布是显式的人类动作。 从 08-11 第一次 npm 发布起,流程就是两段:每个 PR 都跑一次无凭据的打包排练;真正的 npm 发布只能由人手动触发,从 dsh-v* tag 出发,挂在需要审批的环境上。08-20 又把发布 job 拆进独立的工作流文件,让它连"被跳过的灰色检查"都不再出现在 PR 面板上。那个文件头部的注释写得很直白:
This workflow is manual-only (workflow_dispatch) and intentionally does not listen to pull_request or push: publication must always be an explicit, reviewed act from a dsh-v* tag, and it must never appear as a PR check.
(这个工作流只能手动触发,故意不监听 PR 和 push:发布必须永远是从 dsh-v* tag 出发的、显式且经过审阅的动作,绝不能出现在 PR 检查里。)
发布 note 里的对应原则:"A human creates the tag after the commit merges to master; CI never writes to the repository and needs no write permission."(commit 合入 master 之后由人来打 tag;CI 永远不写仓库,也不需要写权限。)tag 都是轻量 tag,仓库里没有打 tag 的时刻,只能看被指向的提交:8 个已发布版本从发布 PR 合入到 npm 出现间隔 24 到 50 分钟;0.1.2-rc.1 的发布 PR 上午 10:35 合入,npm 下午 14:21 才出现,仍是"合入之后有人打 tag、有人审批"的形态。
2. 文档站也只从 tag 发布。 08-21 的一篇 note 把文档站从"每次合入 master 就上线"改成和 npm 一样只在 release tag 前进。问题描述是:仓库私有但文档站公开,"a merge published documentation to the internet within minutes — including pages describing work that no released artifact contained"(一次合并几分钟内就把没发布的功能写到了互联网上)。被否决的备选里有一条最值得记:给文档合并加人工审批被否,理由是:
an approval prompt on every documentation merge is a prompt reviewers learn to clear without reading
(每次文档合并都弹一个审批,审批者会学会不看就点过。)
这是第 03 章"机械门禁优于文字规范"的一个变体:例行的人工审批和文字规范一样不可靠,只有让发布本身成为稀有、显式的动作,审批才有意义。
3. 一次事故,一道门禁,以及门禁的边界。 09-03,一个新包带着旧版本号合入 master:它创建时同批发布的包共用的版本号(他们叫 family version)还是 0.1.2-alpha.5,合入时已经升到 rc.1,而它的 CI 是在版本升级之前跑绿的。静态约束检查和整个发布车道一起变红,所有基于它的 PR 跟着红。当天的 note 把这条原本只覆盖 packages/* 的静态版本检查按包名扩到整个家族(apps/、根 manifest、私有包),并且把门禁做不到的部分也写了下来:
No in-repo gate re-runs a pull request's checks when its base moves, and master had no branch protection requiring an up-to-date base.
(仓库内没有门禁会在 PR 的 base 移动后重跑它的检查,master 也没有开"必须基于最新 base"的分支保护。)
Consequences 段直接承认这道门禁"cannot prevent a stale-base merge"(拦不住基于过期 base 的合并),那是平台分支保护的活。能写进仓库的规则写进仓库,写不进仓库的明说它在哪。次日同样的漂移又出现了一次:release 分支升到 0.1.3-alpha.1 后并入的 master 带着一个仍写 0.1.2-rc.1 的新包,5 分钟后在 release PR 里被一个对齐提交修正,提交正文为空,仓库里没有记录这次是门禁报错还是人工发现。
4. 一条到期没删的自毁条款。 快照时的根 AGENTS.md 有一节叫"Pre-release stance: foundation over blast radius",第一句就是自毁条款:"Remove this section at the first tagged release."(第一个 tag 发布时删除本节。)现存最早的 tag 是 08-17,这一节又活了 17 天:替换它的提交 08-31 写成、09-03 才随 PR #3400 合入 master,触发它的不是 tag,而是已发布的数据:
Session format v0 shipped in an alpha release, so a structural writer change can no longer treat existing JSONL as disposable pre-release state.
(Session 格式 v0 已经随 alpha 发出去了,写端的结构变更不能再把现有 JSONL 当可丢弃的预发布状态。)
替换后的规则叫"adjacent migration":读端可以增加一个带版本名的后继,但永远不移动、不覆盖、不删除已提交的代际。一周前(08-25 提交、08-28 合入)一次全仓库把 code-mode 改名为 ptc 的重构,跳过了所有写进会话日志的词汇(持久化事件类型、日志里的插件名、子调用 id 段),提交正文写明这些要等 Session 格式 v0 到 v1 的迁移落地后走自己的迁移。"自由重命名"的自由,在第一份数据落到用户磁盘上时就结束了。
门禁是双向的¶
第 03 章讲了门禁怎么加。这三周新增了 7 个 verify-* 脚本,但同一时期也拆了、翻转了、降级了、放宽了若干门禁。五种动作各看一个案例。
加。 08-23 的 UI 文案本地化门禁。之前已经有类型化的 locale 字典和中英字典键对齐检查,packages/client/AGENTS.md 里也有一句"Product copy is Chinese"的文字规则,但 note 的第一条被否备选写着:
Rely on review and AGENTS.md alone. Rejected because the existing rule and typed dictionaries coexisted with hundreds of bypasses; reviewers need a source-level failure at the introducing line.
(只靠 review 和 AGENTS.md:否决,因为既有规则和类型字典与数百处绕过共存;reviewer 需要在引入的那一行就看到失败。)
这是"门禁优于文字"最直接的一条新证据。同一 commit 在根 AGENTS.md 加了一行规则并链接 note,文字、门禁、决策三件套齐全。
拆。 拆除 knip(死代码检测)的 PR 08-19 发起、08-28 合入。理由不是它没用,而是它需要一份人工维护的平行事实,当时那份配置有 790 行:
The generic unused-code result is advisory, while its exceptions are required maintenance.
(通用的未用代码报告只是建议性的,而它的例外清单却是强制维护项。)
每次包布局变动都要跟着改一份手工维护、只是近似真实加载路径的清单。note 同时写下了代价("reviewers and simplification work must prove removals against the real loading paths",删代码从此要拿真实加载路径来证明)和重新引入的条件(未来的检查必须理解清单驱动的加载,不能靠逐工作区的忽略清单)。门禁要以真实事实为输入;如果门禁自己需要一份手工维护的平行事实,它就退化成了文字规范的另一种形态。
翻转。 第 03 章提过"每上一道闸门,同时记录它会诱导什么坏行为"。这三周有一个完整样本。原规则要求每个包发布一个 ./invariant 伴随模块(运行时断言该包与其他包之间关系的入口),没有可断言关系的包写一个"解释过的空实现"。08-28 的审计发现仓库里有 209 个这样的空实现,每个都带源文件、导出、发布条目、构建接线和注册测试,"expressed a negative conclusion without adding a runtime assertion"(只表达了一个否定结论,没有增加任何运行时断言)。处理不是废除门禁,而是把方向翻过来:拒绝空安装器,无关系的包必须整体省略并在 README 写明理由。删 209 个空实现,外加一个只调用自身实现来"验证"自身的探针,保留 39 个有独立观测的;那次提交删了 11,398 行。code-review skill 里对应的检查项同 PR 改写。规则的执行成本一旦可见,规则本身会被翻转,而不是被继续解释。
降级。 08-25,Windows 覆盖率车道被移出"所有检查通过"的必需列表,commit 正文写"Other PRs are blocked by Windows ACP half-close tests timing out. Keep the coverage job running for signal, but remove it from all-checks-passed.needs until the Windows skip fix is validated."(其他 PR 被 Windows 上超时的测试卡住;保留这个 job 作为信号,但在修复验证前移出必需列表。)到 09-04 它仍未恢复为阻塞检查。08-31 一篇关于 Windows flaky 预算的 note 给了定性:"excluded … because it is unstable, not because its verdict is unimportant"(被排除是因为它不稳定,不是因为它的结论不重要)。门禁在测机器而不是测代码时,先降级再修,而不是硬扛。
放宽。 多个测试超时从 15 秒、30 秒放宽到 90 秒。两次套件级放宽(08-27、08-29)的 note 都写明了放弃了什么:
That detection is traded away deliberately: the 15 s ceiling was firing on contention rather than on regressions, so what it caught was the shared volume, not the code.
(这项检测是有意放弃的:15 秒上限触发的是资源争用而不是回归,它抓到的是共享磁盘,不是代码。)
车道级的超时从 30 秒到 60 秒再到 90 秒(08-25、08-26)则只有 commit 正文,没有 note。第 03 章的习惯有了反向版本:每放宽一道闸门,记录它放弃了哪种检测能力。
门禁抓不到的东西,也留了证据¶
08-24 顶层 examples 目录退役,字数预算 manifest 里对应的条目被删掉。次日(08-25)一次文档标准重写把 docs/AGENTS.md 里的预算目标改成逐项列举 manifest 上限,用的却是 08-24 之前的数字,于是已退役的"examples/AGENTS.md 310"以正文形式第一次出现在文档里;08-29 又有人改这句话,仍然没动它,截至 09-04 仍在。三次改动所有文档门禁都绿:字数门禁读的是 manifest(manifest 本身是对的),链接门禁只查链接,反引号里的路径不在任何门禁的视野内。
一篇日期标为 08-20 的文档质量提案(截至 09-04 仍是 proposed;它实际是 08-25 随同一个 PR 进入仓库的,和那句过时条目在同一个 commit 里)说过这件事:
The gates prove structure and generated freshness, not that maintained prose still names the live mechanism.
(门禁证明的是结构和生成物的新鲜度,不是手写文字还在描述活着的机制。)
同一篇提案指出根 AGENTS.md 已经 1,936 词,超出 1,600 词的目标,"The standard has no room for its next rule"(标准已经没有空间容纳它的下一条规则)。它建议的解法是让预算 manifest 同时记录目标和临时上限,机械检查余量。提案记录了前三片工作(合并文档技能、README 样板、文档快速检查)已经落地,这一片没有做。实际发生的是相反的事:门禁上限先在 08-17 从 1,900 调到 1,950,是一个 Python 测试 commit 顺手改的,它往根 AGENTS.md 加了一条规则,正文没有提预算,也没有搬走或压缩任何内容;08-25 的重写压缩了几句话,但根 AGENTS.md 净增 14 词,同时把目标也改成 1,950。截至 09-04,根 AGENTS.md 恰好 1,950 词。第 03 章讲的"搬走、压缩、最后才调上限"在这里没有被完整执行,目标和上限之间的余量没有了。
规则被推翻的四种姿势¶
三周里有 6 个 PR 被整体 revert。但"推翻"不只有 revert 一种形态,下面四个案例里只有第 1 个是 PR 级 revert。
1. 输入事实有缺口,输出全绿也得回滚。 08-26 一条 AGENTS.md 规则从"SessionEventMap(会话日志里所有事件类型的清单)成员默认必须被读端认识,带 ignorable: true 的除外"改成"每个成员都必须被读端认识",理由是审计了所有第一方生产者,没有人用 ignorable。08-30 整个 PR 被 revert,新 note 写:
That producer inventory did not cover a third-party plugin that currently depends on the field.
(那份生产者清单没有覆盖一个正依赖该字段的第三方插件。)
门禁和测试全绿、PR 正常合入,规则还是错的,因为决策依据的事实不全。这是"管两端"的一个精确注脚:输出端再严,也补不上输入端的事实缺口。被 revert 的那篇 note 没有进 rejected,而是随 revert 一起删除,由新 note 记录反转理由。
2. 15 天后被自己的 note 体系推翻。 08-10 的 note 决定会话遥测默认关闭,被否备选里明确写着"Default session telemetry to FEEDBACK_ONLY. Rejected because recording feedback would still trigger an upload without a deployment explicitly enabling outbound reporting"(把默认设成"仅反馈时上传":否决,因为没有部署方显式开启外发的情况下,记录反馈仍会触发上传)。08-25 的 note 采纳了正是这个被否方案:用户按 /feedback 时上传本会话的原始记录,理由是"the session that exhibited the problem is the one worth uploading, and re-running loses it"(出问题的那个会话才值得上传,重跑就丢了)。旧 note 加了 superseded 交叉引用,没有删。新 note 的 Consequences 也没有粉饰:上传的是未脱敏的原始副本,可能含消息文本、工具参数和工作区路径,而且用户是在上传触发之后才读到说明。决策可逆,但两次决策都在;"从自己的事故里蒸馏"的数据回路由此延伸到了用户端。
3. 前一天拒绝的方案,第二天采纳。 08-24 一个 bug:两个系统提示词段落 order 相同,渲染顺序由插件激活顺序决定,快照不确定。当天的修复 note 把其中一个改成 115.5,并写明"Tie-break equal orders by section name in the registry. Rejected because it would silently reorder every existing tie."(在注册表里按段落名打平局:否决,因为它会悄悄重排所有现存的平局。)08-25 的架构 note 把二十多个包里的字面量 order 集中成稀疏具名带(-1000 到 9900),同 order 按名字打平局,并反过来否决了"继续插小数":"fractions provide no durable spacing rule"(小数给不出持久的间距规则)。前一天的 note 归档,两篇都在。同一个问题连续两天两个结论,不是反复,是从"止血"到"治本"的两步。
4. 25 小时内加上又撤掉。 web_fetch 在三个 Web 预设里从出厂关闭改为出厂开启的那个 PR(#2985;共享 base 层要到 09-01 才默认开启)里,08-24 13:38 加了一次性审批,当晚加固到"DNS 解析前先审批",08-25 14:25 删除审批策略,只保留公网目标校验,不逐次审批。撤销的 commit 正文是空的,也没有新开 note;理由写在同一个 commit 对 06-24 那篇 Web 能力边界决策的修订里,作为新增的一条被否备选:"Require per-call approval before public fetches. Rejected for the shipped presets. Public-address validation blocks SSRF destinations, while per-call confirmation would interrupt ordinary browsing without controlling public data egress reliably: a model can reach the same public network through mounted shell tools."(公网地址校验已经挡住 SSRF 目标;按次确认会打断正常浏览,却不能可靠地控制公网数据外泄,模型通过已挂载的 shell 工具照样能到达同一个公网。)推翻昨天的决定,记录方式是回到原始决策 note 里补一条"被否备选",而不是新写一篇。
决策文档的重量¶
第 02 章讲了 Agent Notes 的设计。三周后它的规模和用法都值得重新看一眼。
数量。 implemented 从 507 涨到 657:新增 176 篇,同期 26 篇移出(17 篇归档、9 篇删除),净增 150。活跃英文 note 总词数从 60 万涨到 76 万,平均每篇新 note 约 1,000 词。快照时存在的 507 篇里有 287 篇在三周内被原地修改过,另有 23 篇被改名或移动。触及最多的几次批量修改依次是:08-22 思维链泄漏清洗(62 篇)、顶层 examples 目录退役(28)、Session 格式迁移(26)、移除 SQLite 持久化后端(26)、code-mode 到 ptc 的改名(25)。除第一项是措辞清洗外,其余都是改名和格式变更引发的事实同步,第 02 章说的"note 与代码同步维护"确实在被大规模执行,代价也随之线性增长。
用法变了。 新增的 176 篇里,174 篇从未出现在 proposed 目录;经过 proposed 的两篇,一篇是快照前就在提案里的 API Proxy 迁移(08-27 转正),另一篇是 09-02 当天写进 proposed、当天就移入 implemented 的。第 02 章那个"先写提案再转正"的例子是特例,常态是 PR 直接带一篇现在时的 note 合入,这符合 README 的规则:重大的未来工作从 proposed 开始,已经做出的决策直接从 implemented 开始。
第一次有人说它重。 上文那篇 08-20 提案统计了全仓库文档体量,活跃 note 580 个文件、63.8 万词,并写道:"These quantities describe maintenance and retrieval pressure, not defects by themselves."(这些数字描述的是维护与检索压力,本身不是缺陷。)实际的治理动作只有一次专门的清扫:08-22 一次归档了 17 篇低价值 note,同日一次思维链泄漏清洗改了 82 篇。archived 三周共增加 33 篇:这 17 篇之外,另有 7 篇在各自的功能或重构 PR 里顺手归档,15 篇新 note 一落地就进了 archived。归档 skill 明确禁止按配额归档,所以这仍是人工触发的批处理。
rejected 不是永久的。 11 篇变 9 篇。一篇随 Session 格式 v2 的提交一起删除,v2 那篇 implemented note 把同一个否决改写进了自己的备选方案一节;另一篇在 08-22 的清扫里删除。两次删除的提交都没写理由。README 的规则是"Keep a rejected note only while it prevents a plausible mistake; otherwise delete"(rejected note 只在它还能防住一个合理的错误时保留,否则删除),到期就整篇删,而不是改写。
Skill 的第二次蒸馏¶
两个技能被合并,提案点名的起因是抄录的事实过期。 08-25,文档标准和文档站同步两个技能合并重建为 dsh-doc,一次 squash 落地,同一提交带入了上文那篇 08-20 提案,提案把合并列为第 1 片工作。提案点名的是站点同步技能:它"told authors to reuse a nonexistent en-docs sidebar and to add sections to a removed sectionOrder",让作者去复用一个不存在的侧边栏、往一个已删除的字段里加节。手册里抄录的机器值没有 owner,门禁全绿也会过期。修法有三层:合并成一个技能,正文只做入口,细则放进 references/ 子目录按需加载(带这种子目录的技能从两个变成四个);新技能加入强制的"Fact-check procedure: test, do not assume"(事实核对流程:测试,不要假设),文档里每条操作性断言"the only admissible evidence … is having run it"(唯一可接受的证据是亲手跑过),跑不通的删掉;仓库第一次给一份 skill 的正文写了回归测试,断言它不再含 en-docs、sectionOrder 和原型期措辞。第 04 章的蒸馏闭环多了一环:skill 本身也要被机械检查。
一个新技能,先补事实再给规则。 08-28 的 dsh-ci-test-reliability 是把这一周 scripts/ 下两个测试套件在自托管 Windows 车道上、在没有改动它们的分支上反复超时的经历蒸馏成的手册(线索在 08-27、08-29 两篇超时预算 note 和次日提交正文里的"the two suites that recently failed on unrelated branches");技能自己的 note 只给了通用定性:"A test can select the correct tier and still pass only when it runs alone."(一个测试可以选对层级,却仍然只在单独运行时才通过。)次日的一个提交说明了为什么光有 skill 不够:
The skill carries the reliability rules, but nothing an agent loads by default said that specs run concurrently at all.
(技能里有可靠性规则,但 agent 默认加载的东西里没有任何一处说 spec 是并发执行的。)
于是 docs/testing.md 新增"How specs execute"一节作为这个事实的唯一归属,两个子目录 AGENTS.md 放短版。事实(执行拓扑)放进 agent 必读的常驻文档,判断规则(怎么分配端口、怎么判断 flake)放进按需加载的 skill。这是第 05 章"喂事实"和第 04 章"蒸馏成手册"的分工在同一个问题上的现场版。note 还写了 skill 升级为门禁的条件:"The skill is advisory … A repeated, statically identifiable defect can still justify an executed repository check."(技能是建议性的;一类反复出现且能静态识别的缺陷,仍然可以成为加一道可执行检查的理由。)
技能正文列了七种"掩盖式修复"予以拒绝:不找等待状态就加超时、加重试、全部串行、吞错误、削弱断言、把不稳定行为归一化掉、清理或断言前加 sleep。同时区分"Restoring a budget is not masking":把测试超时改回 CI 车道本来就允许的上限不算掩盖。同期另一篇 note 记了一条人工裁决:单元测试遗留的临时目录两次耗尽了自托管 Linux CI 主机的 inode,有人提了定期清扫方案,"Human review of #3233 (2026-08-28) rejected the sweep: unit tests must clean up the directories they create instead."(PR #3233 的人工评审否决了清扫:单元测试必须自己清理自己创建的目录。)在 owner 处修,不加一层兜底。
没发生的事。 第 04 章那条半自动 skill 修订流水线,三周内没有任何启动痕迹,note 仍是 proposed,验收记录停在 7 月 15 日的"0 candidates"。code-review skill 的 4 次修订没有一次来自这条流水线:两次是新建 ci-test-reliability 技能的 PR 顺手在 review 清单里加了指向新技能的条目,另两次分别搭在 invariant 清理和 UI 文案本地化门禁两个代码 PR 里。docs/postmortem 自 08-03 起零新增,它自定的范围是"bug 到了不该到的地方(真实用户、已合并的 PR、一次发布)",三周内的 CI 事故(inode 耗尽、flaky 超时)全部走 note 体例记录,postmortem 实践没有废弃,只是留下的 4 篇全是产品缺陷。
缓存感知成了系统性原则¶
第 08 章在 plan-mode 提示词里发现了"for request-cache stability"这一句。三周后它不再是一处巧思:
- 子代理的 report 工具连包删除。 这是子代理向父代理汇报结果的专属工具。理由是子代理专属的工具和提示段"preceded every inherited fork turn"(排在每个继承的 fork 轮次之前),让 fork 出来的子代理请求头在继承的历史之前就和父代理不一样,"forcing the provider to prefill the entire copied transcript again"(迫使供应商把整份复制的记录重新预填)。note 写了重新引入的条件:需要证明子代理确实要用不同的模型请求,并拿出前缀缓存成本的证据。
- fork 不允许换模型。 新增的子代理模型选择功能默认关闭且需要白名单,而 fork 类子代理干脆不提供这个选项,配置注释写着"Fork omits model selection so provider/model stay equal to the parent and the inherited history remains eligible for KV Cache reuse."(fork 不提供模型选择,让 provider 和模型与父代理保持一致,继承的历史才有资格复用 KV 缓存。)
- 模型目录不渲染进工具描述。 一个 provider 可能有几百个模型,写进每个委派工具的描述会撑大每次请求,并且目录一变就改写早期缓存前缀,所以改为按需调用的列表工具。
推理成本结构被反向压进了产品的接口设计。这也解释了为什么他们能说"别省真实 API 测试":省下来的钱在别处。第 08 章附注提到的出厂清单变化里,遥测默认对应上文"推翻 2",子代理 report 工具对应本节第一条,提示词段落排序对应"推翻 3",web_fetch 出厂开启对应"推翻 4"。
这一章对"管两端,放中间"的三条补充¶
- 门禁要以真实事实为输入。 如果一道门禁自己需要一份人工维护的平行事实("拆"那段里 knip 的例外清单),它就退化成了文字规范的另一种形态,该拆。
- 输入端的事实缺口会推翻输出端全绿的规则。 "推翻 1"是样本:门禁、测试全过,规则还是错的。修法不是加更多输出检查,而是补生产者清单。
- 规则的执行成本可见时,规则会被翻转而不是被解释。 209 个空实现、790 行的 knip 配置、到顶的字数预算,都是成本先变得可见,然后规则改向。反过来说,看不见成本的规则会一直活着。
以及一条关于本书自身的:快照会过时。第 01 到 08 章的数字是 2026-08-15 的,这一章是 09-04 的,下一次再看又会不一样。本书在各章里标注了已知过时的地方,但读者动手复现时,一切以自己机器上的输出为准。
复现口径¶
cd deepseek-harness
git rev-list --count 99151657..d347e703 # 2836
git tag -l --merged d347e703 --sort=creatordate # 11 个 tag
git diff --name-status 99151657 d347e703 -- .agents/skills # 技能增删
git diff 99151657 d347e703 -- AGENTS.md # 根规则改动
git log --format='%ad %cd' --date=short 99151657..d347e703 # author vs committer 日期
rc.1 的出厂启动清单已存档在 附件-boot-manifest-0.1.2-rc.1.yml,可与第 08 章的 rc.6 附件对照。