dsh-vibe-math 2.3.12 → 2.3.14
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 -13
- package/cordis.patch.yml +1 -1
- 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/{RELEASE-NOTES-2.3.12.md → docs/release-notes/RELEASE-NOTES-2.3.12.md} +80 -80
- package/docs/release-notes/RELEASE-NOTES-2.3.13.md +137 -0
- package/docs/release-notes/RELEASE-NOTES-2.3.14.md +83 -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 +19 -18
- package/installer.js +115 -41
- package/package.json +43 -37
- package/{audit-formal-sensitivity.mjs → tests/audit-formal-sensitivity.mjs} +342 -342
- package/{audit-installer-compat.test.mjs → tests/audit-installer-compat.test.mjs} +136 -136
- package/tests/audit-installer-policy.test.mjs +261 -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/{RELEASE-NOTES-2.0.22.md → docs/release-notes/RELEASE-NOTES-2.0.22.md} +0 -0
|
@@ -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
|
+
会自动更新。
|
|
@@ -1,115 +1,115 @@
|
|
|
1
|
-
# dsh-vibe-math 2.3.3 — 确认轮审计:`used` 回执曾撤销已成立的证明(v2)+ 契约字面纠错 + 守卫自身加固
|
|
2
|
-
|
|
3
|
-
> 上一版:2.3.2。本版是 2.3.2 之后的**确认轮**(round 3)结果:重新审计本轮改动过的每一处
|
|
4
|
-
> (四套插件、四套套件、共享契约、审计脚本自身),又抓到一处**真实缺陷**、一处**契约与实现字面
|
|
5
|
-
> 相反**、以及一处**守卫自身的脆弱点**。无破坏性变更,默认仍为 `formalVerify: 'off'`。
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## 1. 真实缺陷:一次 `used` 回执会**撤销已成立的证明**(只有 v2)
|
|
10
|
-
|
|
11
|
-
`formal.decision='used'` 的语义是"这一轮碰了形式化 / 写了一份草稿"。契约 §4 里**只有 `defect`
|
|
12
|
-
能撤销证明**,因为撤销意味着审查对象从"忠实性"退回"推导是否正确"、`require` 档对一份**已经跑通的
|
|
13
|
-
归档证明重新关门**。
|
|
14
|
-
|
|
15
|
-
| 架构 | `used` 回执对已有 `passed`/`blocked` 的处理(修复前) |
|
|
16
|
-
|---|---|
|
|
17
|
-
| v3 / v4 / v5 | 保留 `passed`(v3 只保留 passed,`blocked` 会被打回 attempted——见 §2) |
|
|
18
|
-
| **v2** | **无条件写 `status:'attempted'`** —— 而降级发生在**两个 id 空间**上,`proof` 指针还留着,记录自相矛盾 |
|
|
19
|
-
|
|
20
|
-
后果链(实测):对象已 `passed` → 表决者回一句"我这轮又写了遍草稿" → 记录降级为 `attempted`、
|
|
21
|
-
`status.formal.objects` 里不再是 `passed` → 后续审查提示词**丢掉忠实性分支** → `require` 档对一份
|
|
22
|
-
跑通的证明**重新关门**、对象被丢进「形式化待办」。
|
|
23
|
-
|
|
24
|
-
> 这正是 2.3.2 修过的 v4 `formalSetRun` 缺陷的**同一类**("随手一次动作把 passed 抹掉"),
|
|
25
|
-
> 只是长在另一条路径(回执通道)上,而且**只长在一套里**——`AUDIT-CHECKLIST §1.8`(四套同构)
|
|
26
|
-
> 记的就是这种形态。
|
|
27
|
-
|
|
28
|
-
**修复**:v2 的 `used` 分支改为先看**两套 id 空间**的状态(对象侧自己的记录 + `formalGateRecord` 的合并
|
|
29
|
-
视图),取其中**最强**的一个(`passed` > `blocked` > `attempted`):只有两侧都还没尝试过才写 `attempted`,
|
|
30
|
-
否则保留原状态并在活动日志里说明保留了哪一个。四套现在**同构**(v3 另外补上 `blocked` 的保留,见 §2)。
|
|
31
|
-
|
|
32
|
-
## 2. 同一类的第二处:v3 的 `used` 只保留 `passed`,会把 `blocked` 打回 attempted
|
|
33
|
-
|
|
34
|
-
`blocked` 是**门禁已放行**的记录(契约 §4/§8)。v3 的条件写成 `prev.status === 'passed' ? 'passed' : 'attempted'`:
|
|
35
|
-
一个已经用"显式阻塞原因"打开门禁的对象,被一句 `used` 回执打回 `attempted`,门禁**重新关上**。
|
|
36
|
-
已改为 `passed`/`blocked` 都保留(与 v2/v4/v5 一致)。
|
|
37
|
-
|
|
38
|
-
## 3. 契约字面与实现相反(三处)
|
|
39
|
-
|
|
40
|
-
`docs/formal-verification.md` §4 的迁移表是四套的规范来源,但它有两行写错了(代码是对的):
|
|
41
|
-
|
|
42
|
-
| 行 | 原字面 | 现字面 |
|
|
43
|
-
|---|---|---|
|
|
44
|
-
| `formal:{decision:'used'}` | → `attempted` | → `attempted`;**若已是 `passed`/`blocked` 则保持原状**(撤销只有 `defect` 一条路) |
|
|
45
|
-
| `lean_run` 成功/失败 | → `attempted` | 同样**不降级**已成立的 `passed`/`blocked` |
|
|
46
|
-
| (新增)`lean_archive{kind:'proof'}` + **运行失败** | 未写 | → `attempted`、清空 `proof`、并**撤回**旧的归档证明(工作文件刚被覆盖,旧证明不再对应任何代码) |
|
|
47
|
-
|
|
48
|
-
四套的 `实现方案.md` 与 v5 规格里的对应句子同步改正。规范文档写反最危险的地方在于:**下一次修改是
|
|
49
|
-
照它写的**(2.3.2 修好 `used` 之后,如果只读契约就会把修复改回去)。
|
|
50
|
-
|
|
51
|
-
## 4. 守卫自身的脆弱点:注释扫描器不认正则字面量
|
|
52
|
-
|
|
53
|
-
`audit-prompt-invariants.mjs` 的 I1/I13/I14 都建立在"先把注释抹掉、再检查剩下的代码"之上。四个预设里
|
|
54
|
-
都有 `/[\\/:*?"<>|\u0000-\u001f]+/` —— **字符类里含一个双引号**。原扫描器把那个引号当成字符串开头,
|
|
55
|
-
此后整个文件的词法状态就是错的。实测差异:
|
|
56
|
-
|
|
57
|
-
| 预设 | 两种扫描器**逐行不同**的行数 | 典型后果 |
|
|
58
|
-
|---|---|---|
|
|
59
|
-
| v2 | 190 行 | 真实代码行(如 `const abs = …`)被当成注释**抹掉** → 真缺陷可能被漏看 |
|
|
60
|
-
| v3 | 159 行 | 同上 |
|
|
61
|
-
| v4 | 14 行 | 注释被当成代码 → 反模式写进注释就会**误报** |
|
|
62
|
-
| v5 | 121 行 | 同上 |
|
|
63
|
-
|
|
64
|
-
本轮给扫描器加了**正则字面量**支持(含字符类 `[...]`、转义、结尾 flags),并把"守卫的守卫"写成
|
|
65
|
-
**X5–X7 三条自检**(放进 `audit-prompt-invariants.mjs`,任何一次运行都会执行):正则里的引号不得吞掉
|
|
66
|
-
后面的注释、字符串里的 `//`(URL)不得被当成注释、转义斜杠不得提前结束正则,且三者都必须保持行结构。
|
|
67
|
-
实测修复前 X5 变红、修复后全绿。
|
|
68
|
-
|
|
69
|
-
## 5. 本轮新增的行为断言(四套同构,+42 条;另 +6 不变式 / +3 可追溯)
|
|
70
|
-
|
|
71
|
-
| 断言(四套各一份) | 说明 |
|
|
72
|
-
|---|---|
|
|
73
|
-
| `used` 回执**不得**降级已 `passed` 对象 | 记录与 `proof` 指针都保留;v2 修复前**实测变红**(`got attempted`),修复后全绿 |
|
|
74
|
-
| `used` 回执**不得**把 `blocked` 打回 `attempted`(门禁不得被重新关上) | v3 修复前变红 |
|
|
75
|
-
| 一次普通 `lean_run`(带 `target`)**不得**降级 `passed` | 此前只有 v4 套件有这条断言,现四套齐备 |
|
|
76
|
-
| `used` 之后 `require` 门禁**仍然放行** | v2:把该轮驱动到一致为真,断言**没有**产生 `formal-required` 待办 |
|
|
77
|
-
| 真实注册的 schema 必须仍是封闭的、且四个 Lean 参数齐全(2.3.2 的守卫) | 四套各 7 条 |
|
|
78
|
-
|
|
79
|
-
## 5.1 并行回归暴露的**测试脆弱性**(也一并修掉)
|
|
80
|
-
|
|
81
|
-
4 路并行回归第二次跑时 `e2e-v4-fixes` **崩了**(exit 1,只跑了 2 个用例就中止);单独跑 3 次全绿
|
|
82
|
-
(120/120)。形态:驱动循环"安静即停"在框架把卡片落盘**之前**退出 → `assert(existsSync(card))`
|
|
83
|
-
只记录失败**不抛** → 紧随其后的 `readFileSync(card)` 抛 `ENOENT` → **未捕获异常让整个套件中止,
|
|
84
|
-
后面 12 个用例的断言全部丢失**。
|
|
85
|
-
|
|
86
|
-
修法(两条一起):该套件新增 `readArtifact(p, ms=3000)`(先等产物、再防御性读),并把六处"断言后立刻
|
|
87
|
-
读产物"改成"先等产物 → 再断言 → 防御性读"。效果:慢机器上产物晚到 3 秒也能通过;真没写出来则是
|
|
88
|
-
**一条干净的断言失败**,不再吞掉后续用例。这条已写进 `AUDIT-CHECKLIST` §4(连同"发布元数据交给
|
|
89
|
-
序列化器、不要用字符串替换手写 `package.json`"——本轮就这么写出过一次非法 JSON)。
|
|
90
|
-
|
|
91
|
-
## 6. 验收(实测)
|
|
92
|
-
|
|
93
|
-
| 套件 / 脚本 | 2.3.2 | 2.3.3 |
|
|
94
|
-
|---|---|---|
|
|
95
|
-
| `formal-verify-v2.test.mjs` | 319 | **334** |
|
|
96
|
-
| `formal-verify-v3.test.mjs` | 283 | **294** |
|
|
97
|
-
| `formal-verify-v4.test.mjs` | 269 | **277** |
|
|
98
|
-
| `formal-verify-v5.test.mjs` | 145 | **153** |
|
|
99
|
-
| `audit-prompt-invariants.mjs` | 145 | **151**(+ X5–X7 扫描器自检及其行结构断言) |
|
|
100
|
-
| `audit-spec-traceability.mjs` | 91 | **94**(契约 §4 三行的字面校验) |
|
|
101
|
-
| `audit-prompt-invariants.mjs --self-probe` | 5/5 | **5/5** |
|
|
102
|
-
| `prompt-v5-integrity.test.mjs` | 506 | 506(语料字节稳定) |
|
|
103
|
-
| `audit-persona-surface.test.mjs` | 197 | 197 |
|
|
104
|
-
|
|
105
|
-
- 全量并行回归 23/23 全绿;49 条 formal 探针全红;四套语料(v2/v3/v4/v5 + persona)连续两次哈希一致;
|
|
106
|
-
- closing verification:**18/18 阶段通过**。
|
|
107
|
-
|
|
108
|
-
## 7. 升级
|
|
109
|
-
|
|
110
|
-
```
|
|
111
|
-
npm i dsh-vibe-math@latest
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
无迁移。新参数默认 `off`,四套在 `off` 档的行为与 2.3.2 完全一致;本版改动只影响
|
|
115
|
-
`formalVerify` 非 `off` 时的记账语义(且都是"少撤销、不误关门"方向)。
|
|
1
|
+
# dsh-vibe-math 2.3.3 — 确认轮审计:`used` 回执曾撤销已成立的证明(v2)+ 契约字面纠错 + 守卫自身加固
|
|
2
|
+
|
|
3
|
+
> 上一版:2.3.2。本版是 2.3.2 之后的**确认轮**(round 3)结果:重新审计本轮改动过的每一处
|
|
4
|
+
> (四套插件、四套套件、共享契约、审计脚本自身),又抓到一处**真实缺陷**、一处**契约与实现字面
|
|
5
|
+
> 相反**、以及一处**守卫自身的脆弱点**。无破坏性变更,默认仍为 `formalVerify: 'off'`。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. 真实缺陷:一次 `used` 回执会**撤销已成立的证明**(只有 v2)
|
|
10
|
+
|
|
11
|
+
`formal.decision='used'` 的语义是"这一轮碰了形式化 / 写了一份草稿"。契约 §4 里**只有 `defect`
|
|
12
|
+
能撤销证明**,因为撤销意味着审查对象从"忠实性"退回"推导是否正确"、`require` 档对一份**已经跑通的
|
|
13
|
+
归档证明重新关门**。
|
|
14
|
+
|
|
15
|
+
| 架构 | `used` 回执对已有 `passed`/`blocked` 的处理(修复前) |
|
|
16
|
+
|---|---|
|
|
17
|
+
| v3 / v4 / v5 | 保留 `passed`(v3 只保留 passed,`blocked` 会被打回 attempted——见 §2) |
|
|
18
|
+
| **v2** | **无条件写 `status:'attempted'`** —— 而降级发生在**两个 id 空间**上,`proof` 指针还留着,记录自相矛盾 |
|
|
19
|
+
|
|
20
|
+
后果链(实测):对象已 `passed` → 表决者回一句"我这轮又写了遍草稿" → 记录降级为 `attempted`、
|
|
21
|
+
`status.formal.objects` 里不再是 `passed` → 后续审查提示词**丢掉忠实性分支** → `require` 档对一份
|
|
22
|
+
跑通的证明**重新关门**、对象被丢进「形式化待办」。
|
|
23
|
+
|
|
24
|
+
> 这正是 2.3.2 修过的 v4 `formalSetRun` 缺陷的**同一类**("随手一次动作把 passed 抹掉"),
|
|
25
|
+
> 只是长在另一条路径(回执通道)上,而且**只长在一套里**——`AUDIT-CHECKLIST §1.8`(四套同构)
|
|
26
|
+
> 记的就是这种形态。
|
|
27
|
+
|
|
28
|
+
**修复**:v2 的 `used` 分支改为先看**两套 id 空间**的状态(对象侧自己的记录 + `formalGateRecord` 的合并
|
|
29
|
+
视图),取其中**最强**的一个(`passed` > `blocked` > `attempted`):只有两侧都还没尝试过才写 `attempted`,
|
|
30
|
+
否则保留原状态并在活动日志里说明保留了哪一个。四套现在**同构**(v3 另外补上 `blocked` 的保留,见 §2)。
|
|
31
|
+
|
|
32
|
+
## 2. 同一类的第二处:v3 的 `used` 只保留 `passed`,会把 `blocked` 打回 attempted
|
|
33
|
+
|
|
34
|
+
`blocked` 是**门禁已放行**的记录(契约 §4/§8)。v3 的条件写成 `prev.status === 'passed' ? 'passed' : 'attempted'`:
|
|
35
|
+
一个已经用"显式阻塞原因"打开门禁的对象,被一句 `used` 回执打回 `attempted`,门禁**重新关上**。
|
|
36
|
+
已改为 `passed`/`blocked` 都保留(与 v2/v4/v5 一致)。
|
|
37
|
+
|
|
38
|
+
## 3. 契约字面与实现相反(三处)
|
|
39
|
+
|
|
40
|
+
`docs/formal-verification.md` §4 的迁移表是四套的规范来源,但它有两行写错了(代码是对的):
|
|
41
|
+
|
|
42
|
+
| 行 | 原字面 | 现字面 |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| `formal:{decision:'used'}` | → `attempted` | → `attempted`;**若已是 `passed`/`blocked` 则保持原状**(撤销只有 `defect` 一条路) |
|
|
45
|
+
| `lean_run` 成功/失败 | → `attempted` | 同样**不降级**已成立的 `passed`/`blocked` |
|
|
46
|
+
| (新增)`lean_archive{kind:'proof'}` + **运行失败** | 未写 | → `attempted`、清空 `proof`、并**撤回**旧的归档证明(工作文件刚被覆盖,旧证明不再对应任何代码) |
|
|
47
|
+
|
|
48
|
+
四套的 `实现方案.md` 与 v5 规格里的对应句子同步改正。规范文档写反最危险的地方在于:**下一次修改是
|
|
49
|
+
照它写的**(2.3.2 修好 `used` 之后,如果只读契约就会把修复改回去)。
|
|
50
|
+
|
|
51
|
+
## 4. 守卫自身的脆弱点:注释扫描器不认正则字面量
|
|
52
|
+
|
|
53
|
+
`audit-prompt-invariants.mjs` 的 I1/I13/I14 都建立在"先把注释抹掉、再检查剩下的代码"之上。四个预设里
|
|
54
|
+
都有 `/[\\/:*?"<>|\u0000-\u001f]+/` —— **字符类里含一个双引号**。原扫描器把那个引号当成字符串开头,
|
|
55
|
+
此后整个文件的词法状态就是错的。实测差异:
|
|
56
|
+
|
|
57
|
+
| 预设 | 两种扫描器**逐行不同**的行数 | 典型后果 |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| v2 | 190 行 | 真实代码行(如 `const abs = …`)被当成注释**抹掉** → 真缺陷可能被漏看 |
|
|
60
|
+
| v3 | 159 行 | 同上 |
|
|
61
|
+
| v4 | 14 行 | 注释被当成代码 → 反模式写进注释就会**误报** |
|
|
62
|
+
| v5 | 121 行 | 同上 |
|
|
63
|
+
|
|
64
|
+
本轮给扫描器加了**正则字面量**支持(含字符类 `[...]`、转义、结尾 flags),并把"守卫的守卫"写成
|
|
65
|
+
**X5–X7 三条自检**(放进 `audit-prompt-invariants.mjs`,任何一次运行都会执行):正则里的引号不得吞掉
|
|
66
|
+
后面的注释、字符串里的 `//`(URL)不得被当成注释、转义斜杠不得提前结束正则,且三者都必须保持行结构。
|
|
67
|
+
实测修复前 X5 变红、修复后全绿。
|
|
68
|
+
|
|
69
|
+
## 5. 本轮新增的行为断言(四套同构,+42 条;另 +6 不变式 / +3 可追溯)
|
|
70
|
+
|
|
71
|
+
| 断言(四套各一份) | 说明 |
|
|
72
|
+
|---|---|
|
|
73
|
+
| `used` 回执**不得**降级已 `passed` 对象 | 记录与 `proof` 指针都保留;v2 修复前**实测变红**(`got attempted`),修复后全绿 |
|
|
74
|
+
| `used` 回执**不得**把 `blocked` 打回 `attempted`(门禁不得被重新关上) | v3 修复前变红 |
|
|
75
|
+
| 一次普通 `lean_run`(带 `target`)**不得**降级 `passed` | 此前只有 v4 套件有这条断言,现四套齐备 |
|
|
76
|
+
| `used` 之后 `require` 门禁**仍然放行** | v2:把该轮驱动到一致为真,断言**没有**产生 `formal-required` 待办 |
|
|
77
|
+
| 真实注册的 schema 必须仍是封闭的、且四个 Lean 参数齐全(2.3.2 的守卫) | 四套各 7 条 |
|
|
78
|
+
|
|
79
|
+
## 5.1 并行回归暴露的**测试脆弱性**(也一并修掉)
|
|
80
|
+
|
|
81
|
+
4 路并行回归第二次跑时 `e2e-v4-fixes` **崩了**(exit 1,只跑了 2 个用例就中止);单独跑 3 次全绿
|
|
82
|
+
(120/120)。形态:驱动循环"安静即停"在框架把卡片落盘**之前**退出 → `assert(existsSync(card))`
|
|
83
|
+
只记录失败**不抛** → 紧随其后的 `readFileSync(card)` 抛 `ENOENT` → **未捕获异常让整个套件中止,
|
|
84
|
+
后面 12 个用例的断言全部丢失**。
|
|
85
|
+
|
|
86
|
+
修法(两条一起):该套件新增 `readArtifact(p, ms=3000)`(先等产物、再防御性读),并把六处"断言后立刻
|
|
87
|
+
读产物"改成"先等产物 → 再断言 → 防御性读"。效果:慢机器上产物晚到 3 秒也能通过;真没写出来则是
|
|
88
|
+
**一条干净的断言失败**,不再吞掉后续用例。这条已写进 `AUDIT-CHECKLIST` §4(连同"发布元数据交给
|
|
89
|
+
序列化器、不要用字符串替换手写 `package.json`"——本轮就这么写出过一次非法 JSON)。
|
|
90
|
+
|
|
91
|
+
## 6. 验收(实测)
|
|
92
|
+
|
|
93
|
+
| 套件 / 脚本 | 2.3.2 | 2.3.3 |
|
|
94
|
+
|---|---|---|
|
|
95
|
+
| `formal-verify-v2.test.mjs` | 319 | **334** |
|
|
96
|
+
| `formal-verify-v3.test.mjs` | 283 | **294** |
|
|
97
|
+
| `formal-verify-v4.test.mjs` | 269 | **277** |
|
|
98
|
+
| `formal-verify-v5.test.mjs` | 145 | **153** |
|
|
99
|
+
| `audit-prompt-invariants.mjs` | 145 | **151**(+ X5–X7 扫描器自检及其行结构断言) |
|
|
100
|
+
| `audit-spec-traceability.mjs` | 91 | **94**(契约 §4 三行的字面校验) |
|
|
101
|
+
| `audit-prompt-invariants.mjs --self-probe` | 5/5 | **5/5** |
|
|
102
|
+
| `prompt-v5-integrity.test.mjs` | 506 | 506(语料字节稳定) |
|
|
103
|
+
| `audit-persona-surface.test.mjs` | 197 | 197 |
|
|
104
|
+
|
|
105
|
+
- 全量并行回归 23/23 全绿;49 条 formal 探针全红;四套语料(v2/v3/v4/v5 + persona)连续两次哈希一致;
|
|
106
|
+
- closing verification:**18/18 阶段通过**。
|
|
107
|
+
|
|
108
|
+
## 7. 升级
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
npm i dsh-vibe-math@latest
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
无迁移。新参数默认 `off`,四套在 `off` 档的行为与 2.3.2 完全一致;本版改动只影响
|
|
115
|
+
`formalVerify` 非 `off` 时的记账语义(且都是"少撤销、不误关门"方向)。
|