dsh-vibe-math 1.2.1 → 1.2.3
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/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-vibe-math",
|
|
3
3
|
"description": "Multi-agent mathematical problem-solving & verification frameworks for DeepSeek Harness — THREE agent presets in one install: vibe-math-v1 (classic pipeline), vibe-math-v2 (probability-driven: qs.json + Propos knowledge base + explorer→solver→review/debate verdict), and 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). Installing this bundle auto-installs all three presets into the DSH preset root.",
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.3",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "installer.js",
|
|
7
7
|
"exports": {
|
|
@@ -405,6 +405,7 @@ export function apply(ctx) {
|
|
|
405
405
|
function composeProblemMd(p) {
|
|
406
406
|
const lines = []
|
|
407
407
|
lines.push('# 问题|' + (p.标题 || p.id))
|
|
408
|
+
lines.push(anchorLine('标题', p.标题 || p.id))
|
|
408
409
|
lines.push(anchorLine('ID', p.id))
|
|
409
410
|
lines.push(anchorLine('类型', '问题'))
|
|
410
411
|
lines.push(anchorLine('状态', p.状态 || '求解中'))
|
|
@@ -447,6 +448,7 @@ export function apply(ctx) {
|
|
|
447
448
|
function composePropositionMd(p) {
|
|
448
449
|
const lines = []
|
|
449
450
|
lines.push('# 命题|' + (p.标题 || p.id))
|
|
451
|
+
lines.push(anchorLine('标题', p.标题 || p.id))
|
|
450
452
|
lines.push(anchorLine('ID', p.id))
|
|
451
453
|
lines.push(anchorLine('类型', '命题'))
|
|
452
454
|
lines.push(anchorLine('状态', p.状态 || '未定论'))
|
|
@@ -498,6 +500,7 @@ export function apply(ctx) {
|
|
|
498
500
|
function composeMethodMd(m) {
|
|
499
501
|
const lines = []
|
|
500
502
|
lines.push('# 方法|' + (m.标题 || m.id))
|
|
503
|
+
lines.push(anchorLine('标题', m.标题 || m.id))
|
|
501
504
|
lines.push(anchorLine('ID', m.id))
|
|
502
505
|
lines.push(anchorLine('类型', m.类型 || '方法'))
|
|
503
506
|
lines.push(anchorLine('状态', m.状态 || '经验'))
|
|
@@ -890,32 +893,74 @@ export function apply(ctx) {
|
|
|
890
893
|
|
|
891
894
|
// ================= prompts =================
|
|
892
895
|
function personaText(key) { return params[key] ? (String(params[key]) + '\n\n') : '' }
|
|
893
|
-
function
|
|
894
|
-
return '
|
|
895
|
-
'\n1) TRUST LAYERS — the single most important rule:\n' +
|
|
896
|
+
function kcTrustLayers() {
|
|
897
|
+
return '\n1) TRUST LAYERS — the single most important rule:\n' +
|
|
896
898
|
'- Verified/ 中的内容 = 绝对可信(已被验证器判定为真/假并生成只读副本):可直接引用。\n' +
|
|
897
899
|
'- Propos/ 中 状态: 已验证·真/假 的命题 = 可信(以 Verified/ 副本为准)。\n' +
|
|
898
900
|
'- 其余一切(未定论命题、Progress/ 研究日志、Methods/ 中未验证断言、Notes/)= 经验性记录/参考,绝不能当作已成立事实引用。\n' +
|
|
899
|
-
'- 概率语义:1 = 绝对正确(可当已知事实);0 = 绝对错误;0 与 1 之间 = 未定论/待验证。\n'
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
'-
|
|
904
|
-
'-
|
|
905
|
-
'
|
|
906
|
-
'
|
|
907
|
-
'
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
901
|
+
'- 概率语义:1 = 绝对正确(可当已知事实);0 = 绝对错误;0 与 1 之间 = 未定论/待验证。\n'
|
|
902
|
+
}
|
|
903
|
+
function kcObjectModels() {
|
|
904
|
+
return '\n2) OBJECT MODELS(md 卡片,软规范:头部锚点行 + 正文自由叙述):\n' +
|
|
905
|
+
'- 问题卡 Problems/<id>.md:{ 标题, ID, 类型:问题, 状态:原始|求解中|等待依赖|已解决|死路, 优先级, 依赖:[], 被依赖:[], 来源:原始|后生, 计划(由调度器按规划代理的计划自动更新:一句话说明下一轮安排), ## 陈述(完整问题陈述,每个记号/对象都要完整定义), ## 来源与动机(后生问题:产生流程/动机/如何回填主线), ## 解法候选(### 解法 N|标题|概率X|状态Y + 叙述式完整解法)}。\n' +
|
|
906
|
+
'- 命题卡 Propos/<分类>/<id>.md:{ 标题, ID, 类型:命题, 状态:未定论|已验证·真|已验证·假, 概率, 优先级, 依赖:[], ## 陈述(完整), ## 证明尝试(### 证明 N|…|概率X|状态Y), ## 证伪尝试(### 证伪 N|…|概率X|状态Y)}。\n' +
|
|
907
|
+
'- 证明/证伪尝试语义:`## 证明尝试`=为证实而写的论证;`## 证伪尝试`=专门反驳/反例的论证。**失败的"找反例未果"/sanity check 是支持性证据,不属于证伪尝试**;不要写入 `## 证伪尝试`(否则系统会当作待验证的反驳去验证)。对仍未完成的证明/证伪,明确标注缺口而非伪装完成。\n' +
|
|
908
|
+
'- 方法卡 Methods/<id>.md:{ 标题, ID, 类型:方法, 状态:经验|应用验证|含已验证断言, 可信断言:[](只允许已进 Verified/ 的 ID), 上级体系/子方法/相关, 适用场景, ## 核心内容, ## 定义与记号, ## 应用记录, ## 改进历史 }。\n' +
|
|
909
|
+
'- 收口规则:某个解法/证明/证伪 概率=1 → 问题已解决 / 命题已验证(状态/概率锚点由调度器改写)。\n'
|
|
910
|
+
}
|
|
911
|
+
function kcFolders() {
|
|
912
|
+
return '\n3) FOLDERS:Problems/ 问题清单;Progress/ 研究日志(每问题一个聚合索引 <qid>.md + 每方向一个文件 <qid>/<dirId>.md,按方向按轮续写);Propos/ 命题库;Methods/ 理论发明库;Verified/ 绝对可信(只读);Reliable/ 可信参考文献(只读);Notes/ 自由笔记;Logs/ 审计;State/ 调度器私有——不要读也不要改。\n'
|
|
913
|
+
}
|
|
914
|
+
function kcMethodLibrary() {
|
|
915
|
+
return '\n4) METHOD LIBRARY RULES:开工前先查 Methods/(含全局 VibeMath/Methods/),有可复用方法/体系则引用其 ID;用后必须在 methods_used 上报(含效果与改进建议);本轮新发明/经验性总结必须在 new_inventions 上报(类型:理论体系|框架|工具|方法|思想|范式|技巧)——若与某张已有方法卡同类,在内容描述里注明"可并入 m-xxx"以便 Method Keeper 合并而非重复建卡。**重要区分**:methods_used 只能填**已存在方法卡的 ID**(形如 m-abc12345,来自 AVAILABLE METHODS 列表);你自己刚想出的新方法/新技巧不属于 methods_used,请如实填入 new_inventions(由 Method Keeper 蒸馏建卡);千万不要把方法名/标题文字当 id 填进 methods_used。\n'
|
|
916
|
+
}
|
|
917
|
+
function kcOutputQuality() {
|
|
918
|
+
return '\n5) OUTPUT QUALITY RULES:完整性、不断章取义——任何输出的问题/命题/结论都要给出完整陈述并补全所依赖的对象/环境/背景定义;引用必须给出处(文件路径 + ID + 锚点/节),事实只引 Verified/;若结论依赖临时假设 p,必须显式写「若 <p 完整陈述> 成立,则:…」。你的机器回复是一个 JSON 对象(```json 围栏内),JSON 之外不要再输出其他文本——任何要写进 md 的内容都通过文件工具写入,不要当作聊天气泡输出。'
|
|
919
|
+
}
|
|
920
|
+
// 写文件共用规则(仅供真正写 md 的代理:solver / method-keeper):写锁、上报、回退;不含具体归属文件(按角色注入)
|
|
921
|
+
function kcWriteRules() {
|
|
922
|
+
return '\nWRITE-INTO-MD WORKFLOW(优先推荐):把研究内容直接写进你的归属 Markdown 文件,而不是塞进回复 JSON。\n' +
|
|
923
|
+
'- **并发写安全**:写任何文件前先 `vibe_math_claim_write({target:"<相对项目根的路径>"})` 申请写锁(同一文件同一时刻只允许一个代理写;返回 busy 请稍后重试),写完 `vibe_math_release_write({target})`。不同方向是不同文件,天然不冲突。\n' +
|
|
924
|
+
'- **写完必须上报**:用 `vibe_math_sync_meta({meta:{kind:"solver|methods", ...}})` 上报轻量元数据(方向状态/存活率/引理 id+证明/方法卡 id/新发明/解法),让调度器更新索引与调度——内容留在 md,只有调度元数据与**待验证的证明**才进机读接口。\n' +
|
|
925
|
+
'- **分类一致性**:你写引理卡到 `Propos/<分类>/`,sync_meta 里该引理的 `分类` 字段必须严格等于那个目录名(否则调度器会按别处去查,找不到你写的卡)。\n' +
|
|
926
|
+
'- 若你的环境无法真正写文件(文件工具不可用/被拒),回退:把要写的内容放进回复 JSON 的 `__writes` 数组(`[{"path":"<目标>","content":"<全文>"}]`)并同样配 `meta`,由调度器落盘。两种方式二选一,不要重复。\n'
|
|
927
|
+
}
|
|
928
|
+
// 求解器专属:方向叙述 + 引理命题卡(带有完整证明)
|
|
929
|
+
function kcSolverFiles() {
|
|
930
|
+
return '你的归属文件:\n' +
|
|
931
|
+
'- 求解器:把该方向的完整叙述(本轮进展/子路线/可行性信号/教训/完整解法文本)写进 `Progress/<问题id>/<方向id>.md`;聚合索引 `Progress/<问题id>.md` 由调度器维护,不要动它。\n' +
|
|
932
|
+
'- 新引理:写一张完整命题卡到 `Propos/<分类>/<p-id>.md`,含锚点 `- 标题:`、`- ID/类型/状态/概率/优先级` 与 `## 陈述`;证明写进 `### 证明 1|标题|概率X|状态Y` 段落(完整证明文本是验证必需,否则验证器只能验裸命题)。\n'
|
|
933
|
+
}
|
|
934
|
+
// 方法整理代理专属:方法卡
|
|
935
|
+
function kcKeeperFiles() {
|
|
936
|
+
return '你的归属文件:\n' +
|
|
937
|
+
'- 方法整理代理:写 `Methods/<m-id>.md`,含 `- 标题/ID/类型/状态/可信断言/适用场景` 与 `## 核心内容`/`## 应用记录`/`## 改进历史`。\n'
|
|
938
|
+
}
|
|
939
|
+
// 基础核心(所有代理都需:可信层级 / 对象模型 / 文件夹 / 输出质量)
|
|
940
|
+
function coreKnowledgeContext() {
|
|
941
|
+
return 'KNOWLEDGE BASE & DATA MODEL (definition contract you MUST follow):\n' +
|
|
942
|
+
kcTrustLayers() + kcObjectModels() + kcFolders() + kcOutputQuality()
|
|
943
|
+
}
|
|
944
|
+
// 研究类角色(explorer / solver / method-keeper):再加方法库规则;explorer 不写文件所以不带写-文件段
|
|
945
|
+
function researchKnowledgeContext() { return coreKnowledgeContext() + kcMethodLibrary() }
|
|
946
|
+
// 验证器:只返回 Result/Reason,不需要写文件与方法上报规则
|
|
947
|
+
function verifierKnowledgeContext() { return coreKnowledgeContext() }
|
|
948
|
+
function solverKnowledgeContext() { return researchKnowledgeContext() + kcWriteRules() + kcSolverFiles() }
|
|
949
|
+
function methodKeeperKnowledgeContext() { return researchKnowledgeContext() + kcWriteRules() + kcKeeperFiles() }
|
|
950
|
+
function knowledgeContextText(role) {
|
|
951
|
+
const k = params.knowledgeContext ? String(params.knowledgeContext)
|
|
952
|
+
: (role === 'verifier' ? verifierKnowledgeContext()
|
|
953
|
+
: role === 'explorer' ? researchKnowledgeContext()
|
|
954
|
+
: role === 'method-keeper' ? methodKeeperKnowledgeContext()
|
|
955
|
+
: solverKnowledgeContext())
|
|
956
|
+
return k ? ('\n' + k + '\n') : ''
|
|
957
|
+
}
|
|
915
958
|
function capabilitiesText(role) {
|
|
916
|
-
|
|
917
|
-
const
|
|
918
|
-
const
|
|
959
|
+
// explorer 是研究/探索角色,工具预算与 solver 一致(网络/脚本/调用次数),仅 verifier 使用 verifier 配置
|
|
960
|
+
const isSolver = role === 'solver' || role === 'explorer'
|
|
961
|
+
const maxCalls = isSolver ? params.solverMaxToolCalls : params.verifierMaxToolCalls
|
|
962
|
+
const netOn = isSolver ? params.solverAllowNetwork : params.verifierAllowNetwork
|
|
963
|
+
const scrOn = isSolver ? params.solverAllowScripts : params.verifierAllowScripts
|
|
919
964
|
const toolParts = []
|
|
920
965
|
if (netOn !== false) toolParts.push('web search / literature lookup')
|
|
921
966
|
if (scrOn !== false) toolParts.push('symbolic/numeric computation (running scripts)')
|
|
@@ -925,9 +970,15 @@ export function apply(ctx) {
|
|
|
925
970
|
? ('- You may use external tools (' + toolParts.join(', ') + ') to assist; ' + ((maxCalls && Number(maxCalls) > 0) ? ('call such external tools AT MOST ' + maxCalls + ' times this round.\n') : 'no per-round limit by default.\n'))
|
|
926
971
|
: '- External tools: none enabled for you this round.\n'
|
|
927
972
|
t += '- You may READ any file under Verified/ as a known, trusted dependency.\n'
|
|
928
|
-
t +=
|
|
929
|
-
|
|
930
|
-
|
|
973
|
+
t += (role === 'verifier'
|
|
974
|
+
? '- You should BASE your verification on Verified/ and on Propos/ objects already marked 已验证·真/假; verify the TARGET against the rigorous standard, not against Methods/ or unproven claims.\n'
|
|
975
|
+
: '- You should BASE your reasoning on Propos/ (propositions with proofs/refutations and probabilities), Methods/ (reusable theories/tools), Reliable/ (trusted references), and Verified/.\n')
|
|
976
|
+
t += (role === 'verifier'
|
|
977
|
+
? '- You ONLY return Result/Reason JSON — you do not write files and you do not use the WRITE-INTO-MD workflow.\n'
|
|
978
|
+
: (role === 'explorer'
|
|
979
|
+
? '- Your output is the direction set (structural metadata): report it via the metadata form (meta.kind=directions); the scheduler writes it into the research log. You do NOT write per-direction files.\n'
|
|
980
|
+
: '- Write your research content directly into your assigned Markdown file (see WRITE-INTO-MD WORKFLOW) and return ONLY lightweight scheduling metadata; if your file tools are unavailable, fall back to the __writes + meta JSON described in the OUTPUT CONTRACT.\n'))
|
|
981
|
+
t += '\nHOW TO READ EXISTING KNOWLEDGE: these are Markdown files. COARSE SCAN first: use read/grep on the anchor header lines (- 标题/- ID/- 状态/- 概率/- 优先级/- 依赖) to locate relevant objects — do NOT load full prose yet. FINE READ after: read the full card for 陈述/证明/证伪/解法/核心内容 sections.\n'
|
|
931
982
|
return t
|
|
932
983
|
}
|
|
933
984
|
function methodsIndexText() {
|
|
@@ -940,14 +991,14 @@ export function apply(ctx) {
|
|
|
940
991
|
}
|
|
941
992
|
function explorerPrompt(q) {
|
|
942
993
|
return personaText('explorerPersona') + 'You are a research mathematician orchestrating strategy for one problem.\n\nPROBLEM (id: ' + q.id + '): ' + q.陈述 + '\n' +
|
|
943
|
-
knowledgeContextText() +
|
|
994
|
+
knowledgeContextText('explorer') +
|
|
944
995
|
methodsIndexText() +
|
|
945
|
-
capabilitiesText('
|
|
946
|
-
'\nDo a first-stage METACOGNITIVE BRAINSTORM: decompose constraints, test boundary/extreme cases, map to similar known problems. First check the AVAILABLE METHODS list — if a listed method/system
|
|
996
|
+
capabilitiesText('explorer') +
|
|
997
|
+
'\nDo a first-stage METACOGNITIVE BRAINSTORM: decompose constraints, test boundary/extreme cases, map to similar known problems. First check the AVAILABLE METHODS list — if a listed method/system underlies a direction you will propose, reference its id in methods_used (this is a REFERENCE, not an application — you are only suggesting the direction builds on it, not claiming you used it). ' +
|
|
947
998
|
'Then propose 3-6 DIVERSE, mutually distinct solution directions (e.g. analytic method, constructive proof, contradiction, numeric approximation + limit passage, categorical abstraction, ...). ' +
|
|
948
999
|
'Record each direction with its core assumption and an initial feasibility estimate. Every direction must be self-contained: title / method / core_assumption written completely, defining every object they mention — no 断章取义.\n\n' +
|
|
949
|
-
'feasibility ∈ [0,1]. Respond with ONLY a single JSON object
|
|
950
|
-
'{"directions":[{"id":"d1","title":"...","method":"...","core_assumption":"...","feasibility":0.5}],"methods_used":[{"id":"m-...","效果":"
|
|
1000
|
+
'feasibility ∈ [0,1] = your estimate of the probability this direction leads to a full solution. Respond with ONLY a single JSON object in a ```json code fence (no prose outside it). Register the directions as metadata; the scheduler writes them into the research log:\n' +
|
|
1001
|
+
'{"meta":{"kind":"directions","qid":"<qid>","directions":[{"id":"d1","title":"...","method":"...","core_assumption":"...","feasibility":0.5}],"methods_used":[{"id":"m-...","效果":"<为何该方向借鉴它>","建议":"..."}],"new_inventions":[{"类型":"方法|工具|...","标题":"...","内容描述":"...","是否已入库":false}]}}'
|
|
951
1002
|
}
|
|
952
1003
|
function rederivePrompt(q, prog) {
|
|
953
1004
|
const prior = prog.map(function (d) {
|
|
@@ -955,13 +1006,13 @@ export function apply(ctx) {
|
|
|
955
1006
|
(d.routes && d.routes.length ? ' | routes: ' + d.routes.map(function (r) { return r.title + '[' + (r.feasibility_signal || '') + ']' }).join('; ') : '')
|
|
956
1007
|
}).join('\n')
|
|
957
1008
|
return personaText('explorerPersona') + 'You are a research mathematician re-deriving strategy for a problem whose prior directions stalled or failed.\n\nPROBLEM (id: ' + q.id + '): ' + q.陈述 + '\n\nPRIOR DIRECTIONS (with blockers):\n' + prior + '\n' +
|
|
958
|
-
knowledgeContextText() +
|
|
1009
|
+
knowledgeContextText('explorer') +
|
|
959
1010
|
methodsIndexText() +
|
|
960
|
-
capabilitiesText('
|
|
1011
|
+
capabilitiesText('explorer') +
|
|
961
1012
|
'\nQuantitatively analyze the historical progress, blocker causes, and feasibility decay of each prior direction. Discard directions already proven dead ends (unless a new tool/idea changes that). ' +
|
|
962
1013
|
'Then deeply DERIVE 1-3 BRAND-NEW directions never tried before, each with a one-line motivation. Return the UNION of high-potential leftover directions and the brand-new directions (drop dead ends).\n\n' +
|
|
963
|
-
'Respond with ONLY a single JSON object
|
|
964
|
-
'{"directions":[{"id":"d1","title":"...","method":"...","core_assumption":"...","feasibility":0.5,"
|
|
1014
|
+
'feasibility ∈ [0,1]. Respond with ONLY a single JSON object in a ```json code fence (no prose outside it). Register the directions as metadata; the scheduler writes them into the research log:\n' +
|
|
1015
|
+
'{"meta":{"kind":"directions","qid":"<qid>","directions":[{"id":"d1","title":"...","method":"...","core_assumption":"...","feasibility":0.5}],"methods_used":[{"id":"m-...","效果":"...","建议":"..."}],"new_inventions":[{"类型":"方法|工具|...","标题":"...","内容描述":"...","是否已入库":false}]}}'
|
|
965
1016
|
}
|
|
966
1017
|
function directionSummary(d) {
|
|
967
1018
|
return 'id ' + d.id + '「' + d.title + '」method=' + d.method + ' | round=' + d.round + ' status=' + d.status +
|
|
@@ -985,7 +1036,7 @@ export function apply(ctx) {
|
|
|
985
1036
|
let head = personaText('solverPersona') + 'You are a dedicated solver agent working ONE solution direction of a math problem (agent_self_iteration).\n\n'
|
|
986
1037
|
head += 'PROBLEM (id: ' + q.id + '): ' + q.陈述 + '\nDIRECTION: ' + dir.title + ' (method: ' + dir.method + '; core assumption: ' + dir.core_assumption + ')\nROUND: ' + round + ' of ' + params.solverMaxRounds + '\n'
|
|
987
1038
|
if (round > 1 || (progressText && progressText.length)) head += '\nYOUR PRIOR PROGRESS / OTHER DIRECTIONS:\n' + progressText + '\n'
|
|
988
|
-
head += knowledgeContextText()
|
|
1039
|
+
head += knowledgeContextText('solver')
|
|
989
1040
|
head += methodsIndexText()
|
|
990
1041
|
head += capabilitiesText('solver')
|
|
991
1042
|
head += '\nStart from the last recorded node of direction ' + dir.id + ' (inherit progress, or branch a sub-route under it). Consult AVAILABLE METHODS first — reuse a listed method/system when it fits (report it in methods_used). Each round you MUST produce, even if incomplete:\n' +
|
|
@@ -995,10 +1046,15 @@ export function apply(ctx) {
|
|
|
995
1046
|
'- an updated survival probability for this direction;\n' +
|
|
996
1047
|
'- ANY new theory/tool/method/idea you invented or summarized this round in new_inventions (类型:理论体系|框架|工具|方法|思想|范式|技巧) — the Method Keeper will distill it into the theory library.'
|
|
997
1048
|
head += '\nIf you encounter an EXTREMELY complex auxiliary conjecture/sub-problem q_sub: list it in "sub_questions" as a PROBLEM-class object with its COMPLETE statement (every object/definition/notation fully defined — 不断章取义), together with p_{q-tmp}: a PROPOSITION-class TEMPORARY ASSUMPTION answering q_sub. TEMPORARILY ASSUME p_{q-tmp} holds and continue the main line — every later proposition/conclusion depending on it MUST be stated as "若 <p_{q-tmp} 的完整陈述> 成立,则:..." (complete definitions).\n'
|
|
998
|
-
head += '\nIMPORTANT — PROBABILITY RULES FOR NEW RESULTS: any 概率 /
|
|
999
|
-
head += '\nIf you obtain a COMPLETE solution: adversarially self-check (construct counterexamples, test boundary conditions) BEFORE declaring success;
|
|
1000
|
-
head += '\
|
|
1001
|
-
|
|
1049
|
+
head += '\nIMPORTANT — PROBABILITY RULES FOR NEW RESULTS: any 概率 / prob / solution_prob / survival you output for NEW results must be strictly BETWEEN 0 and 1 (they await independent verifier confirmation). NEVER mark your own fresh lemma or solution as 1 or 0 — that is the verifiers\' job. Only facts already recorded in Verified/ count as certain.\n'
|
|
1050
|
+
head += '\nIf you obtain a COMPLETE solution: adversarially self-check (construct counterexamples, test boundary conditions) BEFORE declaring success; write the full solution prose into your direction Progress file and put the solution into the `solution_text` field of the meta.\n'
|
|
1051
|
+
head += '\nSTATUS SEMANTICS — report the truth, do not hedge: `success` = you produced a complete, self-consistent solution; `dead-end` = the direction is MATHEMATICALLY dead (a decisive blocker / a core sub-assumption refuted / a step proven impossible); `continue` = still viable and you made real progress this round. Do NOT use `dead-end` merely because you ran out of time — capping rounds is the controller\'s decision (solverMaxRounds), not yours; if you progressed but didn\'t finish, report `continue` with the new survival.\n'
|
|
1052
|
+
head += '\nLEMMA RULES: every lemma you register MUST carry a complete proof in `lemmas[].proof` (and in the card\'s `## 证明尝试`). If a claim is only partly argued, do NOT register it as a finished lemma — either prove it fully or record it as an explicit gap/conjecture stating the missing step, so the verifier knows exactly what is (and is not) being claimed. Incomplete "lemmas" waste verification and can mislead.\n'
|
|
1053
|
+
head += '\nOUTPUT CONTRACT — pick ONE channel. Write content into Markdown; only lightweight scheduling metadata (and verification-required proofs) cross the machine reply.\n' +
|
|
1054
|
+
'CHANNEL A (recommended, you can write files): write the full round narrative into `Progress/' + q.id + '/' + dir.id + '.md` and each new lemma card into `Propos/<分类>/<id>.md`, then reply ONLY this metadata object:\n' +
|
|
1055
|
+
'{"meta":{"kind":"solver","qid":"' + q.id + '","dirId":"' + dir.id + '","round":' + round + ',"survival":0.5,"status":"continue|success|dead-end","dead_end_reason":"... or null","lemmas":[{"id":"p-...","title":"...","statement":"...","proof":"<完整证明文本,供验证器核验>","prob":0.6,"分类":"<引理卡目录名,必须与你要写入的 Propos/<分类>/ 目录严格一致>","优先级":1}],"methods_used":[{"id":"m-...","效果":"...","建议":"..."}],"new_inventions":[{"类型":"...","标题":"...","内容描述":"...","是否已入库":false}],"solution_prob":0.85,"solution_text":"<完整解法文本,或 null>","sub_questions":[{"q_sub_title":"...","q_sub_statement":"完整问题陈述(含所有对象/定义)","assumption_title":"p_{q-tmp} 标题","assumption_statement":"完整假设陈述(含所有定义)"}]}}\n' +
|
|
1056
|
+
'CHANNEL B (your file tools are unavailable): put the content you would have written into __writes and carry the same meta:\n' +
|
|
1057
|
+
'{"__writes":[{"path":"Progress/' + q.id + '/' + dir.id + '.md","content":"<完整本轮叙述>"}],"meta":{"kind":"solver","qid":"' + q.id + '","dirId":"' + dir.id + '",...同上 meta 字段...}}\n' +
|
|
1002
1058
|
'区分规则:methods_used 只能填**已存在的方法卡 ID**(m-…,来自 AVAILABLE METHODS 列表)——引用你自己刚想出的新方法/新技巧不属于 methods_used,请如实填入 new_inventions(它会由 Method Keeper 蒸馏建卡);不要把方法名/标题当 id 填进 methods_used。'
|
|
1003
1059
|
return head
|
|
1004
1060
|
}
|
|
@@ -1009,22 +1065,25 @@ export function apply(ctx) {
|
|
|
1009
1065
|
}
|
|
1010
1066
|
function verifierReviewPrompt(r) {
|
|
1011
1067
|
return personaText('verifierPersona') + 'You are a STRICT peer reviewer verifying one mathematical object. Check it multiple times.\n\nTARGET (r: ' + r.kind + '):\n' + verifierTargetText(r) + '\n' +
|
|
1012
|
-
knowledgeContextText() +
|
|
1068
|
+
knowledgeContextText('verifier') +
|
|
1013
1069
|
capabilitiesText('verifier') +
|
|
1014
1070
|
'\nResult ∈ [0,1] = your probability that the TARGET is CORRECT: 1 ONLY when you are fully certain (for a bare proposition: Reason must be a complete proof; for a proof/refutation/solution: you verified every step and Reason confirms the whole chain); 0 ONLY when you are certain it is wrong (Reason must be a rigorous complete refutation / pinpoint the fatal flaw); otherwise a value strictly between 0 and 1.\n' +
|
|
1071
|
+
'\nCalibration: 0.5 means "genuinely undecided — there is a real unresolved gap"; it is NOT a safe hedge, so do not default to 0.5. Give the number your honest confidence from the evidence actually supports.\n' +
|
|
1072
|
+
'\n**Reason is MANDATORY and MUST be non-empty**: name the exact step you verified, or the potential counterexample / fatal flaw, or (for 0.5) the precise gap that blocks a decision. A Result with an empty Reason is non-contributory and will be ignored; never return {"Result":0.5} with no justification.\n' +
|
|
1015
1073
|
'\nCitations: facts may only be cited from Verified/ (or Propos/ 状态: 已验证·真/假). Never cite an unverified or refuted object as a fact — if you need a sub-claim of a refuted card, re-derive it yourself.\n' +
|
|
1016
|
-
'\nIndependently output your initial review
|
|
1017
|
-
'{"Result":0.5,"Reason":"detailed logic chain
|
|
1074
|
+
'\nIndependently output your initial review — ONLY a single JSON object in a ```json code fence, no prose outside it:\n' +
|
|
1075
|
+
'{"Result":0.5,"Reason":"<MANDATORY, non-empty: your detailed logic chain / potential counterexample / supporting evidence>"}'
|
|
1018
1076
|
}
|
|
1019
1077
|
function verifierDebatePrompt(r, transcript) {
|
|
1020
1078
|
return personaText('verifierPersona') + 'You are one reviewer in a DEBATE ("交流群") about this object.\n\nTARGET:\n' + verifierTargetText(r) + '\n' +
|
|
1021
|
-
knowledgeContextText() +
|
|
1079
|
+
knowledgeContextText('verifier') +
|
|
1022
1080
|
capabilitiesText('verifier') +
|
|
1023
1081
|
'\nFULL DEBATE HISTORY SO FAR (每轮所有评审轮流发言的记录):\n' + transcript + '\n' +
|
|
1024
1082
|
'\nRespond to the others (agree / rebut / add new evidence, referencing earlier rounds if needed). If you changed your Result because of them, state the reason explicitly. ' +
|
|
1025
|
-
'Remember: formal/notation-level flaws in an otherwise correct proof should lower confidence only slightly — a mathematically correct argument is not "uncertain" because of typos; near-consensus is not a deadlock.\n' +
|
|
1026
|
-
'
|
|
1027
|
-
'
|
|
1083
|
+
'Remember: formal/notation-level flaws in an otherwise correct proof should lower confidence only slightly — a mathematically correct argument is not "uncertain" because of typos; near-consensus is not a deadlock. Undue swing to 0.5 is discouraged: a bare review merits 0.5 ONLY if there is a genuine undecidable gap, never as a hedge.\n' +
|
|
1084
|
+
'\nReason is MANDATORY and MUST be non-empty; an empty-Reason result (esp. a bare 0.5) is ignored as non-contributory, so always justify your number.\n' +
|
|
1085
|
+
'\nReply with ONLY a single JSON object in a ```json code fence, no prose outside it:\n' +
|
|
1086
|
+
'{"Result":0.5,"Reason":"<MANDATORY, non-empty: updated logic chain / counterexample / proof / refutation>","changed":"brief reason if you changed your Result, else null"}'
|
|
1028
1087
|
}
|
|
1029
1088
|
function plannerPrompt(brief) {
|
|
1030
1089
|
return personaText('plannerPersona') + 'You are the SCHEDULING PLANNER of a multi-agent mathematical research system. Your job: autonomously choose the OPTIMAL schedule — you may lay out the NEXT ' + params.planningHorizon + ' agent-task calls in one plan (they will be executed in order, beyond-capacity ones queued for later ticks).\n\n' +
|
|
@@ -1037,17 +1096,20 @@ export function apply(ctx) {
|
|
|
1037
1096
|
'- {"action":"interrupt","childId":"<childId>","reason":"..."} — stop a running child (direction dead, superseded...).\n' +
|
|
1038
1097
|
'- {"action":"promote","target":"<pId>","reason":"..."} — high-value unresolved proposition → judge problem.\n' +
|
|
1039
1098
|
'- {"action":"wait","target":"<id>","reason":"..."} — advisory: wait for a dependency.\n' +
|
|
1040
|
-
'\nHARD RULES: never re-schedule verified objects; problems with 依赖未就绪 (依赖就绪=false) should wait unless you explicitly accept a temporary assumption; respect capacity (brief.free_slots); PREFER problems whose dependencies are ready and whose directions have the highest survival; DO NOT forget verification — unresolved solutions/proofs/refutations (verify_candidates) will never be checked unless you schedule a verifier; schedule at most ' + params.planningHorizon + ' actions.\n' +
|
|
1099
|
+
'\nHARD RULES: never re-schedule verified objects; problems with 依赖未就绪 (依赖就绪=false) should wait unless you explicitly accept a temporary assumption; respect capacity (brief.free_slots); PREFER problems whose dependencies are ready and whose directions have the highest survival; DO NOT forget verification — unresolved solutions/proofs/refutations (verify_candidates) will never be checked unless you schedule a verifier; DO NOT assume a direction is already being worked just because it is shown "active" in a problem — check brief.problems[].running_solver_dirs and brief.active_agents: schedule a solver for a direction ONLY if that direction is NOT in running_solver_dirs (an "active" direction absent from running_solver_dirs is WAITING to be dispatched, not being worked); schedule at most ' + params.planningHorizon + ' actions.\n' +
|
|
1041
1100
|
'Respond with ONLY a single JSON object wrapped in a ```json code fence — no prose:\n' +
|
|
1042
1101
|
'{"summary":"one-line plan rationale","plan":[{"action":"...","role":"...","target":"...","direction":"...","childId":"...","reason":"..."}]}'
|
|
1043
1102
|
}
|
|
1044
1103
|
function methodKeeperPrompt(digest) {
|
|
1045
1104
|
return personaText('methodKeeperPersona') + 'You are the METHOD KEEPER of a mathematical research system. Your job: distill reusable THEORIES, FRAMEWORKS, TOOLS, METHODS, IDEAS (including experiential ones) invented during solving into the theory library, so future work can apply and extend them — like inventing group theory while solving an equation, or functional analysis while studying variational problems.\n\n' +
|
|
1046
|
-
knowledgeContextText() +
|
|
1105
|
+
knowledgeContextText('method-keeper') +
|
|
1047
1106
|
'\nRECENT WORK DIGEST:\n' + digest + '\n\n' +
|
|
1048
1107
|
'For each pending invention decide: create a NEW method card, or fold it into an EXISTING method (as an improvement). Only list 可信断言 for claims already verified (ids from Verified/) — everything else stays 经验 (experiential). You may propose 上级体系/子方法 links to organize methods into systems.\n' +
|
|
1049
|
-
'
|
|
1050
|
-
'
|
|
1108
|
+
'OUTPUT CONTRACT — pick ONE channel. Write method cards into Markdown; only the created IDs, which cards were used, and improvements cross the machine reply.\n' +
|
|
1109
|
+
'CHANNEL A (recommended, you can write files): write each method card into `Methods/<m-id>.md` (`# 方法|标题` + `- 标题/ID/类型/状态/可信断言/适用场景` + `## 核心内容`/`## 应用记录`/`## 改进历史`), then reply ONLY this metadata:\n' +
|
|
1110
|
+
'{"meta":{"kind":"methods","used":[{"id":"m-...","效果":"...","建议":"..."}],"created":["m-xxx"],"improvements":[{"id":"m-...","改进内容":"...","原因":"..."}]}}\n' +
|
|
1111
|
+
'CHANNEL B (your file tools are unavailable): put the method-card content into __writes and carry the same meta:\n' +
|
|
1112
|
+
'{"__writes":[{"path":"Methods/<m-id>.md","content":"<# 方法|标题 + 锚点 + ## 核心内容... 完整卡面>"}],"meta":{"kind":"methods","used":[...],"created":["m-xxx"],"improvements":[...]}}'
|
|
1051
1113
|
}
|
|
1052
1114
|
|
|
1053
1115
|
// ================= decisions (manual/auto) =================
|
|
@@ -1323,6 +1385,7 @@ export function apply(ctx) {
|
|
|
1323
1385
|
id: q.id, 状态: q.状态, 优先级: q.优先级, 依赖: q.依赖, 依赖就绪: problemDepReady(q),
|
|
1324
1386
|
方向数: dirs.length,
|
|
1325
1387
|
活跃方向: dirs.filter(function (d) { return d.status === 'active' }).map(function (d) { return d.id }),
|
|
1388
|
+
running_solver_dirs: dirs.filter(function (d) { return d.status === 'active' && Object.keys(agentRegistry).some(function (cid) { const m = agentRegistry[cid]; return m && m.qid === q.id && m.direction === d.id && m.role === 'solver' }) }).map(function (d) { return d.id }),
|
|
1326
1389
|
最高存活率: dirs.length ? Math.max.apply(null, dirs.map(function (d) { return Number(d.survival) || 0 })) : null,
|
|
1327
1390
|
解法数: (q.solutions || []).length,
|
|
1328
1391
|
})
|
|
@@ -1437,6 +1500,7 @@ export function apply(ctx) {
|
|
|
1437
1500
|
if (!q || q.状态 === '已解决' || q.优先级 === 'never' || q.状态 === '等待依赖') continue
|
|
1438
1501
|
const dir = (getDirState(q.id) || []).find(function (d) { return d.id === String(a.direction || '') })
|
|
1439
1502
|
if (!dir || dir.status !== 'active') continue
|
|
1503
|
+
if ((dir.round || 0) >= (Number(params.solverMaxRounds) || 3)) continue // 已到轮次上限,不再调度(由后续 re-derive/stall 处理)
|
|
1440
1504
|
const running = Object.keys(agentRegistry).some(function (cid) { const m = agentRegistry[cid]; return m && m.qid === q.id && m.direction === dir.id && m.role === 'solver' })
|
|
1441
1505
|
if (running) continue
|
|
1442
1506
|
} else if (role === 'verifier') {
|
|
@@ -1504,9 +1568,10 @@ export function apply(ctx) {
|
|
|
1504
1568
|
if (!q) return
|
|
1505
1569
|
const dir = (getDirState(q.id) || []).find(function (d) { return d.id === a.direction })
|
|
1506
1570
|
if (!dir) return
|
|
1507
|
-
const
|
|
1508
|
-
|
|
1509
|
-
|
|
1571
|
+
const nextRound = (dir.round || 0) + 1 // 续轮上限由 syncMeta 的 solver 分支约束(见下)
|
|
1572
|
+
const progressText = buildSolverContext(getDirState(q.id), dir, nextRound, params.directionsPerSolver)
|
|
1573
|
+
await spawnChild('solver:' + q.id + ':' + dir.id, solverPrompt(q, dir, nextRound, progressText), { role: 'solver', qid: q.id, direction: dir.id, round: nextRound, description: q.陈述 })
|
|
1574
|
+
logActivity('solver', 'problem ' + q.id + ' direction ' + dir.id + ' solver spawned (plan, round ' + nextRound + ')')
|
|
1510
1575
|
} else if (a.role === 'verifier') {
|
|
1511
1576
|
const cands = await buildVerifyCandidates()
|
|
1512
1577
|
const c = cands.find(function (x) { return x.rId === a.target })
|
|
@@ -1591,9 +1656,11 @@ export function apply(ctx) {
|
|
|
1591
1656
|
if (dir.status === 'success' || dir.status === 'dead-end') continue
|
|
1592
1657
|
const running = Object.keys(agentRegistry).some(function (cid) { const m = agentRegistry[cid]; return m && m.qid === q.id && m.direction === dir.id && m.role === 'solver' })
|
|
1593
1658
|
if (running) continue
|
|
1594
|
-
|
|
1595
|
-
const
|
|
1596
|
-
const
|
|
1659
|
+
if ((dir.round || 0) >= (Number(params.solverMaxRounds) || 3)) { dir.status = 'dead-end'; dir.dead_end_reason = dir.dead_end_reason || '迭代轮限到达(solverMaxRounds=' + params.solverMaxRounds + ')'; await saveDirState(); await writeJournal(q.id); logActivity('solver', 'problem ' + q.id + ' direction ' + dir.id + ' dead-end (round cap reached in heuristic)'); continue }
|
|
1660
|
+
const nextRound = (dir.round || 0) + 1
|
|
1661
|
+
const progressText = buildSolverContext(dirs, dir, nextRound, params.directionsPerSolver)
|
|
1662
|
+
const promptText = solverPrompt(q, dir, nextRound, progressText)
|
|
1663
|
+
const r = await maybeGate('spawn', 'solver for problem ' + q.id + ' direction ' + dir.id, { label: 'solver:' + q.id + ':' + dir.id, promptText: promptText, meta: { role: 'solver', qid: q.id, direction: dir.id, round: nextRound, description: q.陈述 } }, async function (d) { await spawnChild(d.label, d.promptText, d.meta); return { spawned: true } })
|
|
1597
1664
|
if (r && r.gated) return
|
|
1598
1665
|
}
|
|
1599
1666
|
}
|
|
@@ -1781,10 +1848,14 @@ export function apply(ctx) {
|
|
|
1781
1848
|
continue
|
|
1782
1849
|
}
|
|
1783
1850
|
if (methods.has(mu.id)) {
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1851
|
+
// 只记录"有实际问题/方向上下文"的引用;method-keeper 纯整理时的引用(qid/dirId 皆空)不当作应用,
|
|
1852
|
+
// 避免把"整理时引用该方法"误记为"实际应用",从而污染应用计数并触发错误的全局晋升。
|
|
1853
|
+
if (ctx.dirId || ctx.qid) {
|
|
1854
|
+
m.applications = m.applications || []
|
|
1855
|
+
m.applications.push({ at: fmtTime(), 问题: ctx.qid || '', 方向: ctx.dirId || '', text: (mu.效果 || '') + (mu.建议 ? ';建议:' + mu.建议 : '') })
|
|
1856
|
+
await saveMethod(m, false)
|
|
1857
|
+
logActivity('method', 'application record appended to ' + mu.id + ' (问题 ' + ctx.qid + ' 方向 ' + ctx.dirId + ')')
|
|
1858
|
+
}
|
|
1788
1859
|
}
|
|
1789
1860
|
}
|
|
1790
1861
|
}
|
|
@@ -1840,7 +1911,8 @@ export function apply(ctx) {
|
|
|
1840
1911
|
if (parsed && ((Array.isArray(parsed.__writes) && parsed.__writes.length) || (parsed.meta && parsed.meta.kind === 'methods'))) {
|
|
1841
1912
|
await applyAgentWrites(parsed.__writes)
|
|
1842
1913
|
if (parsed.meta && parsed.meta.kind === 'methods') await syncMeta(parsed.meta, { id: childId })
|
|
1843
|
-
|
|
1914
|
+
// 消费已沉淀的发明:新建方法卡或对已有方法的改进都视为已处理本轮 pending(与旧 JSON 路径一致,防 improvements-only 反复触发)
|
|
1915
|
+
if (parsed.meta && ((Array.isArray(parsed.meta.created) && parsed.meta.created.length > 0) || (Array.isArray(parsed.meta.improvements) && parsed.meta.improvements.length > 0))) methodLog.pendingInventions = []
|
|
1844
1916
|
await saveAll(); return
|
|
1845
1917
|
}
|
|
1846
1918
|
if (!parsed) { logActivity('method', 'method keeper returned nothing usable'); await saveAll(); return }
|
|
@@ -2200,7 +2272,10 @@ export function apply(ctx) {
|
|
|
2200
2272
|
}
|
|
2201
2273
|
async function checkTermination() {
|
|
2202
2274
|
const unsolved = allProblems().filter(function (q) { return !(q.状态 === '已解决' || q.优先级 === 'never') })
|
|
2203
|
-
|
|
2275
|
+
// 终止前必须无遗留验证对象 / 待沉淀发明:否则会在命题/解法仍未验证、发明尚未蒸馏时提前停机,
|
|
2276
|
+
// 导致"仅剩验证候选 / 仅剩发明"的工作永远不会被执行(验证/方法库是独立于问题求解的收尾工作)。
|
|
2277
|
+
const leftoverVerify = (await buildVerifyCandidates()).length > 0 || methodLog.pendingInventions.length > 0
|
|
2278
|
+
if (unsolved.length === 0 && !leftoverVerify && Object.keys(agentRegistry).length === 0 && Object.keys(tasks).length === 0 && planQueue.length === 0) {
|
|
2204
2279
|
scheduler.running = false
|
|
2205
2280
|
await releaseProjectLock()
|
|
2206
2281
|
logActivity('stop', 'all active problems solved (never-priority excluded) and no active agents/tasks/plans — scheduler stopped (strict termination)')
|
|
@@ -2317,7 +2392,7 @@ export function apply(ctx) {
|
|
|
2317
2392
|
if (oldDirs && oldDirs.length > 0) await archiveDirections(qid, oldDirs)
|
|
2318
2393
|
const list = (meta.directions || []).map(function (d) {
|
|
2319
2394
|
const old = (getDirState(qid) || []).find(function (x) { return x.id === d.id })
|
|
2320
|
-
return { id: d.id || ('d_' + shortId()), title: d.title || '', method: d.method || old?.method || '', core_assumption: d.core_assumption || old?.core_assumption || '', feasibility: clamp01(d.feasibility != null ? d.feasibility : (old ? old.survival : 0.5)), status: 'active', round: old ? old.round : 0, survival: clamp01(d.survival != null ? d.survival : (old ? old.survival : 0.5)), routes: old?.routes || [], lessons: old?.lessons || [], blockers: old?.blockers || [], lemmas: old?.lemmas || [], journal: old?.journal || [], dead_end_reason: '' }
|
|
2395
|
+
return { id: d.id || ('d_' + shortId()), title: d.title || '', method: d.method || old?.method || '', core_assumption: d.core_assumption || old?.core_assumption || '', feasibility: clamp01(d.feasibility != null ? d.feasibility : (old ? old.survival : 0.5)), status: 'active', round: old ? old.round : 0, survival: clamp01(d.survival != null ? d.survival : (d.feasibility != null ? d.feasibility : (old ? old.survival : 0.5))), routes: old?.routes || [], lessons: old?.lessons || [], blockers: old?.blockers || [], lemmas: old?.lemmas || [], journal: old?.journal || [], dead_end_reason: '' }
|
|
2321
2396
|
})
|
|
2322
2397
|
dirState.set(qid, list)
|
|
2323
2398
|
await saveDirState(); await writeJournal(qid)
|
|
@@ -2337,6 +2412,11 @@ export function apply(ctx) {
|
|
|
2337
2412
|
if (meta.status) dir.status = String(meta.status)
|
|
2338
2413
|
if (meta.dead_end_reason) dir.dead_end_reason = String(meta.dead_end_reason)
|
|
2339
2414
|
if (meta.round) dir.round = Number(meta.round)
|
|
2415
|
+
// 轮次上限:达到 solverMaxRounds 且仍未成功/死路 → 强制死路(新协议路径没有 followup 自迭代,必须靠此收口,与旧路径一致)
|
|
2416
|
+
if ((dir.round || 0) >= (Number(params.solverMaxRounds) || 3) && dir.status !== 'success' && dir.status !== 'dead-end') {
|
|
2417
|
+
dir.status = 'dead-end'
|
|
2418
|
+
dir.dead_end_reason = dir.dead_end_reason || ('迭代轮限到达(solverMaxRounds=' + params.solverMaxRounds + ')')
|
|
2419
|
+
}
|
|
2340
2420
|
// 引理注册(id 由代理在命题卡里自定)
|
|
2341
2421
|
if (Array.isArray(meta.lemmas)) {
|
|
2342
2422
|
for (const l of meta.lemmas) {
|
|
@@ -2360,6 +2440,14 @@ export function apply(ctx) {
|
|
|
2360
2440
|
const p = clamp01(meta.solution_prob)
|
|
2361
2441
|
q.solutions.push({ title: '解法 ' + (q.solutions.length + 1), prob: p >= 1 ? 0.99 : (p <= 0 ? 0.01 : p), status: '未定论', text: String(meta.solution_text).slice(0, 2000) })
|
|
2362
2442
|
}
|
|
2443
|
+
// 子问题/临时假设(与旧 JSON 路径一致):注册 q_sub 问题 + 判断问题 + p-tmp 假设
|
|
2444
|
+
if (Array.isArray(meta.sub_questions)) {
|
|
2445
|
+
for (const sq of meta.sub_questions) {
|
|
2446
|
+
if (!sq || !sq.q_sub_statement) continue
|
|
2447
|
+
const rec = await addSubQuestion(qid, dirId, sq)
|
|
2448
|
+
if (rec) { dir.sub_questions = dir.sub_questions || []; dir.sub_questions.push(rec) }
|
|
2449
|
+
}
|
|
2450
|
+
}
|
|
2363
2451
|
await saveProblem(q); await saveDirState(); await writeJournal(qid)
|
|
2364
2452
|
await consumeMethodFeedback(meta, { qid: qid, dirId: dirId })
|
|
2365
2453
|
logActivity('solver', qid + '/' + dirId + ' meta sync (status=' + (meta.status || '') + ', survival=' + dir.survival + ')')
|
|
@@ -2377,6 +2465,18 @@ export function apply(ctx) {
|
|
|
2377
2465
|
if ((await readText('Methods/' + mid + '.md')) === undefined) await saveMethod(mm, false)
|
|
2378
2466
|
}
|
|
2379
2467
|
}
|
|
2468
|
+
// 改进:把内容写进已有方法卡的 ## 改进历史(与旧 JSON 路径一致)
|
|
2469
|
+
if (Array.isArray(meta.improvements)) {
|
|
2470
|
+
for (const imp of meta.improvements) {
|
|
2471
|
+
if (!imp || !imp.id) continue
|
|
2472
|
+
const m = methods.get(imp.id)
|
|
2473
|
+
if (!m) { logActivity('method', 'improvement referenced unknown method ' + imp.id); continue }
|
|
2474
|
+
m.improvements = m.improvements || []
|
|
2475
|
+
m.improvements.push({ v: m.improvements.length + 1, 原因: imp.原因 || '', text: imp.改进内容 || '' })
|
|
2476
|
+
await saveMethod(m, false)
|
|
2477
|
+
logActivity('method', 'method ' + imp.id + ' improved (v' + m.improvements.length + ')')
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2380
2480
|
await saveAll()
|
|
2381
2481
|
return { ok: true }
|
|
2382
2482
|
}
|
|
@@ -2472,7 +2572,7 @@ export function apply(ctx) {
|
|
|
2472
2572
|
registerTool('vibe_math_lock_status', 'Show the project lock occupancy.', objParams({}), 'vibe_math_lock_status')
|
|
2473
2573
|
registerTool('vibe_math_claim_write', 'Acquire the write lock for one target file (relative to the project root). Call before writing a Markdown file directly.', objParams({ target: { type: 'string' } }, ['target']), 'vibe_math_claim_write')
|
|
2474
2574
|
registerTool('vibe_math_release_write', 'Release the write lock for one target file (relative to the project root).', objParams({ target: { type: 'string' } }, ['target']), 'vibe_math_release_write')
|
|
2475
|
-
registerTool('vibe_math_sync_meta', '
|
|
2575
|
+
registerTool('vibe_math_sync_meta', 'After you write content into Markdown files, report ONLY lightweight scheduling metadata to keep the scheduler state in sync (content stays in the md files). meta.kind must be one of:\n- "directions": {qid, directions:[{id,title,method,core_assumption,feasibility}], methods_used:[{id,效果,建议}], new_inventions:[{类型,标题,内容描述,是否已入库}]}\n- "solver": {qid, dirId, round, survival, status:"continue|success|dead-end", dead_end_reason, lemmas:[{id,title,statement,proof,prob,分类,优先级}], methods_used, new_inventions, solution_prob, solution_text, sub_questions:[{q_sub_title,q_sub_statement,assumption_title,assumption_statement}]}\n- "methods": {used:[{id,效果,建议}], created:[ids], improvements:[{id,改进内容,原因}]}', objParams({ meta: { type: 'object' } }, ['meta']), 'vibe_math_sync_meta')
|
|
2476
2576
|
|
|
2477
2577
|
// /vibe slash command (registered once; routed per session)
|
|
2478
2578
|
ctx.effect(() => commands.register({
|
|
@@ -24,7 +24,7 @@ V3 是在 v1(经典流水线)、v2(概率驱动 + JSON 数据层)基础
|
|
|
24
24
|
|
|
25
25
|
| 维度 | v1(经典流水线) | v2(概率驱动) | v3(论文式自组织) |
|
|
26
26
|
|---|---|---|---|
|
|
27
|
-
| 知识媒介 | JSON(csv/字段) | JSON(qs.json / Propos / Verified 卡) | **md
|
|
27
|
+
| 知识媒介 | JSON(csv/字段) | JSON(qs.json / Propos / Verified 卡) | **md(子代理直接写各自归属的 md:方向日志、引理命题卡、方法卡——写前用 `vibe_math_claim_write` 申请写锁;`vibe_math_sync_meta` 只上报轻量调度元数据;调度器负责聚合索引与锚点回写)** |
|
|
28
28
|
| 书写风格 | 结构化字段 | 结构化字段 | **论文/研究报告式叙述,自组织** |
|
|
29
29
|
| 问题来源记录 | 无 | progress 字段零散记录 | **问题卡"来源与动机"章节 + 依赖图(后生问题自带产生原因与计划)** |
|
|
30
30
|
| 方法论沉淀 | 无 | 无 | **Methods/ 通用理论发明库 + Method Keeper 沉淀循环** |
|
|
@@ -81,13 +81,13 @@ flowchart TB
|
|
|
81
81
|
SCHED -->|"④"| VERI
|
|
82
82
|
SCHED -->|"④ 定期安排"| KEEP
|
|
83
83
|
SCHED -->|"④ 可选"| REP
|
|
84
|
-
EXPL -->|"方向集(
|
|
85
|
-
SOLV -->|"
|
|
84
|
+
EXPL -->|"方向集(meta.directions)"| SCHED
|
|
85
|
+
SOLV -->|"轻元数据 + 新发明(meta)"| SCHED
|
|
86
86
|
VERI -->|"审查/辩论结果(JSON)"| SCHED
|
|
87
|
-
SCHED -->|"⑤
|
|
87
|
+
SCHED -->|"⑤ 聚合索引 + 锚点回写"| PROG
|
|
88
88
|
SCHED -->|"⑤ 注册后生问题/命题"| PROB
|
|
89
89
|
SCHED -->|"⑤"| PROP
|
|
90
|
-
KEEP -->|"⑥
|
|
90
|
+
KEEP -->|"⑥ 沉淀/完善方法(写 Methods/*.md)"| METH
|
|
91
91
|
SCHED -->|"⑦ 裁决回写锚点 + 生成"| VERF
|
|
92
92
|
SCHED -->|"⑧ 记录计划与结果"| LOGS
|
|
93
93
|
SCHED <-->|"读写状态(唯一写者)"| STATE
|
|
@@ -99,7 +99,7 @@ flowchart TB
|
|
|
99
99
|
- **②** 若有可推进工作(待解问题方向、**可验证对象**、待沉淀发明)且并发有空闲 → 构建**规划简报**,调用**规划代理**一次(仅有验证候选而无待解问题时同样触发,保证命题/解法不会因"无问题可解"而永不验证);
|
|
100
100
|
- **③** 规划代理返回**计划**(最多 `planningHorizon` 步动作的 JSON);manual 模式下先挂**计划审批门**;审批/入队后调度器把每步动作的 reason 回写到问题卡的「计划」锚点(`- 计划: 一句话说明下一轮安排`);
|
|
101
101
|
- **④** 调度器逐条**校验**(硬约束)并**执行**:派发/续轮/中断 Explorer、Solver、Verifier,定期安排 Method Keeper 与汇报代理;超出当前并发的动作进入待执行队列跨 tick 消费;
|
|
102
|
-
- **⑤**
|
|
102
|
+
- **⑤** 子代理把研究内容**直接写进各自归属的 md**(求解器→`Progress/<问题id>/<方向id>.md`、引理→`Propos/<分类>/<p-id>.md`、新方法→`Methods/<m-id>.md`),写前用 `vibe_math_claim_write` 申请写锁、写后用 `vibe_math_release_write` 释放(同一文件同一时刻只允许一个代理写,避免并发冲突),再用 `vibe_math_sync_meta` 上报**轻量调度元数据**(方向状态/存活率/引理 id+证明/方法卡 id/新发明/解法;若所在环境无法真正写文件则回退为回复 JSON 的 `__writes` 数组由调度器兜底落盘);调度器据此更新索引与调度,并负责聚合索引 `Progress/<问题id>.md`、状态/概率锚点回写与 `Verified/` 副本生成。
|
|
103
103
|
- **⑥** Method Keeper 提炼近期工作,沉淀新方法条目、合并碎片、完善体系结构;
|
|
104
104
|
- **⑦** 验证裁决由调度器回写锚点(状态/概率)、生成 `Verified/` 副本、更新索引;
|
|
105
105
|
- **⑧** 计划 + 逐条执行结果写入 `Logs/Plans/`,作为下一次规划的"上次计划经验"(规划学习闭环)。
|