@twinsearth/dsh-master 3.2.10 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/README.md +3 -0
  2. package/client.js +50 -0
  3. package/dist-host/cost/attribution.js +183 -0
  4. package/dist-host/cost/audit.js +163 -0
  5. package/dist-host/cost/budget.js +211 -0
  6. package/dist-host/cost/bus.js +95 -0
  7. package/dist-host/cost/cert-chain.js +100 -0
  8. package/dist-host/cost/experiment.js +132 -0
  9. package/dist-host/cost/gate.js +189 -0
  10. package/dist-host/cost/host-surface.js +80 -0
  11. package/dist-host/cost/index.js +312 -0
  12. package/dist-host/cost/ledger-report.js +193 -0
  13. package/dist-host/cost/ledger.js +401 -0
  14. package/dist-host/cost/metrics.js +198 -0
  15. package/dist-host/cost/milestones.js +171 -0
  16. package/dist-host/cost/modules/index.js +5 -0
  17. package/dist-host/cost/modules/manifests.js +130 -0
  18. package/dist-host/cost/policy.js +276 -0
  19. package/dist-host/cost/report.js +156 -0
  20. package/dist-host/cost/reuse-report.js +128 -0
  21. package/dist-host/cost/rsi.js +367 -0
  22. package/dist-host/cost/toolface.js +147 -0
  23. package/dist-host/cost/types.js +31 -0
  24. package/dist-host/kernel.js +28 -2
  25. package/dist-host/plugins/cost-optimizer.js +277 -27
  26. package/dist-host/plugins/superagent-router.js +88 -1
  27. package/dist-host/superagent/types.js +8 -0
  28. package/dist-worker/agent-loop.js +449 -7
  29. package/dist-worker/baseline-fit.js +66 -0
  30. package/dist-worker/budget-guard.js +93 -0
  31. package/dist-worker/ccs.js +99 -0
  32. package/dist-worker/cost-hooks.js +115 -0
  33. package/dist-worker/cost-modules.js +330 -0
  34. package/dist-worker/cost-spi.js +3 -0
  35. package/dist-worker/edg.js +372 -0
  36. package/dist-worker/gdr.js +159 -0
  37. package/dist-worker/index.js +80 -2
  38. package/dist-worker/llm-http.js +20 -0
  39. package/dist-worker/sink-http.js +1 -0
  40. package/dist-worker/spill.js +115 -0
  41. package/dist-worker/tool-batch.js +66 -0
  42. package/dist-worker/tool-compact.js +275 -0
  43. package/dist-worker/tool-disclosure.js +90 -0
  44. package/dist-worker/tools.js +16 -0
  45. package/docs/ARCHITECTURE.md +21 -0
  46. package/docs/CHANGELOG.md +50 -0
  47. package/docs/DESIGN-v3.3.0-cost-optimization.md +1053 -0
  48. package/docs/EXPERIMENT-M5-real-ab.md +82 -0
  49. package/docs/THIRD-PARTY.md +87 -0
  50. package/package.json +1 -1
  51. package/src/cost/attribution.ts +186 -0
  52. package/src/cost/audit.ts +170 -0
  53. package/src/cost/budget.ts +226 -0
  54. package/src/cost/bus.ts +97 -0
  55. package/src/cost/cert-chain.ts +102 -0
  56. package/src/cost/experiment.ts +136 -0
  57. package/src/cost/gate.ts +191 -0
  58. package/src/cost/host-surface.ts +97 -0
  59. package/src/cost/index.ts +316 -0
  60. package/src/cost/ledger-report.ts +186 -0
  61. package/src/cost/ledger.ts +385 -0
  62. package/src/cost/metrics.ts +193 -0
  63. package/src/cost/milestones.ts +170 -0
  64. package/src/cost/modules/index.ts +13 -0
  65. package/src/cost/modules/manifests.ts +129 -0
  66. package/src/cost/policy.ts +276 -0
  67. package/src/cost/report.ts +158 -0
  68. package/src/cost/reuse-report.ts +131 -0
  69. package/src/cost/rsi.ts +364 -0
  70. package/src/cost/toolface.ts +151 -0
  71. package/src/cost/types.ts +298 -0
  72. package/src/kernel.ts +27 -2
  73. package/src/plugins/cost-optimizer.ts +271 -26
  74. package/src/plugins/superagent-router.ts +82 -1
  75. package/src/superagent/types.ts +70 -0
  76. package/worker/agent-loop.ts +444 -7
  77. package/worker/baseline-fit.ts +80 -0
  78. package/worker/budget-guard.ts +156 -0
  79. package/worker/ccs.ts +202 -0
  80. package/worker/cost-hooks.ts +133 -0
  81. package/worker/cost-modules.ts +356 -0
  82. package/worker/cost-spi.ts +283 -0
  83. package/worker/edg.ts +424 -0
  84. package/worker/gdr.ts +233 -0
  85. package/worker/index.ts +84 -3
  86. package/worker/llm-http.ts +18 -0
  87. package/worker/sink-http.ts +5 -2
  88. package/worker/spill.ts +133 -0
  89. package/worker/tool-batch.ts +124 -0
  90. package/worker/tool-compact.ts +317 -0
  91. package/worker/tool-disclosure.ts +131 -0
  92. package/worker/tools.ts +553 -531
  93. package/worker/types.ts +191 -0
