dsh-vibe-math 2.3.16 → 2.4.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 (32) hide show
  1. package/README.en.md +49 -46
  2. package/README.md +48 -45
  3. package/cordis.patch.yml +1123 -10
  4. package/docs/AUDIT-CHECKLIST.md +45 -0
  5. package/docs/COMPAT-AUDIT-ROUND2.md +3 -0
  6. package/docs/COMPAT-AUDIT-ROUND3.md +139 -0
  7. package/docs/generate_framework_diagram_v5.mjs +27 -27
  8. package/docs/release-notes/RELEASE-NOTES-2.4.0.md +172 -0
  9. package/docs/test-timing.md +2 -1
  10. package/installer.js +89 -21
  11. package/package.json +33 -9
  12. package/preset-declaration.js +62 -0
  13. package/prompt-corpus-v5/prompt-corpus-v5.json +7 -7
  14. package/prompt-corpus-v5/prompt-corpus-v5.md +8 -129
  15. package/scripts/build-preset-rows.mjs +146 -0
  16. package/tests/audit-installer-compat.test.mjs +9 -3
  17. package/tests/audit-preset-rows.test.mjs +185 -0
  18. package/tests/audit-v5-integrity.mjs +49 -3
  19. package/tests/e2e-v5-round2.test.mjs +137 -67
  20. package/tests/formal-verify-v5.test.mjs +43 -35
  21. package/tests/prompt-v5-integrity.test.mjs +49 -47
  22. package/tests/selfdrive-v5.mjs +42 -55
  23. package/vibe-math-v2/vibe-math-v2.js +6 -2
  24. package/vibe-math-v3/vibe-math-v3.js +6 -2
  25. package/vibe-math-v4/vibe-math-v4.js +191 -13
  26. package/vibe-math-v5/agent.cordis.yml +8 -8
  27. package/vibe-math-v5/preset.yml +1 -1
  28. package/vibe-math-v5/vibe-math-v5.js +215 -91
  29. package/vibe-math-v5//345/256/236/347/216/260/346/226/271/346/241/210.md +56 -44
  30. package/vibe-math-v5//346/236/266/346/236/204/345/233/276.md +24 -22
  31. package//347/244/272/344/276/213/345/233/276//346/241/206/346/236/266/345/233/276-v5-en.svg +14 -14
  32. package//347/244/272/344/276/213/345/233/276//346/241/206/346/236/266/345/233/276-v5.svg +14 -14
@@ -382,3 +382,48 @@ provider **直接拒绝**。于是"提示词/规格/状态表都写着这个参
382
382
  不能在被 README 当作"当前详解"引用时静默误导(`qs.csv`、`Pending_Verification/` 等 v1 名称在 v2 起已不存在)。
383
383
 
384
384
  ---
