dsh-vibe-math 2.3.15 → 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 (40) hide show
  1. package/README.en.md +93 -87
  2. package/README.md +58 -53
  3. package/cordis.patch.yml +1123 -10
  4. package/docs/AUDIT-CHECKLIST.md +107 -43
  5. package/docs/COMPAT-AUDIT-ROUND2.md +3 -0
  6. package/docs/COMPAT-AUDIT-ROUND3.md +139 -0
  7. package/docs/generate_framework_diagram_v2_en.mjs +595 -0
  8. package/docs/generate_framework_diagram_v3_en.mjs +624 -0
  9. package/docs/generate_framework_diagram_v4.mjs +380 -125
  10. package/docs/generate_framework_diagram_v5.mjs +366 -108
  11. package/docs/release-notes/RELEASE-NOTES-2.3.16.md +165 -0
  12. package/docs/release-notes/RELEASE-NOTES-2.4.0.md +172 -0
  13. package/docs/test-timing.md +4 -3
  14. package/docs//346/236/266/346/236/204/345/233/276.md +3 -1
  15. package/installer.js +89 -21
  16. package/package.json +40 -9
  17. package/preset-declaration.js +62 -0
  18. package/prompt-corpus-v5/prompt-corpus-v5.json +7 -7
  19. package/prompt-corpus-v5/prompt-corpus-v5.md +8 -129
  20. package/scripts/build-preset-rows.mjs +146 -0
  21. package/tests/audit-installer-compat.test.mjs +9 -3
  22. package/tests/audit-preset-rows.test.mjs +185 -0
  23. package/tests/audit-v5-integrity.mjs +49 -3
  24. package/tests/e2e-v5-round2.test.mjs +137 -67
  25. package/tests/formal-verify-v5.test.mjs +43 -35
  26. package/tests/prompt-v5-integrity.test.mjs +49 -47
  27. package/tests/selfdrive-v5.mjs +42 -55
  28. package/vibe-math-v2/vibe-math-v2.js +6 -2
  29. package/vibe-math-v3/vibe-math-v3.js +6 -2
  30. package/vibe-math-v4/vibe-math-v4.js +191 -13
  31. package/vibe-math-v5/agent.cordis.yml +8 -8
  32. package/vibe-math-v5/preset.yml +1 -1
  33. package/vibe-math-v5/vibe-math-v5.js +215 -91
  34. package/vibe-math-v5//345/256/236/347/216/260/346/226/271/346/241/210.md +56 -44
  35. package/vibe-math-v5//346/236/266/346/236/204/345/233/276.md +24 -22
  36. package//347/244/272/344/276/213/345/233/276//346/241/206/346/236/266/345/233/276-v2-en.svg +291 -0
  37. package//347/244/272/344/276/213/345/233/276//346/241/206/346/236/266/345/233/276-v3-en.svg +316 -0
  38. package//347/244/272/344/276/213/345/233/276//346/241/206/346/236/266/345/233/276-v4-en.svg +187 -0
  39. package//347/244/272/344/276/213/345/233/276//346/241/206/346/236/266/345/233/276-v5-en.svg +174 -0
  40. package//347/244/272/344/276/213/345/233/276//346/241/206/346/236/266/345/233/276-v5.svg +14 -14
