dsh-metaphysics 0.57.0 → 0.59.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,174 @@
1
+ ## 0.58.0(2026-11-01,已发布)
2
+
3
+ > 本版主题:把「盘送不进对话」这条路补成三条不依赖宿主的通道(C3),顺手让自动发布可观测、可自愈,再把引文里两句长期误署的话改回原书。
4
+ >
5
+ > 包含:C3 对话桥替代(深链 / 复制 / 结构化参数)、§5.8 自动发布加固、B6 通行说复核、B6 通根透干复核(误署纠正)、B6 第五批(大六壬 3 条)、C4-a 三方合盘、C4-b 择日候选日比较、C4-c 同盘多口径并排、D1+ 首屏耗时回显、A1+ 推导链出处、D4 发布回滚、自检修复(见下)。
6
+
7
+ ## 0.59.0(2026-11-01,待发布)
8
+
9
+ > 本版主题:把「算得更准」这条路主动停下,改走「不骗人」。三件事——知识标签不再冒充「已验证」、分歧按「本盘涉及」分组、新增「本插件不回答什么」清单。都不碰算法:0.58.0 的应期回测已经说明,51.7% 对 29.6% 的随机基线,靠调规则优先级补不上来;能补上来的是「别让用户以为它比实际更可靠」。
10
+
11
+ - **知识标签不再冒充「已验证」**(`engine/interpret-knowledge.js`、`engine/interpret.js`、`src/panel-kit.js`):
12
+ - 问题:三个标签原写作「诸家一致 / 各家有异说 / 待核实」。前两个在用户眼里约等于「可靠」,而实际含义只是「各书都这么写」。「文本里一致」和「世界里成立」共用一个词,是产品在无意中骗人。
13
+ - 改法:标签写全为「文本·诸家一致 / 文本·各家有异说 / 文本·未录入」,前两个强制带前缀;知识区块末尾加一句统一声明——「以上标签只说明典籍文本的一致程度,不表示该技法经过验证;本插件不对任何技法的预测效度作保证」,全报告只出现一次(挂在最后一个带知识卡的维度下,逐维重复反而会被跳过不看)。
14
+ - 证据:`test/interpret-knowledge.test.mjs` 新增 4 条,其中一条是**防止被改回去**的——任何标签不以「文本·」开头即失败;另三条盯声明本身(存在、点明「不表示经过验证」、点明「不作保证」)。
15
+
16
+ - **分歧按「本盘涉及」分组**(`engine/interpret.js`):
17
+ - 问题:文末「这套规则有多稳」把本盘踩到的分歧和「这派别来就吵的」混成一锅,八字一张盘能列十几条,用户看不出哪几条跟自己有关。
18
+ - 改法:按 `seen` 分成两组——先列「本盘涉及 N 处」(只留条目名,正文里已展开过),再列「本体系另有 M 处通行分歧(本盘未涉及,附原注备查)」;两者都没有时写明「本盘未踩到,结论是按一派一路算下来的」。开头与结尾各一句把这层定性钉死:这是**文本层**的分歧,不是谁对谁错的判定,插件不替它们裁决。
19
+ - 证据:`test/interpret-knowledge.test.mjs` 新增 2 条——分组标记必须存在;「本盘涉及」里列出的条目必须真在这张盘的知识卡里出现过(防虚标)。
20
+
21
+ - **新增「本插件不回答什么」清单**(`engine/limits.js`、`engine/interpret.js`、`engine/index.js`、`src/panel-kit.js`):
22
+ - 为什么不做成免责声明:「可能不准」这种句子没有信息量,用户看完还是不知道该信哪部分。有用的写法是——这条为什么做不到、做到哪一步就停了、依据是什么。
23
+ - 通用三条:技法效度未经检验(能复核的只有形式层)、同盘不同命(模型硬缺陷,不是样本不够)、不给医疗法律投资建议。按体系各 1–3 条:六爻不给公历日期且用神两现不代选、八字不预测具体年份事件且旺衰是分档不是评分、紫微飞星层只报路径不判吉凶、梅花不取外应、大六壬应期未做、奇门八门九星入墓未做、塔罗只给通行牌义。
24
+ - 走公共收尾 `withReportMeta` 注入,所以奇门那条不经过正文组装的支路也带得上。面板在报告最末折叠显示(与免责声明分工不同:免责声明是「别全当真」,这里是「具体哪几件不答、为什么」);对话侧全量输出给调用方,不截成标题——模型知道「为什么不答」,才不会自己补一个答案。
25
+ - 证据:`test/limits.test.mjs` 27 条(字段完整 / id 不重复 / 文案 ≥40 字且有实质 / 无绝对化用词 / 七个体系都有专属条目 / 通用三条覆盖三个死穴 / 八字不带六爻条目 / 奇门支路也带上)。其中最关键一条是**清单不能和实现矛盾**:既然写着「应期不给公历日期」,六爻解析全文就不得匹配出 `YYYY年M月D日`;哪天有人在应期里加了日期,这条会先挂。
26
+
27
+ - **修:新增引擎模块漏进构建清单,打包后静默变成 `undefined`**(`tools/build-client.mjs`):`limits` 初版只加了 `import`,没进 `ORDER` 与 `INTERPRET` 栈,源码跑得通、打出来的分块里 `limitsFor is not a function`。表现是 `chunks.test.mjs` 七个体系逐字节比对失败(报 `Qn is not a function` 这类压缩名)、`security.test.mjs` 直接抛错。已把 `limits` 插到 `interpret-knowledge` 之后、并列入 `INTERPRET` 组。**教训写在这里:engine 下新增文件,除了 import 还要进 `ORDER` 和它所属的模块组,否则源码测试全绿、产物静默坏掉。**
28
+
29
+ - **B1 六爻应期收尾:规则顺序纠错 + 补统计显著性**(`engine/yingqi.js`、`tools/backtest-yingqi.mjs`、`test/yingqi.test.mjs`):
30
+ - **发现一个实质错误**:代码里规则的排列几乎是把原文倒过来排的,而注释声称「状态互斥优先级照应期总注的排列:空 → 破 → 动 → 墓 → 太旺 → 衰绝 → 静」。把《各門類應期總注章第又二十六》19 条逐条对下来,真实次序是「静 → 动 → 太旺 → 衰绝 → 入墓 → 六合 → 月破 → 旬空 → 大象吉受克 → 大象凶受克 → 元神总纲 → 化进 → 化退 → 独发独静 → 变爻动爻 → 远近当分 → 再占 → 世空元动 → 世衰元静」。**那句「空 → 破 → … → 静」原文里没有,是编的。**
31
+ - 改法:新增 `RULE_ORDER` 照原文罗列次序,`primary` 重新定义为「按原文次序第一条生效的规则」,不再是「最可能应验的那条」。同时把 `yingqiState` 上那句「状态互斥优先级」的错注释删掉——那里没有选择逻辑,各项独立计算。
32
+ - **对拍补了二项单尾检验,把「百分比」变成「结论」**(`tools/backtest-yingqi.mjs`):并集 15/29=51.7%,随机基线 29.6%,**p=0.0102(显著)**;主规则 8/29=27.6%,按主规则自身支数算基线 17.0%,**p=0.1047(不显著)**。两者一正一反说明:规则集合确实覆盖了原文所记的应验支,但条文之间没有可用的优先次序——这正是面板继续不出日期的依据。
33
+ - **逐规则统计**(新增):`liuhe-xiang-ji`(六合宜相击)7 例中 6,85.7%,p≈1.3×10⁻⁴,过 12 条规则的 Bonferroni 校正(α=0.0042),是本批数据里唯一站得住的单项;`rumu-chong-kai`(入墓喜冲开)6 例 0 中、`jing-zhi-chong`(静而逢值逢冲)7 例 1 中,都低于自身基线。**但这只是报告,不据此调规则**——按这些数字重排就是拿对拍集调参,命中率会变成自己喂出来的。脚本头部与测试注释都写死了这条边界。
34
+ - 新增能力边界 `liuyao-liuyue`:不推演流月推进后的二次变化。依据是一条实占反例(用神伏藏、本可靠日辰冲开,进入下月建后一冲解掉原月建对制它之爻的合,制者复起,出伏失败),这类跨月推演还没做,所以应期只能作「该留意哪几支」。
35
+ - 证据:`test/yingqi.test.mjs` 28 条(+3)。新增两条是防回归的关键——「规则顺序照原文罗列」把 15 个 id 的顺序钉死,改排序必须给原文依据;「同时命中按原文次序取主规则」用「入墓 5 < 月破 7」的用例验证排序真的生效。另修正两个旧用例的日辰(原来取辰,正好是水墓,会把「入墓」拉进来抢主位,测的就不是月破/旬空了)。
36
+
37
+ - **面板一键「复制问事提示」**(`src/panel-kit.js`、`src/web-ui.js`、`src/app.js`、`src/core.js`、`engine/index.js`、`tools/build-client.mjs`):
38
+ - 六爻 / 梅花 / 大六壬 / 奇门 / 塔罗五个体系的结果页,问题行下方出现「复制问事提示」按钮:点一下,当前盘面 + 所问之事打包成一段完整提示,粘到任何对话里都能用。`core.js` 加 `kindOfDirection` 把命盘的七向(财运/事业/感情…)映射到问事的六类(business/career/love…)。
39
+ - 命盘类(八字 / 紫微 / 合盘 / 趋势 / 起名 / 风水 / 称骨 / 星座 / 数字 / 人格)不渲染这个按钮——它们回答的是「这个人是什么结构」,不是「这件事成不成」,给了按钮就是诱导误用。小六壬结果是单行落宫、没有解析报告,按钮也不在它那边,提示走命令行。
40
+ - 引擎侧 `engine/index.js` 导出 `buildEventPrompt` / `ASK_KINDS`;`build-client` 给五个问事分块加 `EVENT_PROMPT` 栈(`qimen-prompt` + `event-prompt`),命盘分块不带,避免无谓体积。本仓 esbuild 不接受 `export {} from`,改为先 `import` 再 `export`。
41
+ - 证据:`test/ask-copy.test.mjs` 14 条——五个问事体系都渲染且只渲染一次、两个命盘类不渲染、引擎确实导出构建器。
42
+
43
+ - **问事解读提示:把「先问清事 → 取用神 → 回到现实」推广到全部问事体系**(`engine/event-prompt.js`、`engine/qimen-prompt.js`、`tools/event-prompt.mjs`、`docs/问事解读提示.md`):
44
+ - 起因:奇门那套要求(先答他所问、不堆术语、每个符号说得出为什么、结论回到现实核对)不该只对奇门成立。六爻、梅花、六壬、塔罗、小六壬一样会被读成「符号念一遍」——世爻旺相所以好、用生体所以吉、这张是死神所以完蛋。
45
+ - 做法:骨架共用(时间确认 → 问事分类 → 取用神给理由 → 读状态 → 三追问自检 → 现实核对 → 表达要求 → 禁止 → 输出格式),**取用神各体系自己给**:六爻世应 + 六亲按事类取(工作官鬼、财妻财、感情男财女官、文书父母)、梅花体用、六壬日干日支 + 三传、塔罗牌位决定含义、小六壬明确说明「没有独立的我,别硬补」。奇门委派给 `qimen-prompt.js`,两套提示内容逐字一致(有断言钉住)。
46
+ - 时间不明一律拦住:问事体系靠起课那一刻定盘,没时刻就没有盘。`timeKnown:false` 时返回「先别起课」的拦截文本,且**不得出现任何盘面符号**(有断言:全文不许匹配世爻/应爻/四柱/值符)。
47
+ - 把「说不清」写进提示,而不是糊过去:六爻用神两现必须标「两现未定」;小六壬必须说明它给不了「我 vs 对方」;梅花体用标了「大吉」也要提醒「吉是条件好,不是结果已经发生」。
48
+ - 用法:`npm run prompt:event -- --system liuyao --kind career --question "…" --lines 9,7,8,8,7,6`,输出一段填好盘面的完整提示;`--no-time` 只出「先问时间」。长文档见 `docs/问事解读提示.md`。
49
+ - 证据:`test/event-prompt.test.mjs` 61 条。含**空话检测**(现实核对里不许出现「结合现实 / 具体情况具体分析 / 视情况而定」)、**自洽检测**(禁止清单里写的,提示自己不能犯)、问题超 200 字截断。
50
+
51
+ - **报告内置「数 / 象 / 辞」三层导读**(`engine/guide.js`、`engine/interpret.js`、`src/panel-kit.js`):
52
+ - 为什么做进插件而不是只放文档:读不懂命盘的人不会去翻 README,他只在结果页划两下就关了。所以导读必须「一进来就看见、但不挡路」——折叠,默认收起,排在「一页读懂」之前。
53
+ - 内容只讲一件事:这份报告里哪部分是算出来的(可复核)、哪部分是命名(可商量)、哪部分是判断(要自己拿主意)。三层各带一句「这一层在本报告里长什么样」,再接三问检验法(坐标 / 关系 / 唯一读法),最后点明纳甲、十神、宫位都是中间件。
54
+ - 数据与渲染分开:`guide.js` 只存文案(纯数据,vm 可测),`panel-kit` 负责画。两套 UI 共用 `resultWithInterpret`,所以面板与离线页同时生效,不用改两处。
55
+ - 证据:`test/guide.test.mjs` 25 条。最要紧的三条是**内容自洽**:三层与三问必须齐(少一层就退化成鸡汤)、问句必须以问号结尾(是提问不是结论)、**全文不得出现效度承诺词**(这段本身就是「效度未验证」的说明,出现「一定」「精准」即自相矛盾)。另有渲染契约:只渲染一次、排在结论之前、默认收起、转义无注入面。
56
+ - 这一版把 `docs/象与数-要义导读.md`(长文)里的核心判准压缩成 90 秒版放进报告,长文留作延伸阅读。
57
+
58
+ - **修:深色主题下选中高亮块的字看不见**(`src/app.js`、`src/core.js`):
59
+ - 症状:深色模式下打开侧栏面板,被点中的那个体系(tab / 分组里的工具项 / 视图开关 / 主按钮 / 分段控件)文字是白的,压在同样浅的品牌色块上,对比度约 1.2:1 —— 等于没有字。
60
+ - 根因不是「颜色没调好」,是**写死了白色**:选中态一律 `background:var(--dsw-alias-brand-primary);color:#fff`,八处都是这么写的。而品牌色在深色主题里通常反而变浅(深色底上才看得见),白字落上去必然糊掉。同一个 `#fff` 在浅色主题下是对的,在深色下是错的,说明它本来就不该被写死。
61
+ - 改法:不再猜一个颜色,改成**运行时量一次宿主真实的品牌色**——往 body 插一个透明探针,`getComputedStyle` 取回解析后的 `backgroundColor`,按 WCAG 相对亮度算出白字与近黑字各自的对比度,挑高的那一侧写进 `:root` 的 `--mp-on-brand`,CSS 只读 `var(--mp-on-brand,#fff)`。系统主题切换(`prefers-color-scheme`)与宿主换 `class` / `data-theme` 时各重算一次;量不到就回落到 `#fff`,不会比改动前更差。
62
+ - 为什么不用媒体查询硬编码两套色:宿主的深色品牌色是什么值,插件无从得知(它可能仍是深蓝,也可能是浅青),猜错一次就是同一个 bug 换个方向复发。
63
+ - 证据:`test/core.test.mjs` 新增 12 条,其中一条走遍 RGB 步长 51 的全色域(216 个底色),断言「挑出来的那侧对比度永远不低于另一侧」,并给出最差值 4.19:1 —— 满足大字号 AA(3:1);中灰如 `#7f7f7f` 两侧都到不了 4.5,这是色彩本身的极限,不是选错。`test/theme.test.mjs` 新增 8 条静态守卫:**品牌色块后到规则结束为止不得再出现写死的白字**,谁改回去谁先挂。
64
+
65
+ - **滴天髓·下篇六亲论录入:家庭这一块从「通行说」升到「可核原文」**(`engine/citations.js`、`engine/interpret-knowledge.js`、`test/fixtures/citation-sources.json`):
66
+ - 起因是「能不能用八字对家庭生活给方向」这个问题。查下来发现,六亲这块在库里只有一条 `smt-liuqin`(三命通会条列名目),夫妻、子女、父母三处的原文一句没录——用户看到的「家庭」解释,实际上没有底本支撑。
67
+ - 补法:从底本(`diancang.xyz/.../ditiansui/153092.html`,下篇六亲论)逐字录入 5 条——夫妻「夫妻因缘宿世来,喜神有意傍天财」、子女「子女根枝一世传,喜神看与杀相连」、父母「父母或降与或替,岁月所关果非细」、女命章、何知章(富/贵/贫/贱四条判据)。原文进 fixture,CI 离线可复验,`test/citations.test.mjs` 的「每条引文的来源正文都在 fixture 里」逐条比对。
68
+ - 关联:`bazi-liuqin` 由 1 条引文扩到 4 条(夫妻/子女/父母各有落点),`bazi-geju-chengbai` 加何知章(成破格 → 富贵贫贱有了原文判据),引文总数 94 → 99。
69
+ - **意外收获,也是本版最硬的一条**:女命章原文「三奇二德虚好语,咸池驿马半推详」——三奇、二德是空口说好话,咸池(桃花)、驿马顶多参考一半。**「神煞不主吉凶」不是今人的现代意见,是《滴天髓》自己说的。** 以前 `bazi-shensha` 只引三命通会(条列名目)+ 子平真诠(主张不主吉凶),只引前者会让人以为插件在给神煞背书;现在两书合看,立场有原文兜底。
70
+ - 边界:六亲论这一篇是韵语提纲,各家注解发挥分歧很大,所以只录原文、不把某家注解当原文引(`dt-liuqin-fuqi` 的 note 写明了这一点)。
71
+
72
+ - 门槛:131 个测试文件 / 6104 条断言全过(较 0.58.0 增 33 条);client.js 256KB / gzip 78KB;产物自检 18 个分块 / 逐模块编译 58 个;性能 29 项在限内。
73
+
74
+ > 下列两条是 0.58.0 之后、本版之前的工作,随本版一并发布。再往下的 C3 对话桥替代 / §5.8 自动发布加固 / push-tag 三条的详细记录属 0.58.0,保留于此备查。
75
+
76
+ ## 未发布
77
+
78
+ - **B1 六爻应期:样本不再等用户,改从《增删卜易》里取;规则层落地,命中率公开且不好看**(`engine/yingqi.js`、`tools/gen-zengshan-cases.mjs`、`tools/backtest-yingqi.mjs`、`test/fixtures/zengshan-cases.json`、`test/yingqi.test.mjs`):
79
+ - 为什么不等用户给卦例。应期对拍要「月建日辰 + 完整六爻 + 断语 + 应期口径 + 实际应验」五样齐,这类样本在《增删卜易》里本来就是成批的(野鹤老人自己拿实占卦例成书)。本地已缓存全书 12.4 万字,170 处「X月Y日占」起式,够用,且不必麻烦用户现编。
80
+ - 收录标准四条全过才收:起式能定位月建日辰;六爻能按行解析;**解析出的六亲/地支/五行与引擎纳甲逐爻一致**(这一条同时充当解析正确性校验——纳甲+六亲由卦宫五行唯一决定,六爻全对基本等于卦没错);断语点名用神(「寅木官星持世」「未土父母動化進神」「財爻持世」「世爻寅木」「X为用神」五种句式);应验句里有可解析的年月日。结果 **29 条收录 / 141 条排除**,每条排除都写了理由(`excluded`),不静默丢弃。变卦名按「原文缩写还原成候选,候选唯一才核」处理(写「之兌」即兑为泽、写「之夬」即泽天夬,「大」这种可指大过/大壮的当未能核验),避免拿缩写误判。
81
+ - 规则层照《各門類應期總注章第又二十六》19 条落成 15 条可判规则;落不到「某支」上的 4 条(独发独静、远近换尺、再占、元神总纲)列进 `NOT_IMPLEMENTED`,不假装做了。取支一律只给地支、不换算公历日期——与既有 `yingqiWindow` 的契约一致。
82
+ - **对拍结果(公开,不好看)**:并集命中 15/29=**51.7%**,平均 3.55 支、随机基线 29.6%;主规则命中 8/29=**27.6%**,与基线持平。结论:按条文取支集合比瞎猜强约 22 个百分点,但目前的规则优先级排序**没有预测力**;逐条看还能看到「化进神」「化退神」各 1 例全落空。因此面板**仍不出日期**,`test/yingqi.test.mjs` 25 条一律用构造盘断言(不拿对拍集调参,否则命中率是自己喂出来的)。
83
+ - 复现:`npm run gen:zengshan` → `npm run backtest:yingqi`。
84
+ - **F 真化改为「判例对齐」**(方案文档同步):公开古籍没有「已验证人生」的化气格命例,做真化命中率等于在没有答案的地方造分;改为取古籍明确判「化气格成」的四柱,只比对条件清单口径,不做命中率宣称。
85
+
86
+ - **发版最后一步补成工具:`tools/push-tag.mjs`**(`package.json` 增 `push:tag` 脚本,`release.mjs` 的提示改指它):
87
+ - 起因:0.58.0 发完 npm,脚本提示 `git tag v0.58.0 && git push origin v0.58.0`,而这台机器 GitHub 443 整段不通(`Connection reset` / 连不上),tag 只能落在本地,远端 release 页面上永远缺一个。
88
+ - 做法:默认取 `package.json` 版本;缺 tag 就建 annotated tag;推送连续三次失败且错误像「连不上」时,自动临时 ed25519 → 注册 deploy key → 走 `ssh.github.com:443` 推 `refs/tags/…` → 无论成败都删 key 与私钥。`--dry-run` 只报告不动手,`--no-create` 只推不建。与自动发布用同一个配置文件,不额外落盘凭据。
89
+ - 证据:`test/push-tag.test.mjs` 22 条(dry-run 不建 tag 也不碰远端、默认 tag 跟版本号、tag 名不合法直接拒绝、SSH 兜底接线与删 key、凭据只从配置文件读)。实测 v0.58.0 走 SSH 兜底推成功,临时 deploy key 168375084 已删。
90
+
91
+ - **C3 对话桥替代**(`engine/bridge.js`、`src/app.js`、`src/web-ui.js`):会话槽位 `conversation.input.right` 不稳,桥一断就没路把盘送进对话;这一版给出三条不依赖宿主的通道。
92
+ - 深链:`#mp=<句柄>&q=<问题>`,参数走 C1 句柄编码,截断或改字报 `E_HANDLE` 而不是静默排成另一张盘。面板首屏先读链接再排盘(表单状态下一帧才生效,同一批值经 `run` 的 over 直传,不会先闪一张旧盘);独立页在 `setTab` 之后填表单再排,并在结果顶部写「已按链接还原:体系|问题」,没填回表单的参数(如合盘对方)如实列出,不悄悄丢。
93
+ - 复制:完整提问(与桥发出去的是同一份)、一句话精简(体系 + 句柄 + 问题,≤200 字)、结构化参数(`{"tool":"metaphysics","args":{handle,…}}`,助手可直接照 args 调 compute)。
94
+ - 面板在追问框下加一排芯片「复制提问 / 复制精简 / 复制参数 / 复制深链」,桥可用时保留、桥缺席时就是主通道;独立页在追问区加「复制提问」、导出栏加「复制深链」。
95
+ - 证据:`test/bridge.test.mjs` 88 条(深链往返与四柱复现、四种写法可解析、六类坏链接不抛异常且带 code、表单还原与未还原提示、三档文本与 JSON、无句柄不编链接、不改盘面对象、面板与独立页接线、bridge 进公共栈);无头 Chrome 实测 `命理排盘.html#mp=…` 打开后四柱与问题一致、坏句柄回落到默认盘。
96
+
97
+ - **§5.8 自动发布加固**(`tools/autopublish.mjs`、计划任务):把「定时跑但出了问题看不出来」补成可观测、可自愈。
98
+ - 每天 23:00 与 23:30 双跑:第二跑在指纹未变时只写一行日志,等于给第一跑的一次兜底重试。
99
+ - 每次运行开头写 `运行开始(auto/dry-run/init/force,pid …)`;**无改动也写一行**(原来是完全静默,事后查不出任务跑没跑);日志超过 512KB 自动裁到最近 800 行。
100
+ - 失败写 `tools/.autopublish-error`(内容含失败原因与时间),成功一次自动删掉;未捕获异常也留痕。该文件进 `.gitignore`。
101
+ - GitHub HTTPS 连续失败且报错像「连不上」(443 / timeout / SSL / RPC failed)时,自动生成临时 ed25519 → 调 API 注册 deploy key → 走 `ssh://git@ssh.github.com:443/...` 推一次 → 无论成败删 key、删本地私钥;「推被拒」不触发兜底。
102
+ - 证据:`test/autopublish.test.mjs` 28 条(未知参数仍立即拒绝且不碰状态文件、加固项接线、dry-run 写运行开始、配置缺失时退出码 1 且写错误文件、失败后不留锁也不改状态)。
103
+
104
+ - **B6 通行说复核(8 张逐张过一遍底本)**(`engine/citations.js`、`engine/interpret-knowledge.js`):
105
+ - `liuyao-jintui-yong` 由通行说改为 refs:《增删卜易》卷二·進神退神章第二十九「進神退神者,爻之動而化也,化進化退,吉凶禍福有喜忌之分,所喜者宜於化進,所忌者宜化退神。」底本已经把喜忌落在进退上;把「喜/忌」具体落到用神/忌神两档仍标为本插件引申(写进知识卡 note)。
106
+ - 其余七张维持通行说,但把「查过什么」写进理由:紫微飞星三张——`《紫微斗數全書》`卷一、卷三全文检索「宮干/飛星/三方同飛/忌轉忌」均无命中,底本只有生年四化;奇门干宫生克——统宗已抓四卷只有「星相克/仪相克/门相克」与「时干克日干」;十干克应——检索到的「十干克應歌訣」署诸葛亮、释意者为近人,属现代韵语,不能当原文;通根透干——当时没定位到,留待联网复核(下一轮已改判,见「B6 通根透干复核」);塔罗逆位——韦特《Pictorial Key to the Tarot》1911 已入公有领域,但原书对逆位态度含混,未给「逆位=受阻/内化」这套固定读法。
107
+ - 53 张卡:45 张已定位原文(+1)、7 张通行说(−1)、1 张待补。`docs/citations.html` 同步重建。
108
+ - 证据:`test/citations.test.mjs` 59 条(新增 3 条:用神化进退落到進神退神章、source 为 verified、通行说剩七张且待补一张)。
109
+
110
+ - **B6 通根透干复核:通行说是误署,改引《滴天髓·干支总论》**(`engine/citations.js`、`engine/interpret-knowledge.js`):
111
+ - 说法查证。常被引作《滴天髓》的「地支所藏之干,本静以待用,透出干头,则显其用矣。故干以通根为美,支以透出为贵」,在**滴天髓底本全文**里检索「本静以待用/干以通根为美/透出干头」零命中;在**《子平真诠》沈孝瞻原文**(论十干十二支,中华典藏本 984 字)里同样零命中。它实际出现在《子平真诠》**评注本**卷一·论十干十二支的注文(附支藏人元图、十二月令人元司令分野表之后的按语)。也就是说:网络通行写法「《滴天髓》云:地支所藏之干……」把注文署给了原书。
112
+ - 改判依据。该注文自身引的才是《滴天髓》:「天全一气,不可使地德莫之载;地全三物,不可使天道莫之容」——这句在本地所收滴天髓底本「干支总论」里逐字可对上,语义正好是「天干要地支承载(通根)、地支藏干要透出天干(透出)」。故本卡只引这句可核的原文,注文那两句写进 `note` 作说明,不冒充原文。
113
+ - 结果:`bazi-tonggen-tougan` 由通行说改为 refs(新增引文 `dt-yiqi-tonggen`,《滴天髓·干支总论》);引文库 93→94 条;**46 张已定位 / 6 张通行说 / 1 张待补**。`docs/citations.html` 现在也会把 `note` 显示在已定位条目下,误引纠正看得见。
114
+ - 证据:`test/citations.test.mjs` 62 条(新增 3 条:改引干支总论、引文确为原句、note 写明误署;通行说计数 7→6)。
115
+
116
+ - **D4 发布回滚**(`tools/release.mjs` + `tools/release-rollback.mjs`):发版失败、或发布后附件核对没通过时,打印一套可照抄的回滚步骤,不自动动 registry。
117
+ - `rollbackPlan()` 按原因出步骤:`publish-failed` 先查「版本条目有没有建出来」;两种情况都给出「`npm dist-tag add …@上一版 latest` → `npm deprecate` 问题版本 → 网页 2FA 删包(automation token 会被 403 拒)→ `npm version patch --no-git-tag-version` → CHANGELOG 改回未发布段」;打过 tag 时再加本地删 tag 与远端删 tag 两步。
118
+ - `release.mjs` 在发布前记住 registry 上的 `dist-tags.latest`,作为回退目标;`npm publish` 失败与 `verifyPublish` 失败都自动打印这套步骤,并给出单独跑的等价命令。
119
+ - 新增 `node tools/release-rollback.mjs`(`npm run rollback:plan`):默认只打印;`--apply dist-tag` 需要 `NPM_TOKEN`,只代为把 latest 指回上一版;`unpublish` / `deprecate` / 删远程 tag 一律只打印,由人确认后执行。
120
+ - 证据:`test/release-rollback.test.mjs` 40 条(两种原因的步骤与命令、无上一版时不猜号、tagged 两步、未知 reason 回落、排版与不打印 token、CLI 退出码与 `--apply` 限制、release.mjs 接线与 verify-only 不把问题版本当上一版)。
121
+
122
+ - **自检修复**(`engine/index.js`、`src/web-ui.js`):两处只在真实浏览器/连续操作下才暴露的一致性问题。
123
+ - `partner2: null` 在排盘前归一化为未传:原先 compute 当它没给,句柄却把 `partner2:null` 编进去,同一对盘会拿到两个句柄。
124
+ - 独立页耗时行改存 `last.perf`,由 `paint()` 末尾补回:切询问方向等重绘会换掉整段结果区,原先那一行随之消失;现在重绘后仍在且只有一行。
125
+ - 证据:`test/hepan-triple.test.mjs` 新增 2 条(null 不出三方、与省略同句柄);`test/perf-instrumentation.test.mjs` 增至 41 条(耗时行入状态、paint 末尾补回);headless Chromium 实测切方向后 `.mp-perf` 仍为 1 行。
126
+
127
+ - **B6 第五批:大六壬原文录入**(`engine/citations.js`):《大六壬大全》维基文库四库全书本,新增 3 条,`daliuren-sike` 由通行说改为 refs。
128
+ - 卷一·起例「十干寄宫」:`甲课寅兮乙课辰,丙戊课巳不须论。丁己课未庚申上,辛戌壬亥是其真。癸课原来丑宫坐,分明不用四正神。`——四课起手。
129
+ - 卷一·起例「贼克法」:`取课先从下贼呼,如无下贼上克初。初传之上名中次,中上加临是末居。三传既定天盘将,此是入式法第一。`——九宗门取初传。
130
+ - 卷二·神将释「月将」:`逆布者谓之月将,其实即十二神也。`——月将定义;加时布盘仍标通行口诀、不标卷次。
131
+ - 引文库合计 **93 条**(八字经典 41 + 引文索引 52),53 张卡里 44 张已定位原文、8 张通行说、1 张待补;`test/fixtures/citation-sources.json` 增至 58 个章页,`docs/citations.html` 同步重建。
132
+ - 证据:`test/citations.test.mjs` 新增 6 条(书目登记、四课三传带 refs、三章定位、无省略号),共 56 条;`test/trace-sources.test.mjs` 同步把大六壬三层的出处改为已核验卷次。
133
+
134
+ - **A1+ 推导链出处**(`engine/trace.js`):16 层的 `source` 统一成「出处;实现:engine/…」,能对上已录入篇名的才写书名卷次。
135
+ - 六爻:六亲对读《增删卜易》卷一·用神章第八;伏神引卷二·飛伏神章第二十八;旺衰引卷一·月將章第十六、日辰章第十七。纳甲、世应明写「规则表 / 通行动诀,本仓未录入古籍章页」。
136
+ - 八字:格局引《子平真诠》八、论用神(专求月令),调候参《穷通宝鉴》五行总论;旺衰**明写本仓量化规则、非古籍定数**;四宫标 Tyme 1.5.4 口径与 704 组对拍、未照录古籍章页。
137
+ - 紫微:格局引《紫微斗数全书》卷三·论人命入格、谈星要论(与引文索引同源)。
138
+ - 奇门:盘面事实引《奇门遁甲统宗》卷一·奇门秘诀总赋;旺衰引卷三;宫位引卷二与卷十一·玄机赋(中);用神表与十干克应明写「本仓表,非古籍原文」。
139
+ - 大六壬:本环境没有可稳定核验的公有领域章页,三层只标「通行口诀,未标卷次」,不拿别书条文冒充。
140
+ - 证据:`test/trace-sources.test.mjs` 35 条(16 层都有实现位置、书名只能在已登记的五本里、所引篇名能在引文库找到、各体系「有据 / 无据」的措辞、Markdown 导出原样保留);`test/trace.test.mjs` 同步文本断言。
141
+
142
+ - **D1+ 首屏耗时回显**(`src/engine-lazy.js`、`src/app.js`、`src/web-ui.js`、`src/panel-kit.js`):
143
+ - `__mpEnsureEngine` 记录每次取块耗时与是否命中缓存(`window.__MP_LAST_LOAD`),不埋点上报、不发网络请求。
144
+ - 面板从点击到两帧后记「首屏」,并拆出引擎取块与排盘两段;连续点两次时旧回调按 `perfSeq` 丢弃,不会把上一次的数字盖到新结果上。
145
+ - 独立页记「排盘」与「渲染(组 HTML + 写 DOM 的同步时间)」,明确不把浏览器真正绘制的那一帧算进来。
146
+ - 结果顶部缝一行灰色小字:`首屏 42ms|引擎 18ms(首次加载)· 排盘 9ms`,悬停说明「本机实测,不含网络与服务端」。缺哪段省略哪段,不编数字、不出 NaN。
147
+ - 证据:`test/perf-instrumentation.test.mjs` 39 条(三种组合的排版、缓存标注与缺省、NaN/负数、懒加载两次调用与缓存、面板/独立页计时接线、无上报调用)。
148
+
149
+ - **C4-a 三方合盘**(`engine/hepan.js · tripleOf` + `engine/index.js`):`hepan` 新增可选 `partner2`(字段同 `partner`),结果多一个 `triple`——
150
+ - `pairs`:三对(你×对方 / 你×第三方 / 对方×第三方)各给 `total`、`level` 与三维度分数,顺序固定;`a-b` 与顶层 `score` 完全一致,另两对与「单独拿这两人排合盘」逐分相同,翻过来排也一样。
151
+ - `best` / `hardest` / `spread` / `focus`:最顺、最需磨合、最高最低分差、三对之间分歧最大的那一维。**分差不足 3 分时不点名**,摘要改说「三对分数接近,不排名」,避免假精确。
152
+ - **不合成「三人总分」**:三方只把三对两两关系并列——和不同的人相处是不同的事,合成一个数会把差异抹平。
153
+ - 八字与紫微两种合盘都支持;`partner2: null` 视同未传,非对象或缺 `datetime` 报 `E_PARTNER` 并点名 `partner2`。
154
+ - 第三人进排盘句柄与影子盘指纹(换第三人=另一组盘,`baseId` 随之改变),下一轮只传 `handle` 即可复现同一组三方。
155
+ - 面板与独立页:合盘 tab 勾「三方合盘(加入第三人)」后展开第三方日期/时刻/性别/出生地;结果区在三维度后加三对并列小表(分数 + 三维度),只在该勾选时出现。
156
+ - 证据:`test/hepan-triple.test.mjs` 54 条(结构、与单独合盘/颠倒顺序一致、最顺与最需磨合、分歧维度、null 与坏输入、文本、紫微、句柄与影子盘、面板表与转义、面板/独立页/模板/宿主 schema 接线)。
157
+
158
+ - **C4-b 择日候选日比较**(`engine/zeri.js` + 面板/独立页):`zeri` 新增可选 `candidates`(2–12 个真实公历日期)。
159
+ - 给了就只比这几天(去重、保持输入顺序),不再按 `startDate` 扫区间;逐日分数与区间模式同一套公式,同一批日子逐分一致。
160
+ - 结果多一个 `compare`:`best`(这一组最高分与结论、同分者)、`spread`(最高与最低分差)、`note`(「胜出只表示更合所问事项,不代表好多少」)。全部因冲属相被排除时 `best` 为 `null`,摘要如实写「都因冲属相被排除」,不硬推一个。
161
+ - 入参守卫:不是数组、少于 2 个、超过 12 个、去重后不足 2 天、`2026-02-30` 这类不存在的日期,一律 `E_INPUT` 并说清改法;区间模式仍必须给 `startDate`。
162
+ - 面板与独立页:择日表单新增「候选日(可空,只比这几天)」,逗号/顿号/空格分隔;结果区在候选模式下画逐日表(日期+农历 / 干支+建除 / 分数 / 结论 / 理由),最优行标「最优」,下方并列推荐、可用、回避与比较口径;区间模式仍用原文案,不铺 60 行表。
163
+ - 候选日进句柄,下一轮只传 `handle` 即可复现同一组比较。
164
+ - 证据:`test/zeri-candidates.test.mjs` 48 条(与区间模式同分、去重、冲煞排除、全排除、五类坏输入、文本、句柄、面板表与转义、四处接线)。
165
+
166
+ - **C4-c 同盘多口径并排**(`engine/diff.js · CALIBER_VIEWS`):口径对照的每一行多回 `views`——只挑会影响结论的几项做两列并排,不改盘、不重算、不判优劣。
167
+ - 八字:日柱 / 时柱 / 旺衰 / 格局(`frame.primaryName`)/ 喜用 / 起运;紫微:命宫 / 身宫支 / 五行局 / 身主 / 起大限;奇门:日柱 / 局数 / 值符 / 值使。字段取两张盘里已有的值,缺省写 `—`,不把对象硬串成 JSON。
168
+ - 摘要里每行多一句「并排:日柱 丙辰 → 乙卯;…」,只列变化项;面板与独立页在根因后加 `mp-cview` 表(列名用档位名,例如「换日 / 不换日」),同样只列变化项。
169
+ - 紫微身宫取 `body.branch`;原先写的 `body.ganzhi` 不存在,会一直显示 `—`。
170
+ - 证据:`test/caliber-diff.test.mjs` 新增 21 条(视图键与行数、单元格格式、子年身主 火星 → 铃星、午年无变化项、奇门晚子时落日柱、文本并排、面板表与转义)。
171
+
1
172
  ## 0.57.0(2026-11-01,已发布)
2
173
 
3
174
  > 本版主题:排盘句柄与一句话改参、推导链 Markdown 导出、喜忌中性档、引文索引三批补录、性能门槛。