dsh-vibe-math 2.7.2 → 2.8.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 (153) hide show
  1. package/LICENSE +21 -21
  2. package/README.en.md +682 -681
  3. package/README.md +683 -682
  4. package/cordis.patch.yml +112 -16
  5. package/docs/AUDIT-CHECKLIST.md +755 -518
  6. package/docs/COMPAT-AUDIT-ROUND2.md +354 -328
  7. package/docs/COMPAT-AUDIT-ROUND3.md +154 -154
  8. package/docs/audit-methodology.md +93 -0
  9. package/docs/final-paper.md +172 -172
  10. package/docs/formal-verification.md +613 -588
  11. package/docs/generate_framework_diagram_v2.py +114 -114
  12. package/docs/generate_framework_diagram_v3.py +127 -127
  13. package/docs/math-computation.md +195 -187
  14. package/docs/parameter-schema.md +37 -0
  15. package/docs/release-notes/README.en.md +2 -0
  16. package/docs/release-notes/README.md +2 -0
  17. package/docs/release-notes/RELEASE-NOTES-2.0.22.md +112 -112
  18. package/docs/release-notes/RELEASE-NOTES-2.1.0.md +143 -143
  19. package/docs/release-notes/RELEASE-NOTES-2.2.0.md +266 -266
  20. package/docs/release-notes/RELEASE-NOTES-2.2.1.md +43 -43
  21. package/docs/release-notes/RELEASE-NOTES-2.2.2.md +88 -88
  22. package/docs/release-notes/RELEASE-NOTES-2.3.0.md +207 -207
  23. package/docs/release-notes/RELEASE-NOTES-2.3.1.md +134 -134
  24. package/docs/release-notes/RELEASE-NOTES-2.3.10.md +105 -105
  25. package/docs/release-notes/RELEASE-NOTES-2.3.11.md +57 -57
  26. package/docs/release-notes/RELEASE-NOTES-2.3.12.md +80 -80
  27. package/docs/release-notes/RELEASE-NOTES-2.3.2.md +145 -145
  28. package/docs/release-notes/RELEASE-NOTES-2.3.3.md +115 -115
  29. package/docs/release-notes/RELEASE-NOTES-2.3.4.md +69 -69
  30. package/docs/release-notes/RELEASE-NOTES-2.3.5.md +63 -63
  31. package/docs/release-notes/RELEASE-NOTES-2.3.6.md +66 -66
  32. package/docs/release-notes/RELEASE-NOTES-2.3.7.md +59 -59
  33. package/docs/release-notes/RELEASE-NOTES-2.3.8.md +45 -45
  34. package/docs/release-notes/RELEASE-NOTES-2.3.9.md +70 -70
  35. package/docs/release-notes/RELEASE-NOTES-2.7.2.en.md +2 -2
  36. package/docs/release-notes/RELEASE-NOTES-2.7.2.md +3 -3
  37. package/docs/release-notes/RELEASE-NOTES-2.7.3.en.md +67 -0
  38. package/docs/release-notes/RELEASE-NOTES-2.7.3.md +67 -0
  39. package/docs/release-notes/RELEASE-NOTES-2.8.0.en.md +65 -0
  40. package/docs/release-notes/RELEASE-NOTES-2.8.0.md +65 -0
  41. package/docs/release-notes/TEMPLATE.md +6 -0
  42. package/docs/release-playbook.md +103 -0
  43. package/docs/slv-playbook.md +117 -0
  44. package/docs/status-report-fields.md +167 -0
  45. package/docs/test-timing.md +158 -154
  46. package/docs//346/236/266/346/236/204/345/233/276.md +77 -77
  47. package/installer.js +793 -783
  48. package/package.json +260 -203
  49. package/prompt-corpus-persona/persona-corpus.json +9 -9
  50. package/prompt-corpus-persona/persona-corpus.md +225 -33
  51. package/prompt-corpus-v2/formal-verify-v2.json +295 -115
  52. package/prompt-corpus-v2/formal-verify-v2.md +2290 -282
  53. package/prompt-corpus-v3/formal-verify-v3.json +112 -112
  54. package/prompt-corpus-v3/formal-verify-v3.md +227 -143
  55. package/prompt-corpus-v4/formal-verify-v4.json +18 -18
  56. package/prompt-corpus-v4/formal-verify-v4.md +49 -44
  57. package/prompt-corpus-v5/prompt-corpus-v5.json +82 -82
  58. package/prompt-corpus-v5/prompt-corpus-v5.md +573 -207
  59. package/scripts/clean-temp.mjs +234 -0
  60. package/scripts/update-doc-counts.mjs +71 -0
  61. package/tests/audit-artifact-docs.mjs +72 -0
  62. package/tests/audit-artifact-docs.mutants.mjs +58 -0
  63. package/tests/audit-engine-faces.mjs +298 -0
  64. package/tests/audit-formal-sensitivity.mjs +345 -342
  65. package/tests/audit-installer-assertions.mutants.mjs +63 -0
  66. package/tests/audit-installer-compat.test.mjs +256 -208
  67. package/tests/audit-installer-policy.test.mjs +41 -8
  68. package/tests/audit-math-computation-contract.mjs +64 -8
  69. package/tests/audit-math-computation-contract.mutants.mjs +106 -0
  70. package/tests/audit-math-computation-parity.mjs +164 -3
  71. package/tests/audit-math-computation-sensitivity.mjs +5 -3
  72. package/tests/audit-package-membership.mjs +57 -0
  73. package/tests/audit-package-membership.mutants.mjs +28 -0
  74. package/tests/audit-participant-set-parity.mjs +160 -0
  75. package/tests/audit-path-discipline.mjs +83 -0
  76. package/tests/audit-path-discipline.mutants.mjs +51 -0
  77. package/tests/audit-persona-sensitivity.mjs +323 -309
  78. package/tests/audit-persona-surface.mutants.mjs +69 -0
  79. package/tests/audit-persona-surface.test.mjs +431 -390
  80. package/tests/audit-prompt-duplication.mjs +143 -0
  81. package/tests/audit-prompt-duplication.mutants.mjs +51 -0
  82. package/tests/audit-prompt-invariants.mjs +589 -508
  83. package/tests/audit-readme-bilingual.test.mjs +152 -0
  84. package/tests/audit-readme-counts.mjs +95 -0
  85. package/tests/audit-readme-counts.mutants.mjs +52 -0
  86. package/tests/audit-registration.mjs +78 -0
  87. package/tests/audit-spec-traceability.mjs +193 -193
  88. package/tests/audit-status-report-fields.mjs +172 -0
  89. package/tests/audit-status-report-fields.mutants.mjs +64 -0
  90. package/tests/audit-v3-registration-parity.mjs +156 -0
  91. package/tests/audit-v5-integrity.mjs +795 -508
  92. package/tests/audit-v5-lean-abstention.mjs +392 -0
  93. package/tests/audit-v5-lean-abstention.mutants.mjs +106 -0
  94. package/tests/audit-v5-prompt-duplication.mjs +88 -0
  95. package/tests/audit-v5-prompt-duplication.mutants.mjs +34 -0
  96. package/tests/audit-v5-sensitivity.mjs +433 -427
  97. package/tests/e2e-identity-a6.mutants.mjs +65 -0
  98. package/tests/e2e-v5-round2.test.mjs +2453 -1981
  99. package/tests/formal-verify-v2.test.mjs +1778 -1724
  100. package/tests/formal-verify-v3.mutants.mjs +117 -0
  101. package/tests/formal-verify-v3.test.mjs +1724 -1671
  102. package/tests/formal-verify-v4.mutants.mjs +152 -0
  103. package/tests/formal-verify-v4.test.mjs +2114 -1574
  104. package/tests/formal-verify-v5.test.mjs +790 -724
  105. package/tests/helpers/doc-counts-format.mjs +41 -0
  106. package/tests/helpers/math-computation-fake-seam.mjs +4 -0
  107. package/tests/math-computation-a1.mutants.mjs +72 -0
  108. package/tests/math-computation-archive-rerun.mutants.mjs +65 -0
  109. package/tests/math-computation-discovery.mutants.mjs +76 -0
  110. package/tests/math-computation-shared.test.mjs +392 -6
  111. package/tests/math-computation-v2.test.mjs +779 -0
  112. package/tests/math-computation-v3.test.mjs +771 -0
  113. package/tests/math-computation-v4.mutants.mjs +133 -0
  114. package/tests/math-computation-v4.test.mjs +739 -0
  115. package/tests/prompt-v5-integrity.test.mjs +1291 -1280
  116. package/tests/run-tests.mjs +393 -202
  117. package/tests/run-tests.mutants.mjs +70 -0
  118. package/tests/selfdrive-v5.mjs +560 -508
  119. package/tests/selfdrive-v5.mutants.mjs +132 -0
  120. package/tests/temp-hygiene.mutants.mjs +80 -0
  121. package/tests/v2-fix-probes.mutants.mjs +104 -0
  122. package/tests/v2-fix-probes.test.mjs +1040 -0
  123. package/tests/v2-list-agents-and-next-step.mutants.mjs +106 -0
  124. package/tests/v2v3-interrupt.mutants.mjs +111 -0
  125. package/tests/v3-fix-probes.mutants.mjs +99 -0
  126. package/tests/v3-fix-probes.test.mjs +892 -0
  127. package/tests/v4-final-paper.mutants.mjs +108 -0
  128. package/tests/v5-institute-fixes.mutants.mjs +218 -0
  129. package/vibe-math-v2/agent.cordis.yml +378 -322
  130. package/vibe-math-v2/math-computation.js +144 -53
  131. package/vibe-math-v2/math-engines.js +12 -12
  132. package/vibe-math-v2/preset.yml +2 -2
  133. package/vibe-math-v2/v2/347/232/204/351/242/235/345/244/226/350/246/201/346/261/202.txt +21 -21
  134. package/vibe-math-v2/vibe-math-v2.js +5097 -4755
  135. package/vibe-math-v2//345/256/236/347/216/260/346/226/271/346/241/210.md +491 -487
  136. package/vibe-math-v3/agent.cordis.yml +422 -356
  137. package/vibe-math-v3/math-computation.js +144 -53
  138. package/vibe-math-v3/math-engines.js +12 -12
  139. package/vibe-math-v3/preset.yml +2 -2
  140. package/vibe-math-v3/vibe-math-v3.js +6235 -5873
  141. package/vibe-math-v3//345/256/236/347/216/260/346/226/271/346/241/210.md +649 -649
  142. package/vibe-math-v4/agent.cordis.yml +438 -402
  143. package/vibe-math-v4/math-computation.js +144 -53
  144. package/vibe-math-v4/math-engines.js +12 -12
  145. package/vibe-math-v4/preset.yml +2 -2
  146. package/vibe-math-v4/vibe-math-v4.js +4490 -4269
  147. package/vibe-math-v4//345/256/236/347/216/260/346/226/271/346/241/210.md +1015 -1013
  148. package/vibe-math-v5/agent.cordis.yml +46 -12
  149. package/vibe-math-v5/math-computation.js +144 -53
  150. package/vibe-math-v5/math-engines.js +12 -12
  151. package/vibe-math-v5/vibe-math-v5.js +1266 -229
  152. package/vibe-math-v5//345/256/236/347/216/260/346/226/271/346/241/210.md +1728 -1660
  153. package/vibe-math-v5//346/236/266/346/236/204/345/233/276.md +693 -693