@@ -0,0 +1,165 @@
1
+ # dsh-vibe-math 2.3.16 — 发布说明(中文)
2
+
3
+ > 上一版:2.3.15。本版把**英文文档与英文配图补齐**:英文 README 全篇英文化,并为它单独提供
4
+ > **四张英文版架构图**;同时修正两份 README 里一处与实现不符的 v2 数据层描述,并把 v1 时期的旧架构文档标注清楚。
5
+ > 四套预设的代码、提示词与语料**字节未变**,运行时行为不变。
6
+
7
+ ---
8
+
9
+ ## 概览
10
+
11
+ - **英文 README 全篇英文**:示例对话、参数表、目录树占位符与链接文案都改成英文;只有**必须与实现一致**的真实字面量
12
+ 保留中文(真实目录 / 文件名、真实 JSON 键、真实 Markdown 格式锚点),并在首次出现处加了英文括注。
13
+ - **四张英文版架构图**:`示例图/框架图-v2-en.svg` … `-v5-en.svg`,只被英文 README 引用;四张中文图完全未改动。
14
+ - **修正一处事实错误**:两份 README 此前称 v2 会把 `qs.csv` 回写为 `solved`、并生成 `q1-的解法_<标识>.csv`——
15
+ v2 **从不写任何 CSV**,已按实现改正。
16
+ - **旧架构文档标注范围**:`docs/架构图.md` 描述的是 v1 时期的布局,现在文件开头与 README 的引用处都明确标注为历史文档。
17
+
18
+ ## 变更
19
+
20
+ ### 1. 英文 README 全篇英文化
21
+
22
+ - 示例提示词、参数表、目录树里的占位符(`<项目>` → `<project>` 等)、链接文案全部改为英文。
23
+ - 保留中文的只有**真实字面量**:真实目录与文件名(`示例图/…`、`Verified/命题/`、`Logs/报告.md` 等)、
24
+ 真实 JSON 键(`已解决`、`正确概率`)、真实 Markdown 格式锚点(`- ID/类型/状态/概率/…`、
25
+ `### 解法/证明/证伪 N|标题|概率X|状态Y`),以及会话重建标记 `【会话重建 —— <角色> <id>】`。
26
+ 这些在英文版里首次出现处都加了英文括注,读者不会误以为是漏译。
27
+ - 守卫加强:英文版除上述字面量外不得残留中文正文;中英两版的章节层级、表格行数、代码块数、图片与本地链接
28
+ 必须一一对应,只改一边会被直接检出。
29
+
30
+ ### 2. 四张英文版架构图
31
+
32
+ - 新增 `示例图/框架图-v2-en.svg`、`-v3-en.svg`、`-v4-en.svg`、`-v5-en.svg`,英文 README 单独引用;
33
+ **中文版四张图未做任何改动**(中文 README 只同步了下面第 3、4 两节的修正)。
34
+ - 生成方式:v4/v5 用仓库里现有的零依赖生成脚本加 `--lang=en`;v2/v3 新增零依赖 Node 生成脚本
35
+ `docs/generate_framework_diagram_v{2,3}_en.mjs`(中文 v2/v3 海报仍由原来的 matplotlib 脚本产出,未动)。
36
+ - 英文图内同样只保留真实字面量的中文(例如 v3 的 md 锚点、v4/v5 的 `Verified/命题/<id>.md` 路径),其余全英文;
37
+ 生成脚本自带「文字溢出即告警并以非零码退出」的自检,守卫会校验每张图完整、可解析且正文为英文。
38
+
39
+ ### 3. 修正 v2 数据层描述(两份 README)
40
+
41
+ - 旧文写的是 v1 时代的行为:调度器读 `qs.csv`、把问题回写为 `solved`、解法另存 `q1-的解法_<标识>.csv`。
42
+ - v2 的真实行为:问题与解法都在 `qs/qs.json`(`已解决` 布尔、解法列表带 `正确概率`),
43
+ 定论事实进入 `Verified/<分类>_Verified.json`;**v2 不产生任何 CSV**。
44
+ - 英文版同时补上了这些真实键名的英文含义,读者不必对着陌生键名猜。
45
+
46
+ ### 4. 旧架构文档标注适用范围
47
+
48
+ - `docs/架构图.md` 中的 `qs.csv`、`Pending_Verification/`、`Under_Verification/`、`Temp_Validated/` 等名称
49
+ 在 v2 起已不存在,这些目录在任何一套预设的代码里都找不到。
50
+ - 现在该文件开头写明它描述的是 **v1 历史布局**,并指向当前各版本的实现方案与架构图;
51
+ 两份 README 对它的引用也从「(v2 详解)」改为「(v1 历史架构图)」,不再把旧布局当成当前实现。
52
+
53
+ ## 兼容性
54
+
55
+ - 四套预设(v2 / v3 / v4 / v5)的代码、提示词、语料、参数与工具面**均未变化**,运行时行为完全不变。
56
+ - 中文 README 仍是默认的 `README.md`,npm 页面与 GitHub 首页的默认内容不变;`screenshots.json` 的市场配图也未改动。
57
+ - 包内新增 4 张英文 SVG、2 个英文版生成脚本与本版发布说明;除此之外随包内容的变化只有 README 与文档说明。
58
+ - 本版只涉及文档、配图与测试守卫,不涉及任何运行时行为。
59
+
60
+ ## 升级
61
+
62
+ ```sh
63
+ npm i dsh-vibe-math@latest
64
+ ```
65
+
66
+ 若你在 profile 里把版本钉死了,先升级那个依赖再重启 DSH:
67
+
68
+ ```sh
69
+ dsh plugin --profile <你的 profile> add dsh-vibe-math@latest
70
+ ```
71
+
72
+ 本次未改动预设文件,已安装的预设无需重新同步。无需迁移。
73
+
74
+ ---
75
+
76
+ # dsh-vibe-math 2.3.16 — Release Notes (English)
77
+
78
+ > Previous: 2.3.15. This release finishes the **English documentation and its artwork**: the English
79
+ > README is now fully English and ships with its **own four architecture diagrams**, one statement
80
+ > about v2's data layer that did not match the implementation is corrected in both READMEs, and the
81
+ > v1-era architecture document is labelled as such. The four presets' code, prompts and corpora are
82
+ > **byte-identical**; runtime behaviour is unchanged.
83
+
84
+ ---
85
+
86
+ ## Overview
87
+
88
+ - **The English README is fully English**: example conversations, the parameter table, directory-tree
89
+ placeholders and link labels are all English. Only literals that must stay verbatim for the reader
90
+ to match the implementation stay Chinese (real file and directory names, real JSON keys, real
91
+ Markdown anchors), each glossed in English where it first appears.
92
+ - **Four English architecture diagrams**: `示例图/框架图-v2-en.svg` … `-v5-en.svg`, referenced by the
93
+ English README only; all four Chinese diagram files are untouched.
94
+ - **One factual error fixed**: both READMEs claimed v2 writes `qs.csv` back as `solved` and stores
95
+ `q1-的解法_<标识>.csv`. v2 writes **no CSV at all**; the text now matches the implementation.
96
+ - **The old architecture document states its scope**: `docs/架构图.md` describes the v1-era layout, and
97
+ both the file and the README links to it now say so.
98
+
99
+ ## Changes
100
+
101
+ ### 1. The English README is fully English
102
+
103
+ - Example prompts, the parameter table, directory-tree placeholders (`<项目>` → `<project>`, …) and
104
+ link labels are all English.
105
+ - What stays Chinese is only the **real literals**: real file and directory names (`示例图/…`,
106
+ `Verified/命题/`, `Logs/报告.md`, …), real JSON keys (`已解决`, `正确概率`), real Markdown anchors
107
+ (`- ID/类型/状态/概率/…`, `### 解法/证明/证伪 N|标题|概率X|状态Y`) and the session-rebuild marker
108
+ `【会话重建 —— <角色> <id>】`. Each is glossed in English where it first appears, so nothing reads as
109
+ an untranslated leftover.
110
+ - Stronger guard: outside those literals the English file may not contain Chinese prose, and the two
111
+ READMEs must agree on heading levels, table rows, code fences, images and local links — editing only
112
+ one side now fails the suite.
113
+
114
+ ### 2. Four English architecture diagrams
115
+
116
+ - Added `示例图/框架图-v2-en.svg`, `-v3-en.svg`, `-v4-en.svg` and `-v5-en.svg`, referenced by the English
117
+ README. **The four Chinese diagram files are unchanged** (the Chinese README only receives the two
118
+ corrections described in sections 3 and 4 below).
119
+ - How they are produced: v4/v5 use the existing zero-dependency generator with `--lang=en`; v2/v3 have
120
+ new zero-dependency Node generators, `docs/generate_framework_diagram_v{2,3}_en.mjs` (the Chinese
121
+ v2/v3 posters still come from the original matplotlib scripts, which were not touched).
122
+ - The English diagrams also keep Chinese only for real literals (v3's md anchors, v4/v5's
123
+ `Verified/命题/<id>.md` paths); everything else is English. Each generator warns and exits non-zero
124
+ when a line overflows its container, and a guard verifies that every diagram is complete, parseable
125
+ and English.
126
+
127
+ ### 3. v2's data layer corrected in both READMEs
128
+
129
+ - The old text described v1 behaviour: a scheduler reading `qs.csv`, writing the problem back as
130
+ `solved`, and storing the solution as `q1-的解法_<标识>.csv`.
131
+ - v2's real behaviour: problems and solutions both live in `qs/qs.json` (`已解决` boolean, solution list
132
+ with `正确概率`), and settled facts go to `Verified/<category>_Verified.json`. **v2 produces no CSV.**
133
+ - The English version spells out what those key names mean, so no reader has to guess.
134
+
135
+ ### 4. The old architecture document states its scope
136
+
137
+ - The names in `docs/架构图.md` — `qs.csv`, `Pending_Verification/`, `Under_Verification/`,
138
+ `Temp_Validated/` — have not existed since v2 and appear in none of the shipped presets.
139
+ - The file now opens by saying it documents the **v1 historical layout** and points at the current
140
+ specifications and diagrams; both READMEs now link to it as "(v1-era architecture notes)" instead of
141
+ presenting the old layout as the current implementation.
142
+
143
+ ## Compatibility
144
+
145
+ - The four presets (v2 / v3 / v4 / v5) are **unchanged** in code, prompts, corpora, parameters and tool
146
+ surface; runtime behaviour is identical.
147
+ - The Chinese README is still the default `README.md`, so the npm page and the GitHub landing page keep
148
+ their current content; the marketplace images in `screenshots.json` are unchanged.
149
+ - The package adds four English SVGs, two English generator scripts and this release's notes; apart
150
+ from that, only the READMEs and documentation text changed.
151
+ - Documentation, artwork and test guards only — no runtime behaviour.
152
+
153
+ ## Upgrade
154
+
155
+ ```sh
156
+ npm i dsh-vibe-math@latest
157
+ ```
158
+
159
+ If you pinned the version in a profile, update that dependency first and restart DSH:
160
+
161
+ ```sh
162
+ dsh plugin --profile <your profile> add dsh-vibe-math@latest
163
+ ```
164
+
165
+ No preset files changed, so installed presets need no re-sync. No migration needed.
@@ -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,10 +25,11 @@ 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-readme-bilingual.test.mjs` | ≈ 0.2 s | — | 中英 README 的结构/链接/图片/锚点一致性(纯静态) |
31
- | `tests/audit-diagram-assets.test.mjs` | ≈ 1 s | — | 四张架构图 PNG 必须装得下它自己的画面(解 PNG 与 SVG,纯静态) |
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;纯静态) |
31
+ | `tests/audit-readme-bilingual.test.mjs` | ≈ 0.2 s | — | 中英 README 的结构/链接/图片/锚点一致性(英文版架构图按 `-en` 变体配对;纯静态) |
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) |
33
34
  | `audit-persona-sensitivity.mjs`(11 探针) | ≈ 5 s | — | 本身很快,不需要并行 |
34
35
  | `audit-prompt-invariants.mjs`(157 条,含 X5–X8b 扫描器自检) | 0.4 s | — | 静态 |
@@ -1,4 +1,6 @@
1
- # Vibe Math 架构图
1
+ # Vibe Math 架构图(v1 历史版)
2
+
3
+ > ⚠️ **历史文档**:本文件记录最初 **v1** 版本的架构。图中 `qs.csv`、`Pending_Verification/`、`Under_Verification/`、`Temp_Validated/` 等名称在 **v2 起已不存在**(v2 起问题与解法存于 `qs/qs.json`,定论事实存于 `Verified/<分类>_Verified.json`)。**v2–v5 的实际架构**请以 `README.md` 对应章节、`vibe-math-v2/实现方案.md` 等各版本实现方案与 `示例图/框架图-v2.png`…`-v5.svg` 为准。
2
4
 
3
5
  > 框架 = **一个主代理(助手)+ 一个代码调度器 + 五类子代理** + 一套按项目隔离的持久化数据布局。
4
6
  > 下方的 Mermaid 代码块在 GitHub 上会**原生渲染**成流程图;本文件即图源,改完重新提交即可自动更新。
package/installer.js CHANGED
@@ -117,24 +117,76 @@ function writeState(path, state) {
117
117
  }
118
118
  }
119
119
 
120
- // DSH 适配性自检(能力检测,而非版本号——DSH 不向插件暴露版本)。
120
+ // DSH 适配性自检(版本 + preset 形态 + 能力)。
121
121
  // 检查 preset 运行时需要的宿主服务与关键 API 形状是否可用,缺失时打 warning。
122
- // Best-effort DSH host-version detection. DSH does NOT expose its version through a documented
123
- // service/context property or a guaranteed env var, so we probe in order: an explicit env var
124
- // (future-proofing), then the installed @deepseek-ai/dsh package.json. This is layout-dependent
125
- // (works for a typical global install where @deepseek-ai/dsh is a sibling of this plugin); when it
126
- // cannot resolve, the capability self-check below is still the authoritative gate.
122
+ // Best-effort DSH host-version detection, in order of authority:
123
+ // 1. `process.env.DSH_VERSION` — an explicit override, always honoured first;
124
+ // 2. the `pluginManager` service's bundle list — every host bundle carries the runtime version and
125
+ // `@deepseek-ai/dsh-base` is present in every base-backed profile (service since 0.1.7);
126
+ // 3. `@deepseek-ai/dsh-app-boot`'s exported `getDshRuntimeVersion()` — the documented API; it only
127
+ // resolves when this plugin's module scope can reach the host packages;
128
+ // 4. the installed `@deepseek-ai/dsh/package.json` — the historical probe, still the only source
129
+ // that works on a global <= 0.1.6 install.
130
+ // When none resolves, the capability self-check below is still the authoritative gate.
127
131
  const __require = createRequire(import.meta.url)
128
- function detectDshVersion() {
129
- try { const v = process.env.DSH_VERSION; if (v && String(v).trim()) return String(v).trim() } catch (e) {}
132
+ async function detectDshVersion(ctx) {
133
+ try { const v = process.env.DSH_VERSION; if (v && String(v).trim()) return { version: String(v).trim(), source: 'DSH_VERSION' } } catch (e) {}
134
+ try {
135
+ const pm = (ctx && ctx.get) ? ctx.get('pluginManager') : undefined
136
+ if (pm && typeof pm.listBundles === 'function') {
137
+ const bundles = await pm.listBundles()
138
+ const host = (bundles || []).find((b) => b && (b.name === '@deepseek-ai/dsh-base' || b.name === '@deepseek-ai/dsh'))
139
+ if (host && host.version) return { version: String(host.version), source: 'pluginManager:' + host.name }
140
+ }
141
+ } catch (e) { /* no such service, or it cannot list yet */ }
142
+ try {
143
+ const boot = await import('@deepseek-ai/dsh-app-boot')
144
+ if (boot && typeof boot.getDshRuntimeVersion === 'function') {
145
+ return { version: String(boot.getDshRuntimeVersion()), source: 'dsh-app-boot' }
146
+ }
147
+ } catch (e) { /* host packages are not reachable from this plugin's module scope */ }
130
148
  try {
131
149
  const p = __require.resolve('@deepseek-ai/dsh/package.json')
132
150
  const v = (JSON.parse(readFileSync(p, 'utf8')).version || '').trim()
133
- if (v) return v
134
- } catch (e) { /* host package not resolvable from here — rely on capability check */ }
151
+ if (v) return { version: v, source: '@deepseek-ai/dsh/package.json' }
152
+ } catch (e) { /* not a global install layout — rely on the capability check */ }
135
153
  return undefined
136
154
  }
137
155
 
156
+ /**
157
+ * How this host declares agent presets.
158
+ * 'rows' — DSH >= 0.1.7: composition rows declared in this package's cordis.patch.yml (the rows
159
+ * name our own preset-declaration module, which calls `agentPresets.register`).
160
+ * Nothing reads the preset directory any more.
161
+ * 'directory' — DSH <= 0.1.6: <DSH_HOME>/.agent-presets/<id>/agent.cordis.yml, which is what the
162
+ * copy in apply() installs.
163
+ *
164
+ * Judged from the LOADER TREE, not from the version and not from the `agentPresets` service: that
165
+ * service exists on BOTH lines with different meaning (a directory scanner below 0.1.7, a row registry
166
+ * from 0.1.7 on), and it may not be up yet when a bundle is activated on its own. Missing the row line
167
+ * would skip the only working install path, so this decision has to be the reliable one.
168
+ */
169
+ function detectPresetMechanism(ctx) {
170
+ // 1) the LOADER TREE: only the row-based line mounts the agent-preset package (or its registry).
171
+ // This is visible before any plugin activates, which matters because a bundle activation can run
172
+ // this installer before the services are up (then ctx.get('agentPresets') is still undefined).
173
+ try {
174
+ const loader = (ctx && ctx.get) ? ctx.get('loader') : undefined
175
+ if (loader && typeof loader.entries === 'function') {
176
+ const entries = loader.entries()
177
+ for (const entry of entries) {
178
+ const name = entry && entry.options ? entry.options.name : undefined
179
+ if (name === '@deepseek-ai/dsh-agent-preset' || name === '@deepseek-ai/dsh-agent-preset-registry') return 'rows'
180
+ }
181
+ }
182
+ } catch (e) { /* no loader service: fall through to the service probe */ }
183
+ // 2) the service itself (>= 0.1.7), when it is already available.
184
+ try {
185
+ const ap = (ctx && ctx.get) ? ctx.get('agentPresets') : undefined
186
+ return (ap !== undefined && typeof ap.list === 'function') ? 'rows' : 'directory'
187
+ } catch (e) { return 'directory' }
188
+ }
189
+
138
190
  /**
139
191
  * Minimal semver-range matcher for the host requirement.
140
192
  *
@@ -278,7 +330,10 @@ async function checkHostCapabilities(ctx, logger) {
278
330
  try { manifest = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), 'package.json'), 'utf8')) } catch (e) {}
279
331
  const dshRel = (manifest.dsh && manifest.dsh.compatibility && manifest.dsh.compatibility.dshReleases) || {}
280
332
  const supported = Object.keys(dshRel).sort()
281
- const dshVersion = detectDshVersion()
333
+ const detected = await detectDshVersion(ctx)
334
+ const dshVersion = detected && detected.version
335
+ const versionSource = detected && detected.source
336
+ const mechanism = detectPresetMechanism(ctx)
282
337
  if (dshVersion) {
283
338
  const verdict = dshVersionVerdict(dshVersion, manifest)
284
339
  if (verdict.status === 'incompatible') {
@@ -309,12 +364,10 @@ async function checkHostCapabilities(ctx, logger) {
309
364
  { svc: 'subprocess', methods: ['spawn'], required: false },
310
365
  { svc: 'sandboxPolicy', methods: ['resolve'], required: false },
311
366
  { svc: 'compaction', methods: ['compactIfNeeded'], required: false },
312
- // v5 keeps its institute state in a HOST-ONLY session projection unit, so it wants
313
- // the projection registry and the session store. Both are mounted by dsh-base; if
314
- // either is absent v5 falls back to a hardened JSON state file, so this is a
315
- // degradation rather than a mounting gate.
316
- { svc: 'sessionProjections', methods: ['register', 'stateOf'], required: false },
317
- { svc: 'sessions', methods: ['flush'], required: false },
367
+ // v5 keeps its institute state in a hardened JSON file (State/<institute>.v5state.json) and does
368
+ // NOT use the session-projection registry or the session store any more: DSH refuses to load a
369
+ // session whose log carries event types outside its known set, so writing institute events into
370
+ // the user's session used to make that session unresumable. Neither service is checked here.
318
371
  ]
319
372
  const degradations = []
320
373
  for (let i = 0; i < checks.length; i++) {
@@ -359,13 +412,14 @@ async function checkHostCapabilities(ctx, logger) {
359
412
  }
360
413
  } catch (e) { /* 探测失败不致命 */ }
361
414
  if (degradations.length > 0) {
362
- logger?.warn?.('[dsh-vibe-math] 可选宿主服务缺失,功能会静默降级(不影响挂载):' + degradations.join(';') + '。subprocess 缺失则无法用 shell 创建目录树(仅靠 fs 自动建父目录兜底);sandboxPolicy 缺失则插件写入不带显式围栏;compaction 缺失则 v4 的真实 /compact 路径与 v5 的真实压缩不生效(v5 回退到自述浓缩);sessionProjections 缺失则 v5 的研究所状态回退到加固 JSON 文件(权威源从会话日志投影变为 State/<institute>.v5state.json,跨进程恢复能力下降)。')
415
+ logger?.warn?.('[dsh-vibe-math] 可选宿主服务缺失,功能会静默降级(不影响挂载):' + degradations.join(';') + '。subprocess 缺失则无法用 shell 创建目录树(仅靠 fs 自动建父目录兜底);sandboxPolicy 缺失则插件写入不带显式围栏;compaction 缺失则 v4 的真实 /compact 路径与 v5 的真实压缩不生效(v5 回退到自述浓缩)')
363
416
  }
364
417
  if (problems.length > 0) {
365
- logger?.warn?.('[dsh-vibe-math] 宿主自检:' + problems.length + ' 项不满足(' + problems.join(';') + ')。v2/v3/v4/v5 预设依赖这些宿主服务/API,旧版或未经声明兼容的 DSH 可能无法挂载' + (dshVersion ? '(当前检测到 DSH v' + dshVersion + ',本包适配 ' + (supported.length ? supported.join(' / ') : '(未声明)') + ')' : '') + '。')
418
+ logger?.warn?.('[dsh-vibe-math] 宿主自检:' + problems.length + ' 项不满足(' + problems.join(';') + ')。v2/v3/v4/v5 预设依赖这些宿主服务/API,旧版或未经声明兼容的 DSH 可能无法挂载' + (dshVersion ? '(当前检测到 DSH v' + dshVersion + ',来源 ' + versionSource + ',本包适配 ' + (supported.length ? supported.join(' / ') : '(未声明)') + ')' : '') + '。')
366
419
  } else {
367
- logger?.info?.('[dsh-vibe-math] 宿主自检通过:subagents / agents / tools / commands / fs 服务及关键 API 均可用' + (degradations.length === 0 ? ',可选服务 subprocess / sandboxPolicy / compaction / sessionProjections / sessions 亦齐备' : '(可选服务有缺失,见上方警告)') + (dshVersion ? '(当前 DSH v' + dshVersion + ',本包已声明兼容 ' + supported.join(' / ') + ')' : '') + '。')
420
+ logger?.info?.('[dsh-vibe-math] 宿主自检通过:subagents / agents / tools / commands / fs 服务及关键 API 均可用' + (degradations.length === 0 ? ',可选服务 subprocess / sandboxPolicy / compaction 亦齐备' : '(可选服务有缺失,见上方警告)') + (dshVersion ? '(当前 DSH v' + dshVersion + ',来源 ' + versionSource + ';本包已声明兼容 ' + supported.join(' / ') + ')' : '') + '。')
368
421
  }
422
+ return { dshVersion, versionSource, mechanism }
369
423
  }
370
424
 
371
425
  export async function apply(ctx) {
@@ -376,6 +430,20 @@ export async function apply(ctx) {
376
430
  const presetRoot = join(dshHome, '.agent-presets')
377
431
  const stateFile = join(presetRoot, STATE_FILE)
378
432
 
433
+ // WHICH MECHANISM THIS HOST USES decides whether the directory work below means anything, so it
434
+ // is decided (and reported) before anything is written. The host self-check runs here too.
435
+ const host = await checkHostCapabilities(ctx, logger)
436
+ if (host && host.mechanism === 'rows') {
437
+ logger?.info?.('[dsh-vibe-math] preset 声明方式:本宿主以组合行声明 agent preset' +
438
+ (host.dshVersion ? '(DSH v' + host.dshVersion + ')' : '') + ',本包随附的 cordis.patch.yml 已声明四个 preset(dsh-vibe-math/preset-declaration);' +
439
+ '跳过 ' + presetRoot + ' 目录同步(该目录自 DSH 0.1.7 起不再被读取)。')
440
+ if (existsSync(stateFile)) {
441
+ logger?.info?.('[dsh-vibe-math] 提示:' + presetRoot + ' 里还留着旧版 DSH(≤ 0.1.6)读取过的 preset 副本,' +
442
+ '当前宿主不会再读它们,可以安全删除(要自定义 preset,请在预设选择器里复制一份,或改 profile 的 cordis.patch.yml)。')
443
+ }
444
+ return
445
+ }
446
+
379
447
  // current package version (the source of truth for "is this an upgrade?")
380
448
  let pkgVersion = ''
381
449
  try { pkgVersion = String((JSON.parse(readFileSync(join(here, 'package.json'), 'utf8')).version) || '') } catch (e) { pkgVersion = '' }
@@ -525,7 +593,7 @@ export async function apply(ctx) {
525
593
  logger?.info?.('[dsh-vibe-math] preset files untouched (v' + pkgVersion + ' unchanged): ' + kept +
526
594
  ' file(s) differ from the shipped copy; they will be replaced on the next version change (原件会先备份)')
527
595
  }
528
- await checkHostCapabilities(ctx, logger)
596
+ /* the host self-check ran at the top of apply() — it also decides the preset mechanism */
529
597
  } catch (err) {
530
598
  logger?.warn?.('[dsh-vibe-math] preset install/update failed: %s', String((err && err.message) || err))
531
599
  }