385
+
386
+ ## 8. 宿主版本线适配与发布流程实测教训(2.4.0 起)
387
+
388
+ ### 8.1 一条版本线一个机制:先定"形态",再谈"版本"
389
+
390
+ DSH 的 **agent preset 交付方式**在 0.1.6 → 0.1.7 之间换过一次,且**旧机制是被彻底删除**的:
391
+
392
+ | 版本线 | preset 形态 | 本文档对应做法 |
393
+ |---|---|---|
394
+ | ≤ 0.1.6 | 目录 `<DSH_HOME>/.agent-presets/<id>/{agent.cordis.yml,preset.yml,…}` | `installer.js` 复制(`detectPresetMechanism` 判为 `directory`) |
395
+ | ≥ 0.1.7 | 组合行 `@deepseek-ai/dsh-agent-preset`(`agentPresets.register({id,plugins,…})`) | `cordis.patch.yml` 里的声明行(判为 `rows`,安装器跳过目录同步) |
396
+
397
+ **判定必须用能力,不要用版本号**:`agentPresets` 服务在两条线上都存在但语义不同(旧线是目录扫描器、没有 `register`),
398
+ 所以判定改成读 **loader 入口树**里有没有 `@deepseek-ai/dsh-agent-preset`(或其 registry)——这在任何插件激活之前就可见,
399
+ 而"读服务"在 bundle 被单独激活(`dsh plugin add`)时可能还没就绪。**旧线上"装了但看不见"正是本版修掉的那类缺陷。**
400
+
401
+ ### 8.2 组合行声明的四条硬约束(都是实测出来的)
402
+
403
+ 1. **`dsh.bundle.patch` 必须是字符串**。数组形态只有 ≥ 0.1.7 接受;0.1.5/0.1.6 会把该值直接送进 `path.join`,
404
+ 结果是整个 profile **起不来**(`ERR_INVALID_ARG_TYPE`)。要多个 patch 就合并成一个文件。
405
+ 2. **声明行不要命名宿主包**(如 `@deepseek-ai/dsh-agent-preset`):旧线上该包不存在,行会 `failed to import`,
406
+ 每次启动都报一条激活失败。改成本包自己的模块(`preset-declaration.js`),它在旧线上**什么都不注册且不报错**。
407
+ 3. **声明行不能用 `disabled: !!js` 做版本门**:patch 表达式里 **`ctx.get(...)` 会抛**(实测:常量、`typeof ctx` 正常,
408
+ 任何服务查询都让入口永远不初始化,报 "N entries did not activate")。要按宿主能力分流,就分到**代码里**(运行时读服务)。
409
+ 4. **声明行里的 `name` 不会被改写成文件 URL**(app-boot 只递归 group 的 config),loader 会拿**profile 目录**去解析相对路径
410
+ → `./vibe-math-vN.js` 必 ENOENT、整个 preset 拒绝挂载。必须用**包内子路径**(`dsh-vibe-math/vibe-math-vN/vibe-math-vN.js`)+ `exports` 放行。
411
+
412
+ ### 8.3 不要在宿主的"历史事件"面上存自己的状态
413
+
414
+ 会话日志是**只增不改**的,但**读它是严格的**:持久化层遇到不认识的 `type` 会**拒绝加载整个会话**,除非写入方标了
415
+ `ignorable: true`——而 `Session.append` **无法**设置该字段(只有构造种子能)。所以"把插件状态写进会话日志"这条路
416
+ 会让**用户自己的会话在下次恢复时打不开**(静默:写入成功、失败发生在之后的加载)。自研状态请落在自己的文件里(v5 即如此)。
417
+
418
+ ### 8.4 发布流程:`npm publish` 返回 202 不是失败
419
+
420
+ - `npm publish` 得到 **HTTP 202** + "Your package is being processed…" 时,registry 正在**异步处理**;此时 `npm view` /
421
+ `dist-tags` / 版本 manifest / tarball 都可能是 404 或旧值,**持续数分钟**。
422
+ - 期间重发会得到 **409 `Cannot publish over previously staged version`**——这句措辞会让人误以为被扣下等 2FA 批准
423
+ (`npm stage list` 实测为空,并非 staged)。**正确处理:等待并轮询 packument**(`dist-tags.latest` + `/<pkg>/<ver>` + tarball HEAD),
424
+ **绝不在此时改版本号或内容**。
425
+ - `dsh plugin --profile <p> add` 在 Windows 上可能**在 pnpm 完成后才崩**(`0xC0000409`,报 "pnpm failed"):
426
+ **不要信退出码**,查 `package.json` 的 spec、lockfile、`node_modules` 三处是否一致,不一致就只对齐 manifest。
427
+
428
+ ---
429
+
@@ -323,3 +323,6 @@ e2e-f1-agent-detach CONFIRMED (drives the real AgentRegistry)
323
323
  | R3「v4 硬编码假名、无重试可能半启动」 | v4 的过滤器**只用用户传入的名字**,不硬编码网络/脚本名;该条**不成立**(v4 的真实问题是注册未纳入 `ctx.effect`) |
324
324
  | R1 仅"代码阅读推断" | 本轮**用真实 `AgentRegistry` 可执行复现**(`prove-f1-agent-detach.mjs`,exit 0) |
325
325
  | 「兼容性审计 0 处崩溃」 | 兼容性缺陷确实不是崩溃型,但 F-2 会让子代理**永远起不来**,属功能失效而非"无问题" |
