dsh-vibe-math 2.7.1 → 2.7.3

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 (114) hide show
  1. package/README.en.md +682 -690
  2. package/README.md +19 -27
  3. package/cordis.patch.yml +112 -16
  4. package/docs/AUDIT-CHECKLIST.md +744 -518
  5. package/docs/COMPAT-AUDIT-ROUND2.md +35 -9
  6. package/docs/COMPAT-AUDIT-ROUND3.md +154 -154
  7. package/docs/final-paper.md +172 -172
  8. package/docs/formal-verification.md +588 -588
  9. package/docs/math-computation.md +194 -163
  10. package/docs/parameter-schema.md +37 -0
  11. package/docs/release-notes/README.en.md +49 -0
  12. package/docs/release-notes/README.md +48 -0
  13. package/docs/release-notes/RELEASE-NOTES-2.7.2.en.md +72 -0
  14. package/docs/release-notes/RELEASE-NOTES-2.7.2.md +72 -0
  15. package/docs/release-notes/RELEASE-NOTES-2.7.3.en.md +67 -0
  16. package/docs/release-notes/RELEASE-NOTES-2.7.3.md +67 -0
  17. package/docs/release-notes/TEMPLATE.md +126 -0
  18. package/docs/status-report-fields.md +167 -0
  19. package/docs/test-timing.md +157 -154
  20. package/installer.js +27 -17
  21. package/package.json +55 -3
  22. package/prompt-corpus-persona/persona-corpus.json +9 -9
  23. package/prompt-corpus-persona/persona-corpus.md +225 -33
  24. package/prompt-corpus-v2/formal-verify-v2.json +305 -113
  25. package/prompt-corpus-v2/formal-verify-v2.md +2399 -279
  26. package/prompt-corpus-v3/formal-verify-v3.json +134 -110
  27. package/prompt-corpus-v3/formal-verify-v3.md +409 -141
  28. package/prompt-corpus-v4/formal-verify-v4.json +18 -18
  29. package/prompt-corpus-v4/formal-verify-v4.md +49 -44
  30. package/prompt-corpus-v5/prompt-corpus-v5.json +82 -82
  31. package/prompt-corpus-v5/prompt-corpus-v5.md +513 -259
  32. package/scripts/update-doc-counts.mjs +71 -0
  33. package/tests/audit-artifact-docs.mjs +72 -0
  34. package/tests/audit-artifact-docs.mutants.mjs +58 -0
  35. package/tests/audit-installer-assertions.mutants.mjs +63 -0
  36. package/tests/audit-installer-compat.test.mjs +52 -4
  37. package/tests/audit-installer-policy.test.mjs +41 -8
  38. package/tests/audit-math-computation-contract.mjs +107 -9
  39. package/tests/audit-math-computation-contract.mutants.mjs +106 -0
  40. package/tests/audit-math-computation-parity.mjs +164 -3
  41. package/tests/audit-math-computation-sensitivity.mjs +6 -4
  42. package/tests/audit-package-membership.mjs +57 -0
  43. package/tests/audit-package-membership.mutants.mjs +28 -0
  44. package/tests/audit-participant-set-parity.mjs +160 -0
  45. package/tests/audit-path-discipline.mjs +83 -0
  46. package/tests/audit-path-discipline.mutants.mjs +51 -0
  47. package/tests/audit-persona-sensitivity.mjs +14 -0
  48. package/tests/audit-persona-surface.mutants.mjs +69 -0
  49. package/tests/audit-persona-surface.test.mjs +63 -22
  50. package/tests/audit-prompt-duplication.mjs +143 -0
  51. package/tests/audit-prompt-duplication.mutants.mjs +50 -0
  52. package/tests/audit-prompt-invariants.mjs +43 -5
  53. package/tests/audit-readme-bilingual.test.mjs +152 -0
  54. package/tests/audit-readme-counts.mjs +95 -0
  55. package/tests/audit-readme-counts.mutants.mjs +52 -0
  56. package/tests/audit-registration.mjs +78 -0
  57. package/tests/audit-status-report-fields.mjs +172 -0
  58. package/tests/audit-status-report-fields.mutants.mjs +64 -0
  59. package/tests/audit-v3-registration-parity.mjs +156 -0
  60. package/tests/audit-v5-integrity.mjs +300 -13
  61. package/tests/audit-v5-lean-abstention.mjs +392 -0
  62. package/tests/audit-v5-lean-abstention.mutants.mjs +106 -0
  63. package/tests/audit-v5-prompt-duplication.mjs +88 -0
  64. package/tests/audit-v5-prompt-duplication.mutants.mjs +34 -0
  65. package/tests/audit-v5-sensitivity.mjs +15 -8
  66. package/tests/e2e-identity-a6.mutants.mjs +65 -0
  67. package/tests/e2e-v5-round2.test.mjs +566 -12
  68. package/tests/formal-verify-v2.test.mjs +91 -5
  69. package/tests/formal-verify-v3.mutants.mjs +117 -0
  70. package/tests/formal-verify-v3.test.mjs +85 -6
  71. package/tests/formal-verify-v4.mutants.mjs +152 -0
  72. package/tests/formal-verify-v4.test.mjs +628 -9
  73. package/tests/formal-verify-v5.test.mjs +68 -9
  74. package/tests/helpers/doc-counts-format.mjs +41 -0
  75. package/tests/helpers/math-computation-fake-seam.mjs +4 -0
  76. package/tests/math-computation-a1.mutants.mjs +72 -0
  77. package/tests/math-computation-archive-rerun.mutants.mjs +65 -0
  78. package/tests/math-computation-discovery.mutants.mjs +76 -0
  79. package/tests/math-computation-shared.test.mjs +396 -2
  80. package/tests/math-computation-v2.test.mjs +767 -0
  81. package/tests/math-computation-v3.test.mjs +759 -0
  82. package/tests/math-computation-v4.mutants.mjs +133 -0
  83. package/tests/math-computation-v4.test.mjs +739 -0
  84. package/tests/prompt-v5-integrity.test.mjs +13 -2
  85. package/tests/run-tests.mjs +139 -9
  86. package/tests/run-tests.mutants.mjs +70 -0
  87. package/tests/selfdrive-v5.mjs +53 -1
  88. package/tests/selfdrive-v5.mutants.mjs +132 -0
  89. package/tests/v2-fix-probes.mutants.mjs +100 -0
  90. package/tests/v2-fix-probes.test.mjs +1039 -0
  91. package/tests/v2-list-agents-and-next-step.mutants.mjs +106 -0
  92. package/tests/v3-fix-probes.mutants.mjs +95 -0
  93. package/tests/v3-fix-probes.test.mjs +891 -0
  94. package/tests/v5-institute-fixes.mutants.mjs +190 -0
  95. package/vibe-math-v2/agent.cordis.yml +62 -6
  96. package/vibe-math-v2/math-computation.js +229 -29
  97. package/vibe-math-v2/math-engines.js +12 -12
  98. package/vibe-math-v2/vibe-math-v2.js +458 -119
  99. package/vibe-math-v2//345/256/236/347/216/260/346/226/271/346/241/210.md +5 -1
  100. package/vibe-math-v3/agent.cordis.yml +72 -6
  101. package/vibe-math-v3/math-computation.js +229 -29
  102. package/vibe-math-v3/math-engines.js +12 -12
  103. package/vibe-math-v3/vibe-math-v3.js +482 -139
  104. package/vibe-math-v4/agent.cordis.yml +44 -8
  105. package/vibe-math-v4/math-computation.js +229 -29
  106. package/vibe-math-v4/math-engines.js +12 -12
  107. package/vibe-math-v4/vibe-math-v4.js +245 -52
  108. package/vibe-math-v4//345/256/236/347/216/260/346/226/271/346/241/210.md +2 -0
  109. package/vibe-math-v5/agent.cordis.yml +46 -12
  110. package/vibe-math-v5/math-computation.js +229 -29
  111. package/vibe-math-v5/math-engines.js +12 -12
  112. package/vibe-math-v5/vibe-math-v5.js +1307 -243
  113. package/vibe-math-v5//345/256/236/347/216/260/346/226/271/346/241/210.md +1728 -1655
  114. package/vibe-math-v5//346/236/266/346/236/204/345/233/276.md +693 -693
