dsh-vibe-math 2.2.0 → 2.2.2

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.
@@ -263,6 +263,13 @@ const probes = [
263
263
  from: " if ((now() - (lastActiveAt.get(m.id) || 0)) < idleMs) continue",
264
264
  to: " if (false) continue",
265
265
  },
266
+ {
267
+ name: 'verify-preempts-a-live-meeting',
268
+ ref: 'prompt-v5-integrity.test.mjs',
269
+ guarantee: '㉝ a verification proposed during a meeting must QUEUE, never start concurrently (the two are mutually exclusive)',
270
+ from: " if (meeting) return\n // Only one begin may be in flight.",
271
+ to: " // Only one begin may be in flight.",
272
+ },
266
273
  ]
267
274
 
268
275
  let probesPassed = 0
@@ -0,0 +1,284 @@
1
+ // ============================================================
2
+ // Vibe Math V5 架构图生成器(零依赖,纯 Node)
3
+ //
4
+ // node docs/generate_framework_diagram_v5.mjs
5
+ // → 写出 示例图/框架图-v5.svg
6
+ //
7
+ // v2/v3/v4 用 matplotlib 脚本生成 PNG;v5 用 Node 直接生成 **SVG**:
8
+ // · 本仓库的运行时就包含 Node,不需要额外装 Python / matplotlib;
9
+ // · SVG 是纯文本,diff 友好、可评审、任意缩放不糊。
10
+ // 需要 PNG 时用浏览器打开 SVG 另存,或用无头浏览器截图:
11
+ // chrome --headless=new --window-size=1720,1100 --screenshot=框架图-v5.png 框架图-v5.svg
12
+ //
13
+ // 版式约定(改布局时请遵守,否则会重叠):
14
+ // · 每个 band 的标题在 y+27、副标题在 y+47,**内容从 y+56 开始**;
15
+ // · 左侧 x=40..214 是一条「控制面通道」,只有所办↔框架的连线走这里,
16
+ // 研究所/框架两个 band 从 x=226 开始 —— 这样控制面的箭头不会穿过所内成员;
17
+ // · 生成时会估算文字宽度,超出容器的行会打印 WARN,便于立刻发现溢出。
18
+ // ============================================================
19
+ import { mkdirSync, writeFileSync } from 'node:fs'
20
+ import { dirname, join } from 'node:path'
21
+ import { fileURLToPath } from 'node:url'
22
+
23
+ const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..')
24
+ const OUT = join(ROOT, '示例图', '框架图-v5.svg')
25
+
26
+ const W = 1720, H = 1116
27
+ const FONT = "'Microsoft YaHei','PingFang SC','Hiragino Sans GB','Noto Sans CJK SC','Source Han Sans SC',sans-serif"
28
+ const MONO = "'Cascadia Mono','Consolas','SFMono-Regular',monospace"
29
+
30
+ const C = {
31
+ ink: '#10202e', ink2: '#2c4557', mute: '#5d7788',
32
+ frame: '#0b6fb8', frameBg: '#eaf3fd',
33
+ house: '#b26a00', houseBg: '#fdf5e2',
34
+ data: '#1f7a52', dataBg: '#eef7f1',
35
+ gate: '#b3202c', gateBg: '#fdeef0',
36
+ human: '#5b4bb8', humanBg: '#f1eefc',
37
+ line: '#7d93a3',
38
+ }
39
+
40
+ // band geometry
41
+ const FULL_L = 40, FULL_R = W - 40 // 40 .. 1680
42
+ const MAIN_L = 226, MAIN_R = FULL_R // 研究所 / 框架(让出控制面通道)
43
+ const IN_L = MAIN_L + 22, IN_R = MAIN_R - 22 // 226+22=248 .. 1638
44
+
45
+ const warnings = []
46
+ const esc = (s) => String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
47
+ // 粗略字宽估算:CJK/全角 1.0em,ASCII 0.56em。用来抓文字溢出(比截图更快)。
48
+ const textWidth = (s, fs) => [...String(s)].reduce((n, ch) => n + (/[\u2e80-\u9fff\uff00-\uffef]/.test(ch) ? 1 : 0.56), 0) * fs
49
+ const fits = (s, fs, limit, where) => {
50
+ const w = textWidth(s, fs)
51
+ if (w > limit) warnings.push(`${where}: 文字宽 ${w.toFixed(0)} > 可用 ${limit.toFixed(0)} — ${String(s).slice(0, 42)}…`)
52
+ return w
53
+ }
54
+
55
+ const out = []
56
+ const push = (s) => out.push(s)
57
+
58
+ // ---------- primitives ----------
59
+ function band(x, y, w, h, title, sub, { fill, stroke, titleFill = C.ink }) {
60
+ push(`<rect x="${x}" y="${y}" width="${w}" height="${h}" rx="14" fill="${fill}" stroke="${stroke}" stroke-width="2"/>`)
61
+ fits(title, 15, w - 36, 'band title')
62
+ push(`<text x="${x + 18}" y="${y + 27}" font-size="15" font-weight="700" fill="${titleFill}">${esc(title)}</text>`)
63
+ if (sub) {
64
+ fits(sub, 12, w - 36, 'band sub')
65
+ push(`<text x="${x + 18}" y="${y + 47}" font-size="12" fill="${C.mute}">${esc(sub)}</text>`)
66
+ }
67
+ }
68
+
69
+ function card(x, y, w, h, lines, { fill = '#ffffff', stroke = C.frame, fs = 13, sfs = 11, titleFill = C.ink } = {}) {
70
+ push(`<rect x="${x}" y="${y}" width="${w}" height="${h}" rx="10" fill="${fill}" stroke="${stroke}" stroke-width="1.6"/>`)
71
+ const cx = x + w / 2
72
+ const lead = fs + 4
73
+ const total = (lines.length - 1) * lead
74
+ if (total + fs > h) warnings.push(`card@${x},${y}: ${lines.length} 行需要高 ${(total + fs).toFixed(0)} > 容器 ${h}`)
75
+ let ty = y + h / 2 - total / 2 + fs * 0.36
76
+ lines.forEach((ln, i) => {
77
+ const size = i === 0 ? fs : sfs
78
+ fits(ln, size, w - 16, `card line@${x},${y}`)
79
+ push(`<text x="${cx}" y="${ty.toFixed(1)}" font-size="${size}" font-weight="${i === 0 ? 700 : 400}" `
80
+ + `fill="${i === 0 ? titleFill : C.ink2}" text-anchor="middle">${esc(ln)}</text>`)
81
+ ty += lead
82
+ })
83
+ }
84
+
85
+ function plain(x, y, text, { size = 12, fill = C.ink2, anchor = 'start', weight = 400, mono = false, limit = null, where = 'plain', halo = false } = {}) {
86
+ if (limit) fits(text, size, limit, where)
87
+ // halo: 白色描边垫在文字下,用于压在连线上的标签,避免线从字中间穿过
88
+ push(`<text x="${x}" y="${y}" font-size="${size}" font-weight="${weight}" fill="${fill}" text-anchor="${anchor}"`
89
+ + (halo ? ' paint-order="stroke" stroke="#ffffff" stroke-width="4" stroke-linejoin="round"' : '')
90
+ + (mono ? ` font-family="${MONO}"` : '') + `>${esc(text)}</text>`)
91
+ }
92
+
93
+ function arrow(x1, y1, x2, y2, { color = C.line, dashed = false, both = true, width = 1.6, marker = 'both' } = {}) {
94
+ push(`<line x1="${x1}" y1="${y1}" x2="${x2}" y2="${y2}" stroke="${color}" stroke-width="${width}" `
95
+ + (dashed ? 'stroke-dasharray="7 5" ' : '')
96
+ + (both ? `marker-start="url(#${marker})" ` : '') + `marker-end="url(#${marker})"/>`)
97
+ }
98
+
99
+ function polyline(points, { color = C.human, width = 2, dashed = false, marker = 'bothHuman' } = {}) {
100
+ const d = points.map((p, i) => (i ? 'L' : 'M') + ' ' + p[0] + ' ' + p[1]).join(' ')
101
+ push(`<path d="${d}" fill="none" stroke="${color}" stroke-width="${width}" `
102
+ + (dashed ? 'stroke-dasharray="7 5" ' : '') + `marker-start="url(#${marker})" marker-end="url(#${marker})"/>`)
103
+ }
104
+
105
+ // ---------- document ----------
106
+ push('<?xml version="1.0" encoding="UTF-8"?>')
107
+ push(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${W} ${H}" width="${W}" height="${H}" role="img" aria-label="Vibe Math V5 研究所架构图">`)
108
+ push(`<defs>
109
+ <marker id="both" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M 0 0 L 10 5 L 0 10 z" fill="${C.line}"/></marker>
110
+ <marker id="bothHuman" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M 0 0 L 10 5 L 0 10 z" fill="${C.human}"/></marker>
111
+ <marker id="bothFrame" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M 0 0 L 10 5 L 0 10 z" fill="${C.frame}"/></marker>
112
+ <marker id="bothData" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M 0 0 L 10 5 L 0 10 z" fill="${C.data}"/></marker>
113
+ <marker id="bothHouse" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M 0 0 L 10 5 L 0 10 z" fill="${C.house}"/></marker>
114
+ </defs>`)
115
+ push(`<rect width="${W}" height="${H}" fill="#ffffff"/>`)
116
+ push(`<g font-family="${FONT}">`)
117
+
118
+ // ---- 标题 ----
119
+ plain(W / 2, 40, 'Vibe Math V5 —— 研究所体系', { size: 27, fill: C.ink, anchor: 'middle', weight: 700 })
120
+ plain(W / 2, 67, '框架只是媒介:中继消息 · 沉淀产物 · 计数表决 · 管理上下文。它绝不指派任务 —— 组织与分派是所内院士的职责',
121
+ { size: 13, fill: C.mute, anchor: 'middle', limit: W - 80, where: 'subtitle' })
122
+
123
+ // ---- 求真门槛 ----
124
+ band(FULL_L, 84, FULL_R - FULL_L, 94, '求真门槛 —— 唯一让对象进入 Verified/ 的规则',
125
+ 'm = min(quorumCap, 在册有表决权人数) · 票是 [0,1] 概率:恰好 1 = 断言为真,恰好 0 = 断言为假,严格介于两者 = 弃权/存疑(不计入 m,计入全组平均)',
126
+ { fill: C.gateBg, stroke: C.gate, titleFill: C.gate })
127
+ card(62, 140, 506, 28, ['布尔票 ≥ m 且全部为 1 或全部为 0 → 定论,写入 Verified/'], { stroke: C.gate, fs: 12 })
128
+ card(588, 140, 506, 28, ['同时出现 1 与 0 → 阻塞:少数派无法靠别人弃权把结论推过去'], { stroke: C.gate, fs: 12 })
129
+ card(1114, 140, 524, 28, ['未达门槛 → 留在原库 + 全组平均概率 + 完整辩论录(不强行裁决)'], { stroke: C.gate, fs: 12 })
130
+
131
+ // ---- 所办 ----
132
+ band(FULL_L, 190, FULL_R - FULL_L, 100, '所办(会话根代理 / 人)—— 研究所的对外接口',
133
+ '不参与研究 · 不投票 · 只汇报与转达人的指令;代持平台要求的一次性创建权',
134
+ { fill: C.humanBg, stroke: C.human, titleFill: C.human })
135
+ card(62, 246, 372, 38, ['自然语言接口 + 汇报者', '「求解 XX」「进度如何」「暂停」'], { stroke: C.human, fs: 12, sfs: 10.5 })
136
+ card(452, 246, 372, 38, ['vibe_v5_configure → start', 'message / meeting / hire / fire'], { stroke: C.human, fs: 12, sfs: 10.5 })
137
+ card(842, 246, 330, 38, ['pause / resume / stop', 'set 调参(立即生效)'], { stroke: C.human, fs: 12, sfs: 10.5 })
138
+ card(1190, 246, 448, 38, ['/v5 斜杠命令(与工具等价)', 'configure|start|resume|pause|status|report|members|message|meeting|hire|fire|set'],
139
+ { stroke: C.human, fs: 12, sfs: 9 })
140
+
141
+ // ---- 研究所 ----
142
+ band(MAIN_L, 302, MAIN_R - MAIN_L, 240, '研究所(所内自治)—— 编制、组织与分派都在成员之间完成,框架永不指派',
143
+ '院士 acad:领头人 / 组织与协调中心 · 常驻研究员 r-n:有表决权 · 临时工 t-n:无表决权(由雇主雇入与解雇)',
144
+ { fill: C.houseBg, stroke: C.house, titleFill: '#8a5200' })
145
+ card(IN_L, 362, 300, 142, [
146
+ '院士 acad',
147
+ '领头人 · 组织与协调中心',
148
+ 'L1 建立全所视图(overview)',
149
+ 'L2 拆解并分派任务(assign)',
150
+ 'L3 设定优先级(prioritize)',
151
+ 'L4 召集并主持会议(convene)',
152
+ 'L5 督导进度(nudge)',
153
+ 'L6 调配临时工 · L7 对外代表',
154
+ ], { stroke: C.house, fs: 13.5, sfs: 10.5 })
155
+ plain(IN_L + 150, 520, '四条边界:一票与他人等重 / 分派的是工作不是结论 /', { size: 10, fill: C.gate, anchor: 'middle', limit: 300, where: 'acad note' })
156
+ plain(IN_L + 150, 536, '成员可据理反对 / 不能自我扩张编制', { size: 10, fill: C.gate, anchor: 'middle', limit: 300, where: 'acad note' })
157
+
158
+ const RX = IN_L + 328, RW = 1390 - 328 - 44
159
+ const rcw = (RW - 2 * 20) / 3
160
+ plain(RX, 372, '常驻研究员(有表决权 · 可自主雇佣/解雇自己的临时工)', { size: 11.5, fill: '#8a5200', weight: 700, limit: RW, where: 'researcher label' })
161
+ for (let i = 0; i < 3; i++) {
162
+ card(RX + i * (rcw + 20), 380, rcw, 52, [`常驻研究员 r-${i + 1}`, 'continuable 持久会话 · 自主方向 · 主动汇报'],
163
+ { stroke: C.house, fs: 13, sfs: 10.5 })
164
+ }
165
+ plain(RX, 452, '临时工(无表决权 · 为特定任务临时雇入 · 雇主或院士可解雇)', { size: 11.5, fill: '#8a5200', weight: 700, limit: RW, where: 'temp label' })
166
+ for (let i = 0; i < 3; i++) {
167
+ card(RX + i * (rcw + 20), 460, rcw, 52, [`临时工 t-${i + 1}`, `由 r-${i + 1} 雇入 · 可读/可想/可发言/可写自己的库`],
168
+ { stroke: '#c99a4a', fs: 13, sfs: 10.5 })
169
+ }
170
+ plain(RX, 536, '所内组织动作(分派 · 优先级 · 督办 · 会议 · 用人)由院士发起,不是框架行为 —— 框架只负责送达',
171
+ { size: 10.5, fill: C.mute, limit: RW, where: 'house note' })
172
+
173
+ // ---- 框架 ----
174
+ band(MAIN_L, 566, MAIN_R - MAIN_L, 286, '框架 vibe-v5 —— 只是媒介(middleware):中继 · 沉淀 · 计数 · 调度',
175
+ '每轮发「状态块 + 本轮问句」(规章在 persona 里,不进对话);成员回一个 JSON:say / progress / record / verdict / task_* / hire / fire / reject_assign / input / vote_solved',
176
+ { fill: C.frameBg, stroke: C.frame, titleFill: '#084d80' })
177
+ const chips = [
178
+ ['消息中继(持久邮箱)', '群聊 / 私信 / 致全体表决者', '所办通知 / 分派 / 督办 / 框架提示', '逐收件人落盘 · 先落盘再投递 · 群聊合批'],
179
+ ['会议 / 辩论', '议程 · 实时名册对账 · 随机发言序', '与验证互斥:任一方进行中,另一方排队', '看门狗:卡死即放弃并回到自组织'],
180
+ ['任务板(CAS + DAG)', '开 / 认领 / 释放 / 完成 / 重开 / 分派', '版本号比较交换 · 依赖环检测', '写范围重叠告警 · 解雇自动收回'],
181
+ ['m 票共识验证', '发起 → 独立初评 → 公开辩论重投', '布尔一致 + ≥ m 才定论', 'Verified/ 卡 + 辩论录 + 全组平均概率'],
182
+ ['上下文与活性', '阈值压缩(人设不丢)· 免轮询活动等待', '优先级调度 · 心跳永远重武装', '并发闸 maxParallel · 停滞自动开会'],
183
+ ['编制与雇佣', '院士/研究员可雇自己的临时工', '雇主或院士可真实解雇(释放子会话)', '代号永不复用 · 按人/全所双配额'],
184
+ ]
185
+ const ccw = (IN_R - IN_L - 2 * 22) / 3
186
+ chips.forEach((c, i) => {
187
+ card(IN_L + (i % 3) * (ccw + 22), i < 3 ? 620 : 708, ccw, 78, c, { stroke: C.frame, fs: 12.5, sfs: 10.5 })
188
+ })
189
+ card(IN_L, 796, IN_R - IN_L, 38, [
190
+ '调度器优先级:进行中的会议或验证(二者互斥,永不同时)→ 队列中的验证 → 暂存会议 → 已认领/被分派的在办任务(按 activityTimeoutMs 节流)→ 加急邮件 → 群聊摘要 → 停滞自动开会 → 兜底心跳',
191
+ ], { stroke: C.frame, fs: 11.5 })
192
+
193
+ // ---- 数据面 ----
194
+ band(FULL_L, 876, 790, 196, '状态权威源:会话日志的 host-only 投影单元(键 vibeMathV5)',
195
+ '副作用只是往会话日志追加事件 —— 不进模型上下文(零 token 成本),checkpoint / restore 交给 DSH',
196
+ { fill: C.dataBg, stroke: C.data, titleFill: '#125a3c' })
197
+ card(62, 932, 360, 124, [
198
+ 'applyV5Event(纯折叠,只此一份)',
199
+ '11 类事件:institute / member / task /',
200
+ 'message / delivered / meeting / debate /',
201
+ 'verdict / queue / counters / progress',
202
+ '未知或损坏事件 → 跳过并记入 diagnostics:',
203
+ '可用性优先,绝不因一条坏事件卡死全场',
204
+ ], { stroke: C.data, fs: 12, sfs: 10.5 })
205
+ card(434, 932, 374, 124, [
206
+ 'checkpoint / restore / resume',
207
+ '投影随会话日志一起 checkpoint;restore',
208
+ '时从快照 + 日志尾部重新折叠 → 跨进程与',
209
+ '同进程恢复走同一条代码路径',
210
+ '回退:宿主无 sessionProjections 时改用',
211
+ '加固 JSON:State/<institute>.v5state.json',
212
+ ], { stroke: C.data, fs: 12, sfs: 10.5 })
213
+
214
+ band(852, 876, FULL_R - 852, 196, '文件面:人可读产物(投影之外的一切都只是镜像)',
215
+ '共识的权威在投影;文件是工作区与可读产物,手工改坏不会破坏研究所',
216
+ { fill: C.dataBg, stroke: C.data, titleFill: '#125a3c' })
217
+ card(874, 932, FULL_R - 874 - 22, 124, [
218
+ 'Members/<id>/Progress|Propos|Methods|Subproblems/',
219
+ '只有本人可写,人人可读(跨读被鼓励)',
220
+ 'Shared/Chat/*.md · Shared/Meetings/<mt-id>.md · Shared/Debates/<obj>.md',
221
+ 'Shared/TaskBoard.md · Institutes.md(编制镜像)· State/README.md(说明此处非权威)',
222
+ 'Problems/<id>.md(原问题)· Problems/conclusion.md(结题)· Verified/<类型>/<id>.md(定论,只读)',
223
+ ], { stroke: C.data, fs: 11.5, sfs: 10.5 })
224
+
225
+ // ---- 连线:控制面(左侧通道,不穿过所内成员) ----
226
+ const CHX = 127
227
+ polyline([[CHX, 290], [CHX, 700], [MAIN_L, 700]], { color: C.human, width: 2 })
228
+ plain(CHX, 336, '工具面', { fill: C.human, anchor: 'middle', size: 12, weight: 700, halo: true })
229
+ plain(CHX, 356, 'vibe_v5_*', { fill: C.human, anchor: 'middle', size: 11, halo: true })
230
+ plain(CHX, 374, '/v5 命令', { fill: C.human, anchor: 'middle', size: 11, halo: true })
231
+ plain(CHX, 398, '↓', { fill: C.human, anchor: 'middle', size: 13, weight: 700, halo: true })
232
+ plain(CHX, 470, '汇报', { fill: C.human, anchor: 'middle', size: 12, weight: 700, halo: true })
233
+ plain(CHX, 490, 'status', { fill: C.human, anchor: 'middle', size: 11, halo: true })
234
+ plain(CHX, 508, 'report', { fill: C.human, anchor: 'middle', size: 11, halo: true })
235
+ plain(CHX, 532, '↑', { fill: C.human, anchor: 'middle', size: 13, weight: 700, halo: true })
236
+ plain(CHX, 600, '所办不投票', { fill: C.mute, anchor: 'middle', size: 10, limit: 170, where: 'ch note' })
237
+ plain(CHX, 616, '不能让结论变真', { fill: C.mute, anchor: 'middle', size: 10, limit: 170, where: 'ch note' })
238
+ plain(CHX, 644, '也不替成员', { fill: C.mute, anchor: 'middle', size: 10, limit: 170, where: 'ch note' })
239
+ plain(CHX, 660, '思考或署名', { fill: C.mute, anchor: 'middle', size: 10, limit: 170, where: 'ch note' })
240
+
241
+ // ---- 连线:研究所 ↔ 框架(提示词 / 回执) ----
242
+ arrow(560, 542, 560, 566, { color: C.frame, marker: 'bothFrame', width: 2 })
243
+ arrow(1400, 542, 1400, 566, { color: C.frame, marker: 'bothFrame', width: 2 })
244
+ plain(980, 559, '↑ 每轮提示词(状态块 + 本轮问句)  ↓ 单个 JSON 回执',
245
+ { fill: C.frame, anchor: 'middle', size: 10.5, limit: 780, where: 'prompt label', halo: true })
246
+
247
+ // ---- 连线:所内组织(虚线 = 不由框架执行) ----
248
+ arrow(556, 400, 578, 400, { color: C.house, dashed: true, width: 1.8, marker: 'bothHouse' })
249
+ arrow(556, 430, 578, 430, { color: C.house, dashed: true, width: 1.8, marker: 'bothHouse' })
250
+
251
+ // ---- 连线:框架 ↔ 数据面 ----
252
+ arrow(400, 852, 400, 876, { color: C.data, marker: 'bothData', width: 2 })
253
+ plain(392, 868, 'append / fold / stateOf', { fill: C.data, anchor: 'end', size: 10.5, halo: true })
254
+ arrow(1280, 852, 1280, 876, { color: C.data, marker: 'bothData', width: 2 })
255
+ plain(1288, 868, '读写产物', { fill: C.data, anchor: 'start', size: 10.5, halo: true })
256
+
257
+ // ---- 图例 ----
258
+ plain(52, 1098, '图例', { size: 12, fill: C.ink, weight: 700 })
259
+ const legend = [
260
+ [C.human, '所办 / 人(外部接口,不研究不投票)'],
261
+ [C.house, '所内成员与所内组织(虚线 = 不由框架执行)'],
262
+ [C.frame, '框架(中继 / 沉淀 / 计数 / 调度)'],
263
+ [C.data, '状态与产物'],
264
+ [C.gate, '求真门槛(唯一定论规则)'],
265
+ ]
266
+ legend.forEach(([col, txt], i) => {
267
+ const x = 108 + i * 330
268
+ push(`<rect x="${x}" y="1087" width="14" height="14" rx="3" fill="#ffffff" stroke="${col}" stroke-width="2"/>`)
269
+ plain(x + 21, 1099, txt, { size: 11, fill: C.ink2, limit: 305, where: 'legend' })
270
+ })
271
+
272
+ push('</g>')
273
+ push('</svg>')
274
+
275
+ mkdirSync(dirname(OUT), { recursive: true })
276
+ const svg = out.join('\n')
277
+ writeFileSync(OUT, svg, 'utf8')
278
+ console.log('saved ' + OUT + ' (' + svg.length + ' bytes)')
279
+ if (warnings.length) {
280
+ console.error('\n布局告警(文字可能溢出容器):')
281
+ for (const w of warnings) console.error(' WARN ' + w)
282
+ process.exit(1)
283
+ }
284
+ console.log('layout: no overflow warnings')
@@ -0,0 +1,75 @@
1
+ # Vibe Math 架构图
2
+
3
+ > 框架 = **一个主代理(助手)+ 一个代码调度器 + 五类子代理** + 一套按项目隔离的持久化数据布局。
4
+ > 下方的 Mermaid 代码块在 GitHub 上会**原生渲染**成流程图;本文件即图源,改完重新提交即可自动更新。
5
+
6
+ ```mermaid
7
+ flowchart TB
8
+ subgraph L1["👤 交互层"]
9
+ U["😀 用户(自然语言)"]
10
+ M["🤖 主代理(助手 + 汇报者)<br/>翻译需求 · 汇报进度 · 问答配置<br/>不求解 · 不调度"]
11
+ end
12
+
13
+ subgraph L2["⚙️ 调度层(插件代码)"]
14
+ SCHED["调度器 Scheduler<br/>唯一文件写者<br/>读 qs.csv · 派发子代理 · 推进状态机"]
15
+ end
16
+
17
+ subgraph L3["🧠 子代理层(continuable 持久会话)"]
18
+ BRAIN["🧭 Brainstorm<br/>拆解多个求解方向"]
19
+ SOLV["✍️ Solver × N<br/>逐方向多轮迭代"]
20
+ DERI["🔀 Derive<br/>死路时派生新方向"]
21
+ VERI["🔬 Verifier × ≥3<br/>独立审查 → 辩论 → 裁决"]
22
+ DECI["⚖️ Decider<br/>判定是否解决"]
23
+ end
24
+
25
+ subgraph L4["💾 数据层 · VibeMath/Projects/&lt;项目&gt;/"]
26
+ QS["📋 qs.csv"]
27
+ PEND["📥 Pending_Verification/"]
28
+ UNDR["📂 Under_Verification/"]
29
+ TVAL["✅ Temp_Validated/"]
30
+ KNOW["📚 Verified/ 可信知识库"]
31
+ STATE["🗄️ Progress_Logs/ · VibeMath_State/"]
32
+ end
33
+
34
+ U -->|"求解 XX / 查进度 / 干预"| M
35
+ M -->|"vibe_math_* 工具"| SCHED
36
+
37
+ SCHED -->|"① 派发"| BRAIN
38
+ BRAIN -->|"多个大相径庭的方向"| SCHED
39
+ SCHED -->|"② 每方向一个"| SOLV
40
+ SOLV -->|"结构化结果 JSON"| SCHED
41
+ SOLV -.->|"迭代至卡死"| DERI
42
+ DERI -->|"派生 1~3 个新方向"| SCHED
43
+ SCHED -->|"③ 写盘"| PEND
44
+ SCHED -->|"④ 拆解为最小验证单元"| UNDR
45
+ SCHED -->|"⑤ 派发 ≥3 个"| VERI
46
+ VERI -->|"裁决 JSON"| SCHED
47
+ SCHED -->|"⑥ 通过"| TVAL
48
+ SCHED -->|"⑦ 晋升"| KNOW
49
+ SCHED -->|"⑧ 派发"| DECI
50
+ DECI -->|"⑨ 已解决 → 回写"| QS
51
+ SCHED <-->|"读取问题"| QS
52
+ SCHED <-->|"状态落盘 / 断点恢复"| STATE
53
+ ```
54
+
55
+ ## 主流程(编号对应上图)
56
+
57
+ - **①** 主代理把用户需求翻译成 `vibe_math_add_problem` + `vibe_math_start`,调度器从 `qs.csv` 选问题并派发 **Brainstorm** 子代理;
58
+ - **②** Brainstorm 返回多个「大相径庭」的求解方向,调度器为**每个方向**起一个专属 **Solver**(同一会话内多轮迭代,产出引理/子路线/存活概率/完整解法,以结构化 JSON 返回);
59
+ - **③** 调度器作为**唯一文件写者**,把 Solver 输出落盘到 `Pending_Verification/`;
60
+ - **④** 调度器把待验证输出**拆解为最小验证单元**(`Under_Verification/`);
61
+ - **⑤** 每个单元派 **≥3 个 Verifier** 独立审查 → 辩论 → 裁决(一票否决 / 加权投票);
62
+ - **⑥** 裁决通过 → `Temp_Validated/` → **⑦ 晋升**进 `Verified/` 可信知识库;
63
+ - **⑧** 派 **Decider** 判断新结论是否解决某未解决问题:**⑨** 是则回写 `qs.csv` 为 `solved` 并命名解法文件,否则留作后续方向复用的已知结论;
64
+ - **卡死兜底**:所有方向都走进死路时,派 **Derive** 基于历史痛点派生 1~3 个全新方向,回到 ②。
65
+
66
+ ## 关键特性在图中对应
67
+
68
+ | 特性 | 图中的对应 |
69
+ |---|---|
70
+ | **断点续跑** | `调度器 ⇄ VibeMath_State/` 双向边:任务栈、代理注册表、决策队列、依赖图、验证器历史准确率全部落盘,重启后 `vibe_math_resume` 恢复 |
71
+ | **中途人工干预** | `manual` 模式下,调度器在 ① 派发 / ⑥ 裁决 / ⑦ 晋升 三个节点挂起决策,等主代理用 `vibe_math_list_decisions` / `vibe_math_decide` 处理,随时可切回 `auto` |
72
+ | **唯一写者铁律** | 所有指向数据层的实线都从「调度器」出发;子代理只返回 JSON,从不写文件,跨目录移动走临时原子交换 |
73
+ | **按项目隔离** | 整个数据层位于 `VibeMath/Projects/<项目>/` 下,互不干扰、可随时切换 |
74
+ | **子代理权限调控** | 调度器派发时注入 toolFilter(允许/禁止)与每轮外部工具调用上限 |
75
+ | **可配置** | 默认参数来自 `vibe_math_setting.json`(JSONC 含注释),`/vibe setup` 交互式配置 |
package/package.json CHANGED
@@ -1,88 +1,95 @@
1
- {
2
- "name": "dsh-vibe-math",
3
- "description": "Multi-agent mathematical problem-solving & verification frameworks for DeepSeek Harness — FOUR agent presets in one install: vibe-math-v2 (probability-driven: qs.json + Propos knowledge base + explorer→solver→review/debate verdict), vibe-math-v3 (THIRD-generation, recommended: paper-style Markdown knowledge base with Problems/Progress/Propos/Methods/Verified + planner-agent scheduling that decides the next N actions + universal theory/method invention library + agents write their own Markdown directly via a per-file write lock), and vibe-math-v4 (FOURTH-generation: persistent self-organizing resident subagents that message & meet to decide all tasks, verify only by unanimous consensus, /compact at a context threshold, and stop only when all agree the problem is solved), and vibe-math-v5 (FIFTH-generation research institute: an academician as the organizational centre who decomposes and ASSIGNS work and chairs meetings; permanent researchers who hold the vote and may hire/fire their own temp workers; temp workers with no vote; a group chat and meetings; a durable per-recipient mailbox; a compare-and-set task DAG; and a boolean m-vote consensus rule where an object enters Verified/ only when at least m voting members agree AND every one of them returns exactly 1 or exactly 0). Installing this bundle auto-installs all four presets (v1 was removed at v2.0.0).",
4
- "version": "2.2.0",
5
- "type": "module",
6
- "engines": {
7
- "node": "^22.19.0 || >=24.0.0"
8
- },
9
- "main": "installer.js",
10
- "exports": {
11
- ".": "./installer.js",
12
- "./installer": "./installer.js",
13
- "./cordis.patch.yml": "./cordis.patch.yml"
14
- },
15
- "files": [
16
- "installer.js",
17
- "cordis.patch.yml",
18
- "RELEASE-NOTES-2.0.22.md",
19
- "RELEASE-NOTES-2.1.0.md",
20
- "RELEASE-NOTES-2.2.0.md",
21
- "selfdrive-v5.mjs",
22
- "e2e-v5-round2.test.mjs",
23
- "prompt-v5-integrity.test.mjs",
24
- "audit-v5-sensitivity.mjs",
25
- "audit-v5-integrity.mjs",
26
- "prompt-corpus-v5/prompt-corpus-v5.md",
27
- "prompt-corpus-v5/prompt-corpus-v5.json",
28
- "vibe-math-v2/agent.cordis.yml",
29
- "vibe-math-v2/preset.yml",
30
- "vibe-math-v2/vibe-math-v2.js",
31
- "vibe-math-v2/实现方案.md",
32
- "vibe-math-v2/v2的额外要求.txt",
33
- "vibe-math-v3/agent.cordis.yml",
34
- "vibe-math-v3/preset.yml",
35
- "vibe-math-v3/vibe-math-v3.js",
36
- "vibe-math-v3/实现方案.md",
37
- "vibe-math-v4/agent.cordis.yml",
38
- "vibe-math-v4/preset.yml",
39
- "vibe-math-v4/vibe-math-v4.js",
40
- "vibe-math-v4/实现方案.md",
41
- "vibe-math-v5/agent.cordis.yml",
42
- "vibe-math-v5/preset.yml",
43
- "vibe-math-v5/vibe-math-v5.js",
44
- "vibe-math-v5/实现方案.md"
45
- ],
46
- "license": "MIT",
47
- "keywords": [
48
- "deepseek-harness",
49
- "dsh",
50
- "dsh-plugin",
51
- "agent-preset",
52
- "multi-agent",
53
- "mathematics",
54
- "math",
55
- "theorem-proving",
56
- "verification",
57
- "solver",
58
- "llm-agents"
59
- ],
60
- "repository": {
61
- "type": "git",
62
- "url": "git+https://github.com/ChongCyrus/Vibe-Mathematics.git"
63
- },
64
- "homepage": "https://github.com/ChongCyrus/Vibe-Mathematics#readme",
65
- "bugs": {
66
- "url": "https://github.com/ChongCyrus/Vibe-Mathematics/issues"
67
- },
68
- "dsh": {
69
- "bundle": {
70
- "patch": "./cordis.patch.yml"
71
- },
72
- "minVersion": "0.1.2-rc.1",
73
- "testedVersion": "0.1.5-rc.2",
74
- "compatNote": "依赖宿主提供的 subagents/agents/tools/commands/fs 服务与 @deepseek-ai/dsh-* 插件行;可选 subprocess/sandboxPolicy/compaction。persona 行同时携带 prefix 与 text 两个键,以兼容 0.1.3-alpha.2 的 schema 更名(prefix 必填)与 0.1.2 及更早的 text 键。已在 dsh-v0.1.5-rc.2(@deepseek-ai/dsh-persona 0.1.5-rc.2)上逐行校验全部预设行并通过(v2/v3/v4;v1 已于 v2.0.0 移除)。注意:DSH 0.1.2 起 subagents.startContinuable 的 agentOptions/toolFilter 需要宿主 provider 声明对应 capability(spawn/fork 进程内 provider 均支持),安装器启动时会做能力自检并在旧版宿主上告警。2026 兼容性修复:v2/v3 工具权限名表原先硬编码 web/fetch/bash(未注册名会使 tools.restrict() 抛错、子代理无法建立),现按真实注册名并加带守卫的重试;v4 真实 /compact 原先在 subagent/end 里查 agents.get()(该事件触发时子代理已移出注册表,属死代码),现改为在 subagent/start 捕获 Agent 引用;三套预设的可选服务改为惰性读取,不再在 apply() 快照;v4 的 tools/commands 注册补入 ctx.effect;安装器自检新增 subprocess/sandboxPolicy/compaction。v2.1.0 新增 v5 研究所体系:状态存于宿主 host-only 会话投影单元(键 vibeMathV5),因此自检新增 sessionProjections/sessions(均为可选;缺失时 v5 回退到加固 JSON 状态文件)。v5 不依赖任何 npm 实验包,纯 preset 内单文件实现。v2.2.0 修复实测发现的提示词身份错乱:状态块改为显式接收它所描述的成员,创建成员时先落盘进编制再构造入职提示词,章程快照冻结在入职时,重建会话不再自称“刚入职”,所办调用不再被误判成某位研究员,框架反馈改为独立发送者投递,一次提示词不再重复投递同一条消息,并新增 prompt-v5-integrity 提示词完整性套件 + 可人工复核的提示词语料(随包发布)。",
75
- "compatibility": {
76
- "dshReleases": {
77
- "0.1.2-alpha.4": "compatible",
78
- "0.1.2-alpha.5": "compatible",
79
- "0.1.2-rc.1": "compatible",
80
- "0.1.3-alpha.2": "compatible",
81
- "0.1.5-alpha.1": "compatible",
82
- "0.1.5-alpha.2": "compatible",
83
- "0.1.5-rc.1": "compatible",
84
- "0.1.5-rc.2": "compatible"
85
- }
86
- }
87
- }
88
- }
1
+ {
2
+ "name": "dsh-vibe-math",
3
+ "description": "Multi-agent mathematical problem-solving & verification frameworks for DeepSeek Harness — FOUR agent presets in one install: vibe-math-v2 (probability-driven: qs.json + Propos knowledge base + explorer→solver→review/debate verdict), vibe-math-v3 (THIRD-generation, recommended: paper-style Markdown knowledge base with Problems/Progress/Propos/Methods/Verified + planner-agent scheduling that decides the next N actions + universal theory/method invention library + agents write their own Markdown directly via a per-file write lock), and vibe-math-v4 (FOURTH-generation: persistent self-organizing resident subagents that message & meet to decide all tasks, verify only by unanimous consensus, /compact at a context threshold, and stop only when all agree the problem is solved), and vibe-math-v5 (FIFTH-generation research institute: an academician as the organizational centre who decomposes and ASSIGNS work and chairs meetings; permanent researchers who hold the vote and may hire/fire their own temp workers; temp workers with no vote; a group chat and meetings; a durable per-recipient mailbox; a compare-and-set task DAG; and a boolean m-vote consensus rule where an object enters Verified/ only when at least m voting members agree AND every one of them returns exactly 1 or exactly 0). Installing this bundle auto-installs all four presets (v1 was removed at v2.0.0).",
4
+ "version": "2.2.2",
5
+ "type": "module",
6
+ "engines": {
7
+ "node": "^22.19.0 || >=24.0.0"
8
+ },
9
+ "main": "installer.js",
10
+ "exports": {
11
+ ".": "./installer.js",
12
+ "./installer": "./installer.js",
13
+ "./cordis.patch.yml": "./cordis.patch.yml"
14
+ },
15
+ "files": [
16
+ "AUDIT-CHECKLIST.md",
17
+ "audit-v5-integrity.mjs",
18
+ "audit-v5-sensitivity.mjs",
19
+ "cordis.patch.yml",
20
+ "e2e-v5-round2.test.mjs",
21
+ "installer.js",
22
+ "prompt-v5-integrity.test.mjs",
23
+ "RELEASE-NOTES-2.0.22.md",
24
+ "RELEASE-NOTES-2.1.0.md",
25
+ "RELEASE-NOTES-2.2.0.md",
26
+ "RELEASE-NOTES-2.2.1.md",
27
+ "RELEASE-NOTES-2.2.2.md",
28
+ "selfdrive-v5.mjs",
29
+ "示例图/框架图-v5.svg",
30
+ "docs/架构图.md",
31
+ "docs/generate_framework_diagram_v5.mjs",
32
+ "prompt-corpus-v5/prompt-corpus-v5.json",
33
+ "prompt-corpus-v5/prompt-corpus-v5.md",
34
+ "vibe-math-v2/实现方案.md",
35
+ "vibe-math-v2/agent.cordis.yml",
36
+ "vibe-math-v2/preset.yml",
37
+ "vibe-math-v2/v2的额外要求.txt",
38
+ "vibe-math-v2/vibe-math-v2.js",
39
+ "vibe-math-v3/实现方案.md",
40
+ "vibe-math-v3/agent.cordis.yml",
41
+ "vibe-math-v3/preset.yml",
42
+ "vibe-math-v3/vibe-math-v3.js",
43
+ "vibe-math-v4/实现方案.md",
44
+ "vibe-math-v4/agent.cordis.yml",
45
+ "vibe-math-v4/preset.yml",
46
+ "vibe-math-v4/vibe-math-v4.js",
47
+ "vibe-math-v5/架构图.md",
48
+ "vibe-math-v5/实现方案.md",
49
+ "vibe-math-v5/agent.cordis.yml",
50
+ "vibe-math-v5/preset.yml",
51
+ "vibe-math-v5/vibe-math-v5.js"
52
+ ],
53
+ "license": "MIT",
54
+ "keywords": [
55
+ "deepseek-harness",
56
+ "dsh",
57
+ "dsh-plugin",
58
+ "agent-preset",
59
+ "multi-agent",
60
+ "mathematics",
61
+ "math",
62
+ "theorem-proving",
63
+ "verification",
64
+ "solver",
65
+ "llm-agents"
66
+ ],
67
+ "repository": {
68
+ "type": "git",
69
+ "url": "git+https://github.com/ChongCyrus/Vibe-Mathematics.git"
70
+ },
71
+ "homepage": "https://github.com/ChongCyrus/Vibe-Mathematics#readme",
72
+ "bugs": {
73
+ "url": "https://github.com/ChongCyrus/Vibe-Mathematics/issues"
74
+ },
75
+ "dsh": {
76
+ "bundle": {
77
+ "patch": "./cordis.patch.yml"
78
+ },
79
+ "minVersion": "0.1.2-rc.1",
80
+ "testedVersion": "0.1.5-rc.2",
81
+ "compatNote": "依赖宿主提供的 subagents/agents/tools/commands/fs 服务与 @deepseek-ai/dsh-* 插件行;可选 subprocess/sandboxPolicy/compaction。persona 行同时携带 prefix 与 text 两个键,以兼容 0.1.3-alpha.2 的 schema 更名(prefix 必填)与 0.1.2 及更早的 text 键。已在 dsh-v0.1.5-rc.2(@deepseek-ai/dsh-persona 0.1.5-rc.2)上逐行校验全部预设行并通过(v2/v3/v4;v1 已于 v2.0.0 移除)。注意:DSH 0.1.2 起 subagents.startContinuable 的 agentOptions/toolFilter 需要宿主 provider 声明对应 capability(spawn/fork 进程内 provider 均支持),安装器启动时会做能力自检并在旧版宿主上告警。2026 兼容性修复:v2/v3 工具权限名表原先硬编码 web/fetch/bash(未注册名会使 tools.restrict() 抛错、子代理无法建立),现按真实注册名并加带守卫的重试;v4 真实 /compact 原先在 subagent/end 里查 agents.get()(该事件触发时子代理已移出注册表,属死代码),现改为在 subagent/start 捕获 Agent 引用;三套预设的可选服务改为惰性读取,不再在 apply() 快照;v4 的 tools/commands 注册补入 ctx.effect;安装器自检新增 subprocess/sandboxPolicy/compaction。v2.1.0 新增 v5 研究所体系:状态存于宿主 host-only 会话投影单元(键 vibeMathV5),因此自检新增 sessionProjections/sessions(均为可选;缺失时 v5 回退到加固 JSON 状态文件)。v5 不依赖任何 npm 实验包,纯 preset 内单文件实现。v2.2.2 新增 v5 架构图(示例图/框架图-v5.svg + docs/generate_framework_diagram_v5.mjs 零依赖 Node 生成器 + vibe-math-v5/架构图.md 全套 Mermaid 细节图),并修复在绘制架构图时暴露的真实缺陷:会议进行中提出的验证会并发启动(会议与验证的互斥此前只做了单向),现改为排队。v2.2.1 把「全面检查必查清单」(AUDIT-CHECKLIST.md) 作为随包强制流程发布,提示词/交互正确性列为第一优先审计维度。v2.2.0 修复实测发现的提示词身份错乱:状态块改为显式接收它所描述的成员,创建成员时先落盘进编制再构造入职提示词,章程快照冻结在入职时,重建会话不再自称“刚入职”,所办调用不再被误判成某位研究员,框架反馈改为独立发送者投递,一次提示词不再重复投递同一条消息,并新增 prompt-v5-integrity 提示词完整性套件 + 可人工复核的提示词语料(随包发布)。",
82
+ "compatibility": {
83
+ "dshReleases": {
84
+ "0.1.2-alpha.4": "compatible",
85
+ "0.1.2-alpha.5": "compatible",
86
+ "0.1.2-rc.1": "compatible",
87
+ "0.1.3-alpha.2": "compatible",
88
+ "0.1.5-alpha.1": "compatible",
89
+ "0.1.5-alpha.2": "compatible",
90
+ "0.1.5-rc.1": "compatible",
91
+ "0.1.5-rc.2": "compatible"
92
+ }
93
+ }
94
+ }
95
+ }