326
+
327
+ > **后续轮次**:DSH 0.2.0 的适配审计与四宿主实测记录见 [`COMPAT-AUDIT-ROUND3.md`](COMPAT-AUDIT-ROUND3.md)
328
+ > (预设交付形态换代、会话事件白名单、子代理数量上限、工具名抛错、压缩语义等)。
@@ -0,0 +1,139 @@
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
+ 修复:按 dispatch 结果自身的 `ok:false` 返回 `kind:'error'`(该联合在 0.1.5 上同样存在,故旧线安全)。
77
+
78
+ ### G-9 文档、镜像与工具描述与实现不符
79
+
80
+ v5 的 README、`架构图.md`、`实现方案.md`、它写进用户项目的三个镜像文件头(`Institutes.md`、`Shared/TaskBoard.md`、
81
+ `State/README.md`)以及 `vibe_v5_set` 的**工具描述**都写着"权威状态在会话日志投影里"。修复:全部改为真实位置
82
+ (`State/<研究所>.v5state.json`),并重生成 v5 中英架构图。**这一条是提示词/交互面的事实性修复**,不是文风问题。
83
+
84
+ ### G-10 "旧线不读目录"必须用**能力**判定,不能用版本号
85
+
86
+ `agentPresets` 服务在两条线上**都存在**但语义不同(旧线是目录扫描器、**没有** `register`)——用"服务存在"判形态
87
+ 会在 0.1.5/0.1.6 上误判为"组合行",从而**跳过**唯一有效的目录安装。修复:判定读 **loader 入口树**里是否挂了
88
+ `@deepseek-ai/dsh-agent-preset`(或其 registry);这在任何插件激活之前就可见,而"读服务"在 bundle 被单独激活
89
+ (`dsh plugin add`)时可能尚未就绪。
90
+
91
+ ---
92
+
93
+ ## 2. 四宿主实测矩阵
94
+
95
+ | 宿主 | preset 形态 | 实测结果 |
96
+ |---|---|---|
97
+ | 0.1.5-rc.2 | 目录 | 安装器写入四个目录;声明行静默无副作用;`agentPresets.list()` 列出四个预设 ✅ |
98
+ | 0.1.6-alpha.2 | 目录 | 同上 ✅ |
99
+ | 0.1.7-rc.2 | 组合行 | 声明行注册四个预设(order 20–23);安装器跳过目录(`state` 文件不再被写)✅ |
100
+ | 0.2.0-rc.2 | 组合行 | 同上,且**零激活警告**(此前数组 patch / 宿主包名 / `!!js` 门各会产生一批失败行)✅ |
101
+
102
+ ---
103
+
104
+ ## 3. 已确证**正确**的部分(避免下次重复劳动)
105
+
106
+ - `tools.register` 的形状(`name`/`description`/`parameters` + **必需的** `output:{schema,render}` + `execute`)与
107
+ `parameters` 用原生 JSON Schema 的写法(宿主自己的工具也这么写);handler 返回符合 `output.schema` 的 JSON 字符串 ✓。
108
+ - `commands.register`(`name`/`description`/`input:{hint}`/`handler`)与命令名正则 ✓。
109
+ - `tools.restrict` 的 `{allow,deny}` 形状,以及"未注册名"错误消息仍以 `known global tools: …` 结尾 —— v2/v3 的重试正则
110
+ 逐字符匹配,行为保持 fail-closed ✓。
111
+ - `fs`(resolve/stat/readText/writeText/listDir)、`getPolicy()` 作为 `writeText` 第 5 参数的位置 ✓;`FsDirEntry` 字段无改名 ✓。
112
+ - `subagents.startContinuable` / `sendMessage`(4 参数 + `{signal}`)/ `interrupt`(第二参数为 authority,自 0.1.1 起)/
113
+ `drainContinuableChildren` 的调用形状自 0.1.2-rc.1 起未变 ✓;`agents.get` 在 `subagent/start` 里可解析、在 `subagent/end`
114
+ 里**必然不可解析**——v4/v5 "在 start 时捕获 Agent 引用"的写法继续正确 ✓。
115
+ - `subprocess`(spawn/done/terminate/collected)与 `sandboxPolicy.resolve` ✓;`timer` 服务签名与 disposer 语义 ✓。
116
+ - `sessionProjections.register/stateOf` 的形状本身 ✓(本包不再使用,原因见 G-4)。
117
+
118
+ ---
119
+
120
+ ## 4. 修复实施记录(2.4.0)
121
+
122
+ 见 `docs/release-notes/RELEASE-NOTES-2.4.0.md`「变更」。工程证据(逐条审计报告与探针输出)保存在仓库之外的
123
+ 工作区台账中;本文件只保留结论与判据。
124
+
125
+ 新增守卫:`tests/audit-preset-rows.test.mjs`(生成物与生成器逐字节一致、`dsh.bundle.patch` 必须是字符串、
126
+ 声明行不得命名宿主包、不得使用会调用服务的 `!!js` 门、每条组合必须含 `present`/`command-goal`/`isolate`/`workflow-ptc`、
127
+ 冻结的 0.1.x 组合保持原样);`docs/AUDIT-CHECKLIST.md` 新增 §8 把上述四条硬约束写成流程。
128
+
129
+ ---
130
+
131
+ ## 5. 刻意不改(附理由)
132
+
133
+ | 项 | 决定 | 理由 |
134
+ |---|---|---|
135
+ | v2/v3 使用全局 `setInterval`/`setTimeout` | 保留 | 预设是**文件行**,不经动态包 vm 沙箱(沙箱只包动态包宿主半);实测可用,且 `ctx.effect` 内已正确清理。仅修掉"插件运行时没有全局定时器"这句**错误注释**。 |
136
+ | 工具卡片呈现(`presentCall`/`presentResult`) | 不加 | 纯外观增强,与本次适配无关;未来要加需同步四套。 |
137
+ | `subagents.listChildren` 元素类型变化(`SubagentCatalogEntry`) | 不处理 | 四套预设均未调用。 |
138
+ | `additionalProperties:false` 的 `parameters` | 保留 | 宿主 `tools.register` 不校验 `parameters`;仅当预设改造成**动态包**时 `defineTool` 才会拒绝(届时再改)。 |
139
+ | `followup` 回退分支 | 保留 | 该分支只在 0.1.1 及更早存在;本包声明的下限是 0.1.2-alpha.4,其中 `0.1.2-alpha.*` 是否仍带 `followup` 未实测,保留分支零成本且更稳。 |
@@ -134,34 +134,34 @@ const STRINGS = {
134
134
  },