@@ -5,7 +5,7 @@
5
5
  方法:**活体契约目录**(Host Inspect `Service.listService` / `Event.listEvents` / `Tool.listTools`)+ 宿主包源码逐行核对 + 可执行复现脚本
6
6
 
7
7
  > 本文件替代 `COMPAT-AUDIT-0.1.5-rc.2.md` 作为当前兼容性结论。
8
- > 上一轮审计提出的 R1–R7 **从未被修复**(在 `FIX-REPORT-2026.md` 中检索 R1–R7 零命中),本文件逐条重新独立验证。
8
+ > 上一轮审计提出的 R1–R7 **从未被修复**(在 `FIX-REPORT-2026.md`(**该文件不存在**:已发布报告留下的**悬空引用**;权威记录在本文与审计台账,不在仓库里) 中检索 R1–R7 零命中),本文件逐条重新独立验证。
9
9
 
10
10
  ---
11
11
 
@@ -125,7 +125,10 @@
125
125
  `runShell` 的返回值**在 `ensureDirs` 的调用点无人检查**(`:905/:925/:1051` 都是 `await ensureDirs()` 后继续)。
126
126
  **后果**:若 `powershell`/`sh` 不可用或返回非 0,目录不会被创建,而唯一的兜底是 `fs.writeText` 自动建父目录;一旦某条写入路径不经过 `fs.writeText`,落盘就会失败且**没有任何报错**。属"mock 覆盖不到、实机才暴露"的一类。
127
127
 
128
- ### F-5 `getPolicy()` 回退会静默改变沙箱围栏根(中)
128
+ ### F-5 `getPolicy()` 回退会静默改变沙箱围栏根(中)
129
+
130
+ > **断言用例的准确命名(`2649a47` 的更正)**:**case 1 = 宿主根本没有 `sandboxPolicy` 服务**(策略路径从不运行);**case 1b = 服务存在但围栏根不可解释(`{allow,deny}`)⇒ 退化为 no-op**。早先 F-5 行里"无可比根"的说法**过宽**,以此处为准。
131
+
129
132
 
130
133
  `v2:140`、`v3:206`、`v4:113` 三处同构:
131
134
 
@@ -302,15 +305,24 @@ e2e-f1-agent-detach CONFIRMED (drives the real AgentRegistry)
302
305
 
303
306
  ### 未修(需你决策,风险与取舍已说明)
304
307
 
305
- | 编号 | 说明 | 为何未动 |
306
- |---|---|---|
307
- | **F-4b** | 插件行在 `compaction` 隔离组**外** → 取到宿主根 compaction,预设阈值不生效 | 修法是**把插件行移进该组**,但会同时改变它对组内其它服务的可见性;**需先确认这是否为有意设计** |
308
- | **F-4c** | `ensureDirs()` 依赖外部二进制且返回值无人检查 | 属"实机才暴露"一类;改动会影响启动路径,建议与你的实机验证一起做 |
309
- | **F-7** | v2/v3 用全局 `setInterval` 而非 `ctx.interval` | 已核实**不是功能故障**(在 `ctx.effect` 内且正确清理),仅是未用宿主 timer 服务 |
308
+ | 编号 | 说明 | 为何未动 | 状态 |
309
+ |---|---|---|---|
310
+ | **F-4b** | 插件行在 `compaction` 隔离组**外** → 取到宿主根 compaction,预设阈值不生效 | 修法是**把插件行移进该组**,但会同时改变它对组内其它服务的可见性;**需先确认这是否为有意设计** | **待你决策**(风险与取舍已说明) |
311
+ | **F-4c** | `ensureDirs()` 依赖外部二进制且返回值无人检查 | 属"实机才暴露"一类;改动会影响启动路径,建议与你的实机验证一起做 | **已关闭**(§14.2:已在后续批次修复,见 §7 的回归测试) |
312
+ | **F-7** | v2/v3 用全局 `setInterval` 而非 `ctx.interval` | 已核实**不是功能故障**(在 `ctx.effect` 内且正确清理),仅是未用宿主 timer 服务 | **非缺陷**(已核实,无需改动) |
313
+
314
+ **同一清单的其余状态**(F-1…F-11 全表,按编号;本表只列需要动作的三条):
315
+
316
+ - **已修复并各有回归测试**:F-1 / F-2 / F-3 / F-4 / F-5 / F-8(见 §7)——**F-4c 现已并入这一组**(§14.2)。
317
+ - **已知限制(不修)**:F-8。
318
+ - **已有守卫**:F-9 —— `tests/audit-corrupt-file-guard.test.mjs` 钉住该行为。
319
+ - **待定**:F-10 / F-11(尚未决策,机制未验证)。
320
+ - **非缺陷**:F-7。
321
+ - **本清单是唯一权威的"未修 / 需决策"入口**;按**标题文本**定位本表,不要引用行号(行号会漂移)。已发布说明里的悬空引用见文末"已知且有意不修的悬空引用"一节。
310
322
 