@@ -1,487 +1,491 @@
1
- # Vibe Mathematics —— 多代理数学问题求解与验证框架
2
-
3
- > **状态说明(round-3 补记)**:本文是**设计期文档**,写于 `math_computation`(数学计算工具)、
4
- > `leanAsync`/`leanJobsMaxParallel`/`leanSearchPaths`(Lean 异步作业与复用)、`paperEditor` 与
5
- > `paper.lock.json`(最终论文定稿/写锁)等新功能之前;**功能与参数的权威描述以 `docs/` 为准**
6
- > (`docs/math-computation.md`、`docs/formal-verification.md`、`docs/final-paper.md`、`docs/test-timing.md`),
7
- > 参数表以 README 的双语「共用参数 / 各预设专属参数」表为准。本文保留其原始设计意图,不再逐条追平。
8
-
9
- 项目需具备以下核心功能:
10
-
11
- 1. **断点续跑**:保存各代理的对话记录及任务栈,支持状态恢复。
12
- 2. **人工干预**:允许在任意时刻手动介入工作流,例如调整代理参数、控制会话、决策关键节点,并可随时在“人工 / 自动(预设)”模式间切换。
13
- 3. **进度汇报**:每隔一段时间(如发生变动、出现新进展、发生新调用或代理会话结束时),委托主代理汇总当前进展及各代理状态。
14
- 4. **多会话并行隔离**:DSH 的 agent preset 是 standing mount——同一 preset 的所有会话共享同一个插件实例,因此插件**必须自行按根会话 id 隔离内部状态**(`rootAgent`、当前项目、调度器、代理注册表、决策队列、参数、任务栈等全部 per-session)。两个会话可同时各跑一个项目,各自的子代理挂在各自会话名下、互不干扰;当前项目按会话持久化(`VibeMath/current.<会话id>.json`,兼容读取旧 `current.json`)。
15
-
16
- ---
17
-
18
- ## 路径与核心对象
19
-
20
- ### 一、问题清单文件
21
- 路径:`qs/qs.json`
22
- 每个问题对象至少包含以下属性:
23
-
24
- - `概述`:问题的完整描述;若包含预定义对象(数学对象、引理、定理名称等),需一并给出其完整定义。
25
- - `已解决`:布尔值,标记当前是否已解决。
26
- - `解法列表`:每个解法需包含:
27
- - `完整解法`:详细步骤。
28
- - `正确概率`:数值(越大越优先验证/调度)。
29
- - `优先级`:整数(值越小越优先调度),支持动态调整(依据进度、可行性、难度、关键性、价值等)。若为 `never` 则永不调度。
30
- - `progress`:过往进度与经验,包括各方向、路线的尝试记录、教训、阻碍及可行性评估。
31
- - 其他必要属性(按需添加)。
32
-
33
- ### 二、命题存储文件
34
- 路径:`Propos/{分类名}_Propos.json`(按类型、领域或相关性分类,便于快速查阅)
35
- 每个命题至少包含以下属性:
36
-
37
- - `概述`:完整描述;含预定义对象时需补充其定义。
38
- - `布尔估计`:当前命题为真的可能性(概率值)。
39
- - `细类型`:JSON对象,如 `{"积分": {"不等式": {}}, "级数": {}}`。
40
- - `证明列表`,`证伪列表`:每个条目包含:
41
- - `完整过程`:证明或证伪的详细步骤。
42
- - `正确概率`:数值(越大越优先验证/调度)。
43
- - `支持信息/依据`:尽可能强的支撑证据。
44
- - `优先级`:同问题清单,支持动态调整,`never` 表示永不调度。
45
- - `progress`:过往进度与经验。
46
- - 其他必要属性(按需添加)。
47
-
48
- ### 三、可信赖文件(如参考文献)
49
- 路径:`Reliable/`
50
-
51
- ---
52
-
53
- ## 权限与参数
54
-
55
- - **权限**(可通过参数调控):
56
- 所有任务及子代理在运行过程中,**默认允许**:
57
- - 读取 `Verified/` 路径下的任何文件作为已知依赖;
58
- - 不限次数调用外部工具(搜索引擎、符号计算库、论文数据库)进行文献检索或数值辅助验证。
59
- - **参数**:
60
- (此处可扩展具体参数设置,尽量能够实现尽量多的调控)
61
-
62
- 所有代理基于 `Propos/` 和 `Reliable/` 作为已有认知进行推理与判断。额外告知子代理:可借助工具通过索引读取 JSON,粗读定位关键索引,再细读具体内容。
63
-
64
- ---
65
-
66
- ## 调度器
67
-
68
- ### 注意事项
69
- 1. 所有涉及调用新代理的操作,必须等待 `active_sub_agents_count < MAX_PARALLEL_THRESHOLD` 时方可执行。
70
- 2. 主程序的控制以编程方式实现,不由代理自行调度。
71
- 3. 若 `Propos/` 中存在重要性、关键性足够高但尚未证明或证伪的命题,可将其加入问题清单,供后续求解器调度。
72
- 4. 当某个问题的解法列表中存在正确概率为 `1` 的解法时,该问题状态更新为“已解决”,优先级设为 `never`。当某个命题的证明/证伪列表中存在正确概率为 `1` 的证明/证伪时,该命题的正确概率更新为 `1`(或 `0`),优先级设为 `never`。
73
-
74
- ### 主循环
75
- **终止条件**:问题清单中所有问题均已解决,则终止。
76
-
77
- 循环可执行以下两个任务:
78
-
79
- #### 1. 求解与扩充待验证解法和结论
80
- - **目标**:按优先级提取问题,调用求解器,确定方向并发放任务。
81
- 过程中获得的所有有价值结论/命题及其证明,加入 `Propos/` 并标注属性(可由相应代理决策,但须符合规则)。
82
- 若完成原问题求解,则将解法加入对应问题的解法列表,并标注属性。
83
- - **具体实现**:
84
- ~~~
85
- 按优先级从 `qs.json` 中取出未解决问题 `q`,调用一个子代理(类型标识为 `explorer-{q}`)执行 `solve(q)`。
86
- ~~~
87
-
88
- #### 2. 验证/判定与更新数据
89
- - **目标**:按优先级验证问题清单中的解法、`Propos/` 中的命题或命题的证明,并更新其属性。
90
- - **具体实现**:
91
- ~~~
92
- 按优先级从 `qs.json` 或 `Propos/` 中选择尚未解决/未达`1/0`概率的“命题”、“命题+证明/证伪”或“问题+解法”作为 `r` ,执行 `验证器(r)`。(只有当“命题”的证明、证伪列表为空时才允许选择单个“命题“作为 `r` )
93
- ~~~
94
-
95
- ## 核心函数定义
96
-
97
- ### 1. `solve(q)`
98
-
99
- **构建大方向集 `M_q`**(按数学方法论分类):
100
-
101
- - 若 `q.progress` 为空:
102
- 1. 进行第一阶段**元认知头脑风暴**(约束分解、边界极端测试、相似问题映射);
103
- 2. 将解法拆分为多个**截然不同**的尝试方向 `m_i`(如解析法、构造性证明、反证法、数值逼近+极限过渡、范畴论抽象等);
104
- 3. 记录每个方向的核心假设与初始可行性预估至 `q.progress`,形成初始集合 `M_q = {m_i}`。
105
-
106
- - 若 `q.progress` 非空:
107
- 1. 读取并解析已有进度,对各方向的**历史进展、遇阻原因、可行性衰减曲线**进行量化分析;
108
- 2. 筛除已被充分证明为“死路”的方向(除非有新工具引入);
109
- 3. 基于当前痛点,**深度推导**出 1~3 个从未尝试过的新方向(附推导动机);
110
- 4. 将“遗留高潜方向”与“新生方向”取并集,重构为新的 `M_q`。
111
-
112
- **任务分配与迭代求解**:
113
- 将 `M_q` 中的每个 `m_i` 独立分配给一个专属子代理(类型标识为 `Solver-{q}`),并发执行 `agent_self_iteration(q, m_i)`。
114
-
115
- ---
116
-
117
- ### 2. `agent_self_iteration(q, m)`
118
-
119
- **角色定位**:专注执行方向 `m` 的深度研究,具备自主切换子路线、设定临时假设、自我批判的能力。
120
-
121
- **执行流程**(同会话内持续迭代):
122
-
123
- 1. **起点定位**:参考 `q.progress` 中方向 `m` 的最后记录节点,决定是继承进度继续深挖,还是在大方向下另辟蹊径。
124
- 2. **单次迭代动作**(每轮对话):
125
- - 尝试推进证明/计算;
126
- - **必须产出**(即使未完全解决):
127
- - 本次推导出的**新引理/中间结论**及其完整证明;
128
- - 尝试过的各具体子路线及其进度(概述整个子路线的经历及当前进度)、可行性情况、**明确的可行性信号**(如“遇到不可消除的奇点”、“与某已知定理冲突”等)、遇到的障碍、不可行的原因等;
129
- - 更新对方向 `m` 的整体存活概率评估。
130
- 3. **分支递归(`q_sub` 严格化)**:若遇到**复杂度极高**的附属猜想/子问题 `q_sub`(`q_sub` 为**问题类对象**):
131
- - 记 `p_{q-tmp}` 为对 `q_sub` 的某种回答/答案的**临时假设**(**命题类对象**);
132
- - 把**临时问题 `q_sub`** 与**「判断下述命题是否成立:`p_{q-tmp}`」**两个问题一起加入 `qs.json`(两者的概述、定义必须完整——所涉及的对象、依赖、环境、背景等一律给出完整定义,避免断章取义);
133
- - 将 `p_{q-tmp}` 作为命题对象写入 `Propos/`(布尔估计记 `0.5`,`progress` 标注“临时假设 · 依赖 `q_sub`”);若该假设被证伪,则依赖它的主线结论需重新审视;
134
- - 依赖关系**必须落库**:处在某条在力假设之下的引理会带上 `依赖假设` 字段(`vibe_math_list_propositions`
135
- 与验证提示词都会显示它),假设被证伪时依赖它的结论被标记 `依赖假设已证伪` 并重新进入验证候选;
136
- - “判断下述命题是否成立:p_{q-tmp}”这个问题**自带一条种子解法**(就是"该假设成立"这一候选回答,概率 `0.5`,
137
- 不是定论)。没有它,验证候选集里永远没有属于这个问题的对象(裸 `p-tmp-*` 命题被显式跳过),
138
- 于是 `p_{q-tmp}` 永远停在 `0.5`、判断问题永不收口、终止规则不可达;
139
- - 在当前线程中,**临时假设 `p_{q-tmp}` 成立**,继续推进主线;
140
- - 后续所得命题/结论中**凡依赖该假设的**,必须把假设作为前提显式写出,形如「若 `p_{q-tmp}` 成立,则:...」(概述、定义完整,不断章取义)。
141
- 4. **终止条件(进入 `END` 状态)**:
142
- - **成功**:得到完整的 `q` 解法,并执行严格的**自我对抗性检查**(尝试构造反例,检查边界条件)。若自检不通过,修正后重新计数迭代;
143
- - **失败/超时**:迭代次数达到预设上限(如 3 轮),或判定方向 `m` 已无可行路径。
144
- 5. **最终输出(原子写入)**:
145
- - 若得到原问题 `q` 的解法,则写入 `qs.json` 中对应问题的解法列表,并设置属性。注意写入时,该解法的正确概率必须小于 `1`(待验证器验证)。
146
- - 将所有产出的结论/命题及完整证明写入 `Propos/`,合理设置属性(如优先级反映其对原问题解决的重要性/关键性程度)。写入时,命题的正确概率必须小于 `1`(待验证器验证)。
147
- - 将过程中所有失败路线的详细归因,以及对问题的各个方向下各个路线、尝试的进度/进展及经验教训、遇到的阻碍、可行性评估等写入 `q.progress`。
148
-
149
- ---
150
-
151
- ### 3. `验证器(r)`
152
-
153
- **核心机制**:多代理独立审查 → 同步辩论(“交流群”)→ 共识达成(或强制裁决)。
154
-
155
- **输入**:单个验证对象 `r`,允许为:
156
- - 单个命题;
157
- - 命题与命题的证明/证伪;
158
- - 问题与问题的解法。
159
-
160
- 分别进行对应判定:
161
- - 命题是否成立;
162
- - 命题的证明/证伪过程是否正确;
163
- - 问题的解法是否正确。
164
-
165
- **执行策略**:
166
-
167
- 1. **独立审查阶段**
168
- - 向多个子代理(身份为“严苛审稿人”)分别发送 `r`,每个代理多次检查待验证对象是否成立。要求各代理独立输出初始审查报告,包含:
169
- - `Result`:所判定对象正确的概率值,取值 `[0,1]`(仅当判定为确定正确或错误时取 `1` 或 `0`,否则介于两者之间)。
170
- - `Reason`:详细逻辑链、潜在反例、支撑依据。若判定为 `0`,则 `Reason` 为严谨完整的证伪过程;若 `r` 为单个命题且判定为 `1`,则 `Reason` 为该命题的完整证明。
171
- - 所有代理在收到彼此报告前不得互相通信,确保初始判断独立无偏。
172
-
173
- 2. **辩论阶段(“交流群”轮流发言)**
174
- - 所有代理进入同一虚拟“交流群”,按随机或既定顺序依次发言,每轮发言需包含:
175
- - 当前自己的 `Result` 与 `Reason`;
176
- - 对其他代理先前发言的回应(赞同、反驳或提出新证据);
177
- - 若因他人意见改变立场,需明确说明转变理由。
178
- - 辩论持续多轮(例如上限 5 轮),每轮每个代理必须发言一次。
179
- - 每轮结束后检查是否所有代理的 `Result` 已一致(全为 `1` 或全为 `0`):
180
- - 若一致,立即终止辩论,进入最终输出;
181
- - 若不一致,继续下一轮,直至达到最大轮数。
182
-
183
- 3. **共识判定与强制裁决**
184
- - 若达到最大轮数后仍未一致,则按预设参数采用以下方式之一:
185
- - 均衡机制(`verdictMode='flat'`):取各评审**自报概率的均值**(只有精确的 `1`/`0` 才是绝对真/假,
186
- `0<Result<1` 是"它为真的概率";不再把高置信分歧折叠成固定的 `0.5`);
187
- - 强制裁决机制(`verdictMode='forced'`):按验证者的历史准确率与布尔票置信度加权求平均,得到
188
- `(0,1)` 内的判定结果。准确率按**稳定身份**(`provider/model`)记,且只在对象**后来**取得布尔
189
- 定论时回溯计分——按一次性的子代理 id 记(恒 `0.5`)或拿本次聚合值给同一批评审打分都是自指的。
190
- - 无论哪种机制,中段结果(`0<r<1`)都**不是**定论:对象重新变为可验证(冷却期后重新入选),
191
- 绝不把中段结果当成绝对真/假来写卡片或收口。
192
- - 每次裁定需要**至少 2 名独立评审**:票数不足时先补派,补不足就搁置该对象等冷却期后重试,
193
- 绝不退化成单票结论。为保证"另一个对象也凑得齐 2 票",单个验证对象同时占用的评审槽位不超过
194
- `maxParallelThreshold - 2`(容量宽裕时就是 `verifierCount`)。
195
-
196
- 4. **更新数据**
197
- - 若 `r` 为单个命题,则记 `a = r`;若 `r` 为“命题+证明/证伪”或“问题+解法”,则记 `a` 为 `r` 中的那个证明/证伪/解法。
198
- - 若判定对象是**命题本身**且结果为 `0`:更新 `a` 的布尔估计为 `0`,并将完整证伪过程记录到证伪列表(概率 `1`);
199
- - 若判定对象是**某一条证明/证伪**且结果为 `0`:那只表示**这一条过程无效**(`a` 的正确概率记 `0`、`已验`),
200
- **不是**"命题为假"——绝不因此向对侧列表伪造一条概率 `1` 的反条目,也绝不改写命题的布尔估计。
201
- 伪否定会经由收口规则变成一张"已验证·假"的卡片,那正是这条规则要避免的(与 `defect` 同类事故)。
202
- - 若判定结果为 `1`:更新 `a` 的正确概率为 `1`,并将完整证明过程记录到证明列表;
203
- - 若判定结果介于 `0` 和 `1` 之间:更新 `a` 的正确概率为该结果,并分别向证明、证伪列表添加根据辩论得出的尽可能正确的过程/支撑信息及相应概率;对象在冷却期后重新进入验证候选(中段值不是定论)。
204
- - 辩论全程发言记录存入 `Verification_logs/` 对应日志,便于复盘与审计。
205
-
206
- ---
207
- ---
208
-
209
- ## Lean 形式化验证(`formalVerify`)
210
-
211
- > 本节实现 `docs/formal-verification.md` 中 v2/v3/v4/v5 **共用契约**;参数名、路径、
212
- > 工具名、提示词语义、门禁规则、索引格式都与该契约一致。
213
-
214
- **为什么要有它**:多代理交叉验证的本质是**共识**,不是**证明**。Lean 把"我认为"换成"机器已核对",
215
- 于是验证的**审查对象**从"推导是否正确"变成**"Lean 代码是否忠实于命题原文"**(定义/对象/条件/假设/结论
216
- 是否逐条一致)——后者人(和代理)确实审得动。注意 `passed` **不等于**命题为真:它只表示"形式化代码
217
- 通过了内核检查",忠实性仍需 m 票审查。
218
-
219
- ### 一、参数(四个,与其它架构同名同语义)
220
-
221
- | 参数 | 类型 | 取值 | 默认 | 含义 |
222
- |---|---|---|---|---|
223
- | `formalVerify` | enum | `off` \| `encourage` \| `require` | `off` | 三档开关,见下 |
224
- | `leanCommand` | string | 任意可执行文件名 | `lean` | 要执行的 Lean 可执行文件(例:`lake`) |
225
- | `leanArgs` | string[] | —— | `[]` | 插在 `.lean` 文件名**之前**的附加参数(例:`["env","lean"]` 配合 `leanCommand="lake"`) |
226
- | `leanTimeoutMs` | integer | 正整数(下限 1000) | `120000` | 单次 Lean 运行的超时上限(毫秒) |
227
-
228
- - 四个参数都出现在:`vibe_math_set_params` 的 schema、`PARAM_SCHEMA`
229
- (`vibe_math_setup` / `vibe_math_template` / `/vibe setup` 的参数表)、`vibe_math_status`
230
- 与 `vibe_math_report` 的可读参数表,并随 `vibe_math_setting.json` 持久化。
231
- - **校验规则**:`formalVerify` 非三档之一 → 回退 `off`(**绝不**回退到更强的档位:一个拼写
232
- 错误若静默启用强制形式化,会让所有结论被门禁拦下);非正的 `leanTimeoutMs` → 删除该键并回退
233
- 默认值;空白的 `leanCommand` → 回退 `lean`。
234
- - **模式是动态的**:所有与档位相关的提示词文本都在**构造提示词的那一刻**由 `params.formalVerify`
235
- 现算(`formalPromptBlock` / `formalWorkLine`),不写进任何"入职时冻结"的快照;运行中切换档位
236
- 后,下一条提示词立即反映新模式。
237
-
238
- ### 二、三档语义
239
-
240
- - **`off`(默认)= 真正的无操作**:提示词里不出现任何 Lean 字样;验证流程、门禁、归档行为与
241
- 改动前完全一致(卡片里也不写形式化行)。三个 Lean 工具**仍然注册**(注册是静态的),
242
- 只是框架不告诉代理它们存在;人/代理主动调用时照常工作。
243
- - **`encourage` = 鼓励但不强制**:验证提示词注入"先判断实现难度,能形式化就优先写 Lean;
244
- 一旦 Lean 通过,你唯一需要确认的就是**忠实性**";平时工作提示词注入"顺手形式化"段落
245
- (把常用/可能复用的对象、假设、新定义归档到全局库,写之前先 `lean_lib` 查重)。
246
- **不设门禁**:没有任何 Lean 产物时验证照常收口。
247
- - **`require` = 强制 + 门禁**:注入同样的文本但语气为"必须",并在"写 Verified 卡片/判定定论"
248
- 这**唯一的收口点**加门禁——对象的形式化状态必须是 `passed`(有 Lean 产物且最近一次运行
249
- `exitCode === 0`)或 `blocked`(代理给出了显式难度判断/阻塞原因,`note` 非空);
250
- 否则本次裁定**不生效**:记为 `undecided`(原因 `formal-required`)、写入 `Formal/TODO.md`、
251
- 在活动日志里公告、**不写** Verified 卡片、**不改变**对象原有的概率/权重字段
252
- (`布尔估计` / `已解决` / `优先级` 一律保持原状),对象留在原库,可形式化后再次提议验证。
253
- 门禁是**兜底**:正常情况下验证提示词已先告知表决者要么形式化、要么记录阻塞。
254
-
255
- ### 三、路径布局
256
-
257
- ```
258
- <VibeMath 根>/
259
- ├─ Formal/ # 全局可复用 Lean 库(跨项目,故意在项目树之外)
260
- │ ├─ Lib/<name>.lean + Lib/Index.md # 可复用定义/对象/假设
261
- │ └─ Proved/<name>.lean + Proved/Index.md # 已成立的命题/引理(机器已核对)
262
- └─ Projects/<项目>/
263
- ├─ Formal/<对象id>.lean # 该对象的形式化工作文件
264
- ├─ Formal/Index.md # 对象 → 状态 → 文件 → 归档证明 → 运行结果 → 难度判断
265
- ├─ Formal/TODO.md # require 模式下的「形式化待办」
266
- └─ Verified/Lean/<对象id>.lean # 归档证明:与定论卡片同处 Verified/
267
- ```
268
-
269
- - 文件 id 一律过 v2 既有的 id 安全化函数 `safeId`(去分隔符、去 `..`),防止路径穿越。
270
- - `lean_run` 只接受位于 **`<VibeMath 根>`** 之内的路径。边界是 VibeMath 根而**不是**项目根:
271
- 全局库有意放在项目树之外,所以"爬出项目但仍留在 VibeMath 内"合法;爬出 VibeMath 根之上、
272
- 或一个不相干的绝对路径/Windows 绝对路径,一律拒绝(`V2_INVALID_ARGUMENT`)。
273
- 实现用纯词法规范化(`normalizeAbsPath` + `leanAbsPath`),不做文件系统访问——
274
- 单纯的 `startsWith(root)` 挡不住 `…/Projects/../../../../etc/evil.lean`。
275
-
276
- ### 四、对象的形式化记录与持久化
277
-
278
- 每个对象一条 `formal` 记录:`{status: none|attempted|passed|blocked, file, proof, decision, note, run:{at,ok,exitCode,ms,stdoutTail,stderrTail}, updatedAt}`。
279
- v2 **没有会话投影**,所以记录与待办一起持久化在 v2 自己的状态文件
280
- `VibeMath_State/formal.json`(由既有 `readJson`/`writeJson` 读写,随 `saveAll` 落盘、`loadState`
281
- 读回),因此 `resume` 之后门禁不会"失忆"。索引 `Formal/Index.md` 是它的人类可读镜像。
282
-
283
- **两套 id 的对齐**:验证对象用 rId(如 `r-pGate`、`r-q1-s0`),而代理归档时给的是对象 id
284
- (如 `pGate`)。`lean_archive` 在写归档记录的同时同步 `r-<对象id>` 的验证记录;
285
- 门禁与提示词取记录时两个方向都认(`formalGateRecord`),避免"代理确实形式化了,门禁却仍
286
- 按未尝试处理"的假阴性。
287
-
288
- > **必须注意**:`syncVerificationTarget` 只更新**已经存在**的别名键,所以"归档写了对象 id、
289
- > rId 侧还没有记录"是首次形式化后的**真实状态**。因此**门禁的判定**也必须走
290
- > `formalGateRecord`(`deferForFormal`),不能只看 `formalOf(rId)`:否则一个已 `passed`
291
- > 的对象会被判为未形式化,而且这次搁置本身会写下 `r-<id> = status:'none'`,此后每一轮都
292
- > 继续搁置并重开一次完整辩论——对象**永远无法定论**(真实缺陷,已由套件第 13 节守住)。
293
-
294
- ### 五、三个工具
295
-
296
- | 工具 | 作用 |
297
- |---|---|
298
- | `vibe_math_lean_run` | 在 `<VibeMath 根>` 内的一个 `.lean` 文件上执行工具链并原样回报:`{ok, exitCode, signal, ms, command, stdout, stderr, file, timedOut}`;`target=<对象 id>` 时同时记录该对象的运行结果。**绝不向调度循环抛异常**:工具链缺失 → `LEAN_NOT_FOUND`;宿主无 `subprocess` 服务 → `NO_SUBPROCESS`;spawn 失败 → `LEAN_SPAWN_FAILED`;超时 → `LEAN_TIMEOUT`。**超时是主动的**(契约 §7):`handle.done` 与一个 `cap` 毫秒的计时器竞速,计时器到点时尽力调用 `handle.terminate()`,再给出可读的超时结果;`done` 先到就清掉计时器(不留悬挂 timer)。 |
299
- | `vibe_math_lean_archive` | `kind='def'` → 全局 `Formal/Lib/<name>.lean`;`kind='lemma'` → 全局 `Formal/Proved/<name>.lean`(两者都会重建对应 `Index.md`;`run:false` 可跳过执行)。`kind='proof'` → `Formal/<target>.lean`,且**该文件最近一次运行通过**时再写 `Verified/Lean/<target>.lean` 并把对象标为 `passed`,否则标为 `attempted`。`kind='blocked'` → 记录显式难度判断/阻塞原因(`note` 空 → 拒绝)并把对象标为 `blocked`。`kind='def'/'lemma'` 的返回值在**运行未通过**时不得声称"可直接 import 复用"(工具返回值同样是代理读到的文字)。 |
300
- | `vibe_math_lean_lib` | 扫描并重建三处索引(项目 `Formal/Index.md`、全局 `Lib/Index.md`、全局 `Proved/Index.md`),返回可复用库清单,供代理写新定义前查重;`refresh:false` 时只读不重建 |
301
-
302
- 参数 schema:
303
-
304
- | 工具 | 参数 |
305
- |---|---|
306
- | `lean_run` | `file`(string, 必填)、`target`(string)、`timeout_ms`(integer) |
307
- | `lean_archive` | `kind`(enum: `def`\|`lemma`\|`proof`\|`blocked`, 必填)、`name`(string)、`target`(string)、`content`(string)、`from`(string)、`note`(string)、`run`(boolean) |
308
- | `lean_lib` | `refresh`(boolean) |
309
-
310
- ### 六、错误码(本节新增,全部为**可读结果**而非异常)
311
-
312
- | 错误码 | 触发条件 |
313
- |---|---|
314
- | `V2_INVALID_ARGUMENT` | `file` 缺失 / 非 `.lean` / 越界路径;`kind` 非法;缺 `name`(`def`/`lemma`)或 `target`(`proof`/`blocked`);`content` 与 `from` 皆缺;`blocked` 的 `note` 为空;`from` 越界 |
315
- | `V2_NOT_FOUND` | 目标 `.lean` 文件不存在(越界但仍在 VibeMath 内的路径也走这里) |
316
- | `V2_WRITE_FAILED` | 归档文件写入失败 |
317
- | `LEAN_NOT_FOUND` | `resolveExecutable(leanCommand)` 失败(宿主上没装工具链) |
318
- | `LEAN_SPAWN_FAILED` | `subprocess.spawn` 抛错 |
319
- | `LEAN_RUN_FAILED` | `handle.done` 拒绝 |
320
- | `LEAN_TIMEOUT` | 运行耗时达到 `leanTimeoutMs` |
321
- | `NO_SUBPROCESS` | 宿主没有 `subprocess` 服务 |
322
-
323
- ### 七、提示词注入点
324
-
325
- | 提示词 | 注入内容 |
326
- |---|---|
327
- | `verifierReviewPrompt(r)` | `formalPromptBlock(r.rId)`(非 off 档)+ 判定指引 |
328
- | `verifierDebatePrompt(r, transcript)` | 同上——**辩论轮也必须带**,否则辩论阶段的代理会丢掉"审查对象已变成忠实性"这一变化 |
329
- | `solverPrompt` / `explorerPrompt` / `rederivePrompt` | `formalWorkLine()`("顺手形式化",`off` 档为空串)。可复用库的路径写 **`<VibeMath 根>/Formal/Proved/`**(`Formal/Proved/` 在项目根下并不存在,只写相对路径会让代理去项目里找一个永远找不到的目录) |
330
- | `vibe_math_status` / `vibe_math_report` / 卡片 / 索引 | 可读参数表、形式化记录概览、`- 形式化: <状态>` |
331
-
332
- 对象已 `passed` 时,验证提示词改为强调**忠实性审查**("你不需要重新检查推导");
333
- 已 `blocked` 时改为要求复核"这个阻塞判断是否成立"。
334
-
335
- **忠实性分支里的"撤回"措辞必须与档位一致**(契约 §4.1 第 3 条 / §6.1):
336
- `require` 档才有门禁,所以那里写"本次裁定**不定论**";
337
- `encourage` 档**没有**门禁,撤回证明并不等于搁置裁定,那里必须写明
338
- "**本档没有门禁**:框架不会强制搁置本次裁定——请务必给出弃权值,靠它阻止本轮得出布尔一致结论"。
339
- 承诺一个框架无法强制的"不定论",会让表决者以为不必自己弃权(审计清单 §1.7)。
340
-
341
- ### 八、门禁的实现位置
342
-
343
- - **`writeVerifiedCardIfNeeded(p)`**(命题卡片)与 **`writeVerifiedProblemCardIfNeeded(q)`**
344
- (问题卡片)——"写 Verified 卡片"的唯一收口点。返回 `{ok, deferred}`;被门禁搁置时
345
- 调用方**不得**再做 `布尔估计` / `已解决` / `优先级` 的提升。
346
- - **`settleVerdict(t, v)`**——验证裁定立即生效的那条路径。命题(`r.kind==='proposition'`)、
347
- 命题证明(`'prop-proof'`,仅当 v=1)、问题解法(`'problem-solution'`,仅当 v=1)
348
- 三条分支都在任何状态改动**之前**调用 `formalVerdictDeferred`;被搁置时直接返回,
349
- 对象状态分毫不动。
350
- - **`processStatusUpdates`**——概率=1 的**自动收口**路径。先申请卡片写入许可
351
- (`writeVerifiedCardIfNeeded(p, target)` / `writeVerifiedProblemCardIfNeeded(q, true)`),
352
- 拿到许可才写入 `布尔估计` / `已解决` / `优先级`;被搁置则整条跳过。
353
- - **门禁的判定记录一律取合并后的 `formalGateRecord`**(两套 id 都认,见 §四):
354
- `deferForFormal` 内部即如此。只看 `formalOf(rId)` 会让"代理用对象 id 归档 passed、rId 侧
355
- 还没有记录"这种首次形式化的真实状态被判成未形式化。
356
- - **`settleVerdict` 的「判断命题」转移路径**(`'problem-solution'` 且 `q.判断命题 && !sol.来源列表`):
357
- 它把**源命题**的 `布尔估计` 直接写成 0/1、置 `优先级 = 'never'` 并标记 `已验证`
358
- (此后不再入选验证),这是一次对源命题的布尔裁定;因此对 `v === 1 || v === 0` 必须先
359
- `deferForFormal(ap.id, …)`,被搁置时源命题的概率/优先级/已验证字段**分毫不动**。
360
- (v=1 会被上面那道门禁拦下,v=0 不会——只拦卡片而忽略返回值,会让一个未形式化的命题
361
- 被侧面判为"假"并永久退出调度。真实缺陷,已由套件第 15 节守住。)
362
-
363
- ### 九、回执通道(`formal` 字段)与 `defect` 语义
364
-
365
- > 对应契约 §4、§4.1、§6.3 与 §10 的第 8–11 条。**教训**:本特性首版只在提示词里写了
366
- > "请在回执的 formal 字段写明难度判断",框架**从不解析**它——难度判断静默消失,而套件只断言
367
- > "那句话存在",于是 177 条断言全绿却守着一条**死通道**。措辞断言不等于行为断言。
368
-
369
- #### 9.1 回执真的会被解析并落库
370
-
371
- - 回执契约里出现 `formal` 字段(`formalJsonField` 注入 `verifierReviewPrompt` 与
372
- `verifierDebatePrompt` 的 JSON 示例;`formalReplyNote()` 注入 solver/explorer 工作轮的
373
- "顺手形式化"段落):`{"formal":{"target":"p-x","decision":"used|blocked|defect","file":"Formal/p-x.lean","note":"难度判断/阻塞原因/具体偏差"}}`。
374
- - `absorbFormalFromReply(parsed, memberId)` 接受**顶层 `formal`** 与 **`meta.formal`** 两种位置,
375
- 在三条解析回执的路径上都被调用:`handleVerifier`(验证者)、`handleSolver`、`handleExplorer`
376
- (工作轮)。验证者路径里的调用**先于**裁定:`defect` 必须先把记录降级,紧随其后的
377
- `settleVerdict` 才会在 `require` 档把本次裁定正确地记为未定论。
378
- - `decision` 的落库:`blocked` → 记录 `blocked` + `note`;`defect` → 见 9.2;
379
- `used` → `attempted` + `file`,**但若该对象(两个 id 空间任一)已经是 `passed`/`blocked`,则保持原状态**
380
- ——一次"这一轮碰了形式化"的 `used` 回执**不得**撤销已成立的证明:无条件写 `attempted` 会让投票提示词
381
- 丢掉忠实性分支、`require` 档对一份已跑通的归档证明重新关门,而 `proof` 指针还留着(记录自相矛盾)。
382
- 撤销证明只有 `defect` 一条路(契约 §4)。
383
- - **拒绝规则**(返回 `V2_INVALID_ARGUMENT`,并在活动日志里公告,**不留下任何记录**):
384
- `blocked`/`defect` 的 `note` 为空;缺 `target`(`safeId('')` 会返回 `anon`,绝不允许凭空造记录);
385
- `decision` 不在三值之内。回执通道**绝不抛异常**进调度循环:一次记账失败不该吞掉一次表决。
386
-
387
- #### 9.2 `defect`:忠实性缺陷**不是**"命题为假"
388
-
389
- `passed` 只保证"这段 Lean 代码通过了内核检查",不保证它说的就是命题想说的。表决者逐条核对后
390
- 发现形式化写窄了/写宽了/换了对象/漏了条件时,那是**形式化不合格**,不是命题被证伪:
391
-
392
- - 若让表决者"发现偏差 → 投 0",框架记下的是"**该命题为假**"——用求真更严格的机制,
393
- 反而伪造出一个错误的否定结论。
394
- - 若只记成 `blocked`,门禁会**放行**(`blocked` 本就允许定论),等于带着一个坏形式化去定论。
395
-
396
- 因此 `defect` 是独立的一档,**语义固定**为:
397
-
398
- 1. **表决者**:不得投 `1` 或 `0`;给一个严格介于 0 与 1 之间的值(记为弃权),在 `Reason` 里写清偏差,
399
- 并用回执 `formal:{decision:'defect', note:'<具体偏差>'}` 记录(`note` 必填)。
400
- 2. **框架**(`formalDefectDowngrade`):把形式化记录**降级为 `attempted`**(无论此前是 `passed`
401
- 还是 `blocked`)、清空 `proof`、**撤回**归档证明(工作文件 `Formal/<id>.lean` 保留,代码不丢)、
402
- `note` 记入记录与 `Formal/TODO.md`、在活动日志里公告。
403
-
404
- 「撤回」不是"尽力删除"(`withdrawArchivedProof`):
405
- 1. 先尽力删除(有 `subprocess` 时走 shell),并用 fs **复核真的没了**;
406
- 2. 删不掉(宿主无 `subprocess`、权限、`rm -f` 静默失败)时,把撤回通知**覆写进那个路径**
407
- (`-- 已撤回(<时间>):该形式化被认定与命题原文不一致。` + 指向保留的工作文件),
408
- 使一份已撤回的证明**不可能**再被读成该对象的证明;
409
- 3. 活动日志如实说明发生了哪一种(删除 / 覆写成撤回通知 / ⚠ 两者都失败)。
410
- 候选路径 = **同一对象的全部 id 别名**(对象 id、`r-<id>`、`r-<id>-s0|pf<n>|rf<n>`)在记录里
411
- 引用的 `proof`,加上各 id 直接对应的 `Verified/Lean/<id>.lean`;只处理确实存在(或被记录引用)
412
- 的路径——宿主不能删除时"覆写"会把不存在的文件名**凭空造出来**。
413
- 3. **`require` 档**:降级后 `formalGateOk` 为假 ⇒ 本次裁定**不定论**(`formal-required`),
414
- 对象进入「形式化待办」。修正形式化并重新跑通后再投票。
415
- 4. **唯一可以投 0 的情形**:表决者**独立于这份 Lean 代码**也能确定命题为假(`Reason` 必须写清独立理由)。
416
- 提示词里因此明确写着"发现任何偏差,不要投 0",并且**不再出现**"偏离 → 0"这类指令。
417
-
418
- #### 9.3 两套 id 必须同时同步
419
-
420
- 验证记录以 **rId**(`r-pGate`、`r-q1-s0`)为键,而归档/索引/卡片读的可能是 **对象 id**(`pGate`)。
421
- 回执通道(`blocked` / `defect` / `used`)通过 `putFormalBothIds` 一次写全两侧:回执点名的那个 id、
422
- 它对应的另一侧、以及同一对象的其它验证别名(`r-<id>`、`r-<id>-s0`、`r-<id>-pf1`、`r-<id>-rf2`,
423
- 复用 `syncVerificationTarget` 的既有扫描)。id 解析只有一处 `formalObjectIdOf`(门禁合并查询
424
- `formalGateRecord` 也用它),**不新造第三套映射**。只写一侧的后果是静默错位:`defect` 只写到验证 id 上,
425
- 对象记录仍是 `passed`,`formalGateRecord` 从对象侧读回 `passed`、卡片照旧写"Lean 通过"。
426
-
427
- **这条映射不许"猜后缀"**:`r-<对象id>` 的**对象 id 本身可能以 `-sN`/`-pfN`/`-rfN` 结尾**
428
- (例如命题 `p-ineq-s1` 的验证 id 是 `r-p-ineq-s1`)。若无条件剥离后缀,`formalObjectIdOf` 会把对象
429
- 截成 `p-ineq` —— **另一个对象**:忠实性提示词会打印邻居的证明路径、`defect` 回执会降级邻居的记录并
430
- **撤回邻居的归档证明**,而真正的对象仍然 `passed`(实测复现:`formal-verify-v2` 的 ambiguity 用例在修
431
- 前 6 条断言变红,其中包含"邻居的证明被删除")。因此 `formalObjectIdOf` 按**权威度**取来源:
432
-
433
- 1. 验证任务自己的所有者(`tasks['verify:'+rId].r.pId | qid`)——框架生成 rId 时就知道对象是谁;
434
- 2. 记录里的 `objectId`(`syncVerificationTarget` 与 `putFormalBothIds` 在**手里有对象 id** 时写入,
435
- 因此跨 resume、任务表还没重建时也正确)——但读出来时要求**自洽**(不以 `r-` 开头):状态文件是可以
436
- 被人改的,一个 r 形锚点会让"验证 id → 对象 id"映射到它自己,于是"两套 id 一起写"退化成只写一侧;
437
- 3. 只有在两者都不可用时,才回退到字符串后缀解析。
438
-
439
- #### 9.4 提示词的三条硬要求
440
-
441
- - **工具名一律写全称**:注入文本里只出现注册名 `vibe_math_lean_run` / `vibe_math_lean_archive` /
442
- `vibe_math_lean_lib`;**不得**出现 `lean_run` / `lean_archive` / `lean_lib` 这类缩写——
443
- 那不是注册名,代理照抄会调用一个不存在的工具(工具自己返回的 `hint` 同样算注入文本)。
444
- - **归档可复用定义/引理前必须先跑通**:`vibe_math_lean_archive run=true` 或先 `vibe_math_lean_run`;
445
- 跑不通的代码不得进入 `Formal/Lib` / `Formal/Proved`,否则"可复用库"会被不编译的定义污染。
446
- - **工具链缺失时的出路必须写出来**:`LEAN_NOT_FOUND` 时把代码写下来归档,并在回执的 `note` 里写明
447
- "宿主无 Lean 工具链"——这算显式阻塞原因,`require` 档可以据此放行,代理不会因为装不了 Lean 而卡死。
448
-
449
- #### 9.5 人可读语料
450
-
451
- `prompt-corpus-v2/formal-verify-v2.json` 与 `.md` 由套件落盘(契约 §10.10):框架**真正发出**的每条提示词
452
- 原文,工作区路径归一化为 `<WS>`、VibeMath 根归一化为 `<VIBEMATH>`,因此可 diff、不泄露本机路径。
453
- 覆盖 off 档(无任何 Lean 文字)、encourage/require 的表决初评与辩论、`passed` 后的忠实性分支、
454
- 工作轮的「顺手形式化」段落与 formal 回执契约。套件带 `V2_CORPUS_DIR` 覆盖;当 `V2_PLUGIN` 指向
455
- 变异副本(灵敏度探针)时语料写到临时目录,避免把变异文本写进仓库。
456
-
457
- ### 十、测试
458
-
459
- `formal-verify-v2.test.mjs`(仓库根):用 **mock `subprocess` 服务**(假 Lean:文件中含
460
- `sorry` 或 `-- FAIL` 时 exit 1,否则 exit 0)跑通真实代码路径,覆盖 `off` 无操作、
461
- 参数校验与运行中切换、`encourage` 对 review/debate/work 三类提示词的注入、
462
- `passed` 后切忠实性措辞(并断言**不含**"偏离 → 0"、不含缩写工具名)、三个工具(绿灯/红灯/缺文件/
463
- 越界/非 .lean/缺工具链/四种归档/索引重建、`blocked` 必须有 note)、`require` 门禁(命题与问题两条
464
- 收口点、搁置→形式化→放行、卡片记录形式化状态、`resume` 后不遗忘、`encourage` 不设门禁),
465
- 以及**回执通道的行为断言**(契约 §10.8/§10.9):把带 `formal:{decision:'blocked'|'defect', note}`
466
- 的真实回执喂给框架,断言记录真的落库(`blocked` → `blocked` 且两套 id 同步;`defect` → `attempted`
467
- + `proof` 清空 + `Verified/Lean/<id>.lean` 被删 + `Formal/TODO.md` 出现条目 + 公告),断言缺 `note`
468
- 被 `V2_INVALID_ARGUMENT` 拒绝且不落记录,断言 `defect` 之后 `require` 档**不得定论**(无 Verified 卡片、
469
- 命题布尔估计不变),并落盘人可读语料(§9.5)。
470
-
471
- 后续补强(同一套件):
472
-
473
- - 第 4b 节:超时必须**主动**终止——mock 记录 `terminate()` 调用(`-- HANG` 文件模拟一个不会自己
474
- 结束的运行),断言返回 `LEAN_TIMEOUT` 且真的调用了 `terminate()`;并断言 `done` 先到时计时器
475
- 被清掉(套件用 test-only 的悬挂 `setTimeout` 计数;mock 自身的兜底用真实计时器,不污染计数)。
476
- - 第 13 节:归档写在**对象 id**、`rId` 侧还没有记录时,`require` 档仍必须能定论(门禁读合并记录),
477
- 且该对象**不得**被写进「形式化待办」。
478
- - 第 14 节:`defect` 的撤回覆盖**全部 id 别名**(归档写 `rId`、回执写对象 id 也能删干净);
479
- 宿主**不能删除**时(`{ noSubprocess: true }` 的宿主)归档路径必须不再包含原证明文本、并且带
480
- 撤回通知;活动日志必须说明"覆写"而不是"删除"。
481
- - 第 15 节:`require` 档必须拦住「判断命题」问题解法到**源命题**的转移(`布尔估计` / `优先级` /
482
- `已验证` / 概率=1 条目 / Verified 卡片全部不动,源命题进待办)。
483
- - 模式相关的忠实性措辞:`encourage` 档**不得**出现"本次裁定**不定论**"(改写为"本档没有门禁"),
484
- `require` 档**必须**出现(那里门禁真的会搁置裁定)。
485
- - `kind='def'/'lemma'` 运行未通过时,工具返回值**不得**声称"可直接 import 复用"。
486
-
487
- 套件支持 `V2_PLUGIN` 环境变量指向变异副本,供灵敏度探针使用。
1
+ # Vibe Mathematics —— 多代理数学问题求解与验证框架
2
+
3
+ > **状态说明(round-3 补记)**:本文是**设计期文档**,写于 `math_computation`(数学计算工具)、
4
+ > `leanAsync`/`leanJobsMaxParallel`/`leanSearchPaths`(Lean 异步作业与复用)、`paperEditor` 与
5
+ > `paper.lock.json`(最终论文定稿/写锁)等新功能之前;**功能与参数的权威描述以 `docs/` 为准**
6
+ > (`docs/math-computation.md`、`docs/formal-verification.md`、`docs/final-paper.md`、`docs/test-timing.md`),
7
+ > 参数表以 README 的双语「共用参数 / 各预设专属参数」表为准。本文保留其原始设计意图,不再逐条追平。
8
+
9
+ 项目需具备以下核心功能:
10
+
11
+ 1. **断点续跑**:保存各代理的对话记录及任务栈,支持状态恢复。
12
+ 2. **人工干预**:允许在任意时刻手动介入工作流,例如调整代理参数、控制会话、决策关键节点,并可随时在“人工 / 自动(预设)”模式间切换。
13
+ 3. **进度汇报**:每隔一段时间(如发生变动、出现新进展、发生新调用或代理会话结束时),委托主代理汇总当前进展及各代理状态。
14
+ 4. **多会话并行隔离**:DSH 的 agent preset 是 standing mount——同一 preset 的所有会话共享同一个插件实例,因此插件**必须自行按根会话 id 隔离内部状态**(`rootAgent`、当前项目、调度器、代理注册表、决策队列、参数、任务栈等全部 per-session)。两个会话可同时各跑一个项目,各自的子代理挂在各自会话名下、互不干扰;当前项目按会话持久化(`VibeMath/current.<会话id>.json`,兼容读取旧 `current.json`)。
15
+
16
+ ---
17
+
18
+ ## 路径与核心对象
19
+
20
+ ### 一、问题清单文件
21
+ 路径:`qs/qs.json`
22
+ 每个问题对象至少包含以下属性:
23
+
24
+ - `概述`:问题的完整描述;若包含预定义对象(数学对象、引理、定理名称等),需一并给出其完整定义。
25
+ - `已解决`:布尔值,标记当前是否已解决。
26
+ - `解法列表`:每个解法需包含:
27
+ - `完整解法`:详细步骤。
28
+ - `正确概率`:数值(越大越优先验证/调度)。
29
+ - `优先级`:整数(值越小越优先调度),支持动态调整(依据进度、可行性、难度、关键性、价值等)。若为 `never` 则永不调度。
30
+ - `progress`:过往进度与经验,包括各方向、路线的尝试记录、教训、阻碍及可行性评估。
31
+ - 其他必要属性(按需添加)。
32
+
33
+ ### 二、命题存储文件
34
+ 路径:`Propos/{分类名}_Propos.json`(按类型、领域或相关性分类,便于快速查阅)
35
+ 每个命题至少包含以下属性:
36
+
37
+ - `概述`:完整描述;含预定义对象时需补充其定义。
38
+ - `布尔估计`:当前命题为真的可能性(概率值)。
39
+ - `细类型`:JSON对象,如 `{"积分": {"不等式": {}}, "级数": {}}`。
40
+ - `证明列表`,`证伪列表`:每个条目包含:
41
+ - `完整过程`:证明或证伪的详细步骤。
42
+ - `正确概率`:数值(越大越优先验证/调度)。
43
+ - `支持信息/依据`:尽可能强的支撑证据。
44
+ - `优先级`:同问题清单,支持动态调整,`never` 表示永不调度。
45
+ - `progress`:过往进度与经验。
46
+ - 其他必要属性(按需添加)。
47
+
48
+ ### 三、可信赖文件(如参考文献)
49
+ 路径:`Reliable/`
50
+
51
+ ---
52
+
53
+ ## 权限与参数
54
+
55
+ - **权限**(可通过参数调控):
56
+ 所有任务及子代理在运行过程中,**默认允许**:
57
+ - 读取 `Verified/` 路径下的任何文件作为已知依赖;
58
+ - 不限次数调用外部工具(搜索引擎、符号计算库、论文数据库)进行文献检索或数值辅助验证。
59
+ - **参数**:
60
+ (此处可扩展具体参数设置,尽量能够实现尽量多的调控)
61
+
62
+ 所有代理基于 `Propos/` 和 `Reliable/` 作为已有认知进行推理与判断。额外告知子代理:可借助工具通过索引读取 JSON,粗读定位关键索引,再细读具体内容。
63
+
64
+ ---
65
+
66
+ ## 调度器
67
+
68
+ ### 注意事项
69
+ 1. 所有涉及调用新代理的操作,必须等待 `active_sub_agents_count < MAX_PARALLEL_THRESHOLD` 时方可执行。
70
+ 2. 主程序的控制以编程方式实现,不由代理自行调度。
71
+ 3. 若 `Propos/` 中存在重要性、关键性足够高但尚未证明或证伪的命题,可将其加入问题清单,供后续求解器调度。
72
+ 4. 当某个问题的解法列表中存在正确概率为 `1` 的解法时,该问题状态更新为“已解决”,优先级设为 `never`。当某个命题的证明/证伪列表中存在正确概率为 `1` 的证明/证伪时,该命题的正确概率更新为 `1`(或 `0`),优先级设为 `never`。
73
+
74
+ ### 主循环
75
+ **终止条件**:问题清单中所有问题均已解决,则终止。
76
+
77
+ 循环可执行以下两个任务:
78
+
79
+ #### 1. 求解与扩充待验证解法和结论
80
+ - **目标**:按优先级提取问题,调用求解器,确定方向并发放任务。
81
+ 过程中获得的所有有价值结论/命题及其证明,加入 `Propos/` 并标注属性(可由相应代理决策,但须符合规则)。
82
+ 若完成原问题求解,则将解法加入对应问题的解法列表,并标注属性。
83
+ - **具体实现**:
84
+ ~~~
85
+ 按优先级从 `qs.json` 中取出未解决问题 `q`,调用一个子代理(类型标识为 `explorer-{q}`)执行 `solve(q)`。
86
+ ~~~
87
+
88
+ #### 2. 验证/判定与更新数据
89
+ - **目标**:按优先级验证问题清单中的解法、`Propos/` 中的命题或命题的证明,并更新其属性。
90
+ - **具体实现**:
91
+ ~~~
92
+ 按优先级从 `qs.json` 或 `Propos/` 中选择尚未解决/未达`1/0`概率的“命题”、“命题+证明/证伪”或“问题+解法”作为 `r` ,执行 `验证器(r)`。(只有当“命题”的证明、证伪列表为空时才允许选择单个“命题“作为 `r` )
93
+ ~~~
94
+
95
+ ## 核心函数定义
96
+
97
+ ### 1. `solve(q)`
98
+
99
+ **构建大方向集 `M_q`**(按数学方法论分类):
100
+
101
+ - 若 `q.progress` 为空:
102
+ 1. 进行第一阶段**元认知头脑风暴**(约束分解、边界极端测试、相似问题映射);
103
+ 2. 将解法拆分为多个**截然不同**的尝试方向 `m_i`(如解析法、构造性证明、反证法、数值逼近+极限过渡、范畴论抽象等);
104
+ 3. 记录每个方向的核心假设与初始可行性预估至 `q.progress`,形成初始集合 `M_q = {m_i}`。
105
+
106
+ - 若 `q.progress` 非空:
107
+ 1. 读取并解析已有进度,对各方向的**历史进展、遇阻原因、可行性衰减曲线**进行量化分析;
108
+ 2. 筛除已被充分证明为“死路”的方向(除非有新工具引入);
109
+ 3. 基于当前痛点,**深度推导**出 1~3 个从未尝试过的新方向(附推导动机);
110
+ 4. 将“遗留高潜方向”与“新生方向”取并集,重构为新的 `M_q`。
111
+
112
+ **任务分配与迭代求解**:
113
+ 将 `M_q` 中的每个 `m_i` 独立分配给一个专属子代理(类型标识为 `Solver-{q}`),并发执行 `agent_self_iteration(q, m_i)`。
114
+
115
+ ---
116
+
117
+ ### 2. `agent_self_iteration(q, m)`
118
+
119
+ **角色定位**:专注执行方向 `m` 的深度研究,具备自主切换子路线、设定临时假设、自我批判的能力。
120
+
121
+ **执行流程**(同会话内持续迭代):
122
+
123
+ 1. **起点定位**:参考 `q.progress` 中方向 `m` 的最后记录节点,决定是继承进度继续深挖,还是在大方向下另辟蹊径。
124
+ 2. **单次迭代动作**(每轮对话):
125
+ - 尝试推进证明/计算;
126
+ - **必须产出**(即使未完全解决):
127
+ - 本次推导出的**新引理/中间结论**及其完整证明;
128
+ - 尝试过的各具体子路线及其进度(概述整个子路线的经历及当前进度)、可行性情况、**明确的可行性信号**(如“遇到不可消除的奇点”、“与某已知定理冲突”等)、遇到的障碍、不可行的原因等;
129
+ - 更新对方向 `m` 的整体存活概率评估。
130
+ 3. **分支递归(`q_sub` 严格化)**:若遇到**复杂度极高**的附属猜想/子问题 `q_sub`(`q_sub` 为**问题类对象**):
131
+ - 记 `p_{q-tmp}` 为对 `q_sub` 的某种回答/答案的**临时假设**(**命题类对象**);
132
+ - 把**临时问题 `q_sub`** 与**「判断下述命题是否成立:`p_{q-tmp}`」**两个问题一起加入 `qs.json`(两者的概述、定义必须完整——所涉及的对象、依赖、环境、背景等一律给出完整定义,避免断章取义);
133
+ - 将 `p_{q-tmp}` 作为命题对象写入 `Propos/`(布尔估计记 `0.5`,`progress` 标注“临时假设 · 依赖 `q_sub`”);若该假设被证伪,则依赖它的主线结论需重新审视;
134
+ - 依赖关系**必须落库**:处在某条在力假设之下的引理会带上 `依赖假设` 字段(`vibe_math_list_propositions`
135
+ 与验证提示词都会显示它),假设被证伪时依赖它的结论被标记 `依赖假设已证伪` 并重新进入验证候选;
136
+ - “判断下述命题是否成立:p_{q-tmp}”这个问题**自带一条种子解法**(就是"该假设成立"这一候选回答,概率 `0.5`,
137
+ 不是定论)。没有它,验证候选集里永远没有属于这个问题的对象(裸 `p-tmp-*` 命题被显式跳过),
138
+ 于是 `p_{q-tmp}` 永远停在 `0.5`、判断问题永不收口、终止规则不可达;
139
+ - 在当前线程中,**临时假设 `p_{q-tmp}` 成立**,继续推进主线;
140
+ - 后续所得命题/结论中**凡依赖该假设的**,必须把假设作为前提显式写出,形如「若 `p_{q-tmp}` 成立,则:...」(概述、定义完整,不断章取义)。
141
+ 4. **终止条件(进入 `END` 状态)**:
142
+ - **成功**:得到完整的 `q` 解法,并执行严格的**自我对抗性检查**(尝试构造反例,检查边界条件)。若自检不通过,修正后重新计数迭代;
143
+ - **失败/超时**:迭代次数达到预设上限(如 3 轮),或判定方向 `m` 已无可行路径。
144
+ 5. **最终输出(原子写入)**:
145
+ - 若得到原问题 `q` 的解法,则写入 `qs.json` 中对应问题的解法列表,并设置属性。注意写入时,该解法的正确概率必须小于 `1`(待验证器验证)。
146
+ - 将所有产出的结论/命题及完整证明写入 `Propos/`,合理设置属性(如优先级反映其对原问题解决的重要性/关键性程度)。写入时,命题的正确概率必须小于 `1`(待验证器验证)。
147
+ - 将过程中所有失败路线的详细归因,以及对问题的各个方向下各个路线、尝试的进度/进展及经验教训、遇到的阻碍、可行性评估等写入 `q.progress`。
148
+
149
+ ---
150
+
151
+ ### 3. `验证器(r)`
152
+
153
+ **核心机制**:多代理独立审查 → 同步辩论(“交流群”)→ 共识达成(或强制裁决)。
154
+
155
+ **输入**:单个验证对象 `r`,允许为:
156
+ - 单个命题;
157
+ - 命题与命题的证明/证伪;
158
+ - 问题与问题的解法。
159
+
160
+ 分别进行对应判定:
161
+ - 命题是否成立;
162
+ - 命题的证明/证伪过程是否正确;
163
+ - 问题的解法是否正确。
164
+
165
+ **执行策略**:
166
+
167
+ 1. **独立审查阶段**
168
+ - 向多个子代理(身份为“严苛审稿人”)分别发送 `r`,每个代理多次检查待验证对象是否成立。要求各代理独立输出初始审查报告,包含:
169
+ - `Result`:所判定对象正确的概率值,取值 `[0,1]`(仅当判定为确定正确或错误时取 `1` 或 `0`,否则介于两者之间)。
170
+ - `Reason`:详细逻辑链、潜在反例、支撑依据。若判定为 `0`,则 `Reason` 为严谨完整的证伪过程;若 `r` 为单个命题且判定为 `1`,则 `Reason` 为该命题的完整证明。
171
+ - 所有代理在收到彼此报告前不得互相通信,确保初始判断独立无偏。
172
+
173
+ 2. **辩论阶段(“交流群”轮流发言)**
174
+ - 所有代理进入同一虚拟“交流群”,按随机或既定顺序依次发言,每轮发言需包含:
175
+ - 当前自己的 `Result` 与 `Reason`;
176
+ - 对其他代理先前发言的回应(赞同、反驳或提出新证据);
177
+ - 若因他人意见改变立场,需明确说明转变理由。
178
+ - 辩论持续多轮(例如上限 5 轮),每轮每个代理必须发言一次。
179
+ - 每轮结束后检查是否所有代理的 `Result` 已一致(全为 `1` 或全为 `0`):
180
+ - 若一致,立即终止辩论,进入最终输出;
181
+ - 若不一致,继续下一轮,直至达到最大轮数。
182
+
183
+ 3. **共识判定与强制裁决**
184
+ - 若达到最大轮数后仍未一致,则按预设参数采用以下方式之一:
185
+ - 均衡机制(`verdictMode='flat'`):取各评审**自报概率的均值**(只有精确的 `1`/`0` 才是绝对真/假,
186
+ `0<Result<1` 是"它为真的概率";不再把高置信分歧折叠成固定的 `0.5`);
187
+ - 强制裁决机制(`verdictMode='forced'`):按验证者的历史准确率与布尔票置信度加权求平均,得到
188
+ `(0,1)` 内的判定结果。准确率按**稳定身份**(`provider/model`)记,且只在对象**后来**取得布尔
189
+ 定论时回溯计分——按一次性的子代理 id 记(恒 `0.5`)或拿本次聚合值给同一批评审打分都是自指的。
190
+ - 无论哪种机制,中段结果(`0<r<1`)都**不是**定论:对象重新变为可验证(冷却期后重新入选),
191
+ 绝不把中段结果当成绝对真/假来写卡片或收口。
192
+ - 每次裁定需要**至少 2 名独立评审**:票数不足时先补派,补不足就搁置该对象等冷却期后重试,
193
+ 绝不退化成单票结论。为保证"另一个对象也凑得齐 2 票",单个验证对象同时占用的评审槽位不超过
194
+ `maxParallelThreshold - 2`(容量宽裕时就是 `verifierCount`)。
195
+
196
+ 4. **更新数据**
197
+ - 若 `r` 为单个命题,则记 `a = r`;若 `r` 为“命题+证明/证伪”或“问题+解法”,则记 `a` 为 `r` 中的那个证明/证伪/解法。
198
+ - 若判定对象是**命题本身**且结果为 `0`:更新 `a` 的布尔估计为 `0`,并将完整证伪过程记录到证伪列表(概率 `1`);
199
+ - 若判定对象是**某一条证明/证伪**且结果为 `0`:那只表示**这一条过程无效**(`a` 的正确概率记 `0`、`已验`),
200
+ **不是**"命题为假"——绝不因此向对侧列表伪造一条概率 `1` 的反条目,也绝不改写命题的布尔估计。
201
+ 伪否定会经由收口规则变成一张"已验证·假"的卡片,那正是这条规则要避免的(与 `defect` 同类事故)。
202
+ - 若判定结果为 `1`:更新 `a` 的正确概率为 `1`,并将完整证明过程记录到证明列表;
203
+ - 若判定结果介于 `0` 和 `1` 之间:更新 `a` 的正确概率为该结果,并分别向证明、证伪列表添加根据辩论得出的尽可能正确的过程/支撑信息及相应概率;对象在冷却期后重新进入验证候选(中段值不是定论)。
204
+ - 辩论全程发言记录存入 `Verification_logs/` 对应日志,便于复盘与审计。
205
+
206
+ ---
207
+ ---
208
+
209
+ ## Lean 形式化验证(`formalVerify`)
210
+
211
+ > 本节实现 `docs/formal-verification.md` 中 v2/v3/v4/v5 **共用契约**;参数名、路径、
212
+ > 工具名、提示词语义、门禁规则、索引格式都与该契约一致。
213
+
214
+ **为什么要有它**:多代理交叉验证的本质是**共识**,不是**证明**。Lean 把"我认为"换成"机器已核对",
215
+ 于是验证的**审查对象**从"推导是否正确"变成**"Lean 代码是否忠实于命题原文"**(定义/对象/条件/假设/结论
216
+ 是否逐条一致)——后者人(和代理)确实审得动。注意 `passed` **不等于**命题为真:它只表示"形式化代码
217
+ 通过了内核检查",忠实性仍需 m 票审查。
218
+
219
+ ### 一、参数(四个,与其它架构同名同语义)
220
+
221
+ | 参数 | 类型 | 取值 | 默认 | 含义 |
222
+ |---|---|---|---|---|
223
+ | `formalVerify` | enum | `off` \| `encourage` \| `require` | `off` | 三档开关,见下 |
224
+ | `leanCommand` | string | 任意可执行文件名 | `lean` | 要执行的 Lean 可执行文件(例:`lake`) |
225
+ | `leanArgs` | string[] | —— | `[]` | 插在 `.lean` 文件名**之前**的附加参数(例:`["env","lean"]` 配合 `leanCommand="lake"`) |
226
+ | `leanTimeoutMs` | integer | 正整数(下限 1000) | `120000` | 单次 Lean 运行的超时上限(毫秒) |
227
+
228
+ - 四个参数都出现在:`vibe_math_set_params` 的 schema、`PARAM_SCHEMA`
229
+ (`vibe_math_setup` / `vibe_math_template` / `/vibe setup` 的参数表)、`vibe_math_status`
230
+ 与 `vibe_math_report` 的可读参数表,并随 `vibe_math_setting.json` 持久化。
231
+ - **校验规则**:`formalVerify` 非三档之一 → 回退 `off`(**绝不**回退到更强的档位:一个拼写
232
+ 错误若静默启用强制形式化,会让所有结论被门禁拦下);非正的 `leanTimeoutMs` → 删除该键并回退
233
+ 默认值;空白的 `leanCommand` → 回退 `lean`。
234
+ - **模式是动态的**:所有与档位相关的提示词文本都在**构造提示词的那一刻**由 `params.formalVerify`
235
+ 现算(`formalPromptBlock` / `formalWorkLine`),不写进任何"入职时冻结"的快照;运行中切换档位
236
+ 后,下一条提示词立即反映新模式。
237
+
238
+ ### 二、三档语义
239
+
240
+ - **`off`(默认)= 真正的无操作**:提示词里不出现任何 Lean 字样;验证流程、门禁、归档行为与
241
+ 改动前完全一致(卡片里也不写形式化行)。三个 Lean 工具**仍然注册**(注册是静态的),
242
+ 只是框架不告诉代理它们存在;人/代理主动调用时照常工作。
243
+ - **`encourage` = 鼓励但不强制**:验证提示词注入"先判断实现难度,能形式化就优先写 Lean;
244
+ 一旦 Lean 通过,你唯一需要确认的就是**忠实性**";平时工作提示词注入"顺手形式化"段落
245
+ (把常用/可能复用的对象、假设、新定义归档到全局库,写之前先 `lean_lib` 查重)。
246
+ **不设门禁**:没有任何 Lean 产物时验证照常收口。
247
+ - **`require` = 强制 + 门禁**:注入同样的文本但语气为"必须",并在"写 Verified 卡片/判定定论"
248
+ 这**唯一的收口点**加门禁——对象的形式化状态必须是 `passed`(有 Lean 产物且最近一次运行
249
+ `exitCode === 0`)或 `blocked`(代理给出了显式难度判断/阻塞原因,`note` 非空);
250
+ 否则本次裁定**不生效**:记为 `undecided`(原因 `formal-required`)、写入 `Formal/TODO.md`、
251
+ 在活动日志里公告、**不写** Verified 卡片、**不改变**对象原有的概率/权重字段
252
+ (`布尔估计` / `已解决` / `优先级` 一律保持原状),对象留在原库,可形式化后再次提议验证。
253
+ 门禁是**兜底**:正常情况下验证提示词已先告知表决者要么形式化、要么记录阻塞。
254
+
255
+ ### 三、路径布局
256
+
257
+ ```
258
+ <VibeMath 根>/
259
+ ├─ Formal/ # 全局可复用 Lean 库(跨项目,故意在项目树之外)
260
+ │ ├─ Lib/<name>.lean + Lib/Index.md # 可复用定义/对象/假设
261
+ │ └─ Proved/<name>.lean + Proved/Index.md # 已成立的命题/引理(机器已核对)
262
+ └─ Projects/<项目>/
263
+ ├─ Formal/<对象id>.lean # 该对象的形式化工作文件
264
+ ├─ Formal/Index.md # 对象 → 状态 → 文件 → 归档证明 → 运行结果 → 难度判断
265
+ ├─ Formal/TODO.md # require 模式下的「形式化待办」
266
+ └─ Verified/Lean/<对象id>.lean # 归档证明:与定论卡片同处 Verified/
267
+ ```
268
+
269
+ - 文件 id 一律过 v2 既有的 id 安全化函数 `safeId`(去分隔符、去 `..`),防止路径穿越。
270
+ - `lean_run` 只接受位于 **`<VibeMath 根>`** 之内的路径。边界是 VibeMath 根而**不是**项目根:
271
+ 全局库有意放在项目树之外,所以"爬出项目但仍留在 VibeMath 内"合法;爬出 VibeMath 根之上、
272
+ 或一个不相干的绝对路径/Windows 绝对路径,一律拒绝(`V2_INVALID_ARGUMENT`)。
273
+ 实现用纯词法规范化(`normalizeAbsPath` + `leanAbsPath`),不做文件系统访问——
274
+ 单纯的 `startsWith(root)` 挡不住 `…/Projects/../../../../etc/evil.lean`。
275
+
276
+ ### 四、对象的形式化记录与持久化
277
+
278
+ 每个对象一条 `formal` 记录:`{status: none|attempted|passed|blocked, file, proof, decision, note, run:{at,ok,exitCode,ms,stdoutTail,stderrTail}, updatedAt}`。
279
+ v2 **没有会话投影**,所以记录与待办一起持久化在 v2 自己的状态文件
280
+ `VibeMath_State/formal.json`(由既有 `readJson`/`writeJson` 读写,随 `saveAll` 落盘、`loadState`
281
+ 读回),因此 `resume` 之后门禁不会"失忆"。索引 `Formal/Index.md` 是它的人类可读镜像。
282
+
283
+ **两套 id 的对齐**:验证对象用 rId(如 `r-pGate`、`r-q1-s0`),而代理归档时给的是对象 id
284
+ (如 `pGate`)。`lean_archive` 在写归档记录的同时同步 `r-<对象id>` 的验证记录;
285
+ 门禁与提示词取记录时两个方向都认(`formalGateRecord`),避免"代理确实形式化了,门禁却仍
286
+ 按未尝试处理"的假阴性。
287
+
288
+ > **必须注意**:`syncVerificationTarget` 只更新**已经存在**的别名键,所以"归档写了对象 id、
289
+ > rId 侧还没有记录"是首次形式化后的**真实状态**。因此**门禁的判定**也必须走
290
+ > `formalGateRecord`(`deferForFormal`),不能只看 `formalOf(rId)`:否则一个已 `passed`
291
+ > 的对象会被判为未形式化,而且这次搁置本身会写下 `r-<id> = status:'none'`,此后每一轮都
292
+ > 继续搁置并重开一次完整辩论——对象**永远无法定论**(真实缺陷,已由套件第 13 节守住)。
293
+
294
+ ### 五、三个工具
295
+
296
+ | 工具 | 作用 |
297
+ |---|---|
298
+ | `vibe_math_lean_run` | 在 `<VibeMath 根>` 内的一个 `.lean` 文件上执行工具链并原样回报:`{ok, exitCode, signal, ms, command, stdout, stderr, file, timedOut}`;`target=<对象 id>` 时同时记录该对象的运行结果。**绝不向调度循环抛异常**:工具链缺失 → `LEAN_NOT_FOUND`;宿主无 `subprocess` 服务 → `NO_SUBPROCESS`;spawn 失败 → `LEAN_SPAWN_FAILED`;超时 → `LEAN_TIMEOUT`。**超时是主动的**(契约 §7):`handle.done` 与一个 `cap` 毫秒的计时器竞速,计时器到点时尽力调用 `handle.terminate()`,再给出可读的超时结果;`done` 先到就清掉计时器(不留悬挂 timer)。 |
299
+ | `vibe_math_lean_archive` | `kind='def'` → 全局 `Formal/Lib/<name>.lean`;`kind='lemma'` → 全局 `Formal/Proved/<name>.lean`(两者都会重建对应 `Index.md`;`run:false` 可跳过执行)。`kind='proof'` → `Formal/<target>.lean`,且**该文件最近一次运行通过**时再写 `Verified/Lean/<target>.lean` 并把对象标为 `passed`,否则标为 `attempted`。`kind='blocked'` → 记录显式难度判断/阻塞原因(`note` 空 → 拒绝)并把对象标为 `blocked`。`kind='def'/'lemma'` 的返回值在**运行未通过**时不得声称"可直接 import 复用"(工具返回值同样是代理读到的文字)。 |
300
+ | `vibe_math_lean_lib` | 扫描并重建三处索引(项目 `Formal/Index.md`、全局 `Lib/Index.md`、全局 `Proved/Index.md`),返回可复用库清单,供代理写新定义前查重;`refresh:false` 时只读不重建 |
301
+
302
+ 参数 schema:
303
+
304
+ | 工具 | 参数 |
305
+ |---|---|
306
+ | `lean_run` | `file`(string, 必填)、`target`(string)、`timeout_ms`(integer) |
307
+ | `lean_archive` | `kind`(enum: `def`\|`lemma`\|`proof`\|`blocked`, 必填)、`name`(string)、`target`(string)、`content`(string)、`from`(string)、`note`(string)、`run`(boolean) |
308
+ | `lean_lib` | `refresh`(boolean) |
309
+
310
+ ### 六、错误码(本节新增,全部为**可读结果**而非异常)
311
+
312
+ | 错误码 | 触发条件 |
313
+ |---|---|
314
+ | `V2_INVALID_ARGUMENT` | `file` 缺失 / 非 `.lean` / 越界路径;`kind` 非法;缺 `name`(`def`/`lemma`)或 `target`(`proof`/`blocked`);`content` 与 `from` 皆缺;`blocked` 的 `note` 为空;`from` 越界 |
315
+ | `V2_NOT_FOUND` | 目标 `.lean` 文件不存在(越界但仍在 VibeMath 内的路径也走这里) |
316
+ | `V2_WRITE_FAILED` | 归档文件写入失败 |
317
+ | `LEAN_NOT_FOUND` | `resolveExecutable(leanCommand)` 失败(宿主上没装工具链) |
318
+ | `LEAN_SPAWN_FAILED` | `subprocess.spawn` 抛错 |
319
+ | `LEAN_RUN_FAILED` | `handle.done` 拒绝 |
320
+ | `LEAN_TIMEOUT` | 运行耗时达到 `leanTimeoutMs` |
321
+ | `NO_SUBPROCESS` | 宿主没有 `subprocess` 服务 |
322
+
323
+ ### 七、提示词注入点
324
+
325
+ | 提示词 | 注入内容 |
326
+ |---|---|
327
+ | `verifierReviewPrompt(r)` | `formalPromptBlock(r.rId)`(非 off 档)+ 判定指引 |
328
+ | `verifierDebatePrompt(r, transcript)` | 同上——**辩论轮也必须带**,否则辩论阶段的代理会丢掉"审查对象已变成忠实性"这一变化 |
329
+ | `solverPrompt` / `explorerPrompt` / `rederivePrompt` | `formalWorkLine()`("顺手形式化",`off` 档为空串)。可复用库的路径写 **`<VibeMath 根>/Formal/Proved/`**(`Formal/Proved/` 在项目根下并不存在,只写相对路径会让代理去项目里找一个永远找不到的目录) |
330
+ | `vibe_math_status` / `vibe_math_report` / 卡片 / 索引 | 可读参数表、形式化记录概览、`- 形式化: <状态>` |
331
+
332
+ 对象已 `passed` 时,验证提示词改为强调**忠实性审查**("你不需要重新检查推导");
333
+ 已 `blocked` 时改为要求复核"这个阻塞判断是否成立"。
334
+
335
+ **忠实性分支里的"撤回"措辞必须与档位一致**(契约 §4.1 第 3 条 / §6.1):
336
+ `require` 档才有门禁,所以那里写"本次裁定**不定论**";
337
+ `encourage` 档**没有**门禁,撤回证明并不等于搁置裁定,那里必须写明
338
+ "**本档没有门禁**:框架不会强制搁置本次裁定——请务必给出弃权值,靠它阻止本轮得出布尔一致结论"。
339
+ 承诺一个框架无法强制的"不定论",会让表决者以为不必自己弃权(审计清单 §1.7)。
340
+
341
+ ### 八、门禁的实现位置
342
+
343
+ - **`writeVerifiedCardIfNeeded(p)`**(命题卡片)与 **`writeVerifiedProblemCardIfNeeded(q)`**
344
+ (问题卡片)——"写 Verified 卡片"的唯一收口点。返回 `{ok, deferred}`;被门禁搁置时
345
+ 调用方**不得**再做 `布尔估计` / `已解决` / `优先级` 的提升。
346
+ - **`settleVerdict(t, v)`**——验证裁定立即生效的那条路径。命题(`r.kind==='proposition'`)、
347
+ 命题证明(`'prop-proof'`,仅当 v=1)、问题解法(`'problem-solution'`,仅当 v=1)
348
+ 三条分支都在任何状态改动**之前**调用 `formalVerdictDeferred`;被搁置时直接返回,
349
+ 对象状态分毫不动。
350
+ - **`processStatusUpdates`**——概率=1 的**自动收口**路径。先申请卡片写入许可
351
+ (`writeVerifiedCardIfNeeded(p, target)` / `writeVerifiedProblemCardIfNeeded(q, true)`),
352
+ 拿到许可才写入 `布尔估计` / `已解决` / `优先级`;被搁置则整条跳过。
353
+ - **门禁的判定记录一律取合并后的 `formalGateRecord`**(两套 id 都认,见 §四):
354
+ `deferForFormal` 内部即如此。只看 `formalOf(rId)` 会让"代理用对象 id 归档 passed、rId 侧
355
+ 还没有记录"这种首次形式化的真实状态被判成未形式化。
356
+ - **`settleVerdict` 的「判断命题」转移路径**(`'problem-solution'` 且 `q.判断命题 && !sol.来源列表`):
357
+ 它把**源命题**的 `布尔估计` 直接写成 0/1、置 `优先级 = 'never'` 并标记 `已验证`
358
+ (此后不再入选验证),这是一次对源命题的布尔裁定;因此对 `v === 1 || v === 0` 必须先
359
+ `deferForFormal(ap.id, …)`,被搁置时源命题的概率/优先级/已验证字段**分毫不动**。
360
+ (v=1 会被上面那道门禁拦下,v=0 不会——只拦卡片而忽略返回值,会让一个未形式化的命题
361
+ 被侧面判为"假"并永久退出调度。真实缺陷,已由套件第 15 节守住。)
362
+
363
+ ### 九、回执通道(`formal` 字段)与 `defect` 语义
364
+
365
+ > 对应契约 §4、§4.1、§6.3 与 §10 的第 8–11 条。**教训**:本特性首版只在提示词里写了
366
+ > "请在回执的 formal 字段写明难度判断",框架**从不解析**它——难度判断静默消失,而套件只断言
367
+ > "那句话存在",于是 177 条断言全绿却守着一条**死通道**。措辞断言不等于行为断言。
368
+
369
+ #### 9.1 回执真的会被解析并落库
370
+
371
+ - 回执契约里出现 `formal` 字段(`formalJsonField` 注入 `verifierReviewPrompt` 与
372
+ `verifierDebatePrompt` 的 JSON 示例;`formalReplyNote()` 注入 solver/explorer 工作轮的
373
+ "顺手形式化"段落):`{"formal":{"target":"p-x","decision":"used|blocked|defect","file":"Formal/p-x.lean","note":"难度判断/阻塞原因/具体偏差"}}`。
374
+ - `absorbFormalFromReply(parsed, memberId)` 接受**顶层 `formal`** 与 **`meta.formal`** 两种位置,
375
+ 在三条解析回执的路径上都被调用:`handleVerifier`(验证者)、`handleSolver`、`handleExplorer`
376
+ (工作轮)。验证者路径里的调用**先于**裁定:`defect` 必须先把记录降级,紧随其后的
377
+ `settleVerdict` 才会在 `require` 档把本次裁定正确地记为未定论。
378
+ - `decision` 的落库:`blocked` → 记录 `blocked` + `note`;`defect` → 见 9.2;
379
+ `used` → `attempted` + `file`,**但若该对象(两个 id 空间任一)已经是 `passed`/`blocked`,则保持原状态**
380
+ ——一次"这一轮碰了形式化"的 `used` 回执**不得**撤销已成立的证明:无条件写 `attempted` 会让投票提示词
381
+ 丢掉忠实性分支、`require` 档对一份已跑通的归档证明重新关门,而 `proof` 指针还留着(记录自相矛盾)。
382
+ 撤销证明只有 `defect` 一条路(契约 §4)。
383
+ - **拒绝规则**(返回 `V2_INVALID_ARGUMENT`,并在活动日志里公告,**不留下任何记录**):
384
+ `blocked`/`defect` 的 `note` 为空;缺 `target`(`safeId('')` 会返回 `anon`,绝不允许凭空造记录);
385
+ `decision` 不在三值之内。回执通道**绝不抛异常**进调度循环:一次记账失败不该吞掉一次表决。
386
+
387
+ #### 9.2 `defect`:忠实性缺陷**不是**"命题为假"
388
+
389
+ `passed` 只保证"这段 Lean 代码通过了内核检查",不保证它说的就是命题想说的。表决者逐条核对后
390
+ 发现形式化写窄了/写宽了/换了对象/漏了条件时,那是**形式化不合格**,不是命题被证伪:
391
+
392
+ - 若让表决者"发现偏差 → 投 0",框架记下的是"**该命题为假**"——用求真更严格的机制,
393
+ 反而伪造出一个错误的否定结论。
394
+ - 若只记成 `blocked`,门禁会**放行**(`blocked` 本就允许定论),等于带着一个坏形式化去定论。
395
+
396
+ 因此 `defect` 是独立的一档,**语义固定**为:
397
+
398
+ 1. **表决者**:不得投 `1` 或 `0`;给一个严格介于 0 与 1 之间的值(记为弃权),在 `Reason` 里写清偏差,
399
+ 并用回执 `formal:{decision:'defect', note:'<具体偏差>'}` 记录(`note` 必填)。
400
+ 2. **框架**(`formalDefectDowngrade`):把形式化记录**降级为 `attempted`**(无论此前是 `passed`
401
+ 还是 `blocked`)、清空 `proof`、**撤回**归档证明(工作文件 `Formal/<id>.lean` 保留,代码不丢)、
402
+ `note` 记入记录与 `Formal/TODO.md`、在活动日志里公告。
403
+
404
+ 「撤回」不是"尽力删除"(`withdrawArchivedProof`):
405
+ 1. 先尽力删除(有 `subprocess` 时走 shell),并用 fs **复核真的没了**;
406
+ 2. 删不掉(宿主无 `subprocess`、权限、`rm -f` 静默失败)时,把撤回通知**覆写进那个路径**
407
+ (`-- 已撤回(<时间>):该形式化被认定与命题原文不一致。` + 指向保留的工作文件),
408
+ 使一份已撤回的证明**不可能**再被读成该对象的证明;
409
+ 3. 活动日志如实说明发生了哪一种(删除 / 覆写成撤回通知 / ⚠ 两者都失败)。
410
+ 候选路径 = **同一对象的全部 id 别名**(对象 id、`r-<id>`、`r-<id>-s0|pf<n>|rf<n>`)在记录里
411
+ 引用的 `proof`,加上各 id 直接对应的 `Verified/Lean/<id>.lean`;只处理确实存在(或被记录引用)
412
+ 的路径——宿主不能删除时"覆写"会把不存在的文件名**凭空造出来**。
413
+ 3. **`require` 档**:降级后 `formalGateOk` 为假 ⇒ 本次裁定**不定论**(`formal-required`),
414
+ 对象进入「形式化待办」。修正形式化并重新跑通后再投票。
415
+ 4. **唯一可以投 0 的情形**:表决者**独立于这份 Lean 代码**也能确定命题为假(`Reason` 必须写清独立理由)。
416
+ 提示词里因此明确写着"发现任何偏差,不要投 0",并且**不再出现**"偏离 → 0"这类指令。
417
+
418
+ #### 9.3 两套 id 必须同时同步
419
+
420
+ 验证记录以 **rId**(`r-pGate`、`r-q1-s0`)为键,而归档/索引/卡片读的可能是 **对象 id**(`pGate`)。
421
+ 回执通道(`blocked` / `defect` / `used`)通过 `putFormalBothIds` 一次写全两侧:回执点名的那个 id、
422
+ 它对应的另一侧、以及同一对象的其它验证别名(`r-<id>`、`r-<id>-s0`、`r-<id>-pf1`、`r-<id>-rf2`,
423
+ 复用 `syncVerificationTarget` 的既有扫描)。id 解析只有一处 `formalObjectIdOf`(门禁合并查询
424
+ `formalGateRecord` 也用它),**不新造第三套映射**。只写一侧的后果是静默错位:`defect` 只写到验证 id 上,
425
+ 对象记录仍是 `passed`,`formalGateRecord` 从对象侧读回 `passed`、卡片照旧写"Lean 通过"。
426
+
427
+ **这条映射不许"猜后缀"**:`r-<对象id>` 的**对象 id 本身可能以 `-sN`/`-pfN`/`-rfN` 结尾**
428
+ (例如命题 `p-ineq-s1` 的验证 id 是 `r-p-ineq-s1`)。若无条件剥离后缀,`formalObjectIdOf` 会把对象
429
+ 截成 `p-ineq` —— **另一个对象**:忠实性提示词会打印邻居的证明路径、`defect` 回执会降级邻居的记录并
430
+ **撤回邻居的归档证明**,而真正的对象仍然 `passed`(实测复现:`formal-verify-v2` 的 ambiguity 用例在修
431
+ 前 6 条断言变红,其中包含"邻居的证明被删除")。因此 `formalObjectIdOf` 按**权威度**取来源:
432
+
433
+ 1. 验证任务自己的所有者(`tasks['verify:'+rId].r.pId | qid`)——框架生成 rId 时就知道对象是谁;
434
+ 2. 记录里的 `objectId`(`syncVerificationTarget` 与 `putFormalBothIds` 在**手里有对象 id** 时写入,
435
+ 因此跨 resume、任务表还没重建时也正确)——但读出来时要求**自洽**(不以 `r-` 开头):状态文件是可以
436
+ 被人改的,一个 r 形锚点会让"验证 id → 对象 id"映射到它自己,于是"两套 id 一起写"退化成只写一侧;
437
+ 3. 只有在两者都不可用时,才回退到字符串后缀解析。
438
+
439
+ #### 9.4 提示词的三条硬要求
440
+
441
+ - **工具名一律写全称**:注入文本里只出现注册名 `vibe_math_lean_run` / `vibe_math_lean_archive` /
442
+ `vibe_math_lean_lib`;**不得**出现 `lean_run` / `lean_archive` / `lean_lib` 这类缩写——
443
+ 那不是注册名,代理照抄会调用一个不存在的工具(工具自己返回的 `hint` 同样算注入文本)。
444
+ - **归档可复用定义/引理前必须先跑通**:`vibe_math_lean_archive run=true` 或先 `vibe_math_lean_run`;
445
+ 跑不通的代码不得进入 `Formal/Lib` / `Formal/Proved`,否则"可复用库"会被不编译的定义污染。
446
+ - **工具链缺失时的出路必须写出来**:`LEAN_NOT_FOUND` 时把代码写下来归档,并在回执的 `note` 里写明
447
+ "宿主无 Lean 工具链"——这算显式阻塞原因,`require` 档可以据此放行,代理不会因为装不了 Lean 而卡死。
448
+
449
+ #### 9.5 人可读语料
450
+
451
+ `prompt-corpus-v2/formal-verify-v2.json` 与 `.md` 由套件落盘(契约 §10.10):框架**真正发出**的每条提示词
452
+ 原文,工作区路径归一化为 `<WS>`、VibeMath 根归一化为 `<VIBEMATH>`,因此可 diff、不泄露本机路径。
453
+ 覆盖 off 档(无任何 Lean 文字)、encourage/require 的表决初评与辩论、`passed` 后的忠实性分支、
454
+ 工作轮的「顺手形式化」段落与 formal 回执契约。套件带 `V2_CORPUS_DIR` 覆盖;当 `V2_PLUGIN` 指向
455
+ 变异副本(灵敏度探针)时语料写到临时目录,避免把变异文本写进仓库。
456
+
457
+ ### 十、测试
458
+
459
+ `formal-verify-v2.test.mjs`(仓库根):用 **mock `subprocess` 服务**(假 Lean:文件中含
460
+ `sorry` 或 `-- FAIL` 时 exit 1,否则 exit 0)跑通真实代码路径,覆盖 `off` 无操作、
461
+ 参数校验与运行中切换、`encourage` 对 review/debate/work 三类提示词的注入、
462
+ `passed` 后切忠实性措辞(并断言**不含**"偏离 → 0"、不含缩写工具名)、三个工具(绿灯/红灯/缺文件/
463
+ 越界/非 .lean/缺工具链/四种归档/索引重建、`blocked` 必须有 note)、`require` 门禁(命题与问题两条
464
+ 收口点、搁置→形式化→放行、卡片记录形式化状态、`resume` 后不遗忘、`encourage` 不设门禁),
465
+ 以及**回执通道的行为断言**(契约 §10.8/§10.9):把带 `formal:{decision:'blocked'|'defect', note}`
466
+ 的真实回执喂给框架,断言记录真的落库(`blocked` → `blocked` 且两套 id 同步;`defect` → `attempted`
467
+ + `proof` 清空 + `Verified/Lean/<id>.lean` 被删 + `Formal/TODO.md` 出现条目 + 公告),断言缺 `note`
468
+ 被 `V2_INVALID_ARGUMENT` 拒绝且不落记录,断言 `defect` 之后 `require` 档**不得定论**(无 Verified 卡片、
469
+ 命题布尔估计不变),并落盘人可读语料(§9.5)。
470
+
471
+ 后续补强(同一套件):
472
+
473
+ - 第 4b 节:超时必须**主动**终止——mock 记录 `terminate()` 调用(`-- HANG` 文件模拟一个不会自己
474
+ 结束的运行),断言返回 `LEAN_TIMEOUT` 且真的调用了 `terminate()`;并断言 `done` 先到时计时器
475
+ 被清掉(套件用 test-only 的悬挂 `setTimeout` 计数;mock 自身的兜底用真实计时器,不污染计数)。
476
+ - 第 13 节:归档写在**对象 id**、`rId` 侧还没有记录时,`require` 档仍必须能定论(门禁读合并记录),
477
+ 且该对象**不得**被写进「形式化待办」。
478
+ - 第 14 节:`defect` 的撤回覆盖**全部 id 别名**(归档写 `rId`、回执写对象 id 也能删干净);
479
+ 宿主**不能删除**时(`{ noSubprocess: true }` 的宿主)归档路径必须不再包含原证明文本、并且带
480
+ 撤回通知;活动日志必须说明"覆写"而不是"删除"。
481
+ - 第 15 节:`require` 档必须拦住「判断命题」问题解法到**源命题**的转移(`布尔估计` / `优先级` /
482
+ `已验证` / 概率=1 条目 / Verified 卡片全部不动,源命题进待办)。
483
+ - 模式相关的忠实性措辞:`encourage` 档**不得**出现"本次裁定**不定论**"(改写为"本档没有门禁"),
484
+ `require` 档**必须**出现(那里门禁真的会搁置裁定)。
485
+ - `kind='def'/'lemma'` 运行未通过时,工具返回值**不得**声称"可直接 import 复用"。
486
+
487
+ 套件支持 `V2_PLUGIN` 环境变量指向变异副本,供灵敏度探针使用。
488
+
489
+ ## 状态 / 报告字段:`verifyTasksView`(单一来源)
490
+
491
+ v2 的 **status 与 report 两个视图**里出现的验证任务列表由**同一个** helper `verifyTasksView(tasks)` 产出(`vibe-math-v2.js:2995`;调用点 `:2046` 与 `:4039`),因此两处字段必须**逐个字段一致**;任何"在某一侧顺手补一个字段"的改动都会让两个视图分叉。该一致性由 `tests/formal-verify-v2.test.mjs:1694-1698` 钉住(两侧取自同一 helper 且字段集合相等)。