135
135
 
136
136
  projection: {
137
- bandTitle: '状态权威源:会话日志的 host-only 投影单元(键 vibeMathV5)',
138
- bandSub: '副作用只是往会话日志追加事件 —— 不进模型上下文(零 token 成本),checkpoint / restore 交给 DSH',
137
+ bandTitle: '状态权威源:加固 JSON 文件 State/<institute>.v5state.json',
138
+ bandSub: '同一份纯折叠 applyV5Event · 整份快照经串行 promise 链写入 · 读前必先 load —— 事件不进模型上下文(零 token 成本)',
139
139
  eventsCard: [
140
140
  'applyV5Event(纯折叠,只此一份)',
141
- '11 类事件:institute / member / task /',
141
+ '12 类事件:institute / member / task /',
142
142
  'message / delivered / meeting / debate /',
143
- 'verdict / queue / counters / progress',
143
+ 'verdict / formal / queue / counters / progress',
144
144
  '未知或损坏事件 → 跳过并记入 diagnostics:',
145
145
  '可用性优先,绝不因一条坏事件卡死全场',
146
146
  ],
147
147
  checkpointCard: [
148
- 'checkpoint / restore / resume',
149
- '投影随会话日志一起 checkpoint;restore',
150
- '时从快照 + 日志尾部重新折叠 → 跨进程与',
151
- '同进程恢复走同一条代码路径',
152
- '回退:宿主无 sessionProjections 时改用',
153
- '加固 JSON:State/<institute>.v5state.json',
148
+ '唯一后端:加固 JSON 文件',
149
+ '读之前必先 load;每次提交把整份快照经',
150
+ '一条串行 promise 链写入(后写者不会用旧',
151
+ '子集覆盖新状态);跨进程与同进程恢复走',
152
+ '同一条代码路径:读文件 → 折叠',
153
+ '研究所事件绝不写进宿主会话日志(DSH 拒载未知事件)',
154
154
  ],
155
155
  },
156
156
 
157
157
  files: {
158
- bandTitle: '文件面:人可读产物(投影之外的一切都只是镜像)',
159
- bandSub: '共识的权威在投影;文件是工作区与可读产物,手工改坏不会破坏研究所',
158
+ bandTitle: '文件面:人可读产物(除 State/<institute>.v5state.json 外都只是镜像)',
159
+ bandSub: '权威状态是 State/<institute>.v5state.json;文件是工作区与可读产物,手工改坏不会破坏研究所',
160
160
  card: [
161
161
  'Members/<id>/Progress|Propos|Methods|Subproblems/',
162
162
  '只有本人可写,人人可读(跨读被鼓励)',
163
163
  'Shared/Chat/*.md · Shared/Meetings/<mt-id>.md · Shared/Debates/<obj>.md',
164
- 'Shared/TaskBoard.md · Institutes.md(编制镜像)· State/README.md(说明此处非权威)',
164
+ 'Shared/TaskBoard.md · Institutes.md(编制镜像)· State/README.md(说明权威=同目录 v5state.json)',
165
165
  'Problems/<id>.md(原问题)· Problems/conclusion.md(结题)· Verified/<类型>/<id>.md(定论,只读)',
166
166
  ],
167
167
  },
@@ -272,34 +272,34 @@ const STRINGS = {
272
272
  },
273
273
 