311
323
  - **两个并行深度审计未能返回**(长时间运行后由我中止,无输出)。其覆盖范围(服务 API 逐参数核对、R1–R7 逐条复核)**已由我本人独立完成**,结论即本文件 §1/§2。
312
- - 未逐条验证上一轮 `FIX-REPORT-2026.md` 第四节列出的约 20 条审计编号(v4 D1/D2/D3/D7、v3 D17/D18/M14/M2 等)——这些**只是编号转述**,需先验证机制再改。
313
- - **修复已实施**(见 §7):F-1/F-2/F-3/F-4/F-5/F-8 完成并各有回归测试;F-4b/F-4c/F-7 见 §7 末表,需你决策或留待实机验证。
324
+ - 未逐条验证上一轮 `FIX-REPORT-2026.md`(**该文件不存在**:已发布报告留下的**悬空引用**;权威记录在本文与审计台账,不在仓库里) 第四节列出的约 20 条审计编号(v4 D1/D2/D3/D7、v3 D17/D18/M14/M2 等)——这些**只是编号转述**,需先验证机制再改。
325
+ - **修复已实施**(见 §7):F-1/F-2/F-3/F-4/F-5/F-8 完成并各有回归测试;F-4b/F-7 见 §7 末表,需你决策或留待实机验证。**F-4c 已关闭**:产品改动在 `6aff85a`(`ensureDirs()`/`removeFile()` 失败走 `warnShellOnce`,有界一次),守卫断言与具名红变异(`tests/v3-fix-probes.mutants.mjs` 的 F4c 家族,删掉该告警即红)均已提交——本行原先把 F-4c 与 F-4b/F-7 并列在"需决策",属**陈旧条目**,现更正。
314
326
 
315
327
  ---
316
328
 
@@ -326,3 +338,17 @@ e2e-f1-agent-detach CONFIRMED (drives the real AgentRegistry)
326
338
 
327
339
  > **后续轮次**:DSH 0.2.0 的适配审计与四宿主实测记录见 [`COMPAT-AUDIT-ROUND3.md`](COMPAT-AUDIT-ROUND3.md)
328
340
  > (预设交付形态换代、会话事件白名单、子代理数量上限、工具名抛错、压缩语义等)。