package/docs/CHANGELOG.md CHANGED
@@ -1,3 +1,53 @@
1
+ ## 3.3.0(2026-11-13 已发布)
2
+
3
+ > 三方发布:annotated tag 3.3.0 + GitHub Release + npm @twinsearth/dsh-master@3.3.0。
4
+ > 门禁:G1–G6 全绿(含真实 provider A/B:tokens/task 6263 → 3906.75,成功率 0pp 差),G7 已获用户明确授权。
5
+
6
+ **主题:成本优化系统层(ledger / budget / policy / audit)+ Worker 四切点 + A1 工具输出紧凑化(默认 shadow)。**
7
+
8
+ - 系统层 `src/cost/`:`ledger`(两本账 execution / governance、按模块与任务归因、环形缓冲)、`budget`(默认 task 50k / fork 500k,fail-closed、拒绝不扣额度、可退款)、`policy`(observe → shadow → enforce;enforce 门禁:先 shadow、准确率 ≥0.98、样本 ≥20、零破坏性命中、非空白名单;可随时降级)、`audit`(单向哈希链,篡改即断链);`createCostSystem` 统一组装,`status()` 同时给出 executionSaved / governanceCost / netSaved。
9
+ - Worker 四切点 `worker/cost-hooks.ts`:beforeModelCall / afterModelResponse / beforeToolDispatch / afterToolReceipt;事件经 `sink.cost` 交给宿主(HTTP sink 新增 `cost` 事件、Cordis sink 发 `superagent:cost`);钩子吞掉所有异常,不改变状态机、预算判定与工具执行。
10
+ - `cost-optimizer` 行保持 `estimate/record/summary/reset/status` 兼容面,新增 `ledger()/authorizeBudget()/cost()/requestMode()/setMode()/audit()`;版本 `3.3.0-dev`,`record()` 同时写 execution 账本;角色仍只允许 fork。
11
+ - 测试:新增 `test/cost-system.test.mjs`(两本账/归因/环形、预算 fail-closed 与退款、灰度门禁与回滚、审计断链)与 `test/worker-cost-hooks.test.ts`(切点顺序、异常吞噬、真实 Agent Loop 集成);全量 **197/197**。
12
+ - **M2 · A1 `tool-compact`**:`worker/tool-compact.ts` 对 `fs_read_file`(无损空白压缩)、`fs_list_dir`(`src/`/`a.txt` 紧凑列)、`fs_write_file`(`ok path (+N B)`)、`exec_shell_in_vm`(去空段/合并空行)做格式化;三档 `off/shadow/enforce`,默认 **shadow**(真算「本可节省」但返回原文),仅当紧凑结果更短才替换;未知工具原样透传。
13
+ - A1 归因:`afterToolReceipt` 事件携带 `compaction`(原始/紧凑字符、节省、估算 token);`WorkerResult.cost.compaction` 汇总;`recordWorkerCost()` 把归因单独上报 `cost.recordAttribution()`——**shadow 只计「本可节省」**,enforce 才写入 execution 账本且不重复计入消耗 token。
14
+ - **系统层补全**:`src/cost/attribution.ts`(按模块与任务聚合,enforce 才入账、shadow 只累计)、`src/cost/bus.ts`(成本事件总线 + 瓮城回流出口,订阅者异常隔离、环形缓冲);`createCostSystem()` 新增 `attribute()/subscribe()`,`status()` 增加 `attribution` 与 `bus`。
15
+ - **模块层 SPI**:`worker/cost-spi.ts` 定义 ToolModule / DecisionModule 契约,`worker/cost-modules.ts` 提供注册表(顺序应用、`off` 跳过、异常 fail-open 并记入 `errors`)与 A1 适配器;`agent-loop.ts` 改为只依赖注册表(新增 `WorkerDeps.costModules`),A/B 类模块不再需要改动 Agent Loop。
16
+ - 测试(M2):新增 `test/worker-tool-compact.test.ts`、`test/worker-cost-spi.test.ts`、`test/cost-attribution.test.mjs`,并在 `worker-cost-hooks.test.ts` 增加 shadow/enforce 真实循环断言;另将 Windows 计时类用例改为有界等待,CI 的 windows job 改用串行 `npm run test:clean`。
17
+ - 明确未做(M3–M4):A2 渐进纰漏、A3 批量、B1–B4 决策复用、真实 fork 对照实验、面板成本块。
18
+ - **移植边界**:新增 [`docs/THIRD-PARTY.md`](THIRD-PARTY.md)(参考项目、许可证、允许/禁止清单、当前实现来源核对、新增模块检查清单)与 `test/license-provenance.test.mjs` 自动守卫(SPDX 头、无第三方版权/许可证样板、无 vendored 源码与二进制、零运行时依赖、不 import 参考实现)。当前实现全部自研:系统层为通用工程结构,A1 只处理本项目自有工具的输出形状,B1–B4 仅有 SPI 类型。
19
+ - **目标/非目标落为可测约束**:设计稿 §2.3 给出「5 条目标 → 实现 → 验收证据 → 状态」对照表,§2.4 给出「5 条非目标 → 自动守卫」对照表。
20
+ - **降级留痕(目标 2.1-5)**:模块异常 fail-open 并发出 `degraded` 事件(注册表按「模块+阶段」去重计数,首次与每 20 次上报)→ `costHooks.degraded` → `sink.cost` → `WorkerResult.cost.degraded` → 宿主 `cost.recordDegraded()`(审计 `cost.degraded` + 总线事件 + 按模块计数,**不计入任何节省**);新增 `test/worker-cost-degraded.test.ts` 四条用例(含「模块挂掉但 A1 仍生效、任务仍成功、executionSaved 仍为 0」)。
21
+ - **非目标守卫**:新增 `test/non-goals.test.mjs`——Router 控制面不得引用 `cost/`;`normalizeTicket()` 与 Mandate 契约字段固定;`SERVICE` 五个服务键取值与 3.2.x 一致;`COST_MODULES` 仅 A/B 两族且 bundle 无 `pm-`/`pjm-` 行;版本仍 3.2.10 且 CHANGELOG 保持 `3.3.0-dev`。
22
+ - **两个工具面分开设计(§3.3 / §6.0)**:账本新增 `surface: 'worker' | 'host'` 与 `external` 标记,`netSaved` 只算 Worker 面自研收益;新增可选 `src/cost/host-surface.ts` 适配器(默认关闭、零依赖、不重写任何宿主插件),宿主面外部收益以 `external: true` 单独展示且 `contributesToOwnSavings` 恒为 `false`;`ToolModule` 增加 `surface: 'worker'`。新增 `test/cost-surfaces.test.mjs`(外部收益永不进入 `netSaved`、适配器默认空转、两面对照不混淆)。
23
+ - **M5 真实对照实验(首次真实收益数据)**:`scripts/fork-experiment.mjs` 新增 `--real`(真实 provider + 真实 Worker 代码路径),跑出 20 vs 20 任务:**tokens/task 6263 → 3906.75(−37.6%)**,成功率 100% vs 100%(0pp 差);A1 回执压缩在 20/20 任务生效(估算节省 53,549 tokens),B2/B3 复用尝试 20 · 命中 20(100%)· 跳过模型调用 20 · 真实派发 20 · 失败回落 0。报告见 [`docs/EXPERIMENT-M5-real-ab.md`](EXPERIMENT-M5-real-ab.md)(含「能证明/不能证明」与复现步骤)。`evaluateForkExperiment()` 新增 `harness` 校验:`local-dry-run` 一律判 `harness-not-real`,**dry-run 数据无法冒充 G5 证据**。门禁现状:G1–G6 全绿、`bootstrapOk=true`,仅 G7(发布授权)未满足;里程碑 M1–M4 达标,M5 因瓮城回流范围外未达标。- **M5 交付物完成(离线候选冻结清单 + 面板)**:`src/cost/rsi.ts` 新增 `buildFreezeManifest()`(规范化清单:`inputDigest`/`thresholds`/按 `candidateId` 排序的 `entries`/`manifestDigest`,`autoDeploy:false` 写死)与 `verifyFreezeManifest()`(摘要自校验防手改、**输入漂移检测**、逐条重验阈值与 `usableByActive`);`scripts/rsi-offline.mjs` 新增 `--manifest-out` 与 `--verify`(复核失败退出码 1)。面板只读成本块与瓮城回流接口位(显式 `available:false`)已在 §11 落地。新增 `test/cost-freeze-manifest.test.mjs`(7 条)。
24
+ - **M4 交付物完成(真实替换 + 证书链 + 自动回退)**:新增 `src/cost/cert-chain.ts`(`buildCertChainReport`)——逐张证书核对三件事:原生派发证据、审计落链(能按 `taskId+step+edgeId` 找到记录且 `verify()` 不断链)、账本对账(同 `taskId+step` 金额一致);任一项不成立即 `issue` + 报表失败。失败替换单列为 `fallbacks`/`fallbackReasons` 且**永不计节省**。审计记录补 `dispatched: true`(落链即已派发);服务面新增 `cost.substitutions()` 与 `cost.ledgerEntries()`。新增 `test/cost-cert-chain.test.mjs`(7 条,含真实服务端到端与 Agent Loop 派发失败自动回退)。
25
+ - **M3 交付物完成(命中率 + 「本可节省」报表)**:`ccs.mode:'shadow'` 现在真的做守卫匹配并产出「本可替换」证书(`dispatched:false`、不进审计链),但**绝不跳过模型调用**;新增 `WorkerResult.cost.ccs.attempts`(每次复用尝试含 `reason`/`stage`/`wouldSaveTokens`,命中与未命中都记)与 `shadowCertificates`。新增 `src/cost/reuse-report.ts` + `buildReuseReport()`/`formatReuseReport()`:`hitRate = hits/attempts`(`denominator:'reuse-attempts'`)、`wouldSaveTokens` 与 `actualSavedTokens` 两个字段(shadow 后者恒 0)、6 类 miss 原因固定列 + `byTool` 下钻、样本 <20 明确标注「不足以下结论」。新增 `test/cost-reuse-report.test.mjs`(8 条,含真实 Agent Loop shadow 端到端)。
26
+ - **M2 交付物完成(工具面 token 下降 + 归因)**:新增 `src/cost/toolface.ts` + `scripts/toolface-report.mjs`——用**真实工具定义**计算工具面:全量 347 tokens → 常驻 238 tokens,**每轮省 109 tokens(下降 31.4%)**;A1 回执压缩在 shadow 只报「本可节省」、enforce 才记 `executionSavedTokens`,估算部分单列;A2 的 `load_tools` 装载成本进 **governance** 并从净收益扣除;`disclosure.enabled:false` ⇒ `reductionRatio === 0`(fail-open 可断言);归因把 `a1-compact` 与 `a2-disclosure` 分列不合并。新增 `test/cost-toolface.test.mjs`(7 条)。
27
+ - **M1 交付物完成(记账报表 + 预算闸测试)**:新增 `src/cost/ledger-report.ts` + `scripts/ledger-report.mjs` + `cost.ledgerReport()`——估算/实测分列、两本账不合并、外部面收益单列(明确「不并入」)、`byModule` 固定铺满 8 列(零也列)、`byPhase`/`bySurface`/`byTask`/`timeline` 稳定排序、JSONL 坏行跳过并计数、报表自带 `discipline` 口径声明。**修复 `worker/budget-guard.ts` 的 `settle()` 缺陷**:原实现为死代码 `- 0`,把预留与真实用量重复计入导致额度提前耗尽;新增 `reservedTokens` 跟踪未释放预留,`refund` 同步释放、`settle` 先退预留再记实际。新增 `test/cost-ledger-report.test.mjs`(9 条,含三条预算闸验收)。
28
+ - **§14 里程碑状态机**:新增 `src/cost/milestones.ts` + `scripts/milestones.mjs`——把 M1–M5 表编码成机器可读状态,每阶段分「实现」与「效果证据」判定:M1 效果由测试证明 ⇒ done;M2–M5 实现完成但缺实测 ⇒ `implemented-effect-unmeasured`;**M4 在 M3 守卫准确率达标(samples ≥ 20 且 accuracy ≥ 0.98)前恒为 `blocked-by-dependency`**;M5 的瓮城回流如实标 `fang-relay-out-of-scope`。当前真实状态:实现 5/5、达标 1/5。新增 `test/cost-milestones.test.mjs`(7 条)。
29
+ - **§11 与现有代码的映射落地**:`src/kernel.ts` 新增 `OPTIONAL_SERVICE`(ledger/budget/policy/audit)与 `probeOptionalServices()`(探测不到即 false,不假装存在),`SERVICE.cost` 名称不变;cost-optimizer 额外 provide 四个只读子服务门面;`worker/tools.ts` 增加 `WorkerTool.destructive` 元数据(fs_write_file / exec_shell_in_vm / create_pr)与 `registry.destructive(name)` / `registry.schemaHash(name)`(与 B1 同一哈希算法,Agent Loop 改用注册表值,并按 I3 剔除破坏性工具的边,除非 `allowDestructive`);`worker/llm-http.ts` 透传 `cached_tokens`(`prompt_tokens_details.cached_tokens` 与顶层,拿不到就省略不写 0);`src/superagent/types.ts` 新增 `COST_EVENT_TYPE` / `CostEventEnvelope` / `EdgEdgeView` / `SubstitutionCertView` / `CostSummaryView`;新增 `src/cost/modules/`(7 个模块清单 + `validateManifests()`,实现仍在 worker/,进程边界见设计稿说明);`client.js`「房主」面板新增**只读**成本块(A/B 分列、governance、净节省、净亏任务、命中率,无任何写入);成本路由 `/dsh-master/api/superagent/cost` 增加只读 `service` 段。新增 `test/mapping.test.ts`(7 条)。
30
+ - **§10.2 发布门禁**:新增 `src/cost/gate.ts` + `scripts/gate.mjs`——七道门机械化判定(G1 check / G2 build / G3 test / G4 覆盖 / G5 真实对照 / G6 零残留 / G7 发布授权);G4 扫描 `test/` 源码逐项核验 **13 项必需覆盖**(I1–I8、守卫命中/未命中、schema 漂移、证书回放、归因不重复计),缺项**点名**;G5 要求 ≥10 任务/组、两组**同表**给 tokens/task 与成功率、成功率下降 ≥2pp 直接失败;G6 无检查项视为无证据(不算通过);G7 默认未授权。门禁**敢说不**:任一门不满足即 `ok:false + blockers`,不允许部分通过。新增 `test/cost-gate.test.mjs`(9 条)。当前如实输出:G4 13/13 ✅、G6 无残留 ✅、G5 未满足(无真实数据)、G7 未授权。
31
+ - **§10.1 验收指标报表**:新增 `src/cost/metrics.ts` + `cost.metrics()`——七项指标口径一次给全:tokens/task(含重试/回退/**失败执行**)、成功率(同 scorer,差值 **≥2pp 下降即 `reviewRequired:true`**)、GDR 命中率与未命中分布(**每次复用尝试为分母**)、CCS 替换数与证书完整率(必需字段 + `viaNativeDispatcher` + `trace()` 账本对账,须 100% 可回放)、节省归因按 A1/A2/A3/B1–B4 + `unattributed` 八列、governance 分 `author/rsiOffline/selection/other`、耗时 `medianMs`+`p95Ms`;任一项算不出即 `complete:false + missing[]`(不允许报一半)。同时修正 `trace()` 对账口径:`savedFromLedger` 只算替换产生的账本事件,全部节省另给 `savedFromLedgerAll`。新增 `test/cost-metrics.test.mjs`(6 条)。
32
+ - **§9 安全不变量 I1–I8 由测试守护**:新增 `test/invariants.test.ts`(12 条),逐条覆盖 I1(预算不足不启动模型)、I2(无原生派发器直接拒绝 + 非原生证书被拒)、I3(破坏性默认不入池)、I4(schema 漂移整图作废)、I5(守卫不匹配回落慢模型)、I6(模块异常 degraded 且任务继续)、I7(spill 原文可回读)、I8(取消信号阻断替换)。配套实现:`worker/ccs.ts` 增加取消前置检查(`error:'aborted'`)、`WorkerDeps.signal` 外部取消信号与替换路径串联、替换成功后退回预算预留。
33
+ - **测试稳定性**:Windows 文件传输的两个时序用例改为**仅在串行套件**(`npm run test:clean`,CI 的 windows job 即用它)执行,并行 runner 下跳过,消除负载放大导致的假红。
34
+ - **§8 两条链路联动报表**:新增 `src/cost/report.ts`——A(回执压缩,单价项)与 B(跳过调用,次数项)**两列分列**,`classifyEntry()` 结构互斥(替换产生的账本事件归 `skipped-call-ledger`,两列都不计)并返回 `doubleCountGuard: true`;B 列**只认证书**且只算 `dispatched:true`;`governance.byKind` 区分 `edg.author` / `rsi.offline` / `tools.load`;逐任务给 `executionSaved / governanceAmortized / net / netLoss`,`netLossTasks` 显式列出净亏任务(支持 `amortize:'even'|'per-task'`);`cost.savingsReport()` 与 `status().savingsColumns` 对外。新增 `test/cost-report.test.mjs`(6 条)。
35
+ - **B4 `rsi`(离线自改进)**:新增 `src/cost/rsi.ts`(**离线**,不进 Worker 热路径、不被 `apply()` 调用)与 `scripts/rsi-offline.mjs` 离线 CLI——输入账本摘要 + 替换证书 + 守卫失败分布(+形状纠偏次数),产出三类**候选配置**(`guard-relax` / `template-add` / `guidance-rewrite`,均带 `requiresValidation`);`score()` 用独立验证集打分,`freeze()` 门槛 `samples ≥ 20 && accuracy ≥ 0.98 && destructiveHits === 0 && 有 inputDigest`,不达标 `freeze-refused + reasons`;报表把**候选与基线同表**展示且固定 `autoDeploy: false`;输入 canonical 排序 ⇒ 同一输入同一 `inputDigest`(可复现核对)。新增 `test/cost-rsi.test.mjs`(7 条)。
36
+ - **B3 `ccs`(认证回调替换,首次出现真实节省)**:新增 `worker/ccs.ts`——替换**只经未改动的原生派发器**(`registry.execute`,权限/Mandate/取消/超时/审计全保留,测试逐项断言上下文透传);派发前**必过 budget 闸**(不通过不派发,通过后退回预留额度);派发器抛错 / `【系统拒绝】` / `执行报错` 一律 `dispatched:false + error` 并**回落慢模型,不吞错**;产出完整 `SubstitutionCert`(含被跳过的 `replacedCallbackId`)。Agent Loop 接线:命中 + enforce + 派发成功 ⇒ 注入「模型本该发出的 tool_call + 结果」并跳过该次模型推理(`skippedModelCalls` 计数);默认不配置即 `mode:'off'`、零替换。宿主侧证书写入审计链与账本(同 `taskId+step`,`trace()` 可对账)。新增 `test/worker-ccs.test.ts`(6 条)、`test/cost-substitution.test.mjs`(2 条)。
37
+ - **B2 `gdr`(回执守卫)**:新增 `worker/gdr.ts`——严格五步匹配顺序 **工具名 → schemaHash → 依赖边完成 → 守卫表达式 → 参数可确定性提取**,全过才 `hit`(返回确定性 `args`),任一不满足即 miss 并回落慢模型;miss 带 `reason` + `stage`,覆盖 `no-edge/tool-mismatch/schema-drift/dependency-incomplete/guard-miss/arg-unextractable`;`stats()` 给命中率与按工具分桶,`report()` 按 miss 分布自动产出 RSI 改进建议(样本为空时显式声明,不报假命中率)。新增 `test/worker-gdr.test.ts`(7 条)。
38
+ - **B1 `edg`(可执行决策图)**:新增 `worker/edg.ts`——`EdgEdge` 按规格实现(`schemaHash` / `argSource` / `guard` / `destructive` / `dependsOn`);生命周期 `draft→validated→active→exhausted→archived` 白名单校验;**schema 漂移即整图作废**(`invalidateBySchema`);参数只允许 `literal/regex/jsonpath` 确定性提取,**解析失败即该边不可用(禁止幻觉参数)**;守卫 `regex/jsonpath/equals` + `negate`,表达式非法一律不命中;`destructive:true` 默认不入池;`parseDraftFromModel()` 确定性抽 JSON 块(失败返回 null,不造空图);`createTemplateLibrary()` 支持人工/AI 预置模板;作者成本按图记 `ceil(chars/4)` 供 governance 入账。新增 `test/worker-edg.test.ts`(9 条)。
39
+ - **§7 决策复用 SPI 对齐**:`DecisionModule` 改为规格形态 `author(②) / guard(④) / substitute`,新增 `TurnSnapshot`、`EdgDraft`、`Edg`、`EdgEdge`、`GuardVerdict`、`ToolReceipt`、`SubstitutionCertDraft` 类型(`Edg.frozen` 表达「冻结后才可被 enforce 引用」);注册表新增 `authorGraphs()` / `guardReceipt()` / `substitute()` 编排——`shadow` 只产出证书不执行、`enforce` 才执行、`off` 完全不参与,**非原生派发证书一律拒绝**;`degraded` 阶段扩展 `author`/`guard`/`substitute`。新增 `test/worker-decision-spi.test.ts`(6 条)。当前**无任何真实替换**(跳过慢模型的执行器属 B3,尚未接入 Agent Loop)。
40
+ - **A3 `tool-batch`(批量调用)**:新增 `worker/tool-batch.ts`——首轮**一次**教学写进历史(user 消息,**系统提示词逐字节不变**),之后只做形状纠偏(单轮超上限 / 把批量塞进单工具数组参数),只追加提示、**调用照常执行、不阻断不改写模型程序**;批量执行复用既有 `tool_calls` 顺序执行路径,无新旁路;`mode:'ptc'` 时显式 `{state:'skipped', reason:'unsupported-host'}`(不偷偷降级),`enabled:false` 为 `disabled-by-config`;`WorkerResult.cost.batch` 暴露 `state/reason/mode/taught/corrections`。新增 `test/worker-tool-batch.test.ts`(6 条,含「多调用顺序与语义不变」对照)。
41
+ - **A2 `tool-disclosure`(渐进式纰漏)**:新增 `worker/tool-disclosure.ts`——常驻工具面收敛为 `fs_read_file/fs_list_dir/fs_write_file/exec_shell_in_vm/load_tools`,其余(`create_pr`、PDF/Word/批量改等)改为按需加载;`load_tools` 元工具返回完整 schema 并从下一次模型调用起生效;**装载成本明确记 governance**(`account:'governance'`、`phase:'authoring'`、`meta.kind:'tools.load'`、`module:'a2-disclosure'`),新增 `cost.recordGovernance()` 与 `recordWorkerCost` 上报,`netSaved` 因此诚实变负;`enabled`+`allowlist` 开关,**关闭即恢复全量工具面**(Agent Loop 不过滤 schema,与 3.2.x 逐字节一致);重复加载不重复计费。新增 `test/worker-tool-disclosure.test.ts`、`test/cost-disclosure.test.mjs`。
42
+ - **A1 按 §6 规格补全**:文件读取改为「保留行号 + 空行游程压缩」(`N: 内容` / `⋯起-止`),带行号与不带行号两候选取短者,保证绝不越压越长;shell 的 `grep -n` 形态(`path:line:text`)合并为「同文件一行、命中行带上下文」;错误回执保留首行错误码并追加 `→ 建议:`(覆盖 9 类已知错误,未知码不猜);新增 `worker/spill.ts`——超阈值(默认 6000 字符)先落盘 `<workspace>/.dsh-master/spill/` 再给「头 20 行 + 落盘标记 + 尾 5 行」摘要,标记含路径/字节/行数与回读方式,**仅 enforce 落盘**(shadow 零副作用),路径 jail + 点号剔除 + 单文件/总量/数量三重上限;spill 摘要同样按 `a1-fit-v1` 计量。新增 `test/worker-spill.test.ts`,`test/worker-tool-compact.test.ts` 扩到 8 条。
43
+ - **§6 工具面 SPI 对齐规格**:`ToolModule` 改为 `id / appliesTo / beforeDispatch(③) / afterReceipt(④) / promptCost`,保留 `surface:'worker'` 与 `mode`;注册表新增 `beforeToolDispatch()`(可改写 `name/args`,返回 `null` 即**屏蔽工具**并回结构化提示,**仅 enforce 生效**)与 `promptCost()` 聚合;`WorkerResult.cost.toolPrompt` 同时给出模块自报成本与**实际注入 schema** 的 token/条数;钩子异常按阶段(`beforeDispatch`/`afterReceipt`)留痕并 fail-open;A1 改为 SPI 适配(模块只算候选、由注册表按模式决定是否替换),归因 token 优先采用模块给出的 `savedTokens`(§5.4.1 拟合式)。`test/worker-cost-spi.test.ts` 扩到 11 条用例。
44
+ - **§5.6 事件总线与回流出口**:内部事件统一为三型 `cost:event`(`kind` 区分 ledger/attribution/budget/substitution.rejected 等)、`cost:degraded`、`cost:substitution`,并有测试断言不出现第四种;总线新增 `relays` 出口抽象(不可用只记状态不投递、抛异常累加 `failed` 不阻断主流程);Worker→Router 既有通道新增 `cost` 事件落库,Router 新增 `service.cost(ticketId?)` 摘要与只读路由 `GET /dsh-master/api/superagent/cost`,`status()` 增加 `cost` / `costRelay`;瓮城回流显式 `{target:'fang', available:false, reason:'fang-channel-not-ready'}`,不假装成功也不阻塞主线。新增 `test/cost-bus.test.mjs`。
45
+ - **§5.5 审计链**:新增 `SubstitutionCert`(`edgeId/toolName/schemaHash/guardExpr/receiptDigest/replacedCallbackId/viaNativeDispatcher:true`)与 `audit.appendSubstitution()`——七字段必填、`viaNativeDispatcher` 必须严格为 `true`、`step` 必须非负整数,任一不满足即拒绝且**不落链**;`substitute()` 同时写证书与账本事件并**共用 taskId+step**;新增 `trace({taskId, step?})` 回放「这一省是怎么来的」,给出 `savedFromCertificates / savedFromLedger / reconciled` 对账;审计链对外不暴露任何 update/delete 入口,`records()/substitutions()` 只返回副本。新增 `test/cost-audit.test.mjs`。
46
+ - **§5.4 归因**:`savedTokens` **必须带 moduleId**(缺失 ⇒ `module-missing`,不再默认 `a1-compact`);新增 `attributeTotal()` 按「总额 − 各模块之和」结算,差额进 `unattributed` 且 `attribution-overflow` 直接拒绝;报表新增 `attributedSavedTotal / unattributedSavedTotal / attributedProjectedTotal / unattributedProjectedTotal`(`status().attributionSummary`),两列相加恒等于任务总额;新增 A1 固定拟合式 `worker/baseline-fit.ts`(`a1-fit-v1`:`baseline=ceil((chars+overhead)/4)`、`actual=ceil(chars/4)`),A1 的 `estimatedTokens` 改为拟合差额并上报 `fitVersion`,参数表冻结在 docs §5.4.1 并由 `test/worker-baseline-fit.test.ts` 锁死。新增 `test/cost-attribution-total.test.mjs`。
47
+ - **§5.3 灰度**:`policy` 实现三档语义——`observe` 只计量命中(不落证书、不替换)、`shadow` 真实计算守卫并落证书但仍调慢模型、`enforce` 命中且白名单放行才替换;生效粒度 `global→forkId→taskId` **取最严格档**(窄 scope 不能抬升 global);白名单支持 `{forks,tasks,tags,tools}` 四维(非空维度必须命中)并保留早期扁平数组写法;`requestMode('enforce')` 门禁不变,`force: true` 只能跳过「必须先 shadow」不能跳过准确率/样本;新增 `setScope()`、`recordHit()`、`policyStats()`(命中文档 + 最近 50 张证书)。新增 `test/cost-policy.test.mjs`。
48
+ - **§5.2 预算闸**:`BudgetRule` 支持 `limitTokens`/`limitCost`(至少给一个,否则进 `invalid`;同一 unit 重复记 `duplicate-unit`);超限返回 `masterError('budget-exhausted', …)` 且 `detail` 带结构化 `remaining{tokens,cost}`;拒绝**不扣额度**;`degrade` 档必须在 `degradeModels` 白名单内,否则构造期即退化为 `hard-stop` 并记 `degrade-model-not-allowlisted`,且降级后仍需装得下剩余额度;新增 Worker 侧 `worker/budget-guard.ts`(① 唯一检查点,默认关闭,`DSH_MASTER_BUDGET_*` 或 `WorkerDeps.budget` 开启)——启用后模型**一次都不会被调用**(测试断言 `requests.length===0`)。新增 `test/cost-budget.test.mjs`、`test/worker-budget-guard.test.ts`。
49
+ - **§5.1 账本按事件记账**:新增 `phase`(prompt/completion/tool/authoring/substitution,可由 source 推导)、`turn/step/provider/model/cached/toolName/sessionId` 字段;`query()` 支持 task/fork/session/ticket/module/account/phase/surface/estimated/时间窗;`snapshot()` 增加 `byFork` 与 `tokens`(实测 vs 估算分列 + `estimatedRatio`);可选 JSONL 落盘 `<dataDir>/cost-ledger.jsonl`(逐行追加、失败只计数不阻断、`replay()` 回放且回放不重复落盘);`record()` 把「实测 + 估算」拆成两条事件入账。新增 `test/cost-ledger.test.mjs`、`test/worker-cost-estimated.test.ts`、`test/cost-estimated.test.mjs`。
50
+
1
51
  ## 3.2.10(2026-11-12,tag / GitHub Release / NPM public)
2
52
 
3
53
  **主题:按实测反馈放宽角色矩阵(Router 进入母体、Worker / Worker Agent Loop 进入原身)。**