274
274
  projection: {
275
- bandTitle: 'Source of truth: host-only projection cell of the session log (key vibeMathV5)',
276
- bandSub: 'The only side effect is appending events to the session log, outside the model context (zero token cost)',
275
+ bandTitle: 'Source of truth: hardened JSON file State/<institute>.v5state.json',
276
+ bandSub: 'the same pure applyV5Event fold · serial whole-snapshot writes · load before every read (zero token cost)',
277
277
  eventsCard: [
278
278
  'applyV5Event (pure fold, the only copy)',
279
- '11 kinds of events: institute / member / task /',
279
+ '12 kinds of events: institute / member / task /',
280
280
  'message / delivered / meeting / debate /',
281
- 'verdict / queue / counters / progress',
281
+ 'verdict / formal / queue / counters / progress',
282
282
  'unknown/bad event → skipped and recorded in diagnostics:',
283
283
  'availability first, one bad event never stalls the field',
284
284
  ],
285
285
  checkpointCard: [
286
- 'checkpoint / restore / resume',
287
- 'the projection is checkpointed with the session log; restore',
288
- 're-folds snapshot + log tail → across and within processes',
289
- 'one process recovery takes the same code path',
290
- 'fallback: host without sessionProjections → hardened',
291
- 'JSON: State/<institute>.v5state.json',
286
+ 'the only backend: hardened JSON file',
287
+ 'never read before load; each commit writes the whole',
288
+ 'snapshot through a serial chain, so a late writer cannot',
289
+ 'land a stale subset; across and within processes recovery',
290
+ 'takes one code path: read file → fold. Institute events',
291
+ 'never enter the host session log; DSH refuses unknown ones',
292
292
  ],
293
293
  },
294
294
 
295
295
  files: {
296
- bandTitle: 'File plane: human-readable artifacts (everything outside the projection is only a mirror)',
297
- bandSub: 'The authority for consensus is the projection; files are readable artifacts, breaking them by hand does not damage it',
296
+ bandTitle: 'File plane: readable artifacts (all except State/<institute>.v5state.json are mirrors)',
297
+ bandSub: 'The authority is State/<institute>.v5state.json; everything else is a readable artifact — hand edits change nothing',
298
298
  card: [
299
299
  'Members/<id>/Progress|Propos|Methods|Subproblems/',
300
300
  'only the owner can write, everyone can read (cross-reading is encouraged)',
301
301
  'Shared/Chat/*.md · Shared/Meetings/<mt-id>.md · Shared/Debates/<obj>.md',
302
- 'Shared/TaskBoard.md · Institutes.md (roster mirror) · State/README.md (says the authority is not here)',
302
+ 'Shared/TaskBoard.md · Institutes.md (roster mirror) · State/README.md (says the authority is the sibling v5state.json)',
303
303
  'Problems/<id>.md (original problem) · Problems/conclusion.md (conclusion) · Verified/<type>/<id>.md (conclusion, read-only)',
304
304
  ],
305
305
  },
