dsh-vibe-math 2.3.11 → 2.3.13
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.
- package/README.md +17 -40
- package/{AUDIT-CHECKLIST.md → docs/AUDIT-CHECKLIST.md} +323 -304
- package/docs/COMPAT-AUDIT-ROUND2.md +325 -0
- package/docs/generate_framework_diagram_v2.py +114 -0
- package/docs/generate_framework_diagram_v3.py +127 -0
- package/{RELEASE-NOTES-2.1.0.md → docs/release-notes/RELEASE-NOTES-2.1.0.md} +143 -143
- package/{RELEASE-NOTES-2.2.0.md → docs/release-notes/RELEASE-NOTES-2.2.0.md} +266 -266
- package/{RELEASE-NOTES-2.2.1.md → docs/release-notes/RELEASE-NOTES-2.2.1.md} +43 -43
- package/{RELEASE-NOTES-2.2.2.md → docs/release-notes/RELEASE-NOTES-2.2.2.md} +88 -88
- package/{RELEASE-NOTES-2.3.0.md → docs/release-notes/RELEASE-NOTES-2.3.0.md} +207 -207
- package/{RELEASE-NOTES-2.3.1.md → docs/release-notes/RELEASE-NOTES-2.3.1.md} +134 -134
- package/{RELEASE-NOTES-2.3.10.md → docs/release-notes/RELEASE-NOTES-2.3.10.md} +105 -105
- package/{RELEASE-NOTES-2.3.11.md → docs/release-notes/RELEASE-NOTES-2.3.11.md} +57 -57
- package/docs/release-notes/RELEASE-NOTES-2.3.12.md +80 -0
- package/docs/release-notes/RELEASE-NOTES-2.3.13.md +137 -0
- package/{RELEASE-NOTES-2.3.2.md → docs/release-notes/RELEASE-NOTES-2.3.2.md} +145 -145
- package/{RELEASE-NOTES-2.3.3.md → docs/release-notes/RELEASE-NOTES-2.3.3.md} +115 -115
- package/{RELEASE-NOTES-2.3.4.md → docs/release-notes/RELEASE-NOTES-2.3.4.md} +69 -69
- package/{RELEASE-NOTES-2.3.5.md → docs/release-notes/RELEASE-NOTES-2.3.5.md} +63 -63
- package/{RELEASE-NOTES-2.3.6.md → docs/release-notes/RELEASE-NOTES-2.3.6.md} +66 -66
- package/{RELEASE-NOTES-2.3.7.md → docs/release-notes/RELEASE-NOTES-2.3.7.md} +59 -59
- package/{RELEASE-NOTES-2.3.8.md → docs/release-notes/RELEASE-NOTES-2.3.8.md} +45 -45
- package/{RELEASE-NOTES-2.3.9.md → docs/release-notes/RELEASE-NOTES-2.3.9.md} +70 -70
- package/docs/test-timing.md +18 -17
- package/installer.js +258 -53
- package/package.json +50 -40
- package/{audit-formal-sensitivity.mjs → tests/audit-formal-sensitivity.mjs} +342 -342
- package/tests/audit-installer-compat.test.mjs +136 -0
- package/tests/audit-installer-policy.test.mjs +245 -0
- package/{audit-persona-sensitivity.mjs → tests/audit-persona-sensitivity.mjs} +249 -249
- package/{audit-persona-surface.test.mjs → tests/audit-persona-surface.test.mjs} +349 -349
- package/{audit-prompt-invariants.mjs → tests/audit-prompt-invariants.mjs} +508 -508
- package/{audit-spec-traceability.mjs → tests/audit-spec-traceability.mjs} +193 -193
- package/{audit-v5-integrity.mjs → tests/audit-v5-integrity.mjs} +448 -448
- package/{audit-v5-sensitivity.mjs → tests/audit-v5-sensitivity.mjs} +384 -384
- package/{e2e-v5-round2.test.mjs → tests/e2e-v5-round2.test.mjs} +521 -521
- package/{formal-verify-v2.test.mjs → tests/formal-verify-v2.test.mjs} +1315 -1315
- package/{formal-verify-v3.test.mjs → tests/formal-verify-v3.test.mjs} +1257 -1257
- package/{formal-verify-v4.test.mjs → tests/formal-verify-v4.test.mjs} +1082 -1082
- package/{formal-verify-v5.test.mjs → tests/formal-verify-v5.test.mjs} +708 -708
- package/{prompt-v5-integrity.test.mjs → tests/prompt-v5-integrity.test.mjs} +3 -3
- package/{run-tests.mjs → tests/run-tests.mjs} +121 -118
- package/{selfdrive-v5.mjs → tests/selfdrive-v5.mjs} +470 -470
- package/vibe-math-v4//345/256/236/347/216/260/346/226/271/346/241/210.md +1 -1
- package/vibe-math-v5//345/256/236/347/216/260/346/226/271/346/241/210.md +1 -1
- package/vibe-math-v5//346/236/266/346/236/204/345/233/276.md +1 -1
- package//347/244/272/344/276/213/345/233/276//345/256/236/351/231/205/344/275/277/347/224/250/347/244/272/344/276/213-/351/225/277/346/210/252/345/233/276.png +0 -0
- package//347/244/272/344/276/213/345/233/276//346/241/206/346/236/266/345/233/276-v2.png +0 -0
- package//347/244/272/344/276/213/345/233/276//346/241/206/346/236/266/345/233/276-v3.png +0 -0
- /package/{RELEASE-NOTES-2.0.22.md → docs/release-notes/RELEASE-NOTES-2.0.22.md} +0 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# dsh-vibe-math 2.3.12 — 安装器按 `engines.dsh` 判定宿主 + npm 页不再有裂图 + README 清理
|
|
2
|
+
|
|
3
|
+
> 上一版:2.3.11。三件收尾:① 安装器自检与市场读**同一个**声明;② npm 上 README 的图不再裂;
|
|
4
|
+
> ③ 目录条目文案按实际内容更新(第三方 PR)。另按你的要求删掉了上一版塞进 README 的"插件市场展示"一节。
|
|
5
|
+
> 无预设行为变更,四套预设字节未变。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. 安装器自检改为读 `engines.dsh`(单一事实源)
|
|
10
|
+
|
|
11
|
+
原来安装器按 `dsh.compatibility.dshReleases` 这张**本包自用的表**判断宿主版本,而市场卡片按
|
|
12
|
+
`engines.dsh` 判定——**两个来源可以互相矛盾**(卡片说兼容、日志却告警,或反之)。现在:
|
|
13
|
+
|
|
14
|
+
- `installer.js` 导出两个纯函数:`satisfiesDshRange(version, range, {includePrerelease})` 与
|
|
15
|
+
`dshVersionVerdict(version, manifest)`;
|
|
16
|
+
- 判定顺序:**`engines.dsh`**(顶层优先)→ **`dsh.engines.dsh`** → 都没有才回退到 `dshReleases` 表;
|
|
17
|
+
无法解析的范围返回 `unknown`(只提示、绝不判成 incompatible);
|
|
18
|
+
- 匹配器支持生态里真实出现的写法:`*`/`x`、精确、`^`、`~`、`>=`/`>`/`<=`/`<`、空格分隔的组合、`||` 分支,
|
|
19
|
+
并实现 npm 的**集合级预发布规则**(一个 `||` 分支为一个集合:只有集合里存在与宿主同
|
|
20
|
+
`major.minor.patch` 且自带预发布标签的比较符时,才放行预发布版本);
|
|
21
|
+
- **实测对齐**:用 npm 自带的 **semver 7.8.5** 逐项比对 **320** 组(范围 × 版本 × 两种预发布语义),
|
|
22
|
+
**0 处不一致**;`not-a-range`、`>=1.2`、`1.2.x` 等不支持写法一律返回 `null`(unknown,绝不误判)。
|
|
23
|
+
- 顺手修掉安装器头部注释的陈旧描述("copies ALL THREE agent presets … ships v2/v3/v4 only" →
|
|
24
|
+
四套,v5 自 2.1.0 起就在)。
|
|
25
|
+
|
|
26
|
+
新增随包套件 [`audit-installer-compat.test.mjs`](../../tests/audit-installer-compat.test.mjs)(**54 条断言**,进并行回归):
|
|
27
|
+
匹配器的期望值表(由 semver 7.8.5 生成)、不支持写法必须为 unknown、`dshVersionVerdict` 的优先级与回退、
|
|
28
|
+
以及**两个来源不许矛盾**——`dsh.compatibility` 里每个标 `compatible` 的版本都不得被 `engines.dsh` 判成 incompatible。
|
|
29
|
+
|
|
30
|
+
## 2. npm 页的 README 图不再裂
|
|
31
|
+
|
|
32
|
+
README 展示 5 张本地图,此前只有 v4/v5 的 SVG 随包发布,v2/v3 的 PNG 与实际使用示例长截图**不在 `files` 里**,
|
|
33
|
+
所以 npm 页一直是裂图。现在把 README 引用的**每一张**本地图都纳入 `files`:
|
|
34
|
+
|
|
35
|
+
| 新增随包 | 大小 |
|
|
36
|
+
|---|---|
|
|
37
|
+
| `示例图/框架图-v2.png` | ≈403 KB |
|
|
38
|
+
| `示例图/框架图-v3.png` | ≈559 KB |
|
|
39
|
+
| `示例图/实际使用示例-长截图.png` | ≈2.7 MB |
|
|
40
|
+
|
|
41
|
+
守卫也加了这条不变式:**README 里出现的每个本地图片路径都必须列在 `package.json` `files` 里**
|
|
42
|
+
(历史遗留条目"指向已删除的 v1 图"就是同一类腐烂),以后谁再引用未随包的图会直接判红。
|
|
43
|
+
(实测包体积 1.0 MB → **4.36 MB**(解包 8.89 MB,79 个文件)——若你不想背这张 2.7 MB 的长截图,
|
|
44
|
+
删掉 README 里那一行即可,守卫会要求同步从 `files` 移除。)
|
|
45
|
+
|
|
46
|
+
## 3. README 清理
|
|
47
|
+
|
|
48
|
+
按你的要求,删除了上一版新增的「🏪 插件市场(dsh-market / awesome-dsh-plugin)里的展示」整节
|
|
49
|
+
(那是维护者视角、与用户了解项目无关)。README 里现在没有任何市场/元数据相关内容;
|
|
50
|
+
这些声明仍由 `audit-market-metadata.test.mjs`(仓库级守卫,19 条断言)与发布说明守着。
|
|
51
|
+
|
|
52
|
+
## 4. 目录条目文案(第三方 PR)
|
|
53
|
+
|
|
54
|
+
条目 `data/plugins/ChongCyrus__Vibe-Mathematics.yml` 的描述仍是 v2 时代措辞(只描述一条流水线,
|
|
55
|
+
且把 preset 说成"附带品")。已按实际内容更新并发起 PR:
|
|
56
|
+
|
|
57
|
+
- **PR #5673**:https://github.com/awesome-dsh-plugin/awesome-dsh-plugin/pull/5673
|
|
58
|
+
- 只改我们这一条(1 file, +2/−2),en/zh 同步,无营销词;
|
|
59
|
+
- 分支基于**上游当前 `main`**(你的 fork 停在 2026-08-18、与上游有分叉且无法 fast-forward,
|
|
60
|
+
所以没有动 fork 的 main,只推了一个新分支)。
|
|
61
|
+
|
|
62
|
+
## 5. 验收
|
|
63
|
+
|
|
64
|
+
| 项 | 结果 |
|
|
65
|
+
|---|---|
|
|
66
|
+
| `audit-installer-compat.test.mjs` | **54/0** |
|
|
67
|
+
| `audit-market-metadata.test.mjs` | **19/0**(含"README 图片必须随包") |
|
|
68
|
+
| 匹配器 vs semver 7.8.5 | 320 组,**0 处不一致** |
|
|
69
|
+
| 其余静态守卫 | invariants 157/0(self-probe 5/5)、traceability 94/0、v5-integrity clean、persona-surface 197/0 |
|
|
70
|
+
| 全量并行回归 | **25/25** |
|
|
71
|
+
| closing verification | 18/18 |
|
|
72
|
+
| 发布产物自证 | registry tarball sha1 与本地一致 + 包内跑全部随包套件 |
|
|
73
|
+
|
|
74
|
+
## 6. 升级
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
npm i dsh-vibe-math@latest
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
无迁移;`off` 档行为与四套预设字节均未变。
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# dsh-vibe-math 2.3.13 — 仓库归档 + 安装器改为「版本一变就整体替换」(手改原文先备份)
|
|
2
|
+
|
|
3
|
+
> 上一版:2.3.12。本版**不改四套预设的任何代码/提示词字节**(预设行为与上一版逐字相同),
|
|
4
|
+
> 改的是仓库布局、安装器的更新策略、以及两处守卫。
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. 仓库根目录归档:68 个条目 → 18 个
|
|
9
|
+
|
|
10
|
+
只留下"包必须暴露在顶层"的东西:
|
|
11
|
+
|
|
12
|
+
| 留在根目录 | 为什么不能动 |
|
|
13
|
+
|---|---|
|
|
14
|
+
| `package.json` / `README.md` / `LICENSE` | npm 与 GitHub 的固定位置 |
|
|
15
|
+
| `cordis.patch.yml` | `package.json` 的 `dsh.bundle.patch` 指向它;DSH 靠它把安装器挂进 profile |
|
|
16
|
+
| `screenshots.json` | 插件市场规定它必须与 `package.json` 同级 |
|
|
17
|
+
| `installer.js` | bundle 的唯一插件行(`dsh-vibe-math/installer`),也是 `main` / `exports` |
|
|
18
|
+
| `.gitignore` | — |
|
|
19
|
+
|
|
20
|
+
其余 **59 个文件**按角色归档:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
tests/ 26 个 *.test.mjs + 7 个审计守卫 + 3 个人工探针 + 3 个自驱动记录器 + run-tests.mjs
|
|
24
|
+
docs/ AUDIT-CHECKLIST.md、COMPAT-AUDIT-ROUND2.md、架构图.md、formal-verification.md、
|
|
25
|
+
test-timing.md、4 个架构图生成器
|
|
26
|
+
docs/release-notes/ 18 份历史发布说明(本版 +1)
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
搬动过程中顺带修掉的问题(都是"搬完才看得见"或一直没人看的那一类):
|
|
30
|
+
|
|
31
|
+
1. **5 个硬编码绝对路径**(`D:/wd/vibemath开发/...`、`C:/Users/admin/...`):
|
|
32
|
+
`audit-corrupt-file-guard`、`audit-f1-compact-fix`、`audit-f2-filter-fix`、`audit-fuzz-helpers`、
|
|
33
|
+
`e2e-f1-agent-detach`。其中 **`audit-fuzz-helpers.mjs` 是随包发布的**——写死了作者机器的路径,
|
|
34
|
+
等于对任何用户都跑不了;`e2e-f1-agent-detach` 现在按 `npm root -g` 定位真实宿主包(并在找不到时
|
|
35
|
+
报出所有试过的路径)。
|
|
36
|
+
2. **5 条发布说明里的链接失效**:搬进 `docs/release-notes/` 后,原来按仓库根写的相对链接要上一层。
|
|
37
|
+
3. `README` 里 `` `../COMPAT-AUDIT-ROUND2.md` `` 指的是仓库**外面**——这个引用从来就没对过。
|
|
38
|
+
4. README 链接的 v2/v3 架构图生成器(`.py`)**从未随包发布** → npm 页上点开是 404;现已纳入 `files`。
|
|
39
|
+
5. `docs/test-timing.md`、`docs/AUDIT-CHECKLIST.md` 与各脚本头部的 `Run:` 命令行按新路径更新
|
|
40
|
+
(否则照抄命令就是"找不到文件")。
|
|
41
|
+
|
|
42
|
+
**"纯搬动"有测量为证**:每个套件在**改动前的检出**(临时 git worktree)与**改动后的检出**里各跑一遍,
|
|
43
|
+
把检出路径、`tests/` 这一段、临时目录、缓存串、随机 id 与耗时归一化之后**逐行比对**
|
|
44
|
+
(`_oneoff/layout-invariance.mjs`):**24/26 输出逐字节相同**,另外 2 个是本轮改过内容的文件
|
|
45
|
+
(新增两条链接断言的市场守卫、被改写路径的 v5 套件),**没有一个套件的输出与"套件住在哪里"有关**。
|
|
46
|
+
断言条数与归档前逐项一致;README 的 29 条本地链接与全仓 52 条相对链接 0 失效。
|
|
47
|
+
(顺带发现审计工具自身的盲区:`git ls-files` 默认会把中文路径 C 风格转义,于是 6 个中文名文档——
|
|
48
|
+
含四份 `实现方案.md` 与 `docs/架构图.md`——从来没被链接扫描看过;现已加 `-c core.quotepath=false`,
|
|
49
|
+
扫描面从 28 个 md 扩到 35 个、45 条链接扩到 52 条,仍为 0 失效。)
|
|
50
|
+
|
|
51
|
+
## 2. 安装器:版本一变就整体替换(含手改文件),并先备份原文
|
|
52
|
+
|
|
53
|
+
**旧策略**:版本升级时只替换"哈希与上次安装一致"的文件,你改过的文件被**永久保留**。
|
|
54
|
+
|
|
55
|
+
**新策略**:
|
|
56
|
+
|
|
57
|
+
- 记录里的版本与包版本**不一致**(或根本没有记录的老安装)→ **受管文件全部替换成随包字节,
|
|
58
|
+
不看它是否被改过**;
|
|
59
|
+
- **被替换的手改原文不会丢**:若磁盘上的字节不是"本安装器上次写入的字节",会先备份到
|
|
60
|
+
`<presetRoot>/.vibe-math-backup/<旧版本>/<preset>/<文件>`,并在日志里逐个列出;
|
|
61
|
+
- **同一个版本内不重写任何文件**(重启 DSH 不会改写 preset、也不会扰动它按 mtime 记的生成代际);
|
|
62
|
+
- **缺失文件随时补回**(任何版本);
|
|
63
|
+
- 本包不再发布的 preset 目录照旧清理(记录为"用户持有"的文件保留)。
|
|
64
|
+
|
|
65
|
+
**为什么改**:旧策略最危险之处是"静默的版本混合"。你改一个文件、包升级一次,得到的是
|
|
66
|
+
**一半旧版、一半新版**的 preset——它可能挂不上(`agent.cordis.yml` 与 `vibe-math-vN.js` 不同代),
|
|
67
|
+
也可能挂上了但行为与文档不符,而**从外面完全看不出来**,只能靠人去 diff 一个 5000 行的文件。
|
|
68
|
+
而且一旦被标记为"用户持有",那个文件就**永远不会**再更新,连你后来把它改回原样都不会恢复。
|
|
69
|
+
|
|
70
|
+
**如何正确自定义**:不要改受管文件。复制一份——预设选择器里的复制动作(DSH 的 `agentPresets/copy`),
|
|
71
|
+
或自行把目录复制成新的 id——那份副本属于你,随包更新不会碰它。
|
|
72
|
+
|
|
73
|
+
**发布前的复核又补了两处**(都是新代码自己审出来的):
|
|
74
|
+
|
|
75
|
+
1. **读不到版本时什么都不替换**:manifest 缺失/没有 `version` 字段时不再猜——本次只补回缺失文件、
|
|
76
|
+
并**保留上一次记录的版本号**(这样下次能读到时,日志里的"从哪个版本升级"仍然是对的、备份也落在
|
|
77
|
+
正确的版本目录下)。此前这种情况会被当成"同版本"而静默不动,现在会明确告警说明原因。
|
|
78
|
+
2. **备份报告不再误报失败**:同一版本目录下已存在备份时(例如升级被重跑),保留**最早那份**原文,
|
|
79
|
+
并且不再把它报成"备份失败(原文未保留)"——报错必须只说真话。
|
|
80
|
+
|
|
81
|
+
## 3. 新增与加固的守卫
|
|
82
|
+
|
|
83
|
+
| 守卫 | 变化 |
|
|
84
|
+
|---|---|
|
|
85
|
+
| `tests/audit-installer-policy.test.mjs` | **新增**(52 条断言,随包发布):在临时 DSH_HOME 里驱动真实 `apply()`,用"两个版本的临时包副本"证明基线安装 / 同版本不重写 / 版本一变即替换(且备份原文) / 缺失补回 / 旧 preset 清理 / 读不到版本时不动任何文件,并证明受管清单覆盖四套预设运行时需要的每个文件、备份目录名不会被 DSH 当成 preset |
|
|
86
|
+
| `tests/audit-market-metadata.test.mjs` | 19 → **21** 条:README 的**每一条本地链接**(不再只是图片)都必须真实存在**且**列在 `files` 里 |
|
|
87
|
+
| `final-verify.mjs` 打包阶段 | 把**每一个随包发布的守卫在解包出来的包里各跑一遍**(安装器策略套件还会在包内重新复制四个 preset,因此"`files` 漏了某个 preset 文件"会在打包阶段就红,而不是等到用户装上挂载失败) |
|
|
88
|
+
|
|
89
|
+
两个新增断言的灵敏度都实测过:`_oneoff/probe-installer-policy.mjs`(对着 2.3.12 的安装器 → **10 条**断言变红,
|
|
90
|
+
其中就有"版本一变,被改过的文件必须被替换")、`_oneoff/probe-market-link-guard.mjs`(README 里塞一条
|
|
91
|
+
死链接 / 塞一条"存在但不随包"的链接 → 分别命中对应断言,改回后逐字节还原)。
|
|
92
|
+
|
|
93
|
+
> **发布前复核还做了一次"引用闭合"审计**(`_oneoff/check-reference-closure.mjs`):`package.json` 的
|
|
94
|
+
> `main`/`exports`/`dsh.bundle.patch`/`files` 全部存在;35 个 markdown 的 52 条相对链接全部可解析;
|
|
95
|
+
> 文档与脚本头部的每一条 `node <路径>` 命令行都指向真实文件;代码里"确实写成路径"的字符串字面量
|
|
96
|
+
> (排除运行时工作区路径)无一悬空。反向检查顺带把 `docs/COMPAT-AUDIT-ROUND2.md` 纳入了 `files`
|
|
97
|
+
> ——README 正文点名让它"详见",不随包的话 npm 读者就打不开。
|
|
98
|
+
|
|
99
|
+
## 4. 附:为什么不用 DSH 自带的预设根目录(`agent-presets.roots`)
|
|
100
|
+
|
|
101
|
+
勘察结论(DSH 0.1.5-rc.2):**DSH 没有任何"插件包自带 preset 并自动安装"的机制**。
|
|
102
|
+
|
|
103
|
+
- `dsh plugin add` 只做两件事:在 profile 目录里跑 pnpm、把带 `dsh.bundle` 的依赖并进
|
|
104
|
+
`dsh.profile.bundles`(即 `cordis.patch.yml` 成为一个 patch 层)。它不读、也不安装 preset。
|
|
105
|
+
- `dsh.configTrees`(`@deepseek-ai/dsh-package-manifest` 里唯一像"包自带配置树"的字段)明确写着
|
|
106
|
+
"服务于实验性的镜像打包器……**声明它不会注册任何外部插件行为**"。
|
|
107
|
+
- 原生机制只有**根目录发现**:随包 `system` 根 + 部署配置的 `roots[]` + `$DSH_HOME/.agent-presets`(`user` 根,
|
|
108
|
+
也是唯一可写的)。也就是说,**第三方包面向用户的唯一手段就是写进那个可写根**——正是本安装器在做的事。
|
|
109
|
+
|
|
110
|
+
理论上可以用 patch 层给 `agent-presets` 行塞一个 `roots` 项指向包内目录,但代价与风险都不划算:
|
|
111
|
+
① 按 id 命中的 patch **整体替换**该行的 `config`,于是必须重述 `default` 等字段,等于覆盖部署的默认预设选择;
|
|
112
|
+
② `roots[].path` 在 `scanRoot` 里是 `resolve(expandHomePath(path))`,即**相对 cwd**,只能靠 `!!js` 表达式算出
|
|
113
|
+
绝对路径,脆弱;③ 本包声明的兼容范围是 0.1.2 → 0.1.5,早期版本的 schema 是否接受 `roots` 无从验证,
|
|
114
|
+
而一旦宿主拒绝这个 config,结果是**一个 preset 都装不上**。相比之下,`installer.js` 是一段自包含的复制逻辑,
|
|
115
|
+
只依赖 node 内置模块,任何声明兼容的宿主上都能工作。
|
|
116
|
+
|
|
117
|
+
## 5. 验收
|
|
118
|
+
|
|
119
|
+
| 项 | 2.3.12 | 2.3.13 |
|
|
120
|
+
|---|---|---|
|
|
121
|
+
| 仓库根目录条目 | 68(含 59 个散落文件) | **18**(7 文件 + 11 目录) |
|
|
122
|
+
| 全套件并行回归 | 25/25 | 25/25(断言条数逐项一致) |
|
|
123
|
+
| 布局不变性(改前 vs 改后逐行比对) | — | **25/25 输出相同** |
|
|
124
|
+
| 安装器策略套件 | — | **52/0**(+ 对旧策略 10 条变红的灵敏度探针) |
|
|
125
|
+
| 市场元数据守卫 | 19/0 | **21/0**(+ 2 条链接探针) |
|
|
126
|
+
| README 本地链接 | 29(其中 2 条点开 404) | 29(全部存在且随包) |
|
|
127
|
+
| 发布产物自证 | 通过 | 通过(并在包内跑 6 个随包守卫) |
|
|
128
|
+
|
|
129
|
+
## 6. 升级
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
npm i dsh-vibe-math@latest
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
升级后**重启 DSH**:安装器会把四个 preset 目录的受管文件整体换成 2.3.13 的字节——**包括你手改过的**,
|
|
136
|
+
被替换的手改原文在 `~/.dsh/.agent-presets/.vibe-math-backup/2.3.12/<preset>/`。
|
|
137
|
+
无迁移;参数、工具、提示词与预设行为均未变。
|
|
@@ -1,145 +1,145 @@
|
|
|
1
|
-
# dsh-vibe-math 2.3.2 — 四套深度审计:三处高危门禁缺陷 + 撤回语义统一 + 语料确定性
|
|
2
|
-
|
|
3
|
-
> 上一版:2.3.1。本版是**审计驱动**的修复版:对 v2/v3/v4/v5 各做了一轮逐架构深度审计
|
|
4
|
-
> (插件 + 套件 + 实现方案 + persona + 语料),并做了四个架构之间的**横向对照**。
|
|
5
|
-
> 无破坏性变更,默认仍为 `formalVerify: 'off'`。
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## 0. 三处高危缺陷(都会让"严格验证"失效或不可用)
|
|
10
|
-
|
|
11
|
-
| # | 架构 | 缺陷 | 后果 |
|
|
12
|
-
|---|---|---|---|
|
|
13
|
-
| 1 | **v3** | 四个 Lean 参数**根本没写进 `vibe_math_set_params` 的参数 schema**(该 schema 是 `additionalProperties:false`) | 遵守 schema 的 provider **拒绝这个调用** → 用户**永远无法开启**这个功能;而套件全绿,因为它直接调 handler、**绕过 schema** |
|
|
14
|
-
| 2 | **v2** | `require` 门禁**只读自己那一侧的 id**(`formalOf(rId)`),而代理用**对象 id** 归档、别名同步只更新**已存在**的键 | "归档了 passed、验证侧还没有记录"时门禁**永远搁置**;搁置本身又写下 `rId='none'`,于是**每轮重开一次辩论、对象永远无法定论**、其它对象被饿死 |
|
|
15
|
-
| 3 | **v4** | `formalSetRun` 硬编码 `status:'attempted'`,**把已验证对象的 `passed` 抹掉**(与自己的注释、规格、v2/v5 都矛盾) | 一次随手 `lean_run` 就让对象丢掉"已形式化":投票提示词**丢掉忠实性分支**,`require` 档对**已有绿色归档证明**的对象重新关门 |
|
|
16
|
-
|
|
17
|
-
另有一处**门禁旁路**(v2):`settleVerdict` 的「判断命题」转移在 v=0 时直接写
|
|
18
|
-
`布尔估计=0`/`已验证`/`优先级 never` 并压入 `正确概率:1` 条目,**完全不看门禁**——一个未形式化的
|
|
19
|
-
命题被侧面判为**假**且永久退出调度。已改为先过门禁。
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## 1. 撤回语义统一:**删除 → 复核 → 覆盖撤回说明**
|
|
24
|
-
|
|
25
|
-
2.3.1 只在 v5 做对了。本轮把同一语义推广到四套:撤回归档证明时
|
|
26
|
-
|
|
27
|
-
1. 先删(`subprocess` 可用时);
|
|
28
|
-
2. **用 fs 复核文件真的没了**;
|
|
29
|
-
3. 仍在(宿主没有 `subprocess`、shell 静默失败、权限问题)→ **就地覆盖为撤回说明**
|
|
30
|
-
(`-- 已撤回(<时间>):该形式化被认定与命题原文不一致。` + 指向保留的工作文件);
|
|
31
|
-
4. 公告**如实说明**发生了哪一种(删除 / 覆盖 / ⚠ 两者都失败,请不要把它当作该对象的证明)。
|
|
32
|
-
|
|
33
|
-
此外修掉了两处静默漏洞:v2 只从两个 id 收集 `proof`(别名归档的证明留在盘上);v2/v3/v4 用
|
|
34
|
-
`removeFile` 尽力删除且吞掉结果。
|
|
35
|
-
|
|
36
|
-
**同一类问题还有一处**:`lean_archive kind='proof'` 在**这次跑红**时曾保留 `prev.proof`
|
|
37
|
-
(而工作文件已被新代码覆盖)→ `Formal/Index.md` 会同时显示"attempted/fail"与一条**不再成立的**
|
|
38
|
-
`Verified/Lean/…`,忠实性提示词还会打印这个路径。四套统一为"`proof` 只属于 `passed`",并在跑红时
|
|
39
|
-
撤回旧的归档证明(v4 另外把"随手 `lean_run` 不许降级 passed"补回)。
|
|
40
|
-
|
|
41
|
-
---
|
|
42
|
-
|
|
43
|
-
## 2. 提示词/交互修复(逐条都有断言与探针)
|
|
44
|
-
|
|
45
|
-
| 修复 | 说明 |
|
|
46
|
-
|---|---|
|
|
47
|
-
| **按档位承诺**(四套) | 忠实性分支曾**无条件**宣称"本次裁定**不定论**",而只有 `require` 有门禁。现在 require 保留该承诺,encourage 明确写"**本档没有门禁**:请务必给弃权值,以保证本轮无法得出一致结论";defect 公告、TODO/Index 措辞同样按档位分叉 |
|
|
48
|
-
| **无工具链出路点名两个错误码**(四套) | 只写 `LEAN_NOT_FOUND` 时,遇到 `NO_SUBPROCESS`(宿主没有 subprocess 服务)的代理会当成未知失败而重试;现在两个都点出 |
|
|
49
|
-
| **失败提示要可执行**(v3) | `LEAN_NOT_FOUND`/`NO_SUBPROCESS`/`LEAN_SPAWN_FAILED` 没有编译器输出,却提示"按上面的编译器输出修复" → 改为按失败码给不同的出路 |
|
|
50
|
-
| **活动日志里的工具名**(v4) | 代理可读的日志里写着缩写 `lean_run` → 改为注册名 `vibe_v4_lean_run`;注入文本扫描现在也覆盖 `State/session.json` 的 `activityLog` |
|
|
51
|
-
| **路径指向真实位置**(v2) | 工作轮把可复用引理指向项目内的 `Formal/Proved/`——那是**不存在**的路径(全局库在项目树之外)→ 改为 `<VibeMath 根>/Formal/Proved/` |
|
|
52
|
-
| **红灯不许声称可复用**(v2) | `kind='def'/'lemma'` 跑红时工具返回值仍写"已并入全局可复用库,可直接 import 复用" |
|
|
53
|
-
| **`vibe_math_setup` 重复参数**(v3) | `plannerPersona` 出现两行 |
|
|
54
|
-
| **规格里的幽灵工具**(v4,由我的新审计发现) | `实现方案.md` 把 `vibe_v4_propose_verify(targetId)` 写成工具,而 v4 **没有**这个工具(真机制是回执字段 `propose_verify`) |
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
## 3. 语料确定性(契约 §10 要求"逐字节可 diff")
|
|
59
|
-
|
|
60
|
-
- **v5**:语料每跑一次都变。根因有三层:心跳/会议唤醒依赖**真实时钟**与异步顺序;捕捉心跳时
|
|
61
|
-
"最闲成员"随时间抖动;写入端**只按 kind 排序**,同 kind 内仍随 drain 顺序变化。
|
|
62
|
-
修法:套件加**虚拟时钟**(`ctx.timeout` 接虚拟队列、`sleep(n)` 推进虚拟时间)+心跳在
|
|
63
|
-
**单成员研究所**内捕捉+写入端**全序排序**(kind → owner → prompt)。
|
|
64
|
-
结果:**连跑 6 次哈希全同**,且套件 **7–9 s → 1.7 s**。
|
|
65
|
-
- **v3**:20 条 `planner:*` 条目带随机 plan id 与 epoch 时间戳 → scrub 归一化 + 断言。
|
|
66
|
-
- **v2/v4**:本已稳定;v4 的语料在套件运行中重生成并验证两次哈希一致。
|
|
67
|
-
- 五份语料(四个预设 + persona)现在都通过我的确定性检查(无绝对路径、无时间戳、可重复)。
|
|
68
|
-
|
|
69
|
-
---
|
|
70
|
-
|
|
71
|
-
## 4. 新增的常驻守卫(随包发布,可一键复核)
|
|
72
|
-
|
|
73
|
-
| 脚本 | 作用 |
|
|
74
|
-
|---|---|
|
|
75
|
-
| `audit-prompt-invariants.mjs` | 把历次**真实发生过的提示词/工具面缺陷类别**编码成四套 × 31 条静态不变式(缩写工具名 / "偏离→0" / `defect` 规则缺失或未实现 / 回执契约缺 `defect` / 无 note 放行 / 字段名错 / `off` 档回执未被门禁 / 语料不确定或缺档位 / 探针缺失 / 按档位承诺 / **封闭的 schema 收不下自己文档里的参数** / **schema 声明了、参数层却静默丢弃的键**)。**当前 145/0**,并带 `--self-probe`:在内存里注入这些缺陷形状,要求对应不变式**变红**、未变异的对照跑**仍为绿**(5/5) |
|
|
76
|
-
| `audit-spec-traceability.mjs` | 规格/README 承诺的工具必须真的注册(**能识别"文档里说它不存在"的否定语境**);四个 Lean 参数必须同时被文档与代码接受;契约 §7 的 `terminate()`;契约 §8 的**门禁收口点无旁路**(调用图检查)。**当前 91/0** |
|
|
77
|
-
| `run-tests.mjs` | 并行跑全部套件,打印每项耗时/加速比/最慢几项(本轮又修了 `--only x` 空格形式被静默忽略、`--json` 混入人类输出两个 bug) |
|
|
78
|
-
| `docs/test-timing.md` | 耗时基线 + 并行安全规则 + 虚拟时钟的适用条件(若套件用 `Date.now()` 做超时判据又用 `setInterval` 轮询,冻结时钟会让判据永不超时,必须连轮询定时器一起虚拟化) |
|
|
79
|
-
|
|
80
|
-
### 4.1 新增「工具参数 schema」守卫:文档写了 ≠ 工具收得下
|
|
81
|
-
|
|
82
|
-
本轮最贵的一处缺陷(v3 开不了档)暴露出一整类**既有测试全都盲**的漏洞:四个预设的工具 schema 都由
|
|
83
|
-
`objParams` 以 `additionalProperties:false` **关闭**,因此 schema 没列出的键会被任何遵守 schema 的
|
|
84
|
-
provider **直接拒绝**——可提示词/规格/状态行可以全都在说这个参数,套件也可以全绿(套件直接调 handler、
|
|
85
|
-
绕过 schema)。现在这层有了三重守卫:
|
|
86
|
-
|
|
87
|
-
1. 四套各自的 `formal-verify-vN.test.mjs` 直接检查**真实注册的** schema 对象:schema 必须仍是封闭的、
|
|
88
|
-
必须声明 `formalVerify`/`leanCommand`/`leanArgs`/`leanTimeoutMs`、`formalVerify` 的 enum 必须恰好是
|
|
89
|
-
三档(**已用探针证明**:把 v3 真实注册那一份里的 `leanArgs` 去掉,套件立刻变红);
|
|
90
|
-
2. `audit-prompt-invariants.mjs` 的 I13:**每一处** set 工具定义(v2/v3 有"会话 handler 表"与
|
|
91
|
-
"真实注册"两份)都必须声明这四个参数,且每一份 `objParams` 都必须关闭 schema;
|
|
92
|
-
3. 同脚本的 I14:schema **声明的每个键**都必须被参数层真正接收(v2/v3 的闸门是 `DEFAULT_PARAMS` 键集、
|
|
93
|
-
v4 是 `k in params`、v5 是 `normalizeParams` 的类型列表)——声明而不接收 = 调用返回 `{ok:true}`
|
|
94
|
-
而什么都不发生,是最容易被读成"设置成功"的静默失效。
|
|
95
|
-
|
|
96
|
-
`AUDIT-CHECKLIST.md` 新增 **§1.8「四套同构:任何语义修正必须四套同步」**——本轮三处高危里有两处正是
|
|
97
|
-
"改了一套、另三套没改"或"四套共用同一写法而没人横向对照"造成的。
|
|
98
|
-
|
|
99
|
-
---
|
|
100
|
-
|
|
101
|
-
## 5. 测试与探针(实测)
|
|
102
|
-
|
|
103
|
-
| 套件 | 2.3.1 | 2.3.2 |
|
|
104
|
-
|---|---|---|
|
|
105
|
-
| `formal-verify-v2.test.mjs` | 261 | **319** |
|
|
106
|
-
| `formal-verify-v3.test.mjs` | 247 | **283** |
|
|
107
|
-
| `formal-verify-v4.test.mjs` | 226 | **269** |
|
|
108
|
-
| `formal-verify-v5.test.mjs` | 120 | **145** |
|
|
109
|
-
| `prompt-v5-integrity.test.mjs` | 588 | **506**(语料去重:心跳只记 1 条)+ 虚拟时钟 |
|
|
110
|
-
| `e2e-v4-fixes.test.mjs` | 120 | 120(**修掉并行下的抖动**:T21 的会议看门狗 80 ms 在 CPU 争用下提前放弃会议) |
|
|
111
|
-
|
|
112
|
-
- 全量回归:**连续 3 次并行跑,23/23 全绿**(wall ≈111 s,最新一次实测 wall 111.5 s / sum 221.5 s / x1.99,
|
|
113
|
-
关键路径 `e2e-v4-fixes` 98.1 s);
|
|
114
|
-
- `audit-formal-sensitivity.mjs`:**49 条探针全部按预期变红,0 问题**;
|
|
115
|
-
- `audit-prompt-invariants.mjs`:**145/0**,`--self-probe` **5/5**;`audit-spec-traceability.mjs` **91/0**;
|
|
116
|
-
- `audit-persona-sensitivity.mjs`:11/11 变红;`audit-persona-surface.test.mjs` 197/0;
|
|
117
|
-
- `audit-v5-integrity.mjs` clean;四套 `audit-registration.mjs` 无重复/无缺失;
|
|
118
|
-
- 新增两条 **schema 级探针**:把 v3 真实注册的 schema 里 `leanArgs` 去掉 → v3 套件变红(已实测);
|
|
119
|
-
在 v4/v5 里造一个"声明但不接收"的参数 → `audit-prompt-invariants.mjs` 变红(已实测)。
|
|
120
|
-
|
|
121
|
-
---
|
|
122
|
-
|
|
123
|
-
## 6. 仍然存疑、需要人决定的政策问题(不是 bug,故未擅自改)
|
|
124
|
-
|
|
125
|
-
1. **跑红的 `kind='proof'` 是否应撤销旧证明**:本轮按"`proof` 只属于 `passed`"(契约 §4)统一四套;
|
|
126
|
-
若你认为"随手一次失败不该抹掉已证结论",应改**契约**而不是改代码。
|
|
127
|
-
2. **`off` 档"主动调用工具"算不算无操作**:契约 §2 明确工具仍可用,但那会写 `Formal/Index.md`/状态/公告;
|
|
128
|
-
四个审计都把它记为 policy call,现已在规格里澄清"off 约束的是**框架自身**,主动调用是显式行为"。
|
|
129
|
-
3. **`used` 回执的语义**:契约状态表字面写"→ attempted",而四套实现都**保留** `passed`/`blocked`
|
|
130
|
-
(否则每条"我用了它"的回执都会把 passed 打回 attempted 并重新关门)。建议改契约字面。
|
|
131
|
-
4. **v2 的 id 解析歧义(真实可达)**:`formalObjectIdOf` 把"对象 id 本身以 `-sN/-pfN/-rfN` 结尾"的
|
|
132
|
-
rId 解析错(`r-p-s1 → p`):这类命题的提示词/卡片会引用**另一个对象**的证明、门禁会被那个对象的
|
|
133
|
-
`passed` 放行。正确修法是**在记录里落权威 `objectId`**,但这要先把契约定下来。
|
|
134
|
-
5. **只剩"被门禁搁置"的对象时**:调度器会空转(不会卡死、不会误判终止)——契约没写这种局面该终止还是空转。
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
## 7. 升级
|
|
139
|
-
|
|
140
|
-
```
|
|
141
|
-
npm i dsh-vibe-math@latest
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
无迁移:新参数默认 `off`,四套既有行为与 `off` 一致。升级后重启 DSH;未被手动改过的 preset 文件
|
|
145
|
-
会自动更新。
|
|
1
|
+
# dsh-vibe-math 2.3.2 — 四套深度审计:三处高危门禁缺陷 + 撤回语义统一 + 语料确定性
|
|
2
|
+
|
|
3
|
+
> 上一版:2.3.1。本版是**审计驱动**的修复版:对 v2/v3/v4/v5 各做了一轮逐架构深度审计
|
|
4
|
+
> (插件 + 套件 + 实现方案 + persona + 语料),并做了四个架构之间的**横向对照**。
|
|
5
|
+
> 无破坏性变更,默认仍为 `formalVerify: 'off'`。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 0. 三处高危缺陷(都会让"严格验证"失效或不可用)
|
|
10
|
+
|
|
11
|
+
| # | 架构 | 缺陷 | 后果 |
|
|
12
|
+
|---|---|---|---|
|
|
13
|
+
| 1 | **v3** | 四个 Lean 参数**根本没写进 `vibe_math_set_params` 的参数 schema**(该 schema 是 `additionalProperties:false`) | 遵守 schema 的 provider **拒绝这个调用** → 用户**永远无法开启**这个功能;而套件全绿,因为它直接调 handler、**绕过 schema** |
|
|
14
|
+
| 2 | **v2** | `require` 门禁**只读自己那一侧的 id**(`formalOf(rId)`),而代理用**对象 id** 归档、别名同步只更新**已存在**的键 | "归档了 passed、验证侧还没有记录"时门禁**永远搁置**;搁置本身又写下 `rId='none'`,于是**每轮重开一次辩论、对象永远无法定论**、其它对象被饿死 |
|
|
15
|
+
| 3 | **v4** | `formalSetRun` 硬编码 `status:'attempted'`,**把已验证对象的 `passed` 抹掉**(与自己的注释、规格、v2/v5 都矛盾) | 一次随手 `lean_run` 就让对象丢掉"已形式化":投票提示词**丢掉忠实性分支**,`require` 档对**已有绿色归档证明**的对象重新关门 |
|
|
16
|
+
|
|
17
|
+
另有一处**门禁旁路**(v2):`settleVerdict` 的「判断命题」转移在 v=0 时直接写
|
|
18
|
+
`布尔估计=0`/`已验证`/`优先级 never` 并压入 `正确概率:1` 条目,**完全不看门禁**——一个未形式化的
|
|
19
|
+
命题被侧面判为**假**且永久退出调度。已改为先过门禁。
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 1. 撤回语义统一:**删除 → 复核 → 覆盖撤回说明**
|
|
24
|
+
|
|
25
|
+
2.3.1 只在 v5 做对了。本轮把同一语义推广到四套:撤回归档证明时
|
|
26
|
+
|
|
27
|
+
1. 先删(`subprocess` 可用时);
|
|
28
|
+
2. **用 fs 复核文件真的没了**;
|
|
29
|
+
3. 仍在(宿主没有 `subprocess`、shell 静默失败、权限问题)→ **就地覆盖为撤回说明**
|
|
30
|
+
(`-- 已撤回(<时间>):该形式化被认定与命题原文不一致。` + 指向保留的工作文件);
|
|
31
|
+
4. 公告**如实说明**发生了哪一种(删除 / 覆盖 / ⚠ 两者都失败,请不要把它当作该对象的证明)。
|
|
32
|
+
|
|
33
|
+
此外修掉了两处静默漏洞:v2 只从两个 id 收集 `proof`(别名归档的证明留在盘上);v2/v3/v4 用
|
|
34
|
+
`removeFile` 尽力删除且吞掉结果。
|
|
35
|
+
|
|
36
|
+
**同一类问题还有一处**:`lean_archive kind='proof'` 在**这次跑红**时曾保留 `prev.proof`
|
|
37
|
+
(而工作文件已被新代码覆盖)→ `Formal/Index.md` 会同时显示"attempted/fail"与一条**不再成立的**
|
|
38
|
+
`Verified/Lean/…`,忠实性提示词还会打印这个路径。四套统一为"`proof` 只属于 `passed`",并在跑红时
|
|
39
|
+
撤回旧的归档证明(v4 另外把"随手 `lean_run` 不许降级 passed"补回)。
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 2. 提示词/交互修复(逐条都有断言与探针)
|
|
44
|
+
|
|
45
|
+
| 修复 | 说明 |
|
|
46
|
+
|---|---|
|
|
47
|
+
| **按档位承诺**(四套) | 忠实性分支曾**无条件**宣称"本次裁定**不定论**",而只有 `require` 有门禁。现在 require 保留该承诺,encourage 明确写"**本档没有门禁**:请务必给弃权值,以保证本轮无法得出一致结论";defect 公告、TODO/Index 措辞同样按档位分叉 |
|
|
48
|
+
| **无工具链出路点名两个错误码**(四套) | 只写 `LEAN_NOT_FOUND` 时,遇到 `NO_SUBPROCESS`(宿主没有 subprocess 服务)的代理会当成未知失败而重试;现在两个都点出 |
|
|
49
|
+
| **失败提示要可执行**(v3) | `LEAN_NOT_FOUND`/`NO_SUBPROCESS`/`LEAN_SPAWN_FAILED` 没有编译器输出,却提示"按上面的编译器输出修复" → 改为按失败码给不同的出路 |
|
|
50
|
+
| **活动日志里的工具名**(v4) | 代理可读的日志里写着缩写 `lean_run` → 改为注册名 `vibe_v4_lean_run`;注入文本扫描现在也覆盖 `State/session.json` 的 `activityLog` |
|
|
51
|
+
| **路径指向真实位置**(v2) | 工作轮把可复用引理指向项目内的 `Formal/Proved/`——那是**不存在**的路径(全局库在项目树之外)→ 改为 `<VibeMath 根>/Formal/Proved/` |
|
|
52
|
+
| **红灯不许声称可复用**(v2) | `kind='def'/'lemma'` 跑红时工具返回值仍写"已并入全局可复用库,可直接 import 复用" |
|
|
53
|
+
| **`vibe_math_setup` 重复参数**(v3) | `plannerPersona` 出现两行 |
|
|
54
|
+
| **规格里的幽灵工具**(v4,由我的新审计发现) | `实现方案.md` 把 `vibe_v4_propose_verify(targetId)` 写成工具,而 v4 **没有**这个工具(真机制是回执字段 `propose_verify`) |
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## 3. 语料确定性(契约 §10 要求"逐字节可 diff")
|
|
59
|
+
|
|
60
|
+
- **v5**:语料每跑一次都变。根因有三层:心跳/会议唤醒依赖**真实时钟**与异步顺序;捕捉心跳时
|
|
61
|
+
"最闲成员"随时间抖动;写入端**只按 kind 排序**,同 kind 内仍随 drain 顺序变化。
|
|
62
|
+
修法:套件加**虚拟时钟**(`ctx.timeout` 接虚拟队列、`sleep(n)` 推进虚拟时间)+心跳在
|
|
63
|
+
**单成员研究所**内捕捉+写入端**全序排序**(kind → owner → prompt)。
|
|
64
|
+
结果:**连跑 6 次哈希全同**,且套件 **7–9 s → 1.7 s**。
|
|
65
|
+
- **v3**:20 条 `planner:*` 条目带随机 plan id 与 epoch 时间戳 → scrub 归一化 + 断言。
|
|
66
|
+
- **v2/v4**:本已稳定;v4 的语料在套件运行中重生成并验证两次哈希一致。
|
|
67
|
+
- 五份语料(四个预设 + persona)现在都通过我的确定性检查(无绝对路径、无时间戳、可重复)。
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 4. 新增的常驻守卫(随包发布,可一键复核)
|
|
72
|
+
|
|
73
|
+
| 脚本 | 作用 |
|
|
74
|
+
|---|---|
|
|
75
|
+
| `audit-prompt-invariants.mjs` | 把历次**真实发生过的提示词/工具面缺陷类别**编码成四套 × 31 条静态不变式(缩写工具名 / "偏离→0" / `defect` 规则缺失或未实现 / 回执契约缺 `defect` / 无 note 放行 / 字段名错 / `off` 档回执未被门禁 / 语料不确定或缺档位 / 探针缺失 / 按档位承诺 / **封闭的 schema 收不下自己文档里的参数** / **schema 声明了、参数层却静默丢弃的键**)。**当前 145/0**,并带 `--self-probe`:在内存里注入这些缺陷形状,要求对应不变式**变红**、未变异的对照跑**仍为绿**(5/5) |
|
|
76
|
+
| `audit-spec-traceability.mjs` | 规格/README 承诺的工具必须真的注册(**能识别"文档里说它不存在"的否定语境**);四个 Lean 参数必须同时被文档与代码接受;契约 §7 的 `terminate()`;契约 §8 的**门禁收口点无旁路**(调用图检查)。**当前 91/0** |
|
|
77
|
+
| `run-tests.mjs` | 并行跑全部套件,打印每项耗时/加速比/最慢几项(本轮又修了 `--only x` 空格形式被静默忽略、`--json` 混入人类输出两个 bug) |
|
|
78
|
+
| `docs/test-timing.md` | 耗时基线 + 并行安全规则 + 虚拟时钟的适用条件(若套件用 `Date.now()` 做超时判据又用 `setInterval` 轮询,冻结时钟会让判据永不超时,必须连轮询定时器一起虚拟化) |
|
|
79
|
+
|
|
80
|
+
### 4.1 新增「工具参数 schema」守卫:文档写了 ≠ 工具收得下
|
|
81
|
+
|
|
82
|
+
本轮最贵的一处缺陷(v3 开不了档)暴露出一整类**既有测试全都盲**的漏洞:四个预设的工具 schema 都由
|
|
83
|
+
`objParams` 以 `additionalProperties:false` **关闭**,因此 schema 没列出的键会被任何遵守 schema 的
|
|
84
|
+
provider **直接拒绝**——可提示词/规格/状态行可以全都在说这个参数,套件也可以全绿(套件直接调 handler、
|
|
85
|
+
绕过 schema)。现在这层有了三重守卫:
|
|
86
|
+
|
|
87
|
+
1. 四套各自的 `formal-verify-vN.test.mjs` 直接检查**真实注册的** schema 对象:schema 必须仍是封闭的、
|
|
88
|
+
必须声明 `formalVerify`/`leanCommand`/`leanArgs`/`leanTimeoutMs`、`formalVerify` 的 enum 必须恰好是
|
|
89
|
+
三档(**已用探针证明**:把 v3 真实注册那一份里的 `leanArgs` 去掉,套件立刻变红);
|
|
90
|
+
2. `audit-prompt-invariants.mjs` 的 I13:**每一处** set 工具定义(v2/v3 有"会话 handler 表"与
|
|
91
|
+
"真实注册"两份)都必须声明这四个参数,且每一份 `objParams` 都必须关闭 schema;
|
|
92
|
+
3. 同脚本的 I14:schema **声明的每个键**都必须被参数层真正接收(v2/v3 的闸门是 `DEFAULT_PARAMS` 键集、
|
|
93
|
+
v4 是 `k in params`、v5 是 `normalizeParams` 的类型列表)——声明而不接收 = 调用返回 `{ok:true}`
|
|
94
|
+
而什么都不发生,是最容易被读成"设置成功"的静默失效。
|
|
95
|
+
|
|
96
|
+
`AUDIT-CHECKLIST.md` 新增 **§1.8「四套同构:任何语义修正必须四套同步」**——本轮三处高危里有两处正是
|
|
97
|
+
"改了一套、另三套没改"或"四套共用同一写法而没人横向对照"造成的。
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## 5. 测试与探针(实测)
|
|
102
|
+
|
|
103
|
+
| 套件 | 2.3.1 | 2.3.2 |
|
|
104
|
+
|---|---|---|
|
|
105
|
+
| `formal-verify-v2.test.mjs` | 261 | **319** |
|
|
106
|
+
| `formal-verify-v3.test.mjs` | 247 | **283** |
|
|
107
|
+
| `formal-verify-v4.test.mjs` | 226 | **269** |
|
|
108
|
+
| `formal-verify-v5.test.mjs` | 120 | **145** |
|
|
109
|
+
| `prompt-v5-integrity.test.mjs` | 588 | **506**(语料去重:心跳只记 1 条)+ 虚拟时钟 |
|
|
110
|
+
| `e2e-v4-fixes.test.mjs` | 120 | 120(**修掉并行下的抖动**:T21 的会议看门狗 80 ms 在 CPU 争用下提前放弃会议) |
|
|
111
|
+
|
|
112
|
+
- 全量回归:**连续 3 次并行跑,23/23 全绿**(wall ≈111 s,最新一次实测 wall 111.5 s / sum 221.5 s / x1.99,
|
|
113
|
+
关键路径 `e2e-v4-fixes` 98.1 s);
|
|
114
|
+
- `audit-formal-sensitivity.mjs`:**49 条探针全部按预期变红,0 问题**;
|
|
115
|
+
- `audit-prompt-invariants.mjs`:**145/0**,`--self-probe` **5/5**;`audit-spec-traceability.mjs` **91/0**;
|
|
116
|
+
- `audit-persona-sensitivity.mjs`:11/11 变红;`audit-persona-surface.test.mjs` 197/0;
|
|
117
|
+
- `audit-v5-integrity.mjs` clean;四套 `audit-registration.mjs` 无重复/无缺失;
|
|
118
|
+
- 新增两条 **schema 级探针**:把 v3 真实注册的 schema 里 `leanArgs` 去掉 → v3 套件变红(已实测);
|
|
119
|
+
在 v4/v5 里造一个"声明但不接收"的参数 → `audit-prompt-invariants.mjs` 变红(已实测)。
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 6. 仍然存疑、需要人决定的政策问题(不是 bug,故未擅自改)
|
|
124
|
+
|
|
125
|
+
1. **跑红的 `kind='proof'` 是否应撤销旧证明**:本轮按"`proof` 只属于 `passed`"(契约 §4)统一四套;
|
|
126
|
+
若你认为"随手一次失败不该抹掉已证结论",应改**契约**而不是改代码。
|
|
127
|
+
2. **`off` 档"主动调用工具"算不算无操作**:契约 §2 明确工具仍可用,但那会写 `Formal/Index.md`/状态/公告;
|
|
128
|
+
四个审计都把它记为 policy call,现已在规格里澄清"off 约束的是**框架自身**,主动调用是显式行为"。
|
|
129
|
+
3. **`used` 回执的语义**:契约状态表字面写"→ attempted",而四套实现都**保留** `passed`/`blocked`
|
|
130
|
+
(否则每条"我用了它"的回执都会把 passed 打回 attempted 并重新关门)。建议改契约字面。
|
|
131
|
+
4. **v2 的 id 解析歧义(真实可达)**:`formalObjectIdOf` 把"对象 id 本身以 `-sN/-pfN/-rfN` 结尾"的
|
|
132
|
+
rId 解析错(`r-p-s1 → p`):这类命题的提示词/卡片会引用**另一个对象**的证明、门禁会被那个对象的
|
|
133
|
+
`passed` 放行。正确修法是**在记录里落权威 `objectId`**,但这要先把契约定下来。
|
|
134
|
+
5. **只剩"被门禁搁置"的对象时**:调度器会空转(不会卡死、不会误判终止)——契约没写这种局面该终止还是空转。
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## 7. 升级
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
npm i dsh-vibe-math@latest
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
无迁移:新参数默认 `off`,四套既有行为与 `off` 一致。升级后重启 DSH;未被手动改过的 preset 文件
|
|
145
|
+
会自动更新。
|