341
+
342
+
343
+ ---
344
+
345
+ ## 已知且有意不修的悬空引用(traceability gap, option (a))
346
+
347
+ - `FIX-REPORT-2026.md` **在本仓库中不存在**。**四处**引用:本文件两处(其上方已就地标注),以及**已发布**的 `docs/release-notes/RELEASE-NOTES-2.0.22.md:74`/`:84`。
348
+ - **决定**:已发布的发布说明属于**历史**,不修改(用户立场:不动已发布产物);因此这两处保持原样,作为**已知、有意不修**的缺口记录在此。权威记录以本文件与审计台账为准。
349
+ - 若将来要消除该缺口,正确做法是**补一份** `FIX-REPORT-2026.md` 或在本文件里给出这些编号的完整转述,而**不是**改写已发布说明。
350
+
351
+ ## 未修清单的入口(按标题定位,不按行号)
352
+
353
+ - 本文件的 **`### 未修(需你决策,风险与取舍已说明)`** 一节(F-1…F-11;F-7 非缺陷、F-8 已知限制、F-9 已有 `tests/audit-corrupt-file-guard.test.mjs`、F-10/F-11 待定、**F-4c 已关闭**)是唯一权威的"未修 / 需决策"清单。
354
+ - **按标题文本定位,不写行号**:行号会随编辑漂移,标题是稳定的;链接目标在本仓库内,且本文件随包发布(`files[]`),因此指针不会指向包外。
@@ -1,154 +1,154 @@
1
- # Vibe-Mathematics × DSH 0.2.0-rc.2 —— 第三轮兼容性审计(适配记录)
2
-
3
- > 本轮目标:把四套预设适配 **DSH 0.2.0**(当前版本),同时保住旧版本线;并在过程中把"版本线切换"这件事
4
- > 从"猜"变成"能力探测 + 四宿主实测"。结论先行:**0.2.0 的破坏性变更不是 API 签名**,而是三类:
5
- > ① 预设交付**形态换代**(旧的目录发现被彻底删除);② 新增**硬性行为**(会话事件白名单、子代理数量上限、
6
- > 工具名抛错、压缩的"策略 vs 执行"语义);③ 兼容性判定从 `engines` 扩展为 `peerDependencies`。
7
-
8
- ---
9
-
10
- ## 0. 摘要
11
-
12
- - 并行做了 4 份契约审计(组合行与声明 / `subagents`+`agents`+事件 / `tools`+`commands`+`timer` / `compaction`+`sessionProjections`+`sessions`+`subprocess`+`sandboxPolicy`),
13
- 每份都以**已安装的 0.2.0-rc.2 源码**(`lib/**/*.d.ts` 与实现)为证据。
14
- - 另外做了**四宿主实测**:把本包分别装进 `0.1.5-rc.2`、`0.1.6-alpha.2`、`0.1.7-rc.2`、`0.2.0-rc.2` 的独立 `DSH_HOME`,
15
- 启动后用宿主自己的 `agentPresets.list()` 读回预设清单。这是"预设到底有没有出现在选择器里"的唯一可信判据。
16
- - 结果:修复后四条版本线上预设**都**会出现(旧线走目录、新线走声明行),且新线上**零激活警告**。
17
-
18
- ---
19
-
20
- ## 1. 确证的缺陷
21
-
22
- ### G-1 preset 在新宿主上完全不可见(致命,2.3.x 全线命中)
23
-
24
- DSH 0.1.7 起 agent preset **只**由组合行声明;`$DSH_HOME/.agent-presets/<id>/agent.cordis.yml` 已无人读取
25
- (宿主自带技能 `editing-cordis-compositions` 明写 "Nothing reads that directory any more")。2.3.x 的安装器
26
- 在新宿主上仍会写那个目录:**日志显示安装成功、`~/.dsh/.agent-presets/` 里文件齐全,选择器里却一个都没有。**
27
- 修复:`cordis.patch.yml` 声明四个组合行;安装器的形态判定改为读 **loader 入口树**(见 G-10)。
28
-
29
- ### G-2 组合行声明有三条硬约束(每条都实测过)
30
-
31
- | 约束 | 违反后的现象 | 证据 |
32
- |---|---|---|
33
- | `dsh.bundle.patch` 必须是**字符串** | 0.1.5/0.1.6 把该值直接送进 `path.join` → `ERR_INVALID_ARG_TYPE`,**整个 profile 起不来** | 实测:数组形态在 0.1.5-rc.2 上必然崩 |
34
- | 声明行不能命名**宿主包**(如 `@deepseek-ai/dsh-agent-preset`) | 旧线无此包 → 每次启动 `failed to import` 激活失败 | 实测:0.1.5/0.1.6 上该包不存在 |
35
- | 声明行不能用 **`!!js` 门**(表达式里调 `ctx.get`) | 入口**永不初始化**、预设静默不注册(`N entries did not activate`) | 实测 0.2.0:`!!js "false"` / `typeof ctx` 正常;`ctx.get('fs'\|'agents'\|'pluginManager'\|'agentPresets')` 全部让入口不加载 |
36
-
37
- 因此本包改为:声明行的模块是**自己**的 `preset-declaration.js`(两条线上都可解析),它在运行时读 `agentPresets`
38
- 服务——有就注册,没有就**什么都不做且不报警**。
39
-
40
- ### G-3 声明行里的相对 `name` 解析不到(B3)
41
-
42
- `app-boot` 只会把 `group && Array.isArray(config)` 的条目名改写成 `file://` URL;声明行的 `config.plugins`
43
- 不在其中,loader 便拿**profile 目录**解析 `./vibe-math-vN.js` → ENOENT → **整个 preset 拒绝挂载**。
44
- 修复:改用包内子路径 `dsh-vibe-math/vibe-math-vN/vibe-math-vN.js` + 在 `exports` 放行。
45
-
46
- ### G-4 v5 把状态写进宿主会话日志 → 用户会话不可恢复(致命,数据安全)
47
-
48
- `Session.append(type,data,…)` 构造信封时**无法**设置 `ignorable`(只有构造种子接受该字段);而会话持久化在加载时
49
- 要求"未知事件类型必须 `ignorable === true`",否则抛 `SessionFormatUnsupportedError` **拒绝整个会话**。该规则在
50
- 0.1.5-rc.2 / 0.1.7-rc.2 / 0.2.0-rc.2 上一致存在 → v5 每追加一条 `vibe5/*`,就把**用户自己的会话**变成"写入时无声、
51
- 下次恢复时打不开"。修复:v5 只用加固 JSON(`State/<研究所>.v5state.json`),彻底不碰会话日志,并去掉
52
- `sessions` / `sessionProjections` 依赖;连它写进项目的镜像 Markdown 与**给模型看的工具描述**都一并改正。
53
-
54
- ### G-5 工具过滤里的未注册名让整次派生失败(v4/v5)
55
-
56
- `tools.restrict()` 对不在宿主可限制集合里的名字**直接抛错**,而该调用发生在建立子代理时 → v4/v5 一次配置错误
57
- 就让每次派生失败(v2/v3 早就有"按宿主提示剔除名字并重试"的守卫)。修复:v4/v5 采用同样的守卫,
58
- 并把返回值改成"按宿主提示剔除后重试一次",且**fail-closed**(绝不在过滤全被剔除时"不过滤"启动)。
59
-
60
- ### G-6 宿主新增"每根代理 8 个存活 continuable 子代理"上限
61
-
62
- 0.2.0 新增 `ActivationPool`(`maxActiveSubagents` 默认 8,来自 `subagent` 行的 config,未写入 `.d.ts`),
63
- 超出时抛 `SubagentError{code:'ACTIVATION_LIMIT_REACHED'}`;v4 的 `residentCount` 无上限、v5 的临时工上限之和可达 12
64
- → 撞限。修复:识别该错误码、从宿主消息里记下上限值、明确提示并把该次派生推迟到下一轮(不再让启动循环崩在半途)。
65
-
66
- ### G-7 压缩:策略调用 vs 执行调用(v4/v5)
67
-
68
- `compactIfNeeded(agent,'pressure',signal)` 是**策略**调用,可能什么都不做且返回 `null`(无日志);真正的执行调用是
69
- `compactNow(agent, signal)`。另外 v5 过去从**插件平面**取 compaction,而 preset 自己 `isolate` 了 compaction realm,
70
- 取到的是宿主根实例(配置可能不同)。修复:优先 `compactNow`(特性探测,旧宿主回退到策略调用),v5 改用 agent 自身 ctx 的实例。
71
-
72
- ### G-8 命令"业务失败"被当成成功
73
-
74
- 宿主的 `CommandResult` 联合是 `{kind:'success',text?} | {kind:'error',text}`;四套预设的 `/vibe`、`/v4`、`/v5`
75
- 在**所有失败路径**上都返回 `{kind:'success', text:'{"ok":false,…}'}` → UI 永远显示不出"这条命令被拒绝了"。
76
-
77
- **更正(据实收窄):这条修复不是一次"全仓"修复,而是分两批落地的,本节初稿把"打算做的"写成了"已经做完的"。**
78
-
79
- - **2.4.0(`cc0c220`)只改了 v2 与 v3**(`vibe-math-v2.js` / `vibe-math-v3.js` 的命令 handler)。当时 v4 与 v5 的
80
- handler 仍然无条件 `return {kind:'success', text:JSON.stringify(r,null,2)}`(各自的"无 session"分支也返回
81
- `kind:'success'`)——所以"四套都修了"在 2.4.0 这个提交上是不成立的。
82
- - **v4 与 v5 在 round-A(`8ec5a9c`)才各自补上同一形状**:v4 的命令 handler 改成
83
- `const failed = !r || r.ok === false || (r.ok === undefined && !!r.error)` → `{kind: failed?'error':'success'}`;
84
- v5 改成 `const failed = r !== null && typeof r === 'object' && r.ok === false` → 同样三元返回,并把"无 session"
85
- 分支一并改成 `kind:'error'`。判据:`git log -G "kind:\s*'error'" -- vibe-math-v4/vibe-math-v4.js`(及 v5 同)
86
- **只命中 `8ec5a9c`**;round-C(`4eb3175`)与 round-D(`0dc6ee3`)都没有再碰这两个 handler(前者的 v4 hunk 在
87
- 1354/1854 行,后者的 v5 hunk 止于 4564 行,均在命令 handler 之外)。
88
- - **仓库内的回归证据是 round-C(`4eb3175`)补进来的**:`tests/host-failure-paths.test.mjs` 在该提交首次入库,
89
- 它断言 `/v4 set` 未知键、`/v4` 未知子命令与 `/v5` 未知子命令都返回 `kind:'error'`。round-D(`0dc6ee3`)只是
90
- 把"本节仍把 `/v4` 的修复说成全仓,需据实收窄"记进了待办,没有改代码。
91
- - 该联合在 0.1.5 上同样存在,故旧线安全。也就是说:**"四套最终一致"成立,"四套一次修完"不成立**。
92
-
93
- ### G-9 文档、镜像与工具描述与实现不符
94
-
95
- v5 的 README、`架构图.md`、`实现方案.md`、它写进用户项目的三个镜像文件头(`Institutes.md`、`Shared/TaskBoard.md`、
96
- `State/README.md`)以及 `vibe_v5_set` 的**工具描述**都写着"权威状态在会话日志投影里"。修复:全部改为真实位置
97
- (`State/<研究所>.v5state.json`),并重生成 v5 中英架构图。**这一条是提示词/交互面的事实性修复**,不是文风问题。
98
-
99
- ### G-10 "旧线不读目录"必须用**能力**判定,不能用版本号
100
-
101
- `agentPresets` 服务在两条线上**都存在**但语义不同(旧线是目录扫描器、**没有** `register`)——用"服务存在"判形态
102
- 会在 0.1.5/0.1.6 上误判为"组合行",从而**跳过**唯一有效的目录安装。修复:判定读 **loader 入口树**里是否挂了
103
- `@deepseek-ai/dsh-agent-preset`(或其 registry);这在任何插件激活之前就可见,而"读服务"在 bundle 被单独激活
104
- (`dsh plugin add`)时可能尚未就绪。
105
-
106
- ---
107
-
108
- ## 2. 四宿主实测矩阵
109
-
110
- | 宿主 | preset 形态 | 实测结果 |
111
- |---|---|---|
112
- | 0.1.5-rc.2 | 目录 | 安装器写入四个目录;声明行静默无副作用;`agentPresets.list()` 列出四个预设 ✅ |
113
- | 0.1.6-alpha.2 | 目录 | 同上 ✅ |
114
- | 0.1.7-rc.2 | 组合行 | 声明行注册四个预设(order 20–23);安装器跳过目录(`state` 文件不再被写)✅ |
115
- | 0.2.0-rc.2 | 组合行 | 同上,且**零激活警告**(此前数组 patch / 宿主包名 / `!!js` 门各会产生一批失败行)✅ |
116
-
117
- ---
118
-
119
- ## 3. 已确证**正确**的部分(避免下次重复劳动)
120
-
121
- - `tools.register` 的形状(`name`/`description`/`parameters` + **必需的** `output:{schema,render}` + `execute`)与
122
- `parameters` 用原生 JSON Schema 的写法(宿主自己的工具也这么写);handler 返回符合 `output.schema` 的 JSON 字符串 ✓。
123
- - `commands.register`(`name`/`description`/`input:{hint}`/`handler`)与命令名正则 ✓。
124
- - `tools.restrict` 的 `{allow,deny}` 形状,以及"未注册名"错误消息仍以 `known global tools: …` 结尾 —— v2/v3 的重试正则
125
- 逐字符匹配,行为保持 fail-closed ✓。
126
- - `fs`(resolve/stat/readText/writeText/listDir)、`getPolicy()` 作为 `writeText` 第 5 参数的位置 ✓;`FsDirEntry` 字段无改名 ✓。
127
- - `subagents.startContinuable` / `sendMessage`(4 参数 + `{signal}`)/ `interrupt`(第二参数为 authority,自 0.1.1 起)/
128
- `drainContinuableChildren` 的调用形状自 0.1.2-rc.1 起未变 ✓;`agents.get` 在 `subagent/start` 里可解析、在 `subagent/end`
129
- 里**必然不可解析**——v4/v5 "在 start 时捕获 Agent 引用"的写法继续正确 ✓。
130
- - `subprocess`(spawn/done/terminate/collected)与 `sandboxPolicy.resolve` ✓;`timer` 服务签名与 disposer 语义 ✓。
131
- - `sessionProjections.register/stateOf` 的形状本身 ✓(本包不再使用,原因见 G-4)。
132
-
133
- ---
134
-
135
- ## 4. 修复实施记录(2.4.0)
136
-
137
- 见 `docs/release-notes/RELEASE-NOTES-2.4.0.md`「变更」。工程证据(逐条审计报告与探针输出)保存在仓库之外的
138
- 工作区台账中;本文件只保留结论与判据。
139
-
140
- 新增守卫:`tests/audit-preset-rows.test.mjs`(生成物与生成器逐字节一致、`dsh.bundle.patch` 必须是字符串、
141
- 声明行不得命名宿主包、不得使用会调用服务的 `!!js` 门、每条组合必须含 `present`/`command-goal`/`isolate`/`workflow-ptc`、
142
- 冻结的 0.1.x 组合保持原样);`docs/AUDIT-CHECKLIST.md` 新增 §8 把上述四条硬约束写成流程。
143
-
144
- ---
145
-
146
- ## 5. 刻意不改(附理由)
147
-
148
- | 项 | 决定 | 理由 |
149
- |---|---|---|
150
- | v2/v3 使用全局 `setInterval`/`setTimeout` | 保留 | 预设是**文件行**,不经动态包 vm 沙箱(沙箱只包动态包宿主半);实测可用,且 `ctx.effect` 内已正确清理。仅修掉"插件运行时没有全局定时器"这句**错误注释**。 |
151
- | 工具卡片呈现(`presentCall`/`presentResult`) | 不加 | 纯外观增强,与本次适配无关;未来要加需同步四套。 |
152
- | `subagents.listChildren` 元素类型变化(`SubagentCatalogEntry`) | 不处理 | 四套预设均未调用。 |
153
- | `additionalProperties:false` 的 `parameters` | 保留 | 宿主 `tools.register` 不校验 `parameters`;仅当预设改造成**动态包**时 `defineTool` 才会拒绝(届时再改)。 |
154
- | `followup` 回退分支 | 保留 | 该分支只在 0.1.1 及更早存在;本包声明的下限是 0.1.2-alpha.4,其中 `0.1.2-alpha.*` 是否仍带 `followup` 未实测,保留分支零成本且更稳。 |
1
+ # Vibe-Mathematics × DSH 0.2.0-rc.2 —— 第三轮兼容性审计(适配记录)
2
+
3
+ > 本轮目标:把四套预设适配 **DSH 0.2.0**(当前版本),同时保住旧版本线;并在过程中把"版本线切换"这件事
4
+ > 从"猜"变成"能力探测 + 四宿主实测"。结论先行:**0.2.0 的破坏性变更不是 API 签名**,而是三类:
5
+ > ① 预设交付**形态换代**(旧的目录发现被彻底删除);② 新增**硬性行为**(会话事件白名单、子代理数量上限、
6
+ > 工具名抛错、压缩的"策略 vs 执行"语义);③ 兼容性判定从 `engines` 扩展为 `peerDependencies`。
7
+
8
+ ---
9
+
10
+ ## 0. 摘要
11
+
12
+ - 并行做了 4 份契约审计(组合行与声明 / `subagents`+`agents`+事件 / `tools`+`commands`+`timer` / `compaction`+`sessionProjections`+`sessions`+`subprocess`+`sandboxPolicy`),
13
+ 每份都以**已安装的 0.2.0-rc.2 源码**(`lib/**/*.d.ts` 与实现)为证据。
14
+ - 另外做了**四宿主实测**:把本包分别装进 `0.1.5-rc.2`、`0.1.6-alpha.2`、`0.1.7-rc.2`、`0.2.0-rc.2` 的独立 `DSH_HOME`,
15
+ 启动后用宿主自己的 `agentPresets.list()` 读回预设清单。这是"预设到底有没有出现在选择器里"的唯一可信判据。
16
+ - 结果:修复后四条版本线上预设**都**会出现(旧线走目录、新线走声明行),且新线上**零激活警告**。
17
+
18
+ ---
19
+
20
+ ## 1. 确证的缺陷
21
+
22
+ ### G-1 preset 在新宿主上完全不可见(致命,2.3.x 全线命中)
23
+
24
+ DSH 0.1.7 起 agent preset **只**由组合行声明;`$DSH_HOME/.agent-presets/<id>/agent.cordis.yml` 已无人读取
25
+ (宿主自带技能 `editing-cordis-compositions` 明写 "Nothing reads that directory any more")。2.3.x 的安装器
26
+ 在新宿主上仍会写那个目录:**日志显示安装成功、`~/.dsh/.agent-presets/` 里文件齐全,选择器里却一个都没有。**
27
+ 修复:`cordis.patch.yml` 声明四个组合行;安装器的形态判定改为读 **loader 入口树**(见 G-10)。
28
+
29
+ ### G-2 组合行声明有三条硬约束(每条都实测过)
30
+
31
+ | 约束 | 违反后的现象 | 证据 |
32
+ |---|---|---|
33
+ | `dsh.bundle.patch` 必须是**字符串** | 0.1.5/0.1.6 把该值直接送进 `path.join` → `ERR_INVALID_ARG_TYPE`,**整个 profile 起不来** | 实测:数组形态在 0.1.5-rc.2 上必然崩 |
34
+ | 声明行不能命名**宿主包**(如 `@deepseek-ai/dsh-agent-preset`) | 旧线无此包 → 每次启动 `failed to import` 激活失败 | 实测:0.1.5/0.1.6 上该包不存在 |
35
+ | 声明行不能用 **`!!js` 门**(表达式里调 `ctx.get`) | 入口**永不初始化**、预设静默不注册(`N entries did not activate`) | 实测 0.2.0:`!!js "false"` / `typeof ctx` 正常;`ctx.get('fs'\|'agents'\|'pluginManager'\|'agentPresets')` 全部让入口不加载 |
36
+
37
+ 因此本包改为:声明行的模块是**自己**的 `preset-declaration.js`(两条线上都可解析),它在运行时读 `agentPresets`
38
+ 服务——有就注册,没有就**什么都不做且不报警**。
39
+
40
+ ### G-3 声明行里的相对 `name` 解析不到(B3)
41
+
42
+ `app-boot` 只会把 `group && Array.isArray(config)` 的条目名改写成 `file://` URL;声明行的 `config.plugins`
43
+ 不在其中,loader 便拿**profile 目录**解析 `./vibe-math-vN.js` → ENOENT → **整个 preset 拒绝挂载**。
44
+ 修复:改用包内子路径 `dsh-vibe-math/vibe-math-vN/vibe-math-vN.js` + 在 `exports` 放行。
45
+
46
+ ### G-4 v5 把状态写进宿主会话日志 → 用户会话不可恢复(致命,数据安全)
47
+
48
+ `Session.append(type,data,…)` 构造信封时**无法**设置 `ignorable`(只有构造种子接受该字段);而会话持久化在加载时
49
+ 要求"未知事件类型必须 `ignorable === true`",否则抛 `SessionFormatUnsupportedError` **拒绝整个会话**。该规则在
50
+ 0.1.5-rc.2 / 0.1.7-rc.2 / 0.2.0-rc.2 上一致存在 → v5 每追加一条 `vibe5/*`,就把**用户自己的会话**变成"写入时无声、
51
+ 下次恢复时打不开"。修复:v5 只用加固 JSON(`State/<研究所>.v5state.json`),彻底不碰会话日志,并去掉
52
+ `sessions` / `sessionProjections` 依赖;连它写进项目的镜像 Markdown 与**给模型看的工具描述**都一并改正。
53
+
54
+ ### G-5 工具过滤里的未注册名让整次派生失败(v4/v5)
55
+
56
+ `tools.restrict()` 对不在宿主可限制集合里的名字**直接抛错**,而该调用发生在建立子代理时 → v4/v5 一次配置错误
57
+ 就让每次派生失败(v2/v3 早就有"按宿主提示剔除名字并重试"的守卫)。修复:v4/v5 采用同样的守卫,
58
+ 并把返回值改成"按宿主提示剔除后重试一次",且**fail-closed**(绝不在过滤全被剔除时"不过滤"启动)。
59
+
60
+ ### G-6 宿主新增"每根代理 8 个存活 continuable 子代理"上限
61
+
62
+ 0.2.0 新增 `ActivationPool`(`maxActiveSubagents` 默认 8,来自 `subagent` 行的 config,未写入 `.d.ts`),
63
+ 超出时抛 `SubagentError{code:'ACTIVATION_LIMIT_REACHED'}`;v4 的 `residentCount` 无上限、v5 的临时工上限之和可达 12
64
+ → 撞限。修复:识别该错误码、从宿主消息里记下上限值、明确提示并把该次派生推迟到下一轮(不再让启动循环崩在半途)。
65
+
66
+ ### G-7 压缩:策略调用 vs 执行调用(v4/v5)
67
+
68
+ `compactIfNeeded(agent,'pressure',signal)` 是**策略**调用,可能什么都不做且返回 `null`(无日志);真正的执行调用是
69
+ `compactNow(agent, signal)`。另外 v5 过去从**插件平面**取 compaction,而 preset 自己 `isolate` 了 compaction realm,
70
+ 取到的是宿主根实例(配置可能不同)。修复:优先 `compactNow`(特性探测,旧宿主回退到策略调用),v5 改用 agent 自身 ctx 的实例。
71
+
72
+ ### G-8 命令"业务失败"被当成成功
73
+
74
+ 宿主的 `CommandResult` 联合是 `{kind:'success',text?} | {kind:'error',text}`;四套预设的 `/vibe`、`/v4`、`/v5`
75
+ 在**所有失败路径**上都返回 `{kind:'success', text:'{"ok":false,…}'}` → UI 永远显示不出"这条命令被拒绝了"。
76
+
77
+ **更正(据实收窄):这条修复不是一次"全仓"修复,而是分两批落地的,本节初稿把"打算做的"写成了"已经做完的"。**
78
+
79
+ - **2.4.0(`cc0c220`)只改了 v2 与 v3**(`vibe-math-v2.js` / `vibe-math-v3.js` 的命令 handler)。当时 v4 与 v5 的
80
+ handler 仍然无条件 `return {kind:'success', text:JSON.stringify(r,null,2)}`(各自的"无 session"分支也返回
81
+ `kind:'success'`)——所以"四套都修了"在 2.4.0 这个提交上是不成立的。
82
+ - **v4 与 v5 在 round-A(`8ec5a9c`)才各自补上同一形状**:v4 的命令 handler 改成
83
+ `const failed = !r || r.ok === false || (r.ok === undefined && !!r.error)` → `{kind: failed?'error':'success'}`;
84
+ v5 改成 `const failed = r !== null && typeof r === 'object' && r.ok === false` → 同样三元返回,并把"无 session"
85
+ 分支一并改成 `kind:'error'`。判据:`git log -G "kind:\s*'error'" -- vibe-math-v4/vibe-math-v4.js`(及 v5 同)
86
+ **只命中 `8ec5a9c`**;round-C(`4eb3175`)与 round-D(`0dc6ee3`)都没有再碰这两个 handler(前者的 v4 hunk 在
87
+ 1354/1854 行,后者的 v5 hunk 止于 4564 行,均在命令 handler 之外)。
88
+ - **仓库内的回归证据是 round-C(`4eb3175`)补进来的**:`tests/host-failure-paths.test.mjs` 在该提交首次入库,
89
+ 它断言 `/v4 set` 未知键、`/v4` 未知子命令与 `/v5` 未知子命令都返回 `kind:'error'`。round-D(`0dc6ee3`)只是
90
+ 把"本节仍把 `/v4` 的修复说成全仓,需据实收窄"记进了待办,没有改代码。
91
+ - 该联合在 0.1.5 上同样存在,故旧线安全。也就是说:**"四套最终一致"成立,"四套一次修完"不成立**。
92
+
93
+ ### G-9 文档、镜像与工具描述与实现不符
94
+
95
+ v5 的 README、`架构图.md`、`实现方案.md`、它写进用户项目的三个镜像文件头(`Institutes.md`、`Shared/TaskBoard.md`、
96
+ `State/README.md`)以及 `vibe_v5_set` 的**工具描述**都写着"权威状态在会话日志投影里"。修复:全部改为真实位置
97
+ (`State/<研究所>.v5state.json`),并重生成 v5 中英架构图。**这一条是提示词/交互面的事实性修复**,不是文风问题。
98
+
99
+ ### G-10 "旧线不读目录"必须用**能力**判定,不能用版本号
100
+
101
+ `agentPresets` 服务在两条线上**都存在**但语义不同(旧线是目录扫描器、**没有** `register`)——用"服务存在"判形态
102
+ 会在 0.1.5/0.1.6 上误判为"组合行",从而**跳过**唯一有效的目录安装。修复:判定读 **loader 入口树**里是否挂了
103
+ `@deepseek-ai/dsh-agent-preset`(或其 registry);这在任何插件激活之前就可见,而"读服务"在 bundle 被单独激活
104
+ (`dsh plugin add`)时可能尚未就绪。
105
+
106
+ ---
107
+
108
+ ## 2. 四宿主实测矩阵
109
+
110
+ | 宿主 | preset 形态 | 实测结果 |
111
+ |---|---|---|
112
+ | 0.1.5-rc.2 | 目录 | 安装器写入四个目录;声明行静默无副作用;`agentPresets.list()` 列出四个预设 ✅ |
113
+ | 0.1.6-alpha.2 | 目录 | 同上 ✅ |
114
+ | 0.1.7-rc.2 | 组合行 | 声明行注册四个预设(order 20–23);安装器跳过目录(`state` 文件不再被写)✅ |
115
+ | 0.2.0-rc.2 | 组合行 | 同上,且**零激活警告**(此前数组 patch / 宿主包名 / `!!js` 门各会产生一批失败行)✅ |
116
+
117
+ ---
118
+
119
+ ## 3. 已确证**正确**的部分(避免下次重复劳动)
120
+
121
+ - `tools.register` 的形状(`name`/`description`/`parameters` + **必需的** `output:{schema,render}` + `execute`)与
122
+ `parameters` 用原生 JSON Schema 的写法(宿主自己的工具也这么写);handler 返回符合 `output.schema` 的 JSON 字符串 ✓。
123
+ - `commands.register`(`name`/`description`/`input:{hint}`/`handler`)与命令名正则 ✓。
124
+ - `tools.restrict` 的 `{allow,deny}` 形状,以及"未注册名"错误消息仍以 `known global tools: …` 结尾 —— v2/v3 的重试正则
125
+ 逐字符匹配,行为保持 fail-closed ✓。
126
+ - `fs`(resolve/stat/readText/writeText/listDir)、`getPolicy()` 作为 `writeText` 第 5 参数的位置 ✓;`FsDirEntry` 字段无改名 ✓。
127
+ - `subagents.startContinuable` / `sendMessage`(4 参数 + `{signal}`)/ `interrupt`(第二参数为 authority,自 0.1.1 起)/
128
+ `drainContinuableChildren` 的调用形状自 0.1.2-rc.1 起未变 ✓;`agents.get` 在 `subagent/start` 里可解析、在 `subagent/end`
129
+ 里**必然不可解析**——v4/v5 "在 start 时捕获 Agent 引用"的写法继续正确 ✓。
130
+ - `subprocess`(spawn/done/terminate/collected)与 `sandboxPolicy.resolve` ✓;`timer` 服务签名与 disposer 语义 ✓。
131
+ - `sessionProjections.register/stateOf` 的形状本身 ✓(本包不再使用,原因见 G-4)。
132
+
133
+ ---
134
+
135
+ ## 4. 修复实施记录(2.4.0)
136
+
137
+ 见 `docs/release-notes/RELEASE-NOTES-2.4.0.md`「变更」。工程证据(逐条审计报告与探针输出)保存在仓库之外的
138
+ 工作区台账中;本文件只保留结论与判据。
139
+
140
+ 新增守卫:`tests/audit-preset-rows.test.mjs`(生成物与生成器逐字节一致、`dsh.bundle.patch` 必须是字符串、
141
+ 声明行不得命名宿主包、不得使用会调用服务的 `!!js` 门、每条组合必须含 `present`/`command-goal`/`isolate`/`workflow-ptc`、
142
+ 冻结的 0.1.x 组合保持原样);`docs/AUDIT-CHECKLIST.md` 新增 §8 把上述四条硬约束写成流程。
143
+
144
+ ---
145
+
146
+ ## 5. 刻意不改(附理由)
147
+
148
+ | 项 | 决定 | 理由 |
149
+ |---|---|---|
150
+ | v2/v3 使用全局 `setInterval`/`setTimeout` | 保留 | 预设是**文件行**,不经动态包 vm 沙箱(沙箱只包动态包宿主半);实测可用,且 `ctx.effect` 内已正确清理。仅修掉"插件运行时没有全局定时器"这句**错误注释**。 |
151
+ | 工具卡片呈现(`presentCall`/`presentResult`) | 不加 | 纯外观增强,与本次适配无关;未来要加需同步四套。 |
152
+ | `subagents.listChildren` 元素类型变化(`SubagentCatalogEntry`) | 不处理 | 四套预设均未调用。 |
153
+ | `additionalProperties:false` 的 `parameters` | 保留 | 宿主 `tools.register` 不校验 `parameters`;仅当预设改造成**动态包**时 `defineTool` 才会拒绝(届时再改)。 |
154
+ | `followup` 回退分支 | 保留 | 该分支只在 0.1.1 及更早存在;本包声明的下限是 0.1.2-alpha.4,其中 `0.1.2-alpha.*` 是否仍带 `followup` 未实测,保留分支零成本且更稳。 |