@@ -520,7 +520,7 @@ arrow(556, 430, 578, 430, { color: C.house, dashed: true, width: 1.8, marker: 'b
520
520
 
521
521
  // ---- 连线:框架 ↔ 数据面 ----
522
522
  arrow(400, 940, 400, 964, { color: C.data, marker: 'bothData', width: 2 })
523
- plain(392, 956, 'append / fold / stateOf', { fill: C.data, anchor: 'end', size: 10.5, halo: true })
523
+ plain(392, 956, 'load / commit / fold', { fill: C.data, anchor: 'end', size: 10.5, halo: true })
524
524
  arrow(1280, 940, 1280, 964, { color: C.data, marker: 'bothData', width: 2 })
525
525
  plain(1288, 956, T.links.filesLabel, { fill: C.data, anchor: 'start', size: 10.5, halo: true })
526
526
 
@@ -0,0 +1,172 @@
1
+ # dsh-vibe-math 2.4.0 — 发布说明(中文)
2
+
3
+ > 上一版:2.3.16。本版**适配 DSH 0.2.0**:修复"在新版 DSH 上四个预设装了却看不见"(预设交付机制换代),
4
+ > 并修掉三处会在新宿主上真实发作的缺陷(v5 状态写坏宿主会话、工具过滤导致派生失败、常驻数量上限)。
5
+ > 其中第 2 条是**数据安全级**修复,请优先阅读。
6
+
7
+ ---
8
+
9
+ ## 概览
10
+
11
+ - **新版 DSH 上预设终于可见**:DSH 0.1.7 起 agent preset 改由"组合行"声明,而旧版写入的 `~/.dsh/.agent-presets/`
12
+ 目录**已无人读取**——2.3.x 在新宿主上会"安装成功,但预设选择器里什么都没有"。本版用同一份 bundle 同时适配两条线。
13
+ - **v5 不再写坏你的会话**:v5 过去把研究所事件追加进宿主会话日志,而 DSH 的会话持久化遇到不认识的事件类型会
14
+ **拒绝加载整个会话**——症状是"某次重启后这个会话打不开"。现在研究所状态只落在 `State/<研究所>.v5state.json`。
15
+ - **三处新宿主行为已适配**:工具过滤里的未注册工具名(会让派生直接失败)、宿主对常驻子代理的数量上限、
16
+ 以及"真正执行压缩"的调用。
17
+
18
+ ## 变更
19
+
20
+ ### 1. 适配 DSH 0.2.0:一条 bundle 覆盖两条版本线
21
+
22
+ - **DSH ≥ 0.1.7(含 0.2.0)**:四个预设作为**组合行**随 `cordis.patch.yml` 声明,安装后立即出现在预设选择器里;
23
+ 不再往 `~/.dsh/.agent-presets/` 写文件(该目录在新版里已废弃,安装器会跳过并在日志里说明可安全删除)。
24
+ - **DSH ≤ 0.1.6**:仍走目录形式,安装器照旧写入四个 preset 目录;同一份声明行在旧版上**静默无副作用**、不会报错。
25
+ - 兼容窗口随之更新为 **0.1.2-alpha.4 … 0.2.0-rc.2**(此前 0.2.0 被标为超出范围)。同时声明 `peerDependencies`:
26
+ 新版 DSH 会用它比对宿主版本,不满足时**跳过整个 bundle 并给出可读提示**,而不是挂上一个跑不通的预设。
27
+ - 安装与升级方式不变:桌面版在「设置 → 插件」里安装或更新;命令行 profile 用
28
+ `dsh plugin --profile <你的 profile> add dsh-vibe-math@latest`。
29
+
30
+ ### 2. 修复:v5 的研究所状态会写坏宿主会话(数据安全级)
31
+
32
+ - **症状**:v5 把 `vibe5/*` 事件追加进**你自己的**会话日志;DSH 的会话持久化在加载时要求"不认识的事件类型必须带
33
+ `ignorable: true`",而 `Session.append` 无法设置该字段 → **该会话从此无法恢复**,且写入当时毫无提示。
34
+ - **现在**:研究所状态只写加固 JSON(`State/<研究所>.v5state.json`:同一份事件折叠、串行写、读前必 load),
35
+ **不再向任何宿主会话日志追加事件**,v5 也因此少一个宿主服务依赖。
36
+ - **如果你有旧会话**:修复之前写下的 v5 事件仍可能让那个会话加载失败——在会话列表里新建会话重开研究所即可;
37
+ 镜像 Markdown 与 `Verified/` 下的文件都不受影响。
38
+
39
+ ### 3. 修复:派生不再因工具名或数量上限而整体失败
40
+
41
+ - **工具过滤**:DSH 对 `tools.restrict()` 里未注册的工具名**直接抛错**,而该调用发生在建立子代理时——v4/v5 此前会把
42
+ 整次派生搞失败。现在按宿主提示剔除未注册名后重试一次,并且**绝不回退到"不过滤"**(那等于放开你明确禁止的工具)。
43
+ - **数量上限**:新版 DSH 对每个根代理的**存活 continuable 子代理**设了上限(`subagent` 行的 `maxActiveSubagents`,
44
+ 默认 8)。撞到上限时现在会**明确提示**上限值并把该次派生推迟到下一轮,而不是让启动循环崩在半途。
45
+
46
+ ### 4. 修复:真实压缩与状态描述
47
+
48
+ - v4/v5 的真实 `/compact` 改为优先调用**真正执行压缩**的 `compactNow`(`compactIfNeeded` 是策略调用,可能什么都不做
49
+ 且不报错);v5 同时改为使用 preset 自己隔离域里的 compaction 实例。
50
+ - v5 写入你项目里的镜像文件(`Institutes.md`、`Shared/TaskBoard.md`、`State/README.md`)以及**给模型看的工具说明**
51
+ 曾写着"权威状态在会话日志投影里"——现已改为真实位置(状态 JSON 文件)。
52
+
53
+ ## 兼容性
54
+
55
+ - 四套预设的**提示词、语料与工具面**除上述修复外未变;`~/.dsh/.agent-presets/` 目录形式(DSH ≤ 0.1.6)继续受支持。
56
+ - 不改变任何参数默认值与数据格式;`State/<研究所>.v5state.json` 沿用原有实现(此前是回退路径),老文件可直接复用。
57
+ - 若你为同一个 preset id 自己保存过声明,本包会放弃注册并打印一行说明,以你的声明为准。
58
+ - 新增守卫:`cordis.patch.yml` 与其生成器必须逐字节一致、`dsh.bundle.patch` 必须是字符串、声明行不得命名宿主包、
59
+ 不得使用会调用服务的 `!!js` 门——这四条都是本次实测踩出来的。
60
+
61
+ ## 升级
62
+
63
+ ```sh
64
+ npm i dsh-vibe-math@latest
65
+ ```
66
+
67
+ 桌面版在「设置 → 插件」里更新;命令行 profile 若把版本钉死了,先升级那个依赖再重启 DSH:
68
+
69
+ ```sh
70
+ dsh plugin --profile <你的 profile> add dsh-vibe-math@latest
71
+ ```
72
+
73
+ 升级后**重启 DSH**,然后在预设选择器里确认出现 Vibe Math V2 / V3 / V4 / V5。
74
+
75
+ ---
76
+
77
+ # dsh-vibe-math 2.4.0 — Release Notes (English)
78
+
79
+ > Previous: 2.3.16. This release **adapts the package to DSH 0.2.0**: it fixes "the four presets install
80
+ > but never appear on the new DSH line" (the preset delivery mechanism changed), and it fixes three
81
+ > defects that really fire on the new host (v5 corrupting the user's own session, tool filters breaking
82
+ > delegation, and the host's cap on live child agents). Item 2 is a **data-safety** fix — read it first.
83
+
84
+ ---
85
+
86
+ ## Overview
87
+
88
+ - **The presets are visible again on the current DSH line.** Since 0.1.7 an agent preset is declared as
89
+ a composition row, and nothing reads the `~/.dsh/.agent-presets/` directory any more — so 2.3.x
90
+ installed "successfully" on the new host and then showed **no presets at all**. One bundle now serves
91
+ both lines.
92
+ - **v5 no longer damages your session.** v5 used to append institute events to the host session log, and
93
+ DSH's session persistence **refuses to load a session** that carries an unknown event type — the
94
+ symptom is "that session will not open any more after a restart". Institute state now lives only in
95
+ `State/<institute>.v5state.json`.
96
+ - **Three new host behaviours are handled**: unregistered tool names in a tool filter (which made
97
+ delegation fail outright), the host's cap on live resident children, and the call that actually
98
+ performs a compaction.
99
+
100
+ ## Changes
101
+
102
+ ### 1. DSH 0.2.0 adaptation: one bundle, two version lines
103
+
104
+ - **DSH ≥ 0.1.7 (including 0.2.0)**: the four presets are declared as **composition rows** in
105
+ `cordis.patch.yml` and appear in the preset picker right after installation. Nothing is written to
106
+ `~/.dsh/.agent-presets/` any more (the installer skips it and says in the log that the directory can be
107
+ deleted safely).
108
+ - **DSH ≤ 0.1.6**: the directory form is unchanged — the installer still writes the four preset
109
+ directories, and the same declaration rows are **silently inert** on that line (no boot errors).
110
+ - The supported window is now **0.1.2-alpha.4 … 0.2.0-rc.2** (0.2.0 used to be declared out of range).
111
+ The package also declares `peerDependencies`, which the new DSH uses to **skip an incompatible bundle
112
+ with a readable message** instead of mounting a preset that cannot work.
113
+ - Installing and upgrading are unchanged: Desktop installs or updates through Settings → Plugins; a CLI
114
+ profile uses `dsh plugin --profile <your profile> add dsh-vibe-math@latest`.
115
+
116
+ ### 2. Fix: v5 institute state could make your session unresumable (data safety)
117
+
118
+ - **Symptom**: v5 appended `vibe5/*` events to **your own** session log. On load, DSH's session
119
+ persistence requires an unknown event type to carry `ignorable: true`, and `Session.append` cannot set
120
+ that field — so **that session could never be resumed**, silently at write time.
121
+ - **Now**: institute state is written only to the hardened JSON file (`State/<institute>.v5state.json`:
122
+ the same event fold, serial writes, a mandatory load before read). **Nothing is appended to any host
123
+ session log**, and v5 no longer needs that host service.
124
+ - **If you have older sessions**: events written before this fix can still prevent that particular
125
+ session from loading — open a new institute in a new session. The mirror Markdown and everything under
126
+ `Verified/` are unaffected.
127
+
128
+ ### 3. Fix: delegation no longer fails as a whole because of a tool name or the host cap
129
+
130
+ - **Tool filters**: DSH **throws** for a tool name outside its registered set, and that call happens while
131
+ a child agent is being created — which used to fail the whole delegation in v4/v5. The framework now
132
+ drops the unregistered names (taken from the host's own rejection message) and retries once, and it
133
+ **never falls back to "no filter"** — that would grant exactly what you denied.
134
+ - **The host cap**: the current DSH caps **live continuable children** per root agent
135
+ (`maxActiveSubagents` on the `subagent` row, default 8). Hitting the cap now reports the limit and
136
+ defers that spawn to the next round instead of crashing the startup loop halfway through.
137
+
138
+ ### 4. Fix: real compaction and stale state descriptions
139
+
140
+ - v4/v5's real `/compact` now prefers `compactNow`, the call that actually compacts (`compactIfNeeded` is
141
+ a policy call that may quietly do nothing); v5 also uses the compaction instance from its own preset
142
+ isolate realm.
143
+ - The mirror files v5 writes into your project (`Institutes.md`, `Shared/TaskBoard.md`,
144
+ `State/README.md`) and the **model-facing tool description** used to say the authoritative state was a
145
+ session-log projection. They now state the real location (the state JSON file).
146
+
147
+ ## Compatibility
148
+
149
+ - Aside from the fixes above, the four presets' **prompts, corpora and tool surface are unchanged**, and
150
+ the `~/.dsh/.agent-presets/` directory form (DSH ≤ 0.1.6) remains supported.
151
+ - No parameter default or data format changes; `State/<institute>.v5state.json` uses the implementation
152
+ that already existed as the fallback path, so existing files keep working.
153
+ - If you saved your own declaration for the same preset id, this package gives up its registration and
154
+ logs one line — your declaration wins.
155
+ - New guards: `cordis.patch.yml` must be byte-identical to what its generator emits, `dsh.bundle.patch`
156
+ must be a string, a declaration row must not name a host package, and it must not use a `!!js` gate that
157
+ calls a service — all four were measured the hard way during this adaptation.
158
+
159
+ ## Upgrade
160
+
161
+ ```sh
162
+ npm i dsh-vibe-math@latest
163
+ ```
164
+
165
+ Desktop updates through Settings → Plugins. If a CLI profile pinned the version, update that dependency
166
+ and restart DSH:
167
+
168
+ ```sh
169
+ dsh plugin --profile <your profile> add dsh-vibe-math@latest
170
+ ```
171
+
172
+ After upgrading, **restart DSH** and confirm that Vibe Math V2 / V3 / V4 / V5 appear in the preset picker.
@@ -25,8 +25,9 @@ node tests/audit-v5-integrity.mjs # 静态:v5 完整性/理念门
25
25
 
26
26
  | 脚本 | 串行(sum) | 并行(wall) | 实测输出 |
27
27
  |---|---|---|---|
28
- | `tests/run-tests.mjs`(28 个套件) | ≈ 230 s | **≈ 110 s**(并发 4) | 关键路径 = `e2e-v4-fixes` ≈ 96 s |
28
+ | `tests/run-tests.mjs`(29 个套件) | ≈ 230 s | **≈ 110 s**(并发 4) | 关键路径 = `e2e-v4-fixes` ≈ 96 s |
29
29
  | `tests/audit-installer-policy.test.mjs` | ≈ 1 s | — | 在临时 DSH_HOME 里驱动真实安装器(复制 4 套预设 × 2 个版本) |
30
+ | `tests/audit-preset-rows.test.mjs` | ≈ 0.2 s | — | 四个 preset 的声明行(cordis.patch.yml 与生成器逐字节一致、bundle.patch 必须是字符串、行不得用 `ctx.get` 的 `!!js` 门、组合里必须有 present/command-goal/isolate/workflow-ptc;纯静态) |
30
31
  | `tests/audit-readme-bilingual.test.mjs` | ≈ 0.2 s | — | 中英 README 的结构/链接/图片/锚点一致性(英文版架构图按 `-en` 变体配对;纯静态) |
31
32
  | `tests/audit-diagram-assets.test.mjs` | ≈ 1 s | — | 四张架构图 PNG 必须装得下它自己的画面、四张英文版 SVG 必须存在且正文为英文(解 PNG 与 SVG,纯静态) |
32
33
  | `audit-formal-sensitivity.mjs`(49 探针) | 612.0 s | **154.6 s**(并发 4,speed-up x3.96) | 关键路径 = 12 个 v2 探针(每个 ≈32 s) |