dsh-metaphysics 0.60.0 → 0.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +1550 -1435
  2. package/README.md +17 -14
  3. package/client.almanac.js +24 -24
  4. package/client.bazi.js +120 -112
  5. package/client.chenggu.js +40 -40
  6. package/client.convert.js +22 -22
  7. package/client.daliuren.js +79 -79
  8. package/client.fengshui.js +29 -29
  9. package/client.hepan.js +111 -103
  10. package/client.js +282 -263
  11. package/client.liuyao.js +101 -100
  12. package/client.mbti.js +21 -21
  13. package/client.name.js +71 -71
  14. package/client.numerology.js +21 -21
  15. package/client.qimen.js +82 -82
  16. package/client.star.js +14 -14
  17. package/client.tarot.js +107 -107
  18. package/client.trend.js +81 -81
  19. package/client.xiaoliuren.js +30 -30
  20. package/client.zeri.js +59 -59
  21. package/client.ziwei.js +116 -108
  22. package/engine/citations.js +4 -0
  23. package/engine/diff.js +3 -0
  24. package/engine/event-prompt.js +7 -1
  25. package/engine/followup.js +16 -1
  26. package/engine/index.js +16 -3
  27. package/engine/interpret-knowledge.js +21 -0
  28. package/engine/interpret.js +7 -3
  29. package/engine/liuyao.js +4 -0
  30. package/engine/meihua.js +3 -0
  31. package/engine/name-data.js +24 -78
  32. package/engine/name-extra.js +415 -0
  33. package/engine/name.js +36 -9
  34. package/engine/plain-summary.js +5 -1
  35. package/engine/surname-data.js +249 -0
  36. package/engine/tarot-cards.js +143 -0
  37. package/engine/tarot.js +74 -27
  38. package/engine/yijing-text.js +792 -0
  39. package/engine/zeri-shensha.js +958 -0
  40. package/engine/zeri.js +126 -28
  41. package/engine/ziwei-zuoyao.js +313 -0
  42. package/engine/ziwei.js +37 -1
  43. package/index.js +6 -1
  44. package/package.json +2 -2
  45. package//345/221/275/347/220/206/346/216/222/347/233/230.html +3324 -163
package/CHANGELOG.md CHANGED
@@ -1,1435 +1,1550 @@
1
- ## 0.60.0(2026-11-02,待发布)
2
-
3
- > 本版主题:从「算得对」推进到「用得顺」。新增**我的命盘**(本机档案)与**复制提问**两条日常路径,并把历算、输入守卫、异步竞态、发布闸门里查出来的问题逐条修掉。新增能力不改变既有排盘口径;同一输入、同一 asOf 仍产出同一张盘。
4
-
5
- - **我的命盘:一次录入,下次点卡出盘**(`src/panel-kit.js`、`src/app.js`、`src/web-ui.js`):
6
- - 面板与离线单页共用一套实现与同一个存储键 `dsh-metaphysics/profiles-v1`:存的是出生日期、时刻、性别、出生地这些**输入**,不是结果;只落本机,不上传。
7
- - 卡片照市面排盘 App 的命盘列表:一张卡一个人,点卡直接出盘;改名、置顶、删除收在卡片右上角,悬停或键盘聚焦才出现,触屏常驻。置顶在前,其余按最近排过排序;最多 24 张,超出时淘汰最久没排的那张。
8
- - 档案来自 localStorage,按外部输入对待:逐字段验一遍,日期要真过日历,坏条目整条丢弃,不把 `undefined` 渲染进卡片;同 id 只留第一条。
9
- - 删除点两次才算;改名会把原称呼读回输入框,改完点「更新这张档案」覆盖原档,创建时间、使用次数与置顶状态不变。
10
- - 写入失败不再假装成功:`profilesPut` 报失败,删除/置顶/记次数也回滚到存储里的真实状态;浏览器完全没有 localStorage 时同样按失败回报——否则卡片从界面消失、下次进来又复活。
11
- - 旧版本或手改存储留下的「有日期没时刻」卡不再拿表单里现成的时刻顶上(那会排成另一个人),而是提示先补时刻;这种卡也不算「排过一次」。
12
- - 称呼框是裸 DOM:面板重绘与单页重绘都先把已输入的字存起来,翻置顶、切视图不会把称呼抹掉。
13
-
14
- - **复制提问:把盘面和问题整理成一段话,交给任意 AI**(`engine/followup.js`、`engine/bridge.js`、`src/app.js`、`src/web-ui.js`):
15
- - 追问框优先于「所问之事」:只读主问题时,命盘类没有这个输入框,复制出去的「所问」会永远是默认开场句。
16
- - 包里带上面板已算好的开场结论(直答/说人话),别的模型开场沿用同一口径;盘面摘要与回答骨架一并带上。
17
- - 打包失败时按钮给出「暂无可复制内容」并自动复原,不再毫无反应;切方向 / 重绘结果时追问框里已经输入的字保留。
18
-
19
- - **输入守卫:坏参数不再静默变成另一张盘**(`engine/index.js`、`index.js`、`engine/handle.js`):
20
- - 经度统一整形并校验:数字串转数字;非有限值或超出 −180…180 报 `E_RANGE`,不再走到真太阳时里炸成裸异常,也不再静默少一次修正。
21
- - 地址、问题、revise、ask、姓名等自由文本设长度上限——这些串会整段进句柄,不设限等于允许一次调用把结果撑到几百 KB。
22
- - `datetime` 的秒位真正校验;`asOf` 的小时与分钟必须在范围内,非法值不再被折回另一天。
23
- - 句柄增量拒绝 `__proto__` / `constructor` / `prototype` 键,避免改掉结果对象的原型。
24
- - 联网解析失败不写缓存:不会连着六小时把「解析失败」当成答案;风水不再请求出生地解析(经度对盘面没有影响,发给第三方是纯外泄)。
25
- - `detail` 只接受 `full` / `lean`,写了别的值不再被当成缺省静默放过。
26
-
27
- - **历算修正**(`engine/calendar.js`、`engine/lunar.js`、`engine/dst.js`、`engine/ziwei.js`、`engine/trend.js`、`engine/random.js`、`engine/rectify.js`、`engine/zeri.js`):
28
- - `jdToParts` 的分钟进位会让 23:59:45 塌回「当日 00:00」,日柱退一天;改为先归到整秒再向下取整分,拆出的那一天永远就是这一刻所在的那一天。
29
- - 农历的节气时刻被移了两次时(净偏移约 −12 分),节气落在午夜前后十几分钟内会少算一天,置闰整月错位;修正后 1917 年由「闰三」回到真历表「闰二」、1922 年由「闰六」回到「闰五」。
30
- - 夏令时换表日给出明确说明:起算日 02:00–03:00 的钟面读数在当年不存在,终止日 01:00–02:00 同一读数对应两个真实时刻——按哪种读法折算写进提示。
31
- - 紫微流年改用调用方的 `asOf` 作基准年,同一句柄跨年不再排出不同的流年表;人生 K 线按交运年份切段,与虚岁轴对齐,不再整条线提前一年。
32
- - 随机种子把高位与小数位折进状态:相差 2^32 的种子(如隔 49.7 天的毫秒时间戳)不再摇出同一卦。
33
- - 生时校正的事件限 200 条、年份限 1600–2400、候选时辰去重后最多 24 个;择日事项错误统一带 `E_INPUT`,`days` 的数字串会被规范化,越界或非数字一律报错,不再静默改成 30 天。
34
-
35
- - **输出档位与上下文**(`engine/index.js`、`index.js`、`engine/handle.js`):
36
- - 新增 `detail: "lean"`:只给结论、所问方向那一条与三张表,长论述与「规则·出处」折成一行指针(省约一半文本);盘面、句柄与解析对象不变,影子盘与口径对照也不会把档位当成盘面差异。
37
- - 工具 schema 把梅花与小六壬的 `mode` 合并进同一个字段并写明三组取值,避免同名字段被后定义覆盖。
38
-
39
- - **客户端稳定性**(`src/engine-lazy.js`、`src/app.js`):
40
- - 分块在途请求去重:并发打开两个体系共享同一次下载;失败也清掉在途记录,一次网络抖动不会把分块永久钉在「正在加载」。
41
- - 面板连续排盘 / 连点 tab 时用序号丢弃过期结果:旧请求不再覆盖新盘,也不再在 await 之后把 tab 拨回去。
42
-
43
- - **闸门与发布**(`tools/`):
44
- - `check-html-sinks` 重写:逐插值判定,补上四类旧版漏检(裸变量赋值、一个 `esc(` 救全条、`insertAdjacentHTML` 的第二个实参、`dangerouslySetInnerHTML`),并带可自证的漏检用例。
45
- - 发布脚本不再 `git add -A`:按目录白名单与扩展名逐路径暂存,点开头的运行痕迹不收,重命名记录正确跳过来源路径。
46
- - 新增凭据扫描、对拍报告新鲜度校验、分块体积预算(单块 gzip ≤260KB、18 块合计 ≤2.75MB)。
47
- - `npm test` 现有 147 个测试文件 / 7139 条断言;新测试覆盖档案存储、分块预算、客户端竞态、细节档位、DST 歧义、输入守卫、HTML 注入面、凭据闸。新增断言均通过「把旧实现改回去必须变红」的反向验证。
48
-
49
- - **真机回归**:`e2e-dom` 137 项、`e2e-panel` 89 项全过,覆盖档案存入/回填/改名/置顶/两次删除/缺时刻拦截、复制提问的所问与开场结论、切方向后追问框保留、深色与窄屏布局、全程无 JS 报错。
50
-
51
- ## 0.59.1(2026-11-02,已发布)
52
-
53
- > 已发布:npm `dsh-metaphysics@0.59.1`,shasum `43817f74d114121bbbe947c91abc10a825a287b9`,94 个文件。
54
-
55
- > 本版主题:把「先说结论」从八字/紫微推到全部九个体系,并且堵住三个会让第一屏**说错话**的坑。不新增断法,不改算法;改的是「第一屏能不能读、说的是不是真的」。
56
-
57
- - **九个体系都有第一屏了**(`engine/plain-summary.js`、`engine/index.js`、`src/panel-kit.js`):
58
- - 之前只有八字与紫微在盘面上方给一段人话;六爻、梅花、六壬、奇门、塔罗、合盘、走势七个体系点开就是一整屏术语。
59
- - 现在每个体系一个 `xxxSummary`,统一返回 `{title,chips,lead,sections,advice,caveat,footer}`;`plainSummary()` 分派,`compute()` 统一挂在 `r.brief` 上(生成失败只记 `briefError`,绝不拖垮排盘)。面板侧收成一个 `pp.briefHTML(r)`,九个盘面都只写一行前缀,不再各自判一次、也不会漏一个。
60
- - 各体系讲各自的结构:六爻讲世应/用神/月日/卦体,梅花讲体用,六壬讲三传(起手—转折—落点),奇门讲日干宫与时干宫的门星神,塔罗逐张给位置义,合盘讲日主关系/夫妻宫/五行互补,走势讲「这一步的基调、最亮最闷、怎么用」。
61
- - 证据:`test/plain-summary.test.mjs` 从 63 条扩到 149 条。新增一组「七体系×五项」:给得出、字段里不许漏 `undefined`、每段有实质、至少一条可做的事、结尾写明不是断语、问事的要回显用户那句话。渲染侧另测九个盘面:方框在最前、只渲染一次、带免责尾句、结果无 `undefined`。
62
-
63
- - **六爻停在「综合」:没有用神也给第一屏,并说清为什么**(`engine/plain-summary.js`):
64
- - 问题:用神由「询问方向」定,而方向默认是「综合」。默认状态下卡片一片空白——恰好是大多数第一次点开六爻的人看到的样子。
65
- - 改法:走「世应版」——只讲与问题无关的世爻、应爻、卦体(六冲/六合/伏吟/反吟)与动爻,并在补充说明里写明「不是算不出来,是取用神要先知道问什么」,第一条建议就是让用户补选方向。选定方向后自动切回用神版,两种版本不会同时出现。
66
- - 顺带修一句措辞:动爻原来写「4、5、6 爻动」,会被读成「六个爻都在动」;改成「第 4、5、6 爻动」,标签里的「3 爻动」是数量。
67
-
68
- - **修:选「财运/学业」时,建议那一段是空的**(`engine/plain-summary.js`):命盘的「询问方向」是 wealth/career/love/health/study/travel/general 七档,问事提示的六类是 career/love/business/action/day/other,两套键只有两个重合。不转这一道,「财运」取不到现实核对清单。新增 `DIR2KIND` 映射(财运→生意、学业→工作、健康→其他、出行→推进)。
69
-
70
- - **修:合盘标签渲染成 `undefinedundefined × undefinedundefined`**(`engine/plain-summary.js`):合盘结果里 `dayMaster` 是「丁火」这样一整串,不是 `{stem,element}` 对象——两种写法现在都接住。
71
-
72
- - **修:紫微同一段里既说「成」又说「破」**(`engine/plain-summary.js`):被判冲破的格局原先同时出现在「结构上成的是…」与「被冲破的格局有…」两句里,读的人只会觉得自相矛盾。被冲破的一律不计入「成」,措辞也从「被判为被冲破」改成「冲不等于毁,说的是它不如完好时那么顶用」。
73
-
74
- - **修:奇门宫位写「6宫」**(`engine/plain-summary.js`):读奇门的人认的是乾宫、巽宫,不是阿拉伯数字。宫名从 `PALACE_FIELD` 释义里取,并补上方位(乾宫(西北));中宫仍按寄宫说明。
75
-
76
- - **修:塔罗的「关节牌」取得随机**(`engine/plain-summary.js`):原来取「第一张逆位」,同一副牌换个抽牌顺序结论就换位置。改成取「现在/现况/核心/建议」那一张,没有就取中间一张;标签里也去掉重复的「3 张」。
77
-
78
- - **走势不再读挂钟**(`engine/trend.js`、`engine/index.js`、`engine/plain-summary.js`、`src/core.js`、`src/app.js`、`src/web-ui.js`):
79
- - 原来 `trendSummary` 用 `new Date().getFullYear()` 找「你现在在哪一步」,过了元旦同一条线会自己改口,也过不了 `check-patterns` 的时间约定。
80
- - 改成:`buildTrend` 接受 `nowYear`,`compute` 从 `asOf` 取年,写进 `meta.nowYear`;引擎侧一律不读挂钟。界面(面板与离线页)用 `Core.todayStamp()` 传当天,内嵌在八字页里的 K 线也带上。没给 `asOf` 时不假装知道现在,改说「没给当前日期,所以不标现在在第几步」。
81
- - 顺带多给一句有用的:「走到这一步的第 N 年,再过 M 年换下一步」。
82
-
83
- - **修(最严重的一条):新增模块漏进分块构建,八个体系的产物里静默变成 `briefError`**(`tools/build-client.mjs`):
84
- - `plain-summary` 只挂在八字/紫微的栈上。另外八个分块(六爻、奇门、六壬、塔罗、黄历、择日、称骨、起名…)里 `plainSummary` 是 `undefined`,`compute` 一调就抛,被 try/catch 收进 `briefError`——源码测试全绿,打包后第一屏直接消失。这正是 0.59.0 记过的同一个坑(`limits` 那次)。
85
- - 改法:抽出 `BRIEF` 组,所有会调 `compute` 的分块都带上。`chunks.test.mjs` 的 19 体系逐字节比对当场抓到(报压缩名 `Fe is not a function`)。
86
-
87
- - **修:八字页会同时出现两个「先说结论」**(`src/panel-kit.js`、`src/app.js`、`src/web-ui.js`):K 线随八字页渲染时也带上了自己的人话方框,两个方框抢第一屏。`trendHTML(r, { brief:false })` 用于内嵌,单独看走势时仍然保留。
88
-
89
- - **口径对照不把「人话总结」当盘面差异**(`engine/diff.js`):`brief` 是从盘面派生的叙述,换一档口径必然改写;不剔掉的话,奇门晚子时那一项会从「1 处差异」变成 3 处。
90
-
91
- - **时辰未知:八字三柱模式,紫微/合盘阻断,趋势降级**(`engine/bazi.js`、`engine/index.js`、`src/app.js`、`src/web-ui.js`、`tools/build-html.mjs`):
92
- - 问题:没填时刻就按页面默认时刻排盘,时柱、紫微命宫、起运日照常出现——**看起来像算过,实际是拿占位值算的**。这比算错更糟:错得看不出来。
93
- - 做法:`buildBazi` 接受 `hourUnknown`,内部仍按「正午」跑完整条管线(大运、旺衰要有个基准),但对外把不该被当成已知的东西全部收回——`pillars.hour = null`、命宫/身宫置空(依赖生时支)、输入回显不带钟点、`civilText`/`trueSolarText` 只留日期、大运与交运去掉时刻并标 `precision: 'day'`、五行不含时柱重算、只落在时柱上的神煞整条去掉。**全文不出现 `12:00`**,内部只用语义标记 `provisionalHour: 'noon'`。
94
- - 下游分三类处理:紫微(命宫由生月+生时支定,时支未知整盘不成立)与合盘(夫妻宫、大运依赖时支)→ `HOUR_UNKNOWN` 阻断并给一句可执行引导;趋势 → 降级,顶层带 `hourPrecision: 'day'` 且首行写明「起运按日估算」。
95
- - 摘要第一行固定句:「时柱按正午暂算,涉及时柱的结论仅供参考」——用户先看到「这不是一张完整盘」,才不会被下面的时柱/命宫误导。
96
- - 界面:八字与人生 K 线的时间框旁多一个「时辰未知」勾选(勾上即收起时刻框),面板与独立页同一套行为;紫微/合盘不提供这个勾选,因为给了等于诱导出一个假盘。
97
- - 证据:`test/hour-unknown.test.mjs` 47 条。三条硬断言——全文(JSON + 渲染文本 + 摘要)不得出现 `12:00`;时柱及依赖项必须为空且不得写成已知;提示必须是摘要第一行(无出生地、远期 ΔT 精度提示都不得把它挤到第二行);工具 schema 必须暴露 `hourUnknown`;面板 `pp-warn` 必须逐字含固定句。另有五条守下游:紫微/合盘必须抛 `HOUR_UNKNOWN`、趋势必须带按日标记、默认路径逐字节不变。
98
-
99
- - **修:无地址时固定提示被挤到第二行**(`engine/index.js`、`test/hour-unknown.test.mjs`):地警告与 ΔT 精度提示也在往摘要最前插——固定句先插、后警告再插,「时柱按正午暂算…」就被压到第二行(命中精度提示时第三行)。改为最后再插固定句,并补「无出生地」「2150 远期盘」两条断言:现在无论有没有地址、精度如何,首行都是它。
100
-
101
- - **补:工具 schema 也支持 `hourUnknown`**(`index.js`、`test/hour-unknown.test.mjs`):原先只有面板与离线页能勾三柱,`metaphysics_chart` 的 schema 里没这个参数,Agent 要不到。补上布尔参数与说明(八字三柱、趋势按日、紫微/合盘阻断),并加断言防回退。
102
-
103
- - **面板三柱提示改用固定句**(`src/panel-kit.js`):`pp-warn` 文案统一为「时柱暂缺:只排年/月/日三柱,起运与交运按日估算。时柱按正午暂算,涉及时柱的结论仅供参考。」,与摘要首行逐字一致(有断言)。
104
- - **证据与门禁**:`test:ci` 138 文件全过,断言基线 6737 条(0.59.0 为 6620);真机回归 `e2e-dom` 103 项、`e2e-panel` 43 项(含「方框只渲染一次」);`stress` 200 盘 14 项(p95 2ms、堆增长 +0.46MB)。
105
-
106
- ## 0.59.0(2026-11-01,已发布)
107
-
108
-
109
- > 已发布:npm `dsh-metaphysics@0.59.0`,shasum `4712088541c06b112792c9249fe64d0dbe0dd38d`,93 个文件。
110
-
111
- > 本版主题:把「算得更准」这条路主动停下,改走「不骗人」。三件事——知识标签不再冒充「已验证」、分歧按「本盘涉及」分组、新增「本插件不回答什么」清单。都不碰算法:0.58.0 的应期回测已经说明,51.7% 对 29.6% 的随机基线,靠调规则优先级补不上来;能补上来的是「别让用户以为它比实际更可靠」。
112
-
113
- - **知识标签不再冒充「已验证」**(`engine/interpret-knowledge.js`、`engine/interpret.js`、`src/panel-kit.js`):
114
- - 问题:三个标签原写作「诸家一致 / 各家有异说 / 待核实」。前两个在用户眼里约等于「可靠」,而实际含义只是「各书都这么写」。「文本里一致」和「世界里成立」共用一个词,是产品在无意中骗人。
115
- - 改法:标签写全为「文本·诸家一致 / 文本·各家有异说 / 文本·未录入」,前两个强制带前缀;知识区块末尾加一句统一声明——「以上标签只说明典籍文本的一致程度,不表示该技法经过验证;本插件不对任何技法的预测效度作保证」,全报告只出现一次(挂在最后一个带知识卡的维度下,逐维重复反而会被跳过不看)。
116
- - 证据:`test/interpret-knowledge.test.mjs` 新增 4 条,其中一条是**防止被改回去**的——任何标签不以「文本·」开头即失败;另三条盯声明本身(存在、点明「不表示经过验证」、点明「不作保证」)。
117
-
118
- - **分歧按「本盘涉及」分组**(`engine/interpret.js`):
119
- - 问题:文末「这套规则有多稳」把本盘踩到的分歧和「这派别来就吵的」混成一锅,八字一张盘能列十几条,用户看不出哪几条跟自己有关。
120
- - 改法:按 `seen` 分成两组——先列「本盘涉及 N 处」(只留条目名,正文里已展开过),再列「本体系另有 M 处通行分歧(本盘未涉及,附原注备查)」;两者都没有时写明「本盘未踩到,结论是按一派一路算下来的」。开头与结尾各一句把这层定性钉死:这是**文本层**的分歧,不是谁对谁错的判定,插件不替它们裁决。
121
- - 证据:`test/interpret-knowledge.test.mjs` 新增 2 条——分组标记必须存在;「本盘涉及」里列出的条目必须真在这张盘的知识卡里出现过(防虚标)。
122
-
123
- - **新增「本插件不回答什么」清单**(`engine/limits.js`、`engine/interpret.js`、`engine/index.js`、`src/panel-kit.js`):
124
- - 为什么不做成免责声明:「可能不准」这种句子没有信息量,用户看完还是不知道该信哪部分。有用的写法是——这条为什么做不到、做到哪一步就停了、依据是什么。
125
- - 通用三条:技法效度未经检验(能复核的只有形式层)、同盘不同命(模型硬缺陷,不是样本不够)、不给医疗法律投资建议。按体系各 1–3 条:六爻不给公历日期且用神两现不代选、八字不预测具体年份事件且旺衰是分档不是评分、紫微飞星层只报路径不判吉凶、梅花不取外应、大六壬应期未做、奇门八门九星入墓未做、塔罗只给通行牌义。
126
- - 走公共收尾 `withReportMeta` 注入,所以奇门那条不经过正文组装的支路也带得上。面板在报告最末折叠显示(与免责声明分工不同:免责声明是「别全当真」,这里是「具体哪几件不答、为什么」);对话侧全量输出给调用方,不截成标题——模型知道「为什么不答」,才不会自己补一个答案。
127
- - 证据:`test/limits.test.mjs` 27 条(字段完整 / id 不重复 / 文案 ≥40 字且有实质 / 无绝对化用词 / 七个体系都有专属条目 / 通用三条覆盖三个死穴 / 八字不带六爻条目 / 奇门支路也带上)。其中最关键一条是**清单不能和实现矛盾**:既然写着「应期不给公历日期」,六爻解析全文就不得匹配出 `YYYY年M月D日`;哪天有人在应期里加了日期,这条会先挂。
128
-
129
- - **修:新增引擎模块漏进构建清单,打包后静默变成 `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` 和它所属的模块组,否则源码测试全绿、产物静默坏掉。**
130
-
131
- - **B1 六爻应期收尾:规则顺序纠错 + 补统计显著性**(`engine/yingqi.js`、`tools/backtest-yingqi.mjs`、`test/yingqi.test.mjs`):
132
- - **发现一个实质错误**:代码里规则的排列几乎是把原文倒过来排的,而注释声称「状态互斥优先级照应期总注的排列:空 → 破 → 动 → 墓 → 太旺 → 衰绝 → 静」。把《各門類應期總注章第又二十六》19 条逐条对下来,真实次序是「静 → 动 → 太旺 → 衰绝 → 入墓 → 六合 → 月破 → 旬空 → 大象吉受克 → 大象凶受克 → 元神总纲 → 化进 → 化退 → 独发独静 → 变爻动爻 → 远近当分 → 再占 → 世空元动 → 世衰元静」。**那句「空 → 破 → … → 静」原文里没有,是编的。**
133
- - 改法:新增 `RULE_ORDER` 照原文罗列次序,`primary` 重新定义为「按原文次序第一条生效的规则」,不再是「最可能应验的那条」。同时把 `yingqiState` 上那句「状态互斥优先级」的错注释删掉——那里没有选择逻辑,各项独立计算。
134
- - **对拍补了二项单尾检验,把「百分比」变成「结论」**(`tools/backtest-yingqi.mjs`):并集 15/29=51.7%,随机基线 29.6%,**p=0.0102(显著)**;主规则 8/29=27.6%,按主规则自身支数算基线 17.0%,**p=0.1047(不显著)**。两者一正一反说明:规则集合确实覆盖了原文所记的应验支,但条文之间没有可用的优先次序——这正是面板继续不出日期的依据。
135
- - **逐规则统计**(新增):`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 中,都低于自身基线。**但这只是报告,不据此调规则**——按这些数字重排就是拿对拍集调参,命中率会变成自己喂出来的。脚本头部与测试注释都写死了这条边界。
136
- - 新增能力边界 `liuyao-liuyue`:不推演流月推进后的二次变化。依据是一条实占反例(用神伏藏、本可靠日辰冲开,进入下月建后一冲解掉原月建对制它之爻的合,制者复起,出伏失败),这类跨月推演还没做,所以应期只能作「该留意哪几支」。
137
- - 证据:`test/yingqi.test.mjs` 28 条(+3)。新增两条是防回归的关键——「规则顺序照原文罗列」把 15 个 id 的顺序钉死,改排序必须给原文依据;「同时命中按原文次序取主规则」用「入墓 5 < 月破 7」的用例验证排序真的生效。另修正两个旧用例的日辰(原来取辰,正好是水墓,会把「入墓」拉进来抢主位,测的就不是月破/旬空了)。
138
-
139
- - **真机回归:用本机浏览器把 19 个 tab 逐个点一遍**(`tools/e2e-dom.mjs`、`package.json`):
140
- - 补的是最后一层:冒烟测试跑在 node 里,测得到引擎与渲染函数,测不到事件绑定、表单显隐、勾选后的重渲染、深链落地。这一层用 Chrome 真开页面点。
141
- - 19 个 tab 各查:切得到、有主按钮、能出结果、结果无脏串、**全程无 JS 报错**(监听 `pageerror` 与 `console.error`)。共 103 项断言。
142
- - 另测三条只有真浏览器能测的:① 八字勾「时辰未知」后,结果里必须出现「时柱暂缺」且不含 `12:00`;② 深链 `#mp=…` 直接打开能自动落地出结果;③ 深色主题下扫描全页文字对比度(含渐变背景取平均色)、390px 窄屏无横向溢出且能出结果。
143
- - 用 `playwright-core` + 本机已装的 Chrome/Edge,**不下载浏览器**;找不到浏览器时打印跳过并返回 0,不会把 CI 弄红。
144
- - 过程中修掉两处**误报**(不是产品问题,但值得记):渐变背景只读 `backgroundColor` 会拿到透明、把「浅底深字」判成同色;父容器(`button.tool`)的文字都在子节点里,拿父容器的 `color` 算对比度必然误判——改成只看「直接含文字节点的元素」且渐变取平均色。
145
-
146
- - **全体系稳定性复查:新增冒烟 + 修掉 K 线 id 不稳定**(`test/smoke-all.test.mjs`、`tools/smoke-all.mjs`、`src/panel-kit.js`):
147
- - 为什么加:单测各自盯一块,但整页能出结果的路径有几十条,一条崩就是白屏——上次「时辰未知」崩在 `p.stemTenGod`,引擎 6253 条断言全绿、页面全崩。这次把 19 个 tab 的 36 个用例逐个跑「排盘 → 渲染 → 文本 → 解析」四条链,共 300 条断言。
148
- - 每项查五件事:不抛异常;成品里不留 `undefined / NaN / null / [object Object]`;**同一张盘渲染两次必须字节一致**;关键结构词在(四柱/命宫/值符/世爻/宜忌…);无 `<script>` 与事件属性。
149
- - 另外覆盖:边界日期(1900/1929 时区切换、2024-02-29、2100)、立春前后年柱必须换、晚子时开关必须改日柱、三柱盘与完整盘的年月日柱必须一致、10 条参数错误路径必须给「带错误码的中文提示」、句柄往返、八字×紫微交叉、40 个随机日期采样、以及**交付物自身**——把单页里的 4 段内联脚本各过一遍编译器(产物语法坏了,跑源码的单测永远发现不了)。
150
- - **修掉一个真 bug**:人生 K 线的 `clipPath` id 原来用全局自增(`klineSeq`),导致同一张盘两次渲染出不同 id——截图对拍、快照测试永远对不上。改成盘面内容的短哈希(FNV-1a):不同盘不同 id,同盘永远同 id。
151
- - 用法:`npm run smoke`(也进 `test:ci`,断言数进基线)。
152
-
153
- - **盘面顶部「先说结论」:一段人话总结**(`engine/plain-summary.js`、`engine/index.js`、`src/panel-kit.js`):
154
- - 起因:排完盘先给的是四柱表和一堆术语,普通人第一屏读不动——就算下面写了解析,也读不到第二屏。要的是「先给一段能看懂的话,再给依据」。
155
- - 内容:一个方框,四件事——总纲(日主+生月+冷暖+最需要什么)、你的底色(十神权重前两位翻成人话)、感情这件事(配偶星落在哪、配偶宫坐什么、有没有破冲合)、最容易卡住的地方;末尾给 2–4 条可以立刻做的事,再加一句补充说明与「不是断语」的尾句。
156
- - 硬规矩:**只做「结构 → 人话」的翻译,不下吉凶断语**。「官杀混」可以说成「你容易遇到两种类型的人」,不能说成「你婚姻不好」。同一张盘每次生成的文字逐字相同(有断言钉死确定性)。
157
- - 八字与紫微都有:紫微那版讲命宫主星、身宫落宫、夫妻宫与格局(格局只描述形状,不作吉凶判词)。
158
- - 位置:方框在盘面之前、每份结果只渲染一次;对话侧 `renderText` 也把这段放在最前(`【先说结论】`),模型照它复述就不会一开口是术语表。
159
- - 证据:`test/plain-summary.test.mjs` 38 条。含确定性(两次生成 JSON 全等)、不越界(不许出现「一定会/必然/注定/肯定会」)、时辰未知时必须在补充说明里讲清「只有六个字、约七成信息」、男命取财星不套女命说法、渲染顺序(方框 index < 盘面 index)。
160
-
161
- - **面板一键「复制问事提示」**(`src/panel-kit.js`、`src/web-ui.js`、`src/app.js`、`src/core.js`、`engine/index.js`、`tools/build-client.mjs`):
162
- - 六爻 / 梅花 / 大六壬 / 奇门 / 塔罗五个体系的结果页,问题行下方出现「复制问事提示」按钮:点一下,当前盘面 + 所问之事打包成一段完整提示,粘到任何对话里都能用。`core.js` 加 `kindOfDirection` 把命盘的七向(财运/事业/感情…)映射到问事的六类(business/career/love…)。
163
- - 命盘类(八字 / 紫微 / 合盘 / 趋势 / 起名 / 风水 / 称骨 / 星座 / 数字 / 人格)不渲染这个按钮——它们回答的是「这个人是什么结构」,不是「这件事成不成」,给了按钮就是诱导误用。小六壬结果是单行落宫、没有解析报告,按钮也不在它那边,提示走命令行。
164
- - 引擎侧 `engine/index.js` 导出 `buildEventPrompt` / `ASK_KINDS`;`build-client` 给五个问事分块加 `EVENT_PROMPT` 栈(`qimen-prompt` + `event-prompt`),命盘分块不带,避免无谓体积。本仓 esbuild 不接受 `export {} from`,改为先 `import` 再 `export`。
165
- - 证据:`test/ask-copy.test.mjs` 14 条——五个问事体系都渲染且只渲染一次、两个命盘类不渲染、引擎确实导出构建器。
166
-
167
- - **问事解读提示:把「先问清事 → 取用神 → 回到现实」推广到全部问事体系**(`engine/event-prompt.js`、`engine/qimen-prompt.js`、`tools/event-prompt.mjs`、`docs/问事解读提示.md`):
168
- - 起因:奇门那套要求(先答他所问、不堆术语、每个符号说得出为什么、结论回到现实核对)不该只对奇门成立。六爻、梅花、六壬、塔罗、小六壬一样会被读成「符号念一遍」——世爻旺相所以好、用生体所以吉、这张是死神所以完蛋。
169
- - 做法:骨架共用(时间确认 → 问事分类 → 取用神给理由 → 读状态 → 三追问自检 → 现实核对 → 表达要求 → 禁止 → 输出格式),**取用神各体系自己给**:六爻世应 + 六亲按事类取(工作官鬼、财妻财、感情男财女官、文书父母)、梅花体用、六壬日干日支 + 三传、塔罗牌位决定含义、小六壬明确说明「没有独立的我,别硬补」。奇门委派给 `qimen-prompt.js`,两套提示内容逐字一致(有断言钉住)。
170
- - 时间不明一律拦住:问事体系靠起课那一刻定盘,没时刻就没有盘。`timeKnown:false` 时返回「先别起课」的拦截文本,且**不得出现任何盘面符号**(有断言:全文不许匹配世爻/应爻/四柱/值符)。
171
- - 把「说不清」写进提示,而不是糊过去:六爻用神两现必须标「两现未定」;小六壬必须说明它给不了「我 vs 对方」;梅花体用标了「大吉」也要提醒「吉是条件好,不是结果已经发生」。
172
- - 用法:`npm run prompt:event -- --system liuyao --kind career --question "…" --lines 9,7,8,8,7,6`,输出一段填好盘面的完整提示;`--no-time` 只出「先问时间」。长文档见 `docs/问事解读提示.md`。
173
- - 证据:`test/event-prompt.test.mjs` 61 条。含**空话检测**(现实核对里不许出现「结合现实 / 具体情况具体分析 / 视情况而定」)、**自洽检测**(禁止清单里写的,提示自己不能犯)、问题超 200 字截断。
174
-
175
- - **报告内置「数 / 象 / 辞」三层导读**(`engine/guide.js`、`engine/interpret.js`、`src/panel-kit.js`):
176
- - 为什么做进插件而不是只放文档:读不懂命盘的人不会去翻 README,他只在结果页划两下就关了。所以导读必须「一进来就看见、但不挡路」——折叠,默认收起,排在「一页读懂」之前。
177
- - 内容只讲一件事:这份报告里哪部分是算出来的(可复核)、哪部分是命名(可商量)、哪部分是判断(要自己拿主意)。三层各带一句「这一层在本报告里长什么样」,再接三问检验法(坐标 / 关系 / 唯一读法),最后点明纳甲、十神、宫位都是中间件。
178
- - 数据与渲染分开:`guide.js` 只存文案(纯数据,vm 可测),`panel-kit` 负责画。两套 UI 共用 `resultWithInterpret`,所以面板与离线页同时生效,不用改两处。
179
- - 证据:`test/guide.test.mjs` 25 条。最要紧的三条是**内容自洽**:三层与三问必须齐(少一层就退化成鸡汤)、问句必须以问号结尾(是提问不是结论)、**全文不得出现效度承诺词**(这段本身就是「效度未验证」的说明,出现「一定」「精准」即自相矛盾)。另有渲染契约:只渲染一次、排在结论之前、默认收起、转义无注入面。
180
- - 这一版把 `docs/象与数-要义导读.md`(长文)里的核心判准压缩成 90 秒版放进报告,长文留作延伸阅读。
181
-
182
- - **修:深色主题下选中高亮块的字看不见**(`src/app.js`、`src/core.js`):
183
- - 症状:深色模式下打开侧栏面板,被点中的那个体系(tab / 分组里的工具项 / 视图开关 / 主按钮 / 分段控件)文字是白的,压在同样浅的品牌色块上,对比度约 1.2:1 —— 等于没有字。
184
- - 根因不是「颜色没调好」,是**写死了白色**:选中态一律 `background:var(--dsw-alias-brand-primary);color:#fff`,八处都是这么写的。而品牌色在深色主题里通常反而变浅(深色底上才看得见),白字落上去必然糊掉。同一个 `#fff` 在浅色主题下是对的,在深色下是错的,说明它本来就不该被写死。
185
- - 改法:不再猜一个颜色,改成**运行时量一次宿主真实的品牌色**——往 body 插一个透明探针,`getComputedStyle` 取回解析后的 `backgroundColor`,按 WCAG 相对亮度算出白字与近黑字各自的对比度,挑高的那一侧写进 `:root` 的 `--mp-on-brand`,CSS 只读 `var(--mp-on-brand,#fff)`。系统主题切换(`prefers-color-scheme`)与宿主换 `class` / `data-theme` 时各重算一次;量不到就回落到 `#fff`,不会比改动前更差。
186
- - 为什么不用媒体查询硬编码两套色:宿主的深色品牌色是什么值,插件无从得知(它可能仍是深蓝,也可能是浅青),猜错一次就是同一个 bug 换个方向复发。
187
- - 证据:`test/core.test.mjs` 新增 12 条,其中一条走遍 RGB 步长 51 的全色域(216 个底色),断言「挑出来的那侧对比度永远不低于另一侧」,并给出最差值 4.19:1 —— 满足大字号 AA(3:1);中灰如 `#7f7f7f` 两侧都到不了 4.5,这是色彩本身的极限,不是选错。`test/theme.test.mjs` 新增 8 条静态守卫:**品牌色块后到规则结束为止不得再出现写死的白字**,谁改回去谁先挂。
188
-
189
- - **滴天髓·下篇六亲论录入:家庭这一块从「通行说」升到「可核原文」**(`engine/citations.js`、`engine/interpret-knowledge.js`、`test/fixtures/citation-sources.json`):
190
- - 起因是「能不能用八字对家庭生活给方向」这个问题。查下来发现,六亲这块在库里只有一条 `smt-liuqin`(三命通会条列名目),夫妻、子女、父母三处的原文一句没录——用户看到的「家庭」解释,实际上没有底本支撑。
191
- - 补法:从底本(`diancang.xyz/.../ditiansui/153092.html`,下篇六亲论)逐字录入 5 条——夫妻「夫妻因缘宿世来,喜神有意傍天财」、子女「子女根枝一世传,喜神看与杀相连」、父母「父母或降与或替,岁月所关果非细」、女命章、何知章(富/贵/贫/贱四条判据)。原文进 fixture,CI 离线可复验,`test/citations.test.mjs` 的「每条引文的来源正文都在 fixture 里」逐条比对。
192
- - 关联:`bazi-liuqin` 由 1 条引文扩到 4 条(夫妻/子女/父母各有落点),`bazi-geju-chengbai` 加何知章(成破格 → 富贵贫贱有了原文判据),引文总数 94 → 99。
193
- - **意外收获,也是本版最硬的一条**:女命章原文「三奇二德虚好语,咸池驿马半推详」——三奇、二德是空口说好话,咸池(桃花)、驿马顶多参考一半。**「神煞不主吉凶」不是今人的现代意见,是《滴天髓》自己说的。** 以前 `bazi-shensha` 只引三命通会(条列名目)+ 子平真诠(主张不主吉凶),只引前者会让人以为插件在给神煞背书;现在两书合看,立场有原文兜底。
194
- - 边界:六亲论这一篇是韵语提纲,各家注解发挥分歧很大,所以只录原文、不把某家注解当原文引(`dt-liuqin-fuqi` 的 note 写明了这一点)。
195
-
196
- - 门槛:131 个测试文件 / 6104 条断言全过(较 0.58.0 增 33 条);client.js 256KB / gzip 78KB;产物自检 18 个分块 / 逐模块编译 58 个;性能 29 项在限内。
197
-
198
- > 下列两条是 0.58.0 之后、本版之前的工作,随本版一并发布。再往下的 C3 对话桥替代 / §5.8 自动发布加固 / push-tag 三条的详细记录属 0.58.0,保留于此备查。
199
-
200
- ## 0.58.0(2026-11-01,已发布)
201
-
202
- > 本版主题:把「盘送不进对话」这条路补成三条不依赖宿主的通道(C3),顺手让自动发布可观测、可自愈,再把引文里两句长期误署的话改回原书。
203
- >
204
- > 包含:C3 对话桥替代(深链 / 复制 / 结构化参数)、§5.8 自动发布加固、B6 通行说复核、B6 通根透干复核(误署纠正)、B6 第五批(大六壬 3 条)、C4-a 三方合盘、C4-b 择日候选日比较、C4-c 同盘多口径并排、D1+ 首屏耗时回显、A1+ 推导链出处、D4 发布回滚、自检修复(见下)。
205
-
206
- ## 未发布
207
-
208
- - **凭据扫描进约定闸:token 形态的字符串提交不进去**(`tools/check-patterns.mjs`):
209
- - 起因:npm / GitHub 的发布凭据存在 `<用户目录>/.dsh/metaphysics-autopublish.json`,只从环境变量喂给 `tools/release.mjs`;它一旦被贴进对话、写进文档或提交到仓库,撤回版本也撤不回已推送的历史。
210
- - 新增第 8 条规则:全仓(跳过 `node_modules` / `.git` / `.workbuddy`)扫 `npm_xxx`、`gh[pousr]_xxx`、`github_pat_xxx`、PEM 私钥头。**命中只打印「文件:行」与原因,绝不回显匹配到的内容**——检查本身不能变成泄露通道。
211
- - 自检:往仓库根放一个 `npm_` + 40 位的假串,闸门退出码 1 并指出 `_leak-probe.js:1`;删掉后恢复通过。当前 299 个文件无命中。
212
-
213
- - **面板(宿主侧栏)真机回归:补上最后一层没测过的 UI,并抓到一个三柱盘必崩的 bug**(`tools/e2e-panel.mjs`、`src/app.js`、`package.json`):
214
- - 缺口在哪:单页 E2E 跑的是 `src/web-ui.js`,面板跑的是 `src/app.js`——两条渲染链只有 `panel-kit` 共用。面板自己的状态(勾选联动、本地历史、深链落地、首屏卡片)此前只有静态字符串断言,等于没跑过。
215
- - 怎么测:真 Chrome + **真 React 18**,配一个最小宿主——假 `slots` 注册表(`register` / `inject` / `spec`)、假 `ctx.effect`、`assemble()` 打出的全量 client(含引擎),本机 http 起服务(`file://` 下 localStorage 会抛 SecurityError)。把 `PanelIcon` 画进侧栏、主面板画进 `#main`,然后照用户顺序点:切体系 → 排盘 → 勾「时辰未知」→ 起卦 → 切深色 → 缩到 520px → 带 `#mp=` 深链重开。43 项断言。
216
- - **抓到的真 bug**:`HISTORY_LABEL` 对 `pillars` 逐项取 `.ganzhi`,时柱为 `null` 时抛 `Cannot read properties of null`——表现是「三柱盘一点排盘就报错」,而引擎 6620 条断言全绿(那段代码在面板里,不在引擎里)。已修:过滤空柱,并在文案末尾写「(时柱暂缺)」,别让历史条目看起来像四柱。
217
- - 顺带验了面板独有的几处:勾选后时刻框被禁用、排过的盘进 `localStorage` 并出现在「最近用过」、连点 10 次不崩也不膨胀、深色下选中卡片对比度 8.13:1、520px 容器无横向溢出、深链把面板切到对应体系并带回问题。
218
- - `test/hour-unknown.test.mjs` 补 6 条把 `HISTORY_LABEL` 的逻辑本身钉住(从 `app.js` 取出函数独立求值,不依赖浏览器),免得下次又只有真机才暴露。
219
- - 用法:`npm run e2e:panel`(没有 Chrome/Edge 时打印跳过并返回 0);`npm run e2e` 现在同时跑单页与面板两层。
220
-
221
- - **连续 200 次压测:不崩、不漂、不涨、不串**(`test/stress.test.mjs`、`package.json`):
222
- - 冒烟测「每条路能走通」,压测测「一直走会不会变形」。200 份**不同日期**的输入(八字/紫微/六爻/奇门轮转,逼缓存真的淘汰),预热 20 次后再跑。
223
- - 四条断言:① 200 次零抛错、结果里没有 NaN/undefined/[object Object];② 同一份输入在压测前后**逐字节一致**(抓隐藏计数器、缓存污染);③ 日历三个 LRU 都不超上限,且确实踩到过上限(`termInstant 899/4096`、`termYear 32/32`、`termWindow 8/8`——踩不到说明压测没打中热点);④ 后 50 次不比前 50 次慢(0.5ms vs 0.8ms),p95 ≤40ms。
224
- - 内存单独起一个 `--expose-gc` 子进程量:强制 GC 后堆增长 **+0.44MB**(9.55 → 10.00MB)。同进程量只会量到未回收的垃圾,是噪声不是泄漏。
225
- - 实测:200 次共 127ms,平均 0.61ms/次。用法 `npm run stress`。
226
-
227
- - **B1 六爻应期:样本不再等用户,改从《增删卜易》里取;规则层落地,命中率公开且不好看**(`engine/yingqi.js`、`tools/gen-zengshan-cases.mjs`、`tools/backtest-yingqi.mjs`、`test/fixtures/zengshan-cases.json`、`test/yingqi.test.mjs`):
228
- - 为什么不等用户给卦例。应期对拍要「月建日辰 + 完整六爻 + 断语 + 应期口径 + 实际应验」五样齐,这类样本在《增删卜易》里本来就是成批的(野鹤老人自己拿实占卦例成书)。本地已缓存全书 12.4 万字,170 处「X月Y日占」起式,够用,且不必麻烦用户现编。
229
- - 收录标准四条全过才收:起式能定位月建日辰;六爻能按行解析;**解析出的六亲/地支/五行与引擎纳甲逐爻一致**(这一条同时充当解析正确性校验——纳甲+六亲由卦宫五行唯一决定,六爻全对基本等于卦没错);断语点名用神(「寅木官星持世」「未土父母動化進神」「財爻持世」「世爻寅木」「X为用神」五种句式);应验句里有可解析的年月日。结果 **29 条收录 / 141 条排除**,每条排除都写了理由(`excluded`),不静默丢弃。变卦名按「原文缩写还原成候选,候选唯一才核」处理(写「之兌」即兑为泽、写「之夬」即泽天夬,「大」这种可指大过/大壮的当未能核验),避免拿缩写误判。
230
- - 规则层照《各門類應期總注章第又二十六》19 条落成 15 条可判规则;落不到「某支」上的 4 条(独发独静、远近换尺、再占、元神总纲)列进 `NOT_IMPLEMENTED`,不假装做了。取支一律只给地支、不换算公历日期——与既有 `yingqiWindow` 的契约一致。
231
- - **对拍结果(公开,不好看)**:并集命中 15/29=**51.7%**,平均 3.55 支、随机基线 29.6%;主规则命中 8/29=**27.6%**,与基线持平。结论:按条文取支集合比瞎猜强约 22 个百分点,但目前的规则优先级排序**没有预测力**;逐条看还能看到「化进神」「化退神」各 1 例全落空。因此面板**仍不出日期**,`test/yingqi.test.mjs` 25 条一律用构造盘断言(不拿对拍集调参,否则命中率是自己喂出来的)。
232
- - 复现:`npm run gen:zengshan` → `npm run backtest:yingqi`。
233
- - **F 真化改为「判例对齐」**(方案文档同步):公开古籍没有「已验证人生」的化气格命例,做真化命中率等于在没有答案的地方造分;改为取古籍明确判「化气格成」的四柱,只比对条件清单口径,不做命中率宣称。
234
-
235
- - **发版最后一步补成工具:`tools/push-tag.mjs`**(`package.json` 增 `push:tag` 脚本,`release.mjs` 的提示改指它):
236
- - 起因:0.58.0 发完 npm,脚本提示 `git tag v0.58.0 && git push origin v0.58.0`,而这台机器 GitHub 443 整段不通(`Connection reset` / 连不上),tag 只能落在本地,远端 release 页面上永远缺一个。
237
- - 做法:默认取 `package.json` 版本;缺 tag 就建 annotated tag;推送连续三次失败且错误像「连不上」时,自动临时 ed25519 → 注册 deploy key → 走 `ssh.github.com:443` 推 `refs/tags/…` → 无论成败都删 key 与私钥。`--dry-run` 只报告不动手,`--no-create` 只推不建。与自动发布用同一个配置文件,不额外落盘凭据。
238
- - 证据:`test/push-tag.test.mjs` 22 条(dry-run 不建 tag 也不碰远端、默认 tag 跟版本号、tag 名不合法直接拒绝、SSH 兜底接线与删 key、凭据只从配置文件读)。实测 v0.58.0 走 SSH 兜底推成功,临时 deploy key 168375084 已删。
239
-
240
- - **C3 对话桥替代**(`engine/bridge.js`、`src/app.js`、`src/web-ui.js`):会话槽位 `conversation.input.right` 不稳,桥一断就没路把盘送进对话;这一版给出三条不依赖宿主的通道。
241
- - 深链:`#mp=<句柄>&q=<问题>`,参数走 C1 句柄编码,截断或改字报 `E_HANDLE` 而不是静默排成另一张盘。面板首屏先读链接再排盘(表单状态下一帧才生效,同一批值经 `run` 的 over 直传,不会先闪一张旧盘);独立页在 `setTab` 之后填表单再排,并在结果顶部写「已按链接还原:体系|问题」,没填回表单的参数(如合盘对方)如实列出,不悄悄丢。
242
- - 复制:完整提问(与桥发出去的是同一份)、一句话精简(体系 + 句柄 + 问题,≤200 字)、结构化参数(`{"tool":"metaphysics","args":{handle,…}}`,助手可直接照 args 调 compute)。
243
- - 面板在追问框下加一排芯片「复制提问 / 复制精简 / 复制参数 / 复制深链」,桥可用时保留、桥缺席时就是主通道;独立页在追问区加「复制提问」、导出栏加「复制深链」。
244
- - 证据:`test/bridge.test.mjs` 88 条(深链往返与四柱复现、四种写法可解析、六类坏链接不抛异常且带 code、表单还原与未还原提示、三档文本与 JSON、无句柄不编链接、不改盘面对象、面板与独立页接线、bridge 进公共栈);无头 Chrome 实测 `命理排盘.html#mp=…` 打开后四柱与问题一致、坏句柄回落到默认盘。
245
-
246
- - **§5.8 自动发布加固**(`tools/autopublish.mjs`、计划任务):把「定时跑但出了问题看不出来」补成可观测、可自愈。
247
- - 每天 23:00 与 23:30 双跑:第二跑在指纹未变时只写一行日志,等于给第一跑的一次兜底重试。
248
- - 每次运行开头写 `运行开始(auto/dry-run/init/force,pid …)`;**无改动也写一行**(原来是完全静默,事后查不出任务跑没跑);日志超过 512KB 自动裁到最近 800 行。
249
- - 失败写 `tools/.autopublish-error`(内容含失败原因与时间),成功一次自动删掉;未捕获异常也留痕。该文件进 `.gitignore`。
250
- - GitHub HTTPS 连续失败且报错像「连不上」(443 / timeout / SSL / RPC failed)时,自动生成临时 ed25519 → 调 API 注册 deploy key → 走 `ssh://git@ssh.github.com:443/...` 推一次 → 无论成败删 key、删本地私钥;「推被拒」不触发兜底。
251
- - 证据:`test/autopublish.test.mjs` 28 条(未知参数仍立即拒绝且不碰状态文件、加固项接线、dry-run 写运行开始、配置缺失时退出码 1 且写错误文件、失败后不留锁也不改状态)。
252
-
253
- - **B6 通行说复核(8 张逐张过一遍底本)**(`engine/citations.js`、`engine/interpret-knowledge.js`):
254
- - `liuyao-jintui-yong` 由通行说改为 refs:《增删卜易》卷二·進神退神章第二十九「進神退神者,爻之動而化也,化進化退,吉凶禍福有喜忌之分,所喜者宜於化進,所忌者宜化退神。」底本已经把喜忌落在进退上;把「喜/忌」具体落到用神/忌神两档仍标为本插件引申(写进知识卡 note)。
255
- - 其余七张维持通行说,但把「查过什么」写进理由:紫微飞星三张——`《紫微斗數全書》`卷一、卷三全文检索「宮干/飛星/三方同飛/忌轉忌」均无命中,底本只有生年四化;奇门干宫生克——统宗已抓四卷只有「星相克/仪相克/门相克」与「时干克日干」;十干克应——检索到的「十干克應歌訣」署诸葛亮、释意者为近人,属现代韵语,不能当原文;通根透干——当时没定位到,留待联网复核(下一轮已改判,见「B6 通根透干复核」);塔罗逆位——韦特《Pictorial Key to the Tarot》1911 已入公有领域,但原书对逆位态度含混,未给「逆位=受阻/内化」这套固定读法。
256
- - 53 张卡:45 张已定位原文(+1)、7 张通行说(−1)、1 张待补。`docs/citations.html` 同步重建。
257
- - 证据:`test/citations.test.mjs` 59 条(新增 3 条:用神化进退落到進神退神章、source 为 verified、通行说剩七张且待补一张)。
258
-
259
- - **B6 通根透干复核:通行说是误署,改引《滴天髓·干支总论》**(`engine/citations.js`、`engine/interpret-knowledge.js`):
260
- - 说法查证。常被引作《滴天髓》的「地支所藏之干,本静以待用,透出干头,则显其用矣。故干以通根为美,支以透出为贵」,在**滴天髓底本全文**里检索「本静以待用/干以通根为美/透出干头」零命中;在**《子平真诠》沈孝瞻原文**(论十干十二支,中华典藏本 984 字)里同样零命中。它实际出现在《子平真诠》**评注本**卷一·论十干十二支的注文(附支藏人元图、十二月令人元司令分野表之后的按语)。也就是说:网络通行写法「《滴天髓》云:地支所藏之干……」把注文署给了原书。
261
- - 改判依据。该注文自身引的才是《滴天髓》:「天全一气,不可使地德莫之载;地全三物,不可使天道莫之容」——这句在本地所收滴天髓底本「干支总论」里逐字可对上,语义正好是「天干要地支承载(通根)、地支藏干要透出天干(透出)」。故本卡只引这句可核的原文,注文那两句写进 `note` 作说明,不冒充原文。
262
- - 结果:`bazi-tonggen-tougan` 由通行说改为 refs(新增引文 `dt-yiqi-tonggen`,《滴天髓·干支总论》);引文库 93→94 条;**46 张已定位 / 6 张通行说 / 1 张待补**。`docs/citations.html` 现在也会把 `note` 显示在已定位条目下,误引纠正看得见。
263
- - 证据:`test/citations.test.mjs` 62 条(新增 3 条:改引干支总论、引文确为原句、note 写明误署;通行说计数 7→6)。
264
-
265
- - **D4 发布回滚**(`tools/release.mjs` + `tools/release-rollback.mjs`):发版失败、或发布后附件核对没通过时,打印一套可照抄的回滚步骤,不自动动 registry。
266
- - `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 两步。
267
- - `release.mjs` 在发布前记住 registry 上的 `dist-tags.latest`,作为回退目标;`npm publish` 失败与 `verifyPublish` 失败都自动打印这套步骤,并给出单独跑的等价命令。
268
- - 新增 `node tools/release-rollback.mjs`(`npm run rollback:plan`):默认只打印;`--apply dist-tag` 需要 `NPM_TOKEN`,只代为把 latest 指回上一版;`unpublish` / `deprecate` / 删远程 tag 一律只打印,由人确认后执行。
269
- - 证据:`test/release-rollback.test.mjs` 40 条(两种原因的步骤与命令、无上一版时不猜号、tagged 两步、未知 reason 回落、排版与不打印 token、CLI 退出码与 `--apply` 限制、release.mjs 接线与 verify-only 不把问题版本当上一版)。
270
-
271
- - **自检修复**(`engine/index.js`、`src/web-ui.js`):两处只在真实浏览器/连续操作下才暴露的一致性问题。
272
- - `partner2: null` 在排盘前归一化为未传:原先 compute 当它没给,句柄却把 `partner2:null` 编进去,同一对盘会拿到两个句柄。
273
- - 独立页耗时行改存 `last.perf`,由 `paint()` 末尾补回:切询问方向等重绘会换掉整段结果区,原先那一行随之消失;现在重绘后仍在且只有一行。
274
- - 证据:`test/hepan-triple.test.mjs` 新增 2 条(null 不出三方、与省略同句柄);`test/perf-instrumentation.test.mjs` 增至 41 条(耗时行入状态、paint 末尾补回);headless Chromium 实测切方向后 `.mp-perf` 仍为 1 行。
275
-
276
- - **B6 第五批:大六壬原文录入**(`engine/citations.js`):《大六壬大全》维基文库四库全书本,新增 3 条,`daliuren-sike` 由通行说改为 refs。
277
- - 卷一·起例「十干寄宫」:`甲课寅兮乙课辰,丙戊课巳不须论。丁己课未庚申上,辛戌壬亥是其真。癸课原来丑宫坐,分明不用四正神。`——四课起手。
278
- - 卷一·起例「贼克法」:`取课先从下贼呼,如无下贼上克初。初传之上名中次,中上加临是末居。三传既定天盘将,此是入式法第一。`——九宗门取初传。
279
- - 卷二·神将释「月将」:`逆布者谓之月将,其实即十二神也。`——月将定义;加时布盘仍标通行口诀、不标卷次。
280
- - 引文库合计 **93 条**(八字经典 41 + 引文索引 52),53 张卡里 44 张已定位原文、8 张通行说、1 张待补;`test/fixtures/citation-sources.json` 增至 58 个章页,`docs/citations.html` 同步重建。
281
- - 证据:`test/citations.test.mjs` 新增 6 条(书目登记、四课三传带 refs、三章定位、无省略号),共 56 条;`test/trace-sources.test.mjs` 同步把大六壬三层的出处改为已核验卷次。
282
-
283
- - **A1+ 推导链出处**(`engine/trace.js`):16 层的 `source` 统一成「出处;实现:engine/…」,能对上已录入篇名的才写书名卷次。
284
- - 六爻:六亲对读《增删卜易》卷一·用神章第八;伏神引卷二·飛伏神章第二十八;旺衰引卷一·月將章第十六、日辰章第十七。纳甲、世应明写「规则表 / 通行动诀,本仓未录入古籍章页」。
285
- - 八字:格局引《子平真诠》八、论用神(专求月令),调候参《穷通宝鉴》五行总论;旺衰**明写本仓量化规则、非古籍定数**;四宫标 Tyme 1.5.4 口径与 704 组对拍、未照录古籍章页。
286
- - 紫微:格局引《紫微斗数全书》卷三·论人命入格、谈星要论(与引文索引同源)。
287
- - 奇门:盘面事实引《奇门遁甲统宗》卷一·奇门秘诀总赋;旺衰引卷三;宫位引卷二与卷十一·玄机赋(中);用神表与十干克应明写「本仓表,非古籍原文」。
288
- - 大六壬:本环境没有可稳定核验的公有领域章页,三层只标「通行口诀,未标卷次」,不拿别书条文冒充。
289
- - 证据:`test/trace-sources.test.mjs` 35 条(16 层都有实现位置、书名只能在已登记的五本里、所引篇名能在引文库找到、各体系「有据 / 无据」的措辞、Markdown 导出原样保留);`test/trace.test.mjs` 同步文本断言。
290
-
291
- - **D1+ 首屏耗时回显**(`src/engine-lazy.js`、`src/app.js`、`src/web-ui.js`、`src/panel-kit.js`):
292
- - `__mpEnsureEngine` 记录每次取块耗时与是否命中缓存(`window.__MP_LAST_LOAD`),不埋点上报、不发网络请求。
293
- - 面板从点击到两帧后记「首屏」,并拆出引擎取块与排盘两段;连续点两次时旧回调按 `perfSeq` 丢弃,不会把上一次的数字盖到新结果上。
294
- - 独立页记「排盘」与「渲染(组 HTML + 写 DOM 的同步时间)」,明确不把浏览器真正绘制的那一帧算进来。
295
- - 结果顶部缝一行灰色小字:`首屏 42ms|引擎 18ms(首次加载)· 排盘 9ms`,悬停说明「本机实测,不含网络与服务端」。缺哪段省略哪段,不编数字、不出 NaN。
296
- - 证据:`test/perf-instrumentation.test.mjs` 39 条(三种组合的排版、缓存标注与缺省、NaN/负数、懒加载两次调用与缓存、面板/独立页计时接线、无上报调用)。
297
-
298
- - **C4-a 三方合盘**(`engine/hepan.js · tripleOf` + `engine/index.js`):`hepan` 新增可选 `partner2`(字段同 `partner`),结果多一个 `triple`——
299
- - `pairs`:三对(你×对方 / 你×第三方 / 对方×第三方)各给 `total`、`level` 与三维度分数,顺序固定;`a-b` 与顶层 `score` 完全一致,另两对与「单独拿这两人排合盘」逐分相同,翻过来排也一样。
300
- - `best` / `hardest` / `spread` / `focus`:最顺、最需磨合、最高最低分差、三对之间分歧最大的那一维。**分差不足 3 分时不点名**,摘要改说「三对分数接近,不排名」,避免假精确。
301
- - **不合成「三人总分」**:三方只把三对两两关系并列——和不同的人相处是不同的事,合成一个数会把差异抹平。
302
- - 八字与紫微两种合盘都支持;`partner2: null` 视同未传,非对象或缺 `datetime` 报 `E_PARTNER` 并点名 `partner2`。
303
- - 第三人进排盘句柄与影子盘指纹(换第三人=另一组盘,`baseId` 随之改变),下一轮只传 `handle` 即可复现同一组三方。
304
- - 面板与独立页:合盘 tab 勾「三方合盘(加入第三人)」后展开第三方日期/时刻/性别/出生地;结果区在三维度后加三对并列小表(分数 + 三维度),只在该勾选时出现。
305
- - 证据:`test/hepan-triple.test.mjs` 54 条(结构、与单独合盘/颠倒顺序一致、最顺与最需磨合、分歧维度、null 与坏输入、文本、紫微、句柄与影子盘、面板表与转义、面板/独立页/模板/宿主 schema 接线)。
306
-
307
- - **C4-b 择日候选日比较**(`engine/zeri.js` + 面板/独立页):`zeri` 新增可选 `candidates`(2–12 个真实公历日期)。
308
- - 给了就只比这几天(去重、保持输入顺序),不再按 `startDate` 扫区间;逐日分数与区间模式同一套公式,同一批日子逐分一致。
309
- - 结果多一个 `compare`:`best`(这一组最高分与结论、同分者)、`spread`(最高与最低分差)、`note`(「胜出只表示更合所问事项,不代表好多少」)。全部因冲属相被排除时 `best` 为 `null`,摘要如实写「都因冲属相被排除」,不硬推一个。
310
- - 入参守卫:不是数组、少于 2 个、超过 12 个、去重后不足 2 天、`2026-02-30` 这类不存在的日期,一律 `E_INPUT` 并说清改法;区间模式仍必须给 `startDate`。
311
- - 面板与独立页:择日表单新增「候选日(可空,只比这几天)」,逗号/顿号/空格分隔;结果区在候选模式下画逐日表(日期+农历 / 干支+建除 / 分数 / 结论 / 理由),最优行标「最优」,下方并列推荐、可用、回避与比较口径;区间模式仍用原文案,不铺 60 行表。
312
- - 候选日进句柄,下一轮只传 `handle` 即可复现同一组比较。
313
- - 证据:`test/zeri-candidates.test.mjs` 48 条(与区间模式同分、去重、冲煞排除、全排除、五类坏输入、文本、句柄、面板表与转义、四处接线)。
314
-
315
- - **C4-c 同盘多口径并排**(`engine/diff.js · CALIBER_VIEWS`):口径对照的每一行多回 `views`——只挑会影响结论的几项做两列并排,不改盘、不重算、不判优劣。
316
- - 八字:日柱 / 时柱 / 旺衰 / 格局(`frame.primaryName`)/ 喜用 / 起运;紫微:命宫 / 身宫支 / 五行局 / 身主 / 起大限;奇门:日柱 / 局数 / 值符 / 值使。字段取两张盘里已有的值,缺省写 `—`,不把对象硬串成 JSON。
317
- - 摘要里每行多一句「并排:日柱 丙辰 → 乙卯;…」,只列变化项;面板与独立页在根因后加 `mp-cview` 表(列名用档位名,例如「换日 / 不换日」),同样只列变化项。
318
- - 紫微身宫取 `body.branch`;原先写的 `body.ganzhi` 不存在,会一直显示 `—`。
319
- - 证据:`test/caliber-diff.test.mjs` 新增 21 条(视图键与行数、单元格格式、子年身主 火星 → 铃星、午年无变化项、奇门晚子时落日柱、文本并排、面板表与转义)。
320
-
321
- ## 0.57.0(2026-11-01,已发布)
322
-
323
- > 本版主题:排盘句柄与一句话改参、推导链 Markdown 导出、喜忌中性档、引文索引三批补录、性能门槛。
324
-
325
- - **B6 第二/三/四批原文录入**(`engine/citations.js`):知识卡的「已定位原文」由 17 张增至 **43 张**,通行说由 35 张降至 **9 张**,待补仍 1 张。
326
- - 第二批 7 条,均取自中华典藏网公有领域底本、逐字核验后照录:《三命通会》卷二「论五行旺相休囚死并寄」(旺相休囚死)、卷三「总论诸神煞」(神煞取用)、卷三「论空亡」(空亡)、卷二「论大运」(起运)、卷七「论六亲」(六亲)、卷二「论三刑」(刑冲),以及《穷通宝鉴》「五行总论」(调候)。《穷通宝鉴》该本页首未标卷次,条目只写篇名、不替它补卷号。`bazi-tonggen-tougan` 仍留通行说——《滴天髓》只有「壬水通根透癸」的单条,没有泛论通根透干的段落,不拿个案冒充通则。
327
- - 第三批 6 条:《奇门遁甲统宗》卷一「奇门秘诀总赋」(阴阳遁与超神接气)、卷十一「玄机赋(中)」(六仪击刑、三奇入墓)、卷三(旺相休囚)、卷二(八门迫制与有气无气),以及《梅花易数》卷二「体用生克」。奇门章节只标页面实有的卷次与篇题,`qimen-gan-shengke`(干与落宫生克)留通行说——底本只有「奇仪对日干」的十神条,未见单列干宫生克条,不拿十神条文冒充。
328
- - 第四批 13 条:《增删卜易》(维基文库本,**繁体照录**)——卷一用神、月将、日辰、动变生克冲合、六神、六合、六冲、反伏、各门类应期总注,卷二飞伏神与进神退神;覆盖 `liuyao-yongshen`、`liuyao-fushen`、`liuyao-wangshuai`、`liuyao-yongshen-shuai`、`liuyao-quanggu-shuai`、`liuyao-dongbian`、`liuyao-liushen`、`liuyao-liuhe`、`liuyao-liuchong`、`liuyao-fanyin`、`liuyao-fuyin`、`liuyao-jintui`、`liuyao-yingqi` 十三张卡。`liuyao-jintui-yong` 仍留通行说:底本把进退落在「動而化」的吉凶喜忌与应期上,未见单列「用神化進/化退」条,按用神与忌神分档是本插件引申。
329
- - 引文库合计 **90 条**(八字经典 41 + 引文索引 49:紫微 23、三命通会 6、增删卜易 13、奇门 5、穷通宝鉴 1、梅花 1)。`test/fixtures/citation-sources.json` 同步到 56 个章页快照,`test/citations.test.mjs` 累计 50 条断言(书目登记、卡片带 refs、各条取书与章名、无省略号)。大六壬仍标通行说:本环境无可稳定核验的公有领域章页(ctext 明示禁止抓取、中华典藏网未收)。
330
- - **D3 性能门槛**(`tools/check-perf.mjs`):`tools/bench.mjs` 拆出 `runBench()` 与 `CASES` 供复用(CLI 行为不变,`--json` 仍可用),新增门槛脚本对八体系样本逐项判超限——首次 150ms、p50 10ms、p95 25ms、带解析 250ms、1000 盘 4000ms、RSS 800MB。阈值按文档目标(bazi p50 < 1.5ms、1000 盘 < 400ms)留 5–10 倍余量,拦的是数量级回退而非毫秒级抖动;`DSH_PERF_SCALE=3` 可按倍数为慢机放大上限,不改代码。`npm run bench` 只测不判,`npm run check:perf` 判超限,`test:ci`、GitHub Actions 与 `tools/autopublish.mjs` 的发布闸门都串上。证据:`test/perf.test.mjs` 29 条(八体系基准形状、真实样本判定、超限样本必红、阈值余量与放大、npm/CI/自动发布/README/方案接线);本机实测 bazi 首次约 20ms、p50 0.78ms、1000 盘约 355ms、RSS 约 80MB、带解析 <8ms。
331
- - **自动发布参数校验**(`tools/autopublish.mjs`):只认 `--dry-run` / `--init` / `--force`,其余参数(例如误写 `--dry`)立即以退出码 1 拒绝并列出可用参数,不再静默忽略后照常提交推送;未知参数不触碰状态文件。证据:`test/autopublish.test.mjs` 8 条。
332
- - **C2 一句话改参**(`engine/revise.js`):把「换成紫微看 2030 年事业」「女命」「晚子时算次日」「出生在成都」「不用真太阳时」「详细解读一下」这类原话翻成参数补丁再排盘,可配合 `handle` 使用——上一轮的出生信息不必重报。**只认明确句式**:换体系必须有切换词(换成 / 改成 / 看 / 用 / 按…),单提一句「紫微里怎么说」不换盘;出生年份与时辰一句话给不出分秒,不猜,改为在 `ignored` 里明说改不了、请直传 `datetime`。识别不到时盘面一字不动,`applied` 为空。结果 `revision` 回传 `text` / `applied`(`key`、`label`、`value`、`display`、`from`、`fromDisplay`、`ignored`),旧值翻成中文(`system: bazi → 八字`、布尔 → 开 / 关、`asOf` → 年份),没设过的记「(未设)」而不是编默认值。改参先生效、后跑地址解析与日期补全,换体系会连带改走另一套默认值;句柄记的是改后参数、不含 `revise` 原文,所以同一张盘换个说法得到同一句柄。摘要末尾给「【改参】原话 + 逐条 旧 → 新 + 未处理」,面板与独立页给改参卡(先改动、后句柄)。`revision` 属请求回显,影子盘指纹与口径对照均忽略。
333
- - **C1 排盘句柄**(`engine/handle.js`):每次排盘在结果里回一个自包含短句柄 `mc1.<base64url>.<8 位校验>`,下一次只传 `handle` + 增量参数(`asOf`、`direction`、`question`、换 `system` 看同一时刻另一套盘)即可,不必重报出生信息。句柄把参数本身编码进去而不是存在内存里——宿主一次工具调用可能落在不同进程,内存句柄拿不到下一轮。只收影响盘面的参数:`trace` / `shadow` / `withInterpret` / `cross` / `ask` / `caliber` / `geocode` 这些输出开关不进句柄,所以要不要解析、要不要推导链都不改变句柄;`seed` / `asOf` / 各流派开关必须留下,否则复现不出同一张盘。键序固定(键名排序),参数写法不同也得到同一句柄;校验位用 FNV-1a,截断、改字、错前缀都报 `E_HANDLE` 并给修复提示,不会静默排成另一张盘。base64url 与 UTF-8 均为自带实现(不依赖 Buffer / btoa / TextEncoder),引擎在 Node、浏览器与 vm 沙箱里都能跑。`compute` 入口先 `resolveHandle` 再排盘,显式 `undefined` 不覆盖句柄字段;宿主工具新增 `handle` 参数,并在地址解析、日期补全之前先并回参数,避免追问时漏掉出生地导致真太阳时不同。结果摘要末尾附「【排盘句柄】+ 用法」;面板与独立页给句柄卡与「复制句柄」按钮,并写明「是编码不是加密,含出生时间与出生地,别公开贴出」。影子盘指纹与口径对照忽略 `handle`(它反映的是另一次请求,不是盘面差异)。随机抽牌 / 起卦:句柄复现参数、不复现牌面,要复现须带 `seed`。
334
- - **F 喜忌中性档**(`engine/geju.js`):忌神里全局分量不足 0.5 的另列 `neutral`(含 `element` / `role` / `verb` / `weight`),摘要、解析层、白话层与面板 chip(`中性偏忌 X 0.3 分`)都写明「近零,不作实忌」。**只是展示分档,`avoid` 不变**——局中没有不等于运里不来,大运/流年遇之仍按忌计,评分与调候结论一律不动。
335
- - **A5 推导链导出**(`engine/trace.js`):`trace: true` 时结果同时给 `traceText`——同一份层的 Markdown(标题 + 每层结果/规则/输入表/出处),可直接贴进对话或文档;表格单元格转义 `|` 与换行。面板推导链抽屉加「复制 Markdown」按钮(内容取自隐藏 textarea,与引擎同源,不在前端重排)。五个体系(六爻 / 八字 / 紫微 / 奇门 / 大六壬)共用同一份导出逻辑。
336
- - **测试**:新增 `test/handle.test.mjs`(70 条:往返、增量、换体系、键序、输出开关不进句柄、截断/改字/错前缀、中文与表情、影子盘不受影响、宿主 schema 与执行、面板与独立页接线)、`test/revise.test.mjs`(68 条:九条改参规则的命中与不命中、改参后盘面真变化、未设原值回显、忽略项提示、句柄配合、宿主执行、改参卡转义与接线)、`test/trace-export.test.mjs`(60 条)、`test/yongshen-neutral.test.mjs`(29 条)、`test/citations.test.mjs`(50 条,含 B6 第二/三/四批 23 条)、`test/perf.test.mjs`(29 条)、`test/autopublish.test.mjs`(8 条:未知参数直接拒绝、白名单固定)。当前 **122 个测试文件 / 5653 条断言**,七道闸 + 性能门槛全绿。
337
-
338
- ## 0.56.0(2026-11-01,已发布)
339
-
340
- - **邮件反馈 2026-10-31(三条)**:输入区错位、八字旺衰与喜忌、紫微子年身主。逐条处理记录见 `docs/用户反馈记录.md`。
341
- - **面板输入区对齐**(`src/app.js`):① `.mp-input` / `.mp-textarea` 补 `box-sizing:border-box`——Chrome 下 select 默认 border-box、input 默认 content-box,同为 36px 时 input 实高 50px,底对齐后「性别」下拉比日期框低 14px;② 「晚子时换日」改成与「真太阳时」「联网精确到区县」同构的普通勾选,去掉误加的 `mp-field mp-checks`(继承 `margin-top:13px` 后比同行低 7px),并补 title 说明;③ 降列由视口 `@media` 改为 `.mp-wrap` 容器查询(860px 两列、480px 一列)——侧栏宽度不等于窗口宽度,面板拖到约 600px 而窗口仍是 1200px 时原来照排四列、输入框被压到 117px;「八字 × 紫微 交叉验证」勾选独占一行。无头 Chrome 以面板实际 CSS 在 600/940px 两档复测:同行输入框顶底一致、三项勾选中线一致。独立页本有全局 `*{box-sizing:border-box}`,不受影响。
342
- - **八字旺衰 · 合会折根与虚透减半**(`engine/bazi.js`):地支通根前先看会合——三会成方时同类支不折、印局按 6 成、他局按 1 成;三合成局同类不折、印局 6 成、他局 2 成;六合同类不折、印 8 成、他 5 成,且只折局外那一支(已入会/合局的支归该局);半合/半会不折。天干比劫/印透出而折根后同类藏干不足 0.3 的作**虚透**,帮扶按半计。`strength.parts` 新增 `structure`(折根说明)与 `virtualHelpers`,`detail` 追加「合会折根:…」「虚透X帮扶减半」,`method` 改为「…(三会/三合/六合折根)+ 天干帮扶(虚透减半)…属简化算法,非唯一流派」;推导链旺衰层同步新增「合会折根」「虚透」两行。亥月戊土、年子时丑、日坐寅这一型,旧算法把丑中己土与寅中戊土当足根、天干己土当实帮,判「偏强」并忌土;现判偏弱/身弱、喜火土、忌金水木。416 张盘的五档分布由 52/82/56/114/112(偏弱/中和/身弱/偏强/身强)变为 68/87/69/96/96,偏强与身强各降约 15%。
343
- - **紫微身主两派**(`engine/ziwei.js`):新增第十个流派开关 `shenzhuSchool`——`common`(默认,子午皆火星,与 iztro 及通行排盘一致)/ `verse`(安身主诀「子午安身铃火宿」逐字:子铃星、午火星;维基文库本《紫微斗数全书》卷一、卷三未见此诀,故不标作《全书》原文)。**默认行为变化:子年身主由铃星改为火星**;午年两派都是火星,其余十支不变。子午年盘带 `bodyMasterSchool` 与 `bodyMasterNote`,文本 `【身主】火星(子午皆火星)`、面板 `*` 悬停说明出处;`rules.schools` 列入身主口径。工具 schema、`engine/index.js` 平铺透传、口径对照(紫微 11 → 12 组)同步;`bodyMasterSchool` / `bodyMasterNote` 属口径回显,不计盘面差异。
344
- - **测试**:新增 `test/bazi-strength-structure.test.mjs`(32 条:同型盘偏弱与喜火土、三会/三合/六合/局内支不重复折、同类局与印局、无合会盘不受影响、推导链两行、五档分布不塌缩)、`test/ziwei-shenzhu.test.mjs`(29 条)、`test/panel-form-align.test.mjs`(11 条);`test/caliber-diff.test.mjs` 补子年身主能检出、午年无差异与 12 行渲染;`test/ziwei-schools.test.mjs` 开关数 9 → 10;`test/trace.test.mjs` 的争议样本换成 1962-03-22。当前 **116 个测试文件 / 5366 条断言**,七道闸全绿。
345
- - **自动发布改为只推送**(`tools/autopublish.mjs`):定时任务只跑七道闸、重建产物、提交并推送 `main`,不再自动升版本号、打 tag 或发 npm;push 失败重试 3 次(15s / 30s 退避)。发版仍走 `tools/release.mjs`。
346
- - **B5 玄空替卦与年月日时飞星**(`engine/fengshui.js`):`action:'xuankong'` 新增兼向替卦与年月日时紫白。兼向按「坐山偏离本山中心超过 4.5°」判定,接受 `sittingOffset` / `sittingDegree` / `facingOffset` / `facingDegree`(坐向都给须一致);替星取《沈氏玄空学》坤壬乙诀 24 山全表(1/2/6/7/9 五星),山星/向星改以替星入中,顺逆仍按替星本宫同元龙;同卦兼/出卦兼、原运星与「用替而未替」都在结果里标明,替卦不再套正向旺山旺向表。年月日时紫白按公式派:年逐年退一位;月按年支三组起 8/5/2、逐月退一位;日按冬至–夏至三段起 1/7/4 与 9/3/6,阳遁顺飞、阴遁逆飞;时按日支三组子时起 1/7/4 与 9/3/6,阳遁顺行顺飞、阴遁逆行逆飞;月取节气月、日按公历日且 23:00 后归次日。新增 `fortuneDate` / `fortuneTime` 入参;只给年份时只排年星并提示补日期。摘要、面板九宫卡、独立页表单(兼向度数/飞星日期/时刻)同步;口径异说写进 note,不与「日星一律顺飞」「月按农历月」等派别合并。
347
- - **测试**:新增 `test/fengshui-tigua-zibai.test.mjs`(102 条)——替星表 24 山、4.5° 阈值、同卦兼/出卦兼、8 运子午替星改盘、5 运用替而未替、度数输入与边界、年月日时六个分段锚点、时家冬夏×日支三组、晚子时、中宫文案、摘要/面板/compute 接线;`test/fengshui-ui.test.mjs` +5 条替卦卡与飞星事实;原玄空测试的 scope 与来源条数同步。当前 **113 个测试文件 / 5286 条断言**,七道闸全绿。
348
- - **信息层次与 AI 解读可读性**(`engine/followup.js`):给 8 个体系登记「阅读层次」(八字:基本信息 → 四柱 → 旺衰/格局/用神 → 合冲/神煞 → 大运流年 → 古籍依据;紫微、六爻、梅花、大六壬、奇门、塔罗、风水各有顺序,未知体系走通用兜底)。`askPrompt` 先列层次、再给摘要;回答要求由 4 条改为 5 条:结论 → **骨架事实**(按层次 2–4 行,不掺倾向)→ 最多两条判断(盘面/白话/倾向/边界)→ 只记一件事 → 边界与禁语,并写明「上一层没交代清楚,不要跳到下一层」。层次顺序参考 ziwei.pub/bazi 的分区,只借层次、不复制文案;固定骨架由约 520 字增至约 700 字,仍受 `test/ask-prompt.test.mjs` 的 900 字上限约束。
349
- - **参考资料登记**(`docs/参考资料与对拍来源.md`):记录 ziwei.pub/bazi 的访问日期、采用的命宫/身宫/胎元/胎息口径与信息层次、704 组日期对拍证据,以及未采用的文案/视觉/AI 内容;另列 tyme4ts 与历法、卦例、紫微、八字、奇门对拍入口。约定「先登记再改代码、采用范围必须能指向测试或对拍证据」。
350
- - **测试**:`test/ask-prompt.test.mjs` 由 67 条扩到 81 条——层次顺序、不跳层、骨架段、5 条编号、8 体系非空不重复、未知体系兜底;当前 **112 个测试文件 / 5179 条断言**,七道闸全绿。
351
- - **B4 奇门十干克应 + 六仪入墓**(`engine/qimen-ganying.js`):新增通行 100 组「天盘干加地盘干」表(格名 + 断语 + 底本链接),每宫与中宫随盘带 `ganYing`。底本取 daoisms 通行表,《奇门遁甲元灵经》卷二只存甲、乙、丙三组且措辞不同,作为异文并列、不合并;底本个别讹字按文义校正(么→私、病病→病、得→行、磋砣→蹉跎)。新增六仪入墓(戊墓戌乾六、己庚墓丑艮八、辛壬墓辰巽四、癸墓未坤二),与三奇入墓并列进 `conditions.liuYiRuMu`。摘要、解读层「十干克应」段、面板九宫格与事实行、推导链关系层、知识卡 `qimen-ganying` 与引用索引同步;克应只作取象与读盘线索,与门宫/干宫生克并列,不自动折吉凶。
352
- - **测试**:新增 `test/qimen-ganying.test.mjs`(46 条)——100 组完整无重、抽样条目、六仪入墓映射、60 个时辰 × 480 宫逐宫有克应、全链路显示;`test/trace.test.mjs` 宫位条件断言补十干克应与六仪入墓。当前 **112 个测试文件 / 5165 条断言**,七道闸全绿。
353
- - **B6 引文索引补齐**:知识卡 53 张(新增 `qimen-ganying`),已定位原文 17 张、通行说 35 张、待补 1 张;`docs/citations.html` 重新生成。
354
- - **A1+ 奇门四层推导链**(`engine/trace.js`):新增 `facts → yongshen → states → relations`,依次摊开盘面事实(四柱、节气局数、旬首、值符值使、空亡驿马)、按询问方向取的用神落宫、门/星/天盘干按月令的五态、门迫/宫制门/干宫生克与击刑入墓空亡。用神表由 `engine/qimen-interpret.js` 的 `qimenYongshen()` 单源导出,解读与推导链不再各写一份。
355
- - **A1+ 大六壬三层推导链**(`engine/trace.js`):新增 `tiandipan → sike → sanchuan`,给出月将加时后的十二支天地盘与天将、四课上下神与生克、三传的干支/六亲/天将/旬空与课体。只读结果,不改盘面。
356
- - **接线**:面板与独立页对奇门 / 大六壬默认请求 `trace`;奇门把「询问方向」传入 compute,改方向时只重建用神落宫层,不重新起局。
357
- - **D1+ 拆分 chart 块**(`tools/build-client.mjs`):原 `chart` 拆成 `bazi` / `ziwei` / `hepan` / `trend` 四块,分块总数 15 → 18。八字块内含人生 K 线索与紫微交叉验证,紫微块带八字交叉验证,合盘块同时带两套引擎与紫微合盘模板,人生 K 线块不再背紫微。各块 gzip:bazi 178KB、ziwei 174KB、hepan 177KB、trend 154KB(原 chart 183KB);入口仍为 71KB。分块之间不共享代码,代价是重复的公共栈,换来每个 tab 只取自己需要的块。
358
- - **测试**:`test/chunks.test.mjs` 由 102 条扩到 121 条——18 块注册/自包含/体积、八字与紫微在各自块内开交叉验证、紫微合盘在 hepan 块内复算、切块后缓存不重复拉取;统计 **107 个测试文件 / 4978 条断言**,七道闸全绿。
359
- - **B2 紫微破格**(`engine/ziwei.js`):34 条格局逐条给 `status`(`formed` / `broken` / `n/a`)、`breaks`(哪颗星落在哪一宫)与 `breakRule`。吉格与武贪、双禄交流、火贪铃贪再判破格:三方四正见羊陀火铃、空劫或化忌即破;石中隐玉另判「三方无科禄」、火贪铃贪按「三方有凶杀」、武贪按「武贪化忌」、机月同梁/昌曲/魁钺夹命各按本条原文判。忌格与命无正曜、杀破狼不判破格,明确标 `n/a`。摘要、文本、解读层与面板 chip 同步显示破格数与理由;`test/ziwei-poge.test.mjs`(25 条)扫 312 张盘复核。
360
- - **B6 引文索引**(`engine/citations.js` + `docs/citations.html`):新增《紫微斗数全书》23 条原文(维基文库,卷一/卷三,含卷章与链接),与既有 41 条八字原文合成 64 条引文库;53 张知识卡逐张登记出处(B4 新增 `qimen-ganying`),17 张已定位到可核验原文,其余标「通行说」或「待补」并写清理由,不冒充原文。`test/citations.test.mjs`(27 条)核验「原文子串确实出现在来源正文里」,重建索引页并与磁盘逐字比对;`docs/citations.html` 由 `npm run build:citations` 生成。
361
- - **测试**:新增 2 个测试文件(52 条),当前 **109 个测试文件 / 5030 条断言**,七道闸全绿。
362
- - **B3 四宫口径修正**(`engine/bazi.js`):新增**胎息**(日干五合、日支六合),并把命宫/身宫由「命宫对宫」改为 ziwei.pub 同款 Tyme 1.5.4 口径——命宫=27 减生月与生时支、取模后加二,身宫=11 加两支、取模后加二,干支并入六十甲子。旧口径在 1990-05-12 14:30 得丙戌/庚辰,与紫微派页面(辛巳/己丑)不符;修正后四宫为壬申/壬子/辛巳/己丑。已用 tyme4ts 1.5.4 对 1950–2020 的 **704 组日期逐组对齐,0 处不符**。摘要、解读层「胎命身」、面板 chip、独立页与八字推导链第 3 层(`palaces`)同步;`test/bazi-palaces.test.mjs`(57 条)锁 6 组日期与「胎息=五合六合」「命宫+身宫支序=6」两条结构不变量。
363
- - **B3 专旺成格 / 真从假从**(`engine/geju.js`):专旺补 `status`(成格/待定/破格)与 `breaks`——月令助旺且不见官杀/财星为成格,月令不助为待定,官杀 >1.2 逆势或财 >1.8 耗旺为破格;三合局全另记 `ju`。从格补 `rootWeight`(地支藏干同类/印 + 天干透出)与真假:完全无根、无比劫印绶透出为**真从**,有中气/余气微根或虚透为**假从**;见一个本气根(≥1 分)就不作从格。摘要、解读层「格局依据」、面板 chip(破格虚线、假从/待定警示色)与原文取条同步;破格不再挤占专旺单章,化气与假从同盘时化气优先。`test/bazi-special.test.mjs`(28 条)锁成/待/破与真/假从各档及全链路显示。
364
- - **测试**:新增 2 个测试文件(85 条),当前 **111 个测试文件 / 5119 条断言**,七道闸全绿。
365
-
366
- ## 0.55.0(2026-10-31,已发布)
367
-
368
- 补齐口径对照里的紫微九派,并把邮件反馈里的两处显示口径收紧:五合不再直接写「合化」,自化与生年/大限/流年四化分三层显示。
369
-
370
- - **口径对照补全**(`engine/diff.js`):紫微由闰月、真太阳时两组扩到 11 组,新增亮度表、庚干四化、天马、天空、截空旬空、魁钺、天伤天使、长生、晚子时九类流派开关。默认档与另一档都取自引擎枚举,平铺参数与 `schools` 嵌套都能读;非法值回落默认。切换后 `schools` / `rules.schools` 只是口径回显,不再计入盘面差异。
371
- - **同一张表**:面板折叠卡、独立页、`tools/caliber-diff.mjs` 与工具 `diff: true` 仍共用 `CALIBER_SWITCHES`;紫微卡一次列 11 行,summary 先给「几组影响此盘」。`shadow` / `trace` 属于派生展示,不再参与对照,避免面板里每组开关都被影子盘回显误报成「有变化」。
372
- - **五合措辞**(`engine/bazi.js`):干支关系只标「有合」,摘要与面板写「戊癸合(化火待定)」;是否真化仍由化气格条件另判,不把「合」直接说成「化」。
373
- - **四化分层**(`src/panel-kit.js`):生年四化实心、大限/流年四化空心、自化改为彩色字 + 虚下划线,图例补「虚下划线=自化」,宫位详情同步;自化块带读屏说明。
374
- - **公开对拍补奇门**(`tools/verification.mjs`):接入 `test/fixtures/qimen-20.json` 的 20 个时辰 × 9 宫 = 180 个宫位,逐宫核四柱、局数、值符、值使、星门神与天盘干;报告从 457 行增到 **477 行**,新增「奇门」筛选与卡片。徽章改为披露「128 例 · 5 剔除 · 312 紫微 · 20 奇门 · 12 交运」。
375
- - **CI 同源加固**:构建产物与对拍报告的 `git diff` 前先 `git add -N`,新增的 `client.*.js`、报告页或徽章不再因 untracked 而漏检;`release` 走同一套判据。自动发布指纹补入报告生成器与两份对拍 fixture。
376
- - **工具输出克隆**(`engine/index.js`):`jsonSafe` 不再 `JSON.parse(JSON.stringify())`,改为等价递归深拷贝(NaN→null、-0→0、Date→ISO、数组空位→null、对象内 undefined/函数丢键、循环引用抛错),省掉每次 `compute` 建一遍几百 KB 中间字符串。21 个体系 21 组样本改动前后输出逐字节相同、影子盘 ID 不变。
377
- - **三合表单源**(`engine/shensha.js` / `engine/almanac.js`):将星/驿马/桃花的 `trioKey` 与黄历「三合吉配」「煞方」原本各自维护的三合成员表,改为从 `engine/sanhe.js` 的 `SANHE_GROUPS` 派生,全仓只剩一份三合成员表。
378
- - **测试**:`test/caliber-diff.test.mjs` 由 129 条扩到 205 条——11 组开关、默认档/另一档枚举、嵌套读取、回显忽略、九派逐项能改盘、shadow/trace 不参与对照、11 行渲染;`test/relations.test.mjs` 补五合「待定」与五组干合;`test/layout.test.mjs` 补自化分层与图例;`test/verification.test.mjs` 补奇门 20 例与改坏值符的检出。统计 **107 个测试文件 / 4925 条断言**,七道闸全绿。
379
- - **文档**:README 口径对照、精度与口径、公开对拍三处同步;独立页「方法与验证」补奇门 20 例。
380
- - **版本说明**:0.51.0–0.54.0 未单独发布,能力均并入 0.55.0。已于 2026-10-31 发布:npm latest 从 **0.50.5** 跳到 **0.55.0**(80 个文件,shasum `a8640df32d5451078bd15bf94d7b95da0547f698`),tag 与 GitHub release 同为 `v0.55.0`。
381
-
382
- ## 0.54.0(2026-10-31)
383
-
384
- 把「验了什么、差在哪」做成公开页:新增 `docs/verification.html` 与 README 顶部徽章,报告数字与 CI 共用 `tools/verification.mjs` 一个数据源。
385
-
386
- - **128 条卦例**:《卜筮正宗》成对 93 条 + 静卦 35 条,逐条核本变卦、动爻数、卦宫、缺爻、旬空;源 138 条中被剔除的 5 条连同原书理由逐条列出(动爻标记冲突、缺爻冲突、卦宫冲突、静卦核对失败)。
387
- - **312 张紫微盘 × 34 条格局 = 10,608 条判定**:沿用 `test/ziwei-patterns.test.mjs` 的扫描盘(1950–2025、月日时错开)与独立谓词——只读星位与四化,不调用引擎格局函数;34 条每条至少命中一次,命中分布列在报告折叠区。
388
- - **12 个交运案例**:覆盖阳年男女顺逆、闰日 02-29、真太阳时、立春/晚子时边界、长间隔与 ΔT 近似区间;独立复算取节、三日折一年比例、`jiao/startAge` 同源、闰日十年后退位与口径标注。
389
- - **报告页**:`docs/verification.html` 自包含,无外链脚本 / 样式;可按「一致 / 剔除 + 理由 / 不一致」与体系(六爻 / 紫微 / 交运)筛选,附搜索与 34 格局命中分布;窄屏表格横向滚动,深色跟随系统。README 顶部徽章 `docs/assets/verification-badge.svg` 由同一生成器写出,0 处不符时为绿色。
390
- - **CI 同源**:新增 `test/verification.test.mjs`(23 条)直接 import 生成器,断言 128 / 312 / 12 / 0 不符、剔除项带理由、报告与徽章和生成结果逐字节一致;并故意改坏一条卦宫判定,要求校验器立刻标「不一致」。CI 增加「重建报告 + `git diff`」步骤,`release` 也会重建并校验报告;任何判定变化或忘记重建,CI 都会红。
391
- - **测试**:统计 **107 个测试文件 / 4836 条断言**,七道闸全绿。报告页 390×844 深色无横向溢出,筛选按钮与表格可读。
392
-
393
- ## 0.53.0(2026-10-31)
394
-
395
- 把 `client.js` 按 tab 拆开:入口只留界面与懒加载器,引擎落到 15 个自包含分块,首屏 gzip 从 0.52 的 334KB 降到 71KB(目标 < 100KB)。
396
-
397
- - **拆包协议**:DSH 客户端模块支持 `require.async("./client.<name>.js")`,分块用 `__ModuleLoader__.load({ id, chunk, factory })` 注册。入口 `client.js` 不再内联 `engine/*.js`,只保留 panel-kit / app / core;新增 `src/engine-lazy.js`,按当前 tab 取分块,并把该块统一入口的导出合并到同一个 `Engine` 对象。分块自包含,宿主与入口都缓存已加载的块。
398
- - **分组**:chart(八字 / 紫微 / 合盘 / 人生 K 线)、name、fengshui、liuyao(六爻 / 梅花)、qimen、daliuren、tarot、almanac、convert、zeri、chenggu、xiaoliuren、star、numerology、mbti,共 15 块,覆盖全部 19 个 tab。互相依赖的体系(如合盘双方、八字交叉紫微)落在同一块,避免运行时同步 require 另一个分块。
399
- - **安全降级**:`buildModule` 的 import 解构改为 `(__mods.x || {})`,统一入口对未随块加载的体系引用能安全落空,只有实际被调用的体系需要在场。入口在 `require.async` 缺失时给出明确的宿主版本提示,不静默白屏。
400
- - **界面**:`run()` 与切到人格 tab 前先 `await ensureEngine(k)`,加载期间显示「正在加载本页需要的引擎…」;MBTI 题面不再在未加载时缓存空问卷;独立页与旧宿主没有分块加载器时回退到现成的完整 `Engine`,离线页行为不变。
401
- - **构建与自检**:`tools/build-client.mjs` 生成入口 + `client.<name>.js`,并清理已下线分块的旧文件;`tools/check-bundle.mjs` 现在同时校验入口与每个分块的编译、注册名、返回 `Engine`、与源码逐字节一致,并守住入口 gzip < 100KB;`release` 的产物 diff 与 tarball 关键文件加入分块。构建日志按 UTF-8 字节数报告,不再用字符串长度低估中文体积。
402
- - **体积**:入口 `client.js` 239KB(UTF-8)/ gzip 71KB;最大分块 chart 179KB gzip,六爻 128KB、奇门 123KB、塔罗 122KB、六壬 118KB、起名 98KB,速查类 46–68KB、人格 55KB。首次打开只下载入口,排盘时才取当前 tab 的块。
403
- - **测试**:新增 `test/chunks.test.mjs`(102 条):19 个 tab 全映射、15 个分块的注册名 / 自包含 / 体积、入口体积与懒加载、19 个体系的分块引擎与源码逐字节一致、切回 chart 仍能排紫微、分块缓存不重复拉取、无 interpret 的分块不抹掉 DIRECTIONS。统计 **106 个测试文件 / 4813 条断言**,七道闸全绿。
404
- - **界面验证**:CDP 真机视口 390×844 深色:`innerWidth = scrollWidth = 390`、结果区 366px、`prefers-color-scheme: dark = true`、正文底色 `rgb(18,17,13)`、推导链入口在;无横向溢出。940×900 浅色 `scrollWidth = 940`、结果区 888px。
405
-
406
- ## 0.52.0(2026-10-31)
407
-
408
- 把「结论怎么来的」摊开:新增 A1 推导链 `trace: true`,六爻 / 八字 / 紫微逐层返回 `{field, rule, inputs, result, source}`,面板用右侧抽屉逐级展开。
409
-
410
- - **六爻五层**:纳甲(本卦上下卦 → 六爻干支)→ 六亲(卦宫五行 → 逐爻六亲)→ 世应(八宫世位 → 世 / 应爻)→ 伏神(用神不上卦时取本宫首卦同位,附飞伏生克与出伏判定)→ 旺衰(月建 / 日辰 → 用神五态与全卦逐爻状态)。未选询问方向时明确写「未选询问方向(综合),未取用神」,不再误写成「未指定所问之事」。
411
- - **八字两层**:旺衰分值(日主 / 月令权重 / 通根 / 天干帮扶耗泄 → 分值、档位与 detail)与格局取用(月令格与取格依据、十神分量、调候 → 主格 / 兼格、喜忌、有争议五行)。
412
- - **紫微一层**:格局命中条件(命宫、五行局、命主身主、命中数 → 逐条命中的格局与 evidence;未命中时写明只是不在已收录清单内)。
413
- - **只读与可复现**:`buildTrace` 只读 `compute` 结果,不重算、不读时间与随机,`trace` 开关前后盘面逐字节一致、影子盘 ID 不变;生成失败只挂 `traceError`,不影响主结果。`renderText` 追加【推导链】段,宿主 `metaphysics_chart` 同步暴露 `trace` 布尔参数。
414
- - **界面**:结果顶部新增「推导链」入口(显示层级链与层数),点开为右侧抽屉;每层用 `<details>` 逐级展开,先给规则与结构化输入,再给结果与出处。关闭按钮 44px、遮罩与 Esc 可关、关闭后焦点回入口;窄屏抽屉占满 100vw,深色只换变量,打印隐藏。六爻的询问方向一开始就参与 compute(否则用神会退成综合),改方向时只按新方向重算用神 / 旺衰 / 伏神三层,不重摇一卦。独立页 `#out` 的入场动画从「位移 + 淡入」改为纯淡入——`transform` 动画会为 fixed 子元素建立 containing block,曾把抽屉关在结果卡片里。
415
- - **测试**:新增 `test/trace.test.mjs`(61 条):五层 / 两层 / 一层的字段与顺序、每层 rule / inputs / result / source、伏神在爻上与不上卦两种分支、未选方向说明、改方向 refresh 不重摇也不改原结果、trace 不改盘与不改影子盘 ID、文本层、面板抽屉与转义、面板 / 独立页接线、宿主 schema 与执行。统计 **105 个测试文件 / 4711 条断言**,七道闸全绿。
416
- - **界面验证**:390×844 深色下抽屉贴视口右侧(`rect = 0,0,390,844`)、5 层、首层展开、关闭按钮 44px、无横向溢出;关闭后 `aria-hidden=true`。900px 浅色与既有结果卡均无溢出。
417
-
418
- ## 0.51.0(2026-10-31)
419
-
420
- 给每张盘一个可复制的「影子盘」ID,并把 `client.js` 真正压缩(路线图 A4 + D1)。
421
-
422
- - **A4 影子盘(引擎)**:新增 `engine/fingerprint.js`(规范化 JSON + 35 位短哈希,纯函数)。`compute({ shadow: true })` 在结果上挂 `shadow: { id, baseId, version, system, payload, reproducible, asOfPinned }`。`id` 含版本,`baseId` 不含版本;同一组归一化参数(键序无关、默认值等价、地址与等值经度等价)在任何机器上得到同一 ID,版本升级只改 `id`、不改 `baseId`。
423
- - **版本 diff**:`shadowDiff(previous, current)` 只在 `baseId` 相同时比对,复用 `engine/diff.js` 的标签 / 根因 / 分类,返回「几处变化、根因字段旧值→新值、连带分类」;`compute({ shadow: true })` 的结果可直接比,也可以比 `shadowSnapshot()` 存下的轻量快照。面板与独立页把快照写进本地存储(最多 24 张盘),同盘重排时自动与上次比对,升级后展开就能看到字段级差异。
424
- - **随机起卦不撞 ID**:塔罗 / 六爻未给 `seed` 时,实际抽到的牌面 / 六爻值会算进指纹,两次不同抽牌得到不同 ID,并标「不可复算」;给定 `seed` 或六爻值时同参数同 ID。八字 / 紫微未固定 `asOf` 时提示「流年随此刻变化」。
425
- - **界面**:结果上方新增影子盘卡(ID 等宽、一键复制、版本与基础指纹),有跨版本 / 跨次变化时展开「与上次同盘比对」;共享调色板,深色只换变量,窄屏复制按钮 44px、无横向溢出,打印时强制展开并隐藏复制按钮。面板与独立页同一渲染路径。
426
- - **工具**:宿主 `metaphysics_chart` 新增 `shadow` 布尔参数,版本从 `package.json` 注入;`renderText` 追加【影子盘】行。独立页由 `build-html` 注入 `window.__MP_VER`,不再落到 `dev`。
427
- - **D1 压缩**:`tools/build-client.mjs` 用 esbuild(`minify + target es2020 + charset utf8`)压缩,未安装时退回保守去注释;`client.js` 从 **983KB → 640KB**,gzip **329KB**。`check-bundle` 改为在未压缩源码上逐模块定位、对真实文件做整文件与宿主形态执行,并与压缩重建结果逐字节比对;CI 增加 `npm ci`;`client-bundle` 新增体积断言(低于源码 80%、gzip < 360KB),并改走统一断言工具(失败会真正退出非零)。路线图原定 gzip < 100KB,不做内容拆分与懒加载无法达到,这里按实际体积设闸并写明。
428
- - **界面验证**:390×844 深色下 `scrollWidth = 390`、卡片宽 366、复制按钮 44px、卡片底色 `rgb(33,31,24)`;900px 浅色下卡片 848、复制按钮 40px;模拟旧版本存档后自动 diff 正确显示「版本变化 + 1 处字段」。
429
- - **测试**:新增 `test/shadow.test.mjs`(55 条):ID 确定性 / 键序 / 默认值 / 参数敏感性 / 体系 / asOf、地址与经度等价、版本只改 id、随机牌面不撞 ID、diff 根因与分类、文本层、面板转义与复制按钮、localStorage 自动对盘、宿主 schema 与版本注入。统计 **104 个测试文件 / 4650 条断言**,七道闸全绿。
430
-
431
- ## 0.50.5(已发布 2026-10-31)
432
-
433
- 修 GitHub issue #1:「身弱喜火土,给分析成忌火土了」——顺带修掉同源的「同一五行同时出现在喜用与忌神」。
434
-
435
- - **问题在哪**:`engine/geju.js` 的 `yongshenOf` 先按扶抑定喜忌,再让调候在「调候优先」时把 `climate.avoidElement` 插进 `avoid`;如果这个五行本来就在扶抑的 `favor` 里(例:偏弱己土燥盘,火为印、喜火,调候又忌火),两份列表就会重叠。摘要行仍写「喜水火土……忌金木」,但面板、解读、喜忌筛选各取一份,用户看到的就是「一会儿喜火、一会儿忌火」。身强寒湿盘的水同理。
436
- - **修法**:调候所忌若已在 `favor`,不再插入 `avoid`,改记入 `disputed`(元素、扶抑角色、调候气候),喜用保留该行;调候所需要素仍按原逻辑从 `avoid` 移除。新增 `disputedTenGods`;`detail`、摘要「用神」「寒暖」行、解读「用神」「寒暖」节、白话、面板用神行与寒暖卡都标「有争议」,并说明「保留在喜用,不列入忌」。没有冲突的盘不出现该标记。
437
- - **口径**:这是「两派并存」的显式标注,不改旺衰、不改调候判断、不替用户选边;扶抑与调候仍然各自成立,只是不允许同一行同时被判喜与忌。
438
- - **界面验证**:390px 宽度下,争议行在 366px 内折 2 行,喜忌行与寒暖卡(338/338)均无横向溢出;浅色正文对比度 4.77:1、深色 7.73:1。
439
- - **测试**:新增 `test/yongshen-disputed.test.mjs`(23 条):两张真实争议盘(1962-03-22 偏弱燥火、2000-01-01 偏强寒湿水)的 favor/avoid/disputed/disputedTenGods、无冲突盘不误报、216 盘扫描喜忌无交集、文本 / 解读 / 白话 / 面板四处可见、白话与解读内嵌一致。统计 **103 个测试文件 / 4593 条断言**,七道闸全绿。
440
- - **讨论群二维码**:GitHub README 的外部图片会被改写成 `camo.githubusercontent.com`,部分网络下断链;改挂 GitHub Release 附件直链(不经 camo / raw),并保留微信邀请链接兜底。Chrome 内实测 1161×1623 正常加载,README-only,不改运行时与断言数。
441
-
442
- ## 0.50.4(已并入 0.50.5)
443
-
444
- 把「口径对照」从命令行搬到结果下面:同一个盘只换一个开关(晚子时 / 真太阳时 / 闰月归月 / 奇门取局 / 晚子时归日),差在哪几个字,现在展开就能看见。
445
-
446
- - **缺口在哪**:`engine/diff.js` 与 `tools/caliber-diff.mjs` 0.24 起就有,但只停在 CLI;面板与独立页切口径后只给新盘,用户不知道变的是日柱、命宫还是起运。紫微与奇门的差异还落成 `soul.ganzhi`、`siZhu.day` 这种原始路径,读不出来。
447
- - **引擎**(`engine/index.js`):新增 `caliberCompare(args)`,按 `CALIBER_SWITCHES` 把**当前口径**与**另一档**各排一次,返回 `{currentLabel, altLabel, total, summary, roots, categories}`;对照前剔掉 `cross / verifyPast / question / direction` 等只影响解析与附加模块的参数。`renderText` 在 `result.caliber` 存在时追加【口径对照】段。
448
- - **标签与根因**(`engine/diff.js`):补紫微(命宫 / 身宫 / 宫位 / 星曜 / 大限 / 飞星 / 格局)与奇门(四柱 / 局数 / 阴阳遁)的标签;`soul.ganzhi`、`siZhu.day`、`ju`、`dayun.jiao.at` 等进入根因表。口径回显字段(`juMethod / juMethodNote / lateZiHourMode / leapPolicy`)不再算差异——此前奇门两张完全相同的盘会被报成「2 处」,非闰月紫微也会凭空多 1 处。
449
- - **界面**(`src/panel-kit.js` / `src/app.js` / `src/web-ui.js`):结果下新增折叠的「口径对照」卡;summary 先用一句话说「几组开关中几组影响此盘」,展开后逐行给「当前 · A → 换成 · B」、根因旧值→新值、连带分类计数。只对八字 / 紫微 / 奇门出现;对照失败时不影响主结果。卡内走共享调色板,深色只换变量;窄屏隐藏「展开」提示、summary 保持 44px 触摸目标;打印时强制展开。
450
- - **工具与 CLI**:根 `index.js` 新增 `diff: true`(默认关,每次多排 2–3 张盘);`tools/caliber-diff.mjs` 改用同一个 `caliberCompare`,开关表只维护一份;`tools/build-client.mjs` 把 `diff` 模块打进 `client.js`。
451
- - **口径**:只列同一组输入下的逐字段差异与根因,不判哪套口径更准,不改盘、不折吉凶;没有根因时如实写「无单一根因」(例如真太阳时只改起运时刻、不改柱)。`total` 是变化字段数,不是分数。
452
- - **验证**:390×844 同源 iframe 实测(1996-01-19 23:40 · 安徽池州):`scrollWidth 375 < innerWidth 390`,对照卡 351px,展开后无横向溢出;强制展开深色媒体块后卡底 `#211f18`、正文与注 6.74:1、标题 6.49:1。
453
- - **测试**:`test/caliber-diff.test.mjs` 由 19 条扩到 129 条——开关表、标签 / 根因、口径回显忽略、八字 / 紫微 / 奇门真实盘独立复算(当前→另一档方向、`total / summary / roots` 与 `diffObjects` 对拍)、无变化与无根因边界、XSS 转义、面板 / 独立页 / 工具接线。统计 **102 个测试文件 / 4570 条断言**,七道闸全绿。
454
- - **文档**:讨论群二维码换新图(`docs/assets/dsh-metaphysics-group.jpg`,11 月 6 日前有效),README 有效期同步;旧 PNG 删除、改用新文件名,避免旧图缓存继续命中。不涉及运行时与断言数。
455
-
456
- ## 0.50.3(已并入 0.50.5)
457
-
458
- 给「岁运提示」补上最后一段干支关系:大运与本命四柱的伏吟 / 反吟。以前只比「大运 × 流年」和「流年 × 本命柱」,大运压到本命柱上的那一步一直空着,知识卡的 note 也明写着「未逐年标注」。
459
-
460
- - **引擎**(`engine/bazi.js`):逐年 `suiyun.signals` 新增 `大运伏吟`(当值大运与本命某柱干支相同)与 `大运反吟`(天克地冲),对年 / 月 / 日 / 时四柱逐柱比对;target 写成「第N步大运·某柱」,detail 写明具体干支。整步大运都在,随每年重复列出,note 与解析层都写明「不当成逐年加重」。原四类信号与顺序不变,`岁运并临` 仍优先于同一组大运的 `运年反吟`。
461
- - **接线**:摘要、解析层、面板沿用旧路径;摘要与面板 chip 对「大运」类信号也带柱位(`大运反吟(第8步大运·日柱)`),面板 chip 悬停仍给完整依据。`suiyunClassicOf` 口径不变:任一类信号出现就附《三命通会·卷二·总论岁运》原文。
462
- - **口径**:仍只标干支重复与对冲,不折分数、不判吉凶;大运伏吟/反吟是整步十年的背景,不是逐年加码。选这一条而不是六爻应期具体日期,是因为后者在清单里明确要先建 20 条以上《卜筮正宗》应验日期对拍集,缺语料时输出日期等于拍脑袋。
463
- - **文档与知识卡**:`bazi-suiyun` 由「四类」改「六类」,note 改为交代「连续多年出现、不逐年加重」;README「岁运提示」、清单 §3 与 0.50.3 说明块同步。
464
- - **测试**:`test/suiyun.test.mjs` 的独立参照补上两类(六类信号逐条复算),新增 1950 盘钉住「大运伏吟整步重复 2026–2028」、同年 type+target 不重复、摘要与面板柱位、知识卡六类与 note;`test/sanming.test.mjs` 的无信号样例改用 1996-02-18(1984-10-18 在新口径下已有大运信号)。统计 **102 个测试文件 / 4460 条断言**,七道闸全绿。
465
-
466
- ## 0.50.2(已并入 0.50.5)
467
-
468
- 给 0.49.0 的「人元司权」补上原文出处:录入《三命通会》卷二·论人元司事(典藏网 7529),并如实并列该本与本插件不同的日数分法。
469
-
470
- - **缺口在哪**:0.49.0 起每张八字盘都会算「生在本月第几日、哪一干当权」,知识卡却只写「之说见《渊海子平》」,没有卷次、没有链接,解释层也没有一句原文——这是全插件少数「有算法、无出处」的地方。
471
- - **原文**(`engine/classics.js`):新增 `smt-renyuan`,照录「故支吕所藏者主命,谓之人元……寅中有艮土用事五日,丙火长生五日,甲木二十日;二月建卯,卯中有甲木用事七日,乙木二十三日」,81 字逐字核验通过;来源本写作「支吕」,按「异文不改字」原样保留,不替它改字或圆场。
472
- - **口径分歧**:该本寅月作 5/5/20、卯月作 7/23,本插件通行 30 日表作 7/7/16、10/20;`plain` 与解析层都写明「不是同一套分法、不改取格」,两表并列。新增 scene「人元」,与「岁运」一样不进五条取条表:`compute` 在有 `renyuan` 时挂 `r.renyuanClassic`,摘要人元行加「原文见《三命通会·卷二·论人元司事》」、解析层人元节附原文与白话、面板经通用 section 渲染自动出现;`RENYUAN_TABLE`、旺衰与取格一行未改。
473
- - **知识卡**:`bazi-yueling-siquan` 的 detail/source/note 补上 7529 与 5/5/20,状态仍为 `variant`。
474
- - **文档**:README「古籍原文」「人元司权」「致谢」三处、清单 §二.1 / §三表 / §四.1 与 0.50.2 说明块同步。
475
- - **测试**:`test/classic-quotes.test.mjs` +4(scene 枚举加「人元」、原文/出处/plain、不进五条),`test/sanming.test.mjs` 由 17 条改为 18 条并 +11(结果层/摘要/解析层/面板/知识卡),`test/renyuan.test.mjs` +11(用 `RENYUAN_TABLE` 独立对照原文日数、结果层接线、5/5/20 可见)。统计 **102 个测试文件 / 4432 条断言**,七道闸全绿。
476
-
477
- ## 0.50.1(已发布 2026-10-30)
478
-
479
- 宿主侧栏面板的首屏与独立页并轨:三组卡片、最近用过、分组↔平铺、窄屏收纳,全部从同一份数据生成,不再「页面一套、侧栏一套」。
480
-
481
- - **缺口在哪**:0.39.0 给独立页做了分组首屏(问一件事 / 看一个人 / 查日子、最近用过、分组↔平铺),面板一直是 19 个 tab 平铺加自己那套 `.mp-tabs`——既没有最近用过,也没有「每组先露 4 项」的收纳;窄侧栏里 tab 条先吃掉大半屏,卡片与表单被推到下面。
482
- - **唯一数据源**(新增 `src/groups.mjs`):三组标题、白话提示与 19 个入口(含「人生K」铺满整行)只写一份。`tools/build-html.mjs` 用它在构建时生成页面分组 HTML;`tools/build-client.mjs` 用 `JSON.stringify` 注入 `window.__MPGroups` 给面板。页面产物与面板不再各抄一份,`test/panel-first-screen.test.mjs` 逐项对拍页面生成的入口与数据源。
483
- - **面板首屏**(`src/app.js`):React 版分组卡片(`.mp-tgroup` / `.mp-tool`)、最近用过(`mp.recent.tabs`,最多 3 条,先过 TABS 白名单)、分组↔平铺开关(`mp.first.view`,默认分组)、窄屏折叠(「还有 N 个」/「收起」,带 `aria-expanded`)。两套入口共用 `activate` → `recordRecent` + `switchTo`,排盘参数与结果路径不变。
484
- - **平铺 tab 重构**:19 个 tab 从「分段控件」改为圆角胶囊网格(与独立页同形),窄屏单行横滑、44px 触摸目标;分组视图下 tab 条整体隐藏(`.mp-tabs.hide`)。
485
- - **收纳用容器查询**:侧栏宽度不等于窗口宽度,`@container (max-width:560px)` 让 420px 侧栏与 390px 手机都按「每组 4 项 + 还有 N 个」收,不再用窗口媒体查询猜。
486
- - **口径**:分组只是另一套入口——19 个 tab 原样保留,不改变任何默认值、排盘参数与结果;存储不可用(隐私模式)只少记「最近用过」,面板照常可用。
487
- - **测试**:新增 `test/panel-first-screen.test.mjs` 40 条——分组数据、唯一数据源、页面产物对拍、面板接线、折叠与降级。统计 **102 个测试文件 / 4406 条断言**,七道闸全绿。
488
-
489
- ## 0.50.0(已并入 0.50.1)
490
-
491
- 知识卡 `liuyao-yingqi` 一直写着「应期只作时间窗口的提示」,引擎却一行都没给:用神旺衰算了、伏神出伏算了,轮到「什么时候见分晓」只剩「未做」。这一版把诚实的那一半补上——列出该留意的地支与快慢方向,仍不给具体日期。
492
-
493
- - **引擎**(`engine/liuyao.js`):新增 `yingqiWindow(result, useGod, { monthBranch })`。用神在卦上取用神、不上卦取伏神,每支列出逢值(本支)、逢冲(对支)、逢合(六合支)三支;用神旬空时本支追加「出空填实」、对支追加「冲空」。快慢按月建五态:旺 / 相 → 偏速,休 / 囚 / 死 → 偏缓,月破或旬空 → 待解,缺月建 → 未定;用神两现时逐支归并去重,快慢不一致记未定。结果挂在 `r.yingqi`。
494
- - **四处可见**:摘要加「应期线索:偏缓 · 逢值/逢冲辰 · …(只列地支,不出日期)」;解析层新增「应期线索」一节,逐条写月态与触发支;白话加一句「应期上大体偏远……不换算成具体哪天」;面板在伏神与进退之间加一排 chip(偏速绿、待解琥珀)。
495
- - **口径**:只做「该留意哪一支」与快慢方向——不换算日期、不排先后、不判忌神受制、不叠动变连环;近事以日计、远事以月计,用哪把尺由事情远近决定,不代选。知识卡 `liuyao-yingqi` 仍为 `variant`,`liuyao-yingqi-exact` 仍为 `todo`(具体日期未做)。
496
- - **口径变更连带**:解析层「未纳入」原写「应期仍未做」,现改为「应期的具体日期未做」;`test/liuyao-chufu.test.mjs` 第 212 行同步改断言(从锁旧句改为锁新句),不涉及伏神判定本身。
497
- - **文档**:README「六爻」「精度与口径」两条、清单 §3.1 / §4.3 与 0.50.0 说明块同步;package description 补「应期线索」。
498
- - **测试**:新增 `test/liuyao-yingqi.test.mjs` 73 条——12 支冲合独立复算、64 卦 × 13 组月建(12 支 + 缺月建)× 4 方向 3328 盘逐条复算(月态 / 月破 / 旬空 / 快慢 / 归并去重)、旬空 / 月破 / 用神两现 / 伏神 / 缺月建 / 两现快慢不一六条边界、四处可见与不出现日期、旧结果兼容、确定性。统计 **101 个测试文件 / 4366 条断言**,七道闸全绿。
499
-
500
- ## 0.49.3(已并入 0.50.1)
501
-
502
- 离线页(`命理排盘.html`)的「农历」tab 一直是坏的:转换方向那条分段控件从来没显示出来,农历日期怎么填都被判格式错;同一次真机检查还量出深色主题下「选中态实心底上的白字」只有约 3:1。这一版把断链接通,把强调面文字换成变量(两套配色各自过 WCAG),并顺手收掉窄屏闰月勾选框被拉高的毛病。
503
-
504
- - **断链**(`src/web-ui.js`):① `setTab` 的速查子表单显隐漏了 `#qk-convert`,只有「公历 → 农历」的默认分支能跑,切到「农历 → 公历」的入口根本看不到;② 农历日期正则写成 `/^(d{4})-(d{1,2})-(d{1,2})$/`(少反斜杠),`d` 被当字面量,任何输入都匹配失败;③ 日期标签用硬编码名单判「起卦」,convert 漏在名单外被标成「起卦日期(公历)」。现改为与面板同一套正则,标签跟随 `TIME_KIND` 的 date 类写成「日期(公历)」。
505
- - **深色强调面**(`tools/build-html.mjs`):深色块里的 `.tab.on,.seg button.on,.go{color:#14130f}` 写在基础规则之前,同优先级被后面的 `color:#fff` 盖掉——深色下实际是白字压浅珊瑚底,约 3:1。改为 `--accent-bg / --accent-bg2 / --on-accent / --on-accent-soft` 四个变量,7 处实心强调面(印章、选中 tab、分组卡片、评分格、主按钮、分段按钮、追问/chip)统一走变量。浅色仍是白字压 `#a72c23 → #7d1f18`(6.9 / 9.8:1),深色改为深字压 `#f0a38e → #e2755f`(9.1 / 6.1:1),渐变两端都 ≥4.5:1;页面样式里不再出现 `color:#fff`。
506
- - **口径**:这是一次设计口径变更,先把 `test/theme.test.mjs` 第三节改成锁变量与逐端对比度(含副文字按 alpha 叠色后复算),再改实现;`test/first-screen.test.mjs` 里锁旧元素规则的一条同步换成 `--on-accent` 规则。
507
- - **窄屏(≤640px)**:`#qk-convert` 独占整行,方向分段按钮不再折行;闰月改用 `.field.check`,勾选框保持 18px,触摸区由外层 label 撑到 44px(此前继承输入框的 `min-height:44px`,变成 18×44 长条)。
508
- - **验证**:真 390×844(CDP 设备模拟)浅/深各跑一遍——无横向溢出(scrollW=390)、`农历2026年九月十七 ⇄ 2026-10-26` 正常出结果、日期标签为「日期(公历)」、勾选框 18×18、tab 与主按钮触摸目标 44/48px。
509
- - **测试**:新增 `test/convert-ui.test.mjs` 31 条(两个入口同一套正则、2026-9-17 与闰六月前后边界、每个 `#qk-*` 都有显隐接线、闰月与 datetime 透传、格式错误文案走 textContent);`test/theme.test.mjs` 现为 65 条。统计 **100 个测试文件 / 4293 条断言**,七道闸全绿。
510
-
511
- ## 0.49.2(已并入 0.50.1)
512
-
513
- 黄历卡片里的二十八宿,把「壁水貐」写成了「壁水獝」、「胃土雉」写成了「胃土彘」——两个字都只是动物名,不影响排盘、宜忌与宿值日,但它是用户每天在摘要和面板上能看到的原文。这一版按通行二十八宿名逐字改正,并把整张表在测试里独立重录一遍,逐字对拍。
514
-
515
- - **数据**(`engine/almanac.js`):`MANSIONS` 的壁宿动物 `獝` → `貐`、胃宿动物 `彘` → `雉`;宿名仍按「宿·五行·动物」写法,其余 26 宿未动。四宫、吉凶、五行、值日轮转规则一行未改。
516
- - **口径**:值日宿仍按「日支 + 星期」定,28 日一循环;壁宿落周三(水)、胃宿落周六(土),与七曜一致。本次只改动物名,不改任何日期落到哪一宿。
517
- - **文案**:`engine/almanac.js` 顶部「诚实边界」注释同步——二十八宿、胎神、值日神、吉神方位已收录,未收录的只剩逐日全量吉凶神煞与彭祖百忌(旧注释把已收录项也写成了「未收录」,与返回值的 `scope` 打架)。
518
- - **测试**:新增 `test/almanac-xiu.test.mjs` 60 条——通行表在测试里独立录 28 行逐字对拍(含壁水貐、胃土雉)、四宫各七、动物不重、12 支 × 7 日的七曜顺序、13 段 56 天的 28 日循环与 28 日不重不漏、2026 全年不再出现「獝」「彘」、壁/胃的星期锚点、结果层/文本摘要/面板三处可见、同日两次逐字段一致、400 天宿五行与星期七曜一致。统计 **99 个测试文件 / 4262 条断言**,七道闸全绿。
519
-
520
- ## 0.49.1(已并入 0.50.1)
521
-
522
- 「岁运提示」是引擎里唯一一节没有原文支撑的能力:逐年标出岁运并临 / 运年反吟 / 流年伏吟反吟,读法却是自己写的;知识卡 `bazi-suiyun` 的出处只写「见《三命通会》《渊海子平》」,没有卷次也没有链接。这一版补上《三命通会》卷二「总论岁运」原文,并顺手记下一处口径分歧。
523
-
524
- - **原文**(`engine/classics.js`):新增 `smt-suiyun`(卷二·总论岁运,典藏网 7539),照录「行运以生月为运元,最怕行运与太岁冲克,若岁运冲月必祸;若岁运与日相对,谓之返吟,岁运压日,谓之伏吟,二者不利六亲,非横破财,不为吉兆。」——用 `verify-quotes.pl` 对章页逐字核验通过(67 字,连续子串),白话自撰。
525
- - **口径分歧写进 plain**:原文的「返吟」指岁运与日柱相对、「伏吟」指岁运压日;本插件按通行用法取「干支相同为伏吟、天克地冲为反吟」,两者并列、不合并。末句「不利六亲、破财」是旧说的重话,只作变动提示。新增 `scene: '岁运'`,不挂格局 tag。
526
- - **不进五条上限**(`suiyunClassicOf`):`classicsFor` 仍是「格局两条 + 气候两条 + 总纲一条」;岁运原文只在 `liunian` 真有信号时随该节出现——原文讲的正是冲克,没冲没克时挂出来只会误导。结果挂 `r.suiyunClassic`。
527
- - **三处可见**:摘要「岁运提示」行末加「古籍见《三命通会·卷二·总论岁运》」;解析层「岁运提示」节补原文与白话;面板岁运 chip 下加一行原文(悬停看白话,样式只走 `--muted`),无信号时三处都不出现。
528
- - **知识卡**(`engine/interpret-knowledge.js`):`bazi-suiyun` 的 source 换成带链接的《三命通会》卷二·总论岁运,detail 写明返吟/伏吟的定义分歧;状态仍 `variant`。
529
- - **口径**:只补出处与定义对照,四类信号的判定、分档与「不判吉凶」的边界一行不动。
530
- - **文档**:README「古籍原文」「岁运提示」与致谢、清单 §二·7 与文末注同步;三命通会条目 16 → 17。
531
- - **测试**:`test/sanming.test.mjs` +14 条(原文抽检、章名/链接、scene 与 tag、不进五条表、有/无信号两向的结果层/摘要/解析层/面板表现、知识卡出处),条目计数 16 → 17;`test/classic-quotes.test.mjs` +4 条(原文、出处、plain 口径)并把 scene 枚举加入「岁运」。统计 **98 个测试文件 / 4202 条断言**,七道闸全绿。
532
-
533
- ## 0.49.0(已并入 0.50.1)
534
-
535
- 「月令是什么」此前只答到月支本气:知识卡 `bazi-yueling-siquan` 写着「月内分日轮值」,引擎却一个字段都没给,面板与摘要里也看不到「生在本月第几日、哪一干当权」。这一版把《渊海子平》的人元司权分日落进引擎与解释层,补上清单 §3.3 里挂得最久的争议项。
536
-
537
- - **引擎**(`engine/bazi.js`):新增 `RENYUAN_TABLE` 与 `renyuanOf(monthBranch, birthJdn, termJd)`——固定通行 30 日表(余气 → 中气 → 本气,合计 30 日,如寅月戊7丙7甲16),从「节」的当日算第 1 日,日差取本盘所用时刻(含真太阳时)所在日;第 31 日以后不硬分摊,按本气算并标 `beyond`。返回当权干与五行、所在日段、下一段距今天数、是否在本柱藏干表内。结果挂在 `bazi.renyuan`,并带 `term`(起算的节与时刻)。
538
- - **摘要**(`engine/index.js`):节气行后加一行「人元:X月第N日,干+五行司权(各段日数)」,超出 30 日表时注明。
539
- - **解析层**(`engine/interpret.js`):新增「人元司权」一节,说明从哪个节起算、这一日谁当权、下一段几日起交;同时写明分日只作解释层细节,**不改取格**;司权表比本柱藏干表宽的地方(子月壬、卯月甲、午月丙、酉月庚、亥月戊只出现在司权表)两表各照原样。
540
- - **知识卡**(`engine/interpret-knowledge.js`):`bazi-yueling-siquan` 的 detail 与 note 补齐实现口径,状态仍为 `variant`——7/7/16、9/3/18 等分法未并列实现,轮值不参与旺衰与取格。
541
- - **口径**:只认「节」不认「气」;节当日为第 1 日;30 日表固定,不按流派切换;第 31 日起按本气;司权与取格、旺衰解耦,删掉该字段后 `primary` / `favor` 逐字不变。
542
- - **文档**:README「人元司权」一条;清单 §3.3 与 §4.1 同步,并补实现说明块。
543
- - **测试**:新增 `test/renyuan.test.mjs` 361 条——逐支核表(合计 30、连续、五行、末段为本气、2–3 段)、纯边界(首日/末日/下一段/第 31 日/第 0 日夹取)、12 张真实盘独立复算日差、已知盘 1990-05-12(巳月第 7 日庚)与 1990-11-08(亥月第 1 日戊,不在藏干表)、2023-06-05(第 31 日按本气)、立春前后 30 分钟切换、删字段不改格、确定性、摘要/解析层/知识卡口径,并禁绝「一定/必然/注定/百分百」。统计 **98 个测试文件 / 4185 条断言**,七道闸全绿。
544
-
545
- ## 0.48.0(已并入 0.50.1)
546
-
547
- 在 390×844 的真视口(无头 Edge + DevTools 协议,浅色与系统深色各跑一遍)里把「交叉验证」和三张表量了一遍:大运表六列排到 748px,屏幕只露出左半边,右边界既没有渐隐也没有「还能滑」的提示;交叉验证是五段「八字——…;紫微——…;判断:…」的长句连读;表头 11px 的 `--label` 对 `--band` 只有 3.51:1;目录链接 22px、证据摘要 33px、名词解释 22px,都够不着 44px 的触摸目标。这一版按测量结果改样式与结构,`test/theme.test.mjs` 锁的深色/打印/窄屏规则一条没动,七道闸全绿。
548
-
549
- - **交叉验证改对照卡**(`engine/crosscheck.js`、`src/panel-kit.js`):新增 `crossSection(cross)`,把文本和 `items` 一起交给面板——同一份数据两个去处,面板不用再拆文本。每个方面一张卡:标题行带「同向 / 有张力 / 互补」语气标签(绿 / 琥珀 / 蓝),八字、紫微各占一栏,注释放最后一行;≤640px 改单列,标签跟正文走。Markdown 与工具输出仍是原来的五行文本,口径不变。
550
- - **三张表不再横着截断**:渲染时给每个 `td` 打 `data-label`、表头加 `scope="col"`;≤640px 隐藏表头,一行一张卡、每格用列名当行标,首列抬成卡头。390px 下大运表从 748px 横滑变成 342px 宽的可读卡片,触发事件表同理(418px → 342px);宽屏与打印仍是原表格。
551
- - **对比度**:表头从 `--label` 改 `--ink2`(浅色 3.51 → 10.53:1,深色 9.98:1);卡内标签与备注用 `--muted`(5.29 / 6.74:1)。三档标签、目录链接、正文在两套变量下逐对算 WCAG 亮度比,全部 ≥4.5:1。
552
- - **触摸目标**:窄屏目录改单行横滑胶囊(隐藏滚动条、首尾留 11px),链接与证据摘要、名词解释摘要统一 `min-height:44px`;390px 实测全部 44px,折叠标题 ≥46px。正文宽度不变,页面横向溢出为 0。
553
- - **入口统一**:独立页与面板都改用 `Engine.crossSection`,不再各自拼 `crossText`。
554
- - **侧栏也生效**:dsh 侧栏是「窗口宽、报告窄」,`@media` 不触发;`.mp-it` 声明为查询容器,同一批窄屏规则另挂一份 `@container (max-width:640px)`。实测把报告放进 420px 容器(窗口 1280px):表格 1092px → 396px 且不再横滑、目录链接 44px、对照卡单列,与 390px 视口下的结果一致。
555
- - **测试**:新增 `test/narrow-report.test.mjs` 52 条——结构(五张卡、十个分栏、`data-label` 数量、转义)、窄屏样式规则(含容器查询版)、触摸目标、两套调色板逐对对比度,并反向锁住「表头若改回 label 会掉到 3.51:1」。统计 **97 个测试文件 / 3824 条断言**,七道闸全绿。
556
-
557
- ## 0.47.1(已并入 0.50.1)
558
-
559
- 交叉验证是 README 里挂了很久的能力,但测试只在外围点了六下(条目数、三档词、文本出现),五项判定的阈值、性别分支与节奏真值表一条没锁;顺手查出两处「说得比数据多」的文案。
560
-
561
- - **测试补真**(新增 `test/crosscheck.test.mjs`,71 条):把交叉验证当纯函数测——事业「官杀 + 食伤 ≥ 2」、财富「财 ≥ 2」、感情按性别取「妻星(财)/ 夫星(官杀)」的 1.9 / 2.0 边界;节奏用 5 档 × 煞星轻重共 10 组真值表逐格核判断与说明;再用 10 张真实盘 × 男女共 20 组,从原始 `godStats` / 宫位星曜 / 大运档位独立复算五项判断与文案;另锁条目恰好五项、次序固定、只带六个字段(没有合并分数)、输入不被改写、两次调用同结果、八字入口与紫微入口的对照逐字节一致、`crossText` 五行结构。用「事业阈值 2 改成 3」做过变异检查:2 条立即变红,恢复后 71 条全绿。
562
- - **文案与实现对齐**(`engine/crosscheck.js`):① 节奏一项原先只有一句「一边顺、一边压」,但八字大运为「平」时也会套用——1980-03-05、2005-01-13 等盘就是「平 + 紫微煞星 2 颗」。现在按实情分三句:八字顺而紫微煞星多、八字偏紧而紫微平静、八字为平而紫微煞星多,各写各的处理方式。② 大限没取到时,紫微侧原来写成「大限未取到;无煞星」,把缺数据说成了没有问题;现在只写「大限未取到」。③ 任一侧当前阶段缺失(八字未起运、紫微大限不在范围)时,判断由「同向 / 有张力」改为「互补」,说明里点名缺的是哪边,并写明「不下两边对照的结论」——不再拿「没取到」冒充「没问题」。
563
- - **口径**:五项仍只并列、不合并成总分;三档仍是同向 / 有张力 / 互补,「互补」现在也明确承担「只有一边有信号」这一情形。健康项固定「互补」不变。
564
- - **文档**:README「精度与口径」补一条,写明缺一侧时的标法与节奏说明的分档。
565
- - **测试**:96 个测试文件 / 3772 条断言,七道闸全绿。
566
-
567
- ## 0.47.0(已并入 0.50.1)
568
-
569
- 四墓月(辰戌丑未)此前只取月令本气,藏干透了也用不上、三合会成了局也看不见;同一段代码还把戊辰、戊戌、己丑、己未当成建禄,把透干/会支取到的劫财写成「劫财格」。这一版把《子平真诠》十六「论杂气如何取用」落进引擎与原文库。
570
-
571
- - **取格三级**(`engine/geju.js`):杂气月按「透干 → 三合会支 → 本气」取格。藏干透到年/月/时干仍优先;没有透干时,若其余三支与月支凑齐同一三合局,取局中五行对应的那一藏干(甲生辰月、年支申日支子 → 取水印);三合不齐才回本气。依据里写明走的是哪一条(透于某干 / 某某会成某局 / 以月令本气取格),会支只认三合、不认三会方。
572
- - **两处误标**:`base.god === '比肩'` 原先一律给建禄格,戊辰、戊戌、己丑、己未这类「本气比肩但不在禄位」的杂气月因此冒称建禄——现加禄位校验,改判比肩格并在依据里点明「禄在巳、不在辰」;杂气月由透干或会支取到劫财时,按原文「透乙则用月劫」改判月劫格,不再落到「劫财格」。
573
- - **原文与知识卡**(`engine/classics.js`、`engine/interpret-knowledge.js`):新增 `zp-zaji`(十六、论杂气如何取用,典藏网 53636),原文照录「何谓透干……透而又会,则透与会并用」、白话自撰。用神总纲位由三选一改为四选一:化气 > 四墓杂气 > 组合 > 通用总纲,杂气与组合同现时取杂气;位次不增,整节仍以 5 条为限。知识卡 `bazi-zaji-quyong` 补一条,标「各家有异说」。
574
- - **口径**:原文「兼透则兼用」只给原则,落到单一格名必须择一,本插件取最先透出的那一干;会支只认三合、不认三会方;不判原文所说的「有情 / 无情」。这几点写进 README 与清单,不替分歧圆场。
575
- - **测试**:新增 `test/zaji.test.mjs` 52 条,用 9 张真实盘正反两向钉住——透干压会支(1996-01-19)、会支取用(1985-02-03 / 2005-01-13 / 2002-10-13)、三合不齐回本气(1992-04-05)、非杂气月不启用会支(1979-11-13 / 1985-09-15)、建禄不误标(1989-03-05 / 1983-08-20 / 1990-04-13)、月劫三路(1985-04-05 / 1996-08-05 / 1990-10-28),并核总纲位次序、上限、确定性、摘要/解释层/面板与知识卡。`test/classic-quotes.test.mjs` +5 条,把总纲位改判为四选一并加原文抽检。统计 **95 个测试文件 / 3701 条断言**,七道闸全绿。
576
-
577
- ## 0.46.5(已发布 2026-10-30)
578
-
579
- 「问进对话」只把盘面摘要和问题送进对话,模型得自己再推一遍结论——同一张盘,面板里读到的「说人话」和对话开场可能不是一套口径。这一版把面板已算好的白话结论一并交给模型。
580
-
581
- - **缺口在哪**(`engine/followup.js`):`askPrompt` 只读 `r.summary`,而 `interpret(r, ask)` 产出的 `answer`(直答)与 `plain`(说人话)只存在于面板结果对象 `it` 里。用户点「问进对话」后,模型看到的是原始盘面,开场结论全靠现场发挥;问法或流派稍有出入,就会与面板上的结论打架。
582
- - **改动**:`askPrompt(r, { interpret })` 新增可选解析对象;有 `interpret` 时,在「所问」与「盘面摘要」之间插入「开场结论」小节,原样带上 `answer`(直答)与 `plain`(说人话),并把回答要求第 1 条改成「先沿用上面的开场结论,再用一句不用术语的话说清主线」。调用方没传时回退读 `r.interpret`(`compute({ withInterpret: true })` 的结果);两者都没有就完全不加这一节,固定骨架保持原样。
583
- - **接线**(`src/app.js`):面板两处调用都带 `interpret: result.it`;`LAST` 增加 `it` 字段,输入框右侧的「命理·问」也能拿到同一份白话底稿,而不是只带摘要。
584
- - **账面**:1996 盘(所问「今年考运」)提问文本 2353 → 2669 字,底稿只多 316 字(直答 106 + 说人话 144 + 小节标题),没有把提问撑成小作文;未传解析时逐字不变。
585
- - **口径**:底稿只做「同一口径」的搬运,不改写、不摘要;模型仍被要求压成一句无术语的话,避免直接复读盘面术语。
586
- - **测试**:`test/ask-prompt.test.mjs` +13 条——底稿小节存在且排在摘要之前、直答/说人话原样带入、回答要求指向底稿、未传解析时不加小节、`r.interpret` 自动回退、空解析对象不加空小节、无问题时底稿不说「先答所问」、带底稿仍逐字确定;`test/client-bundle.test.mjs` +2 条锁住面板两处调用都带 `interpret`、桥的 `LAST` 保留解析对象。统计 **94 个测试文件 / 3643 条断言**,七道闸全绿。
587
-
588
- ## 0.46.4(已并入 0.46.5)
589
-
590
- 0.46.3 有三处「写进了文案、没落进代码」:文末分歧清单只列前 4 条、面板仍显示「问题:(未填写)/先答所问」、归属稳定性测试并不存在。这一版把三处补齐,并把它们钉进断言。
591
-
592
- - **分歧清单不再截断**(`engine/interpret.js`):`caveats.slice(0, 4)` 让 1996 盘的 13 条分歧只显示 4 条,另有 9 条不在任何段落、其中 7 条原注整份报告都读不到——与 0.46.3 写的「信息不丢」相反。现在按状态拆开:「待核实」仍归「尚未实现(不猜)」并附原注;其余分歧逐条列出(已展开的只留条目名,未展开的附原注),同一句原注不会出现两遍。
593
- - **没问事就别喊「答所问」**(`src/panel-kit.js`、`engine/index.js`):奇门只选方向时,面板回显原来是「问题:(未填写)|询问方向:财运」,直答标题也固定写「先答所问」。现在没填问题只回显方向,标题改为「先看结论」;填了问题仍用「先答所问」。奇门的直答也从泛泛的「五个维度」改为「排盘事实、用神、宫位条件几节」,并点明所选方向。
594
- - **测试补真**(`test/interpret-dedupe.test.mjs`,28 条):归属稳定性按 7 个方向 × 有事/无事 逐一对拍「卡片→维度」签名;分歧清单断言行数等于条目数、未展开条目的原注必须在、已展开的不重复贴;`knowledgeCount` 同时与「唯一卡片数」「逐维挂载总数」独立核对;面板侧用源码锁住旧「(未填写)」串已删除。0.46.3 里那句没有测试支撑的说法,至此才有对应断言。
595
- - **口径**:信息完整优先于尾部紧凑——文末清单从 4 行回到 13 行,1996 盘解析文本 9099 → 9965 字(无问题)/ 10051 字(有问题),`knowledgeCount` 仍为 10,正文五维没有新增复读。
596
- - **测试**:新增 94 个文件 / 3628 条断言,七道闸全绿。
597
-
598
- ## 0.46.3(已并入 0.46.5)
599
-
600
- 同一段「规则注解」在报告里复读了两三遍:1996 示例盘的 29 条注解里,只有 16 张是不同的卡。这次把注解改成「一张卡全报告只挂一次、每维最多 3 条」,没填问题时也不再假称「你问的这件事」。
601
-
602
- - **缺口在哪**(`engine/interpret.js` 的 `enrichPlain`):知识卡按维度静态挂载,而 `knowledgeFor(system, dimKey)` 对「整体运势 / 事业发展 / 健康」会返回同一批通用条目,于是「月令不是一个月」「大运管十年基调」「同一个格,子平真诠怎么用、三命通会怎么取」这类解释在正文里出现 2–3 次,把五段判断冲散。实测 1996 盘:整体 14 条、事业 10 条(9 条重复)、感情 3 条(2 条重复)、健康 2 条(两条全重复)——29 条里 16 张不同,段落被复读切成碎片。
603
- - **改动**:先按固定维度次序(整体 → 工作 → 事业 → 感情 → 健康)分派,已出现过的 id 跳过,每维再截到 3 条。次序用固定表而不是显示顺序,是因为「所问之事」会把某一维提前——按显示顺序先到先得的话,同一张盘换个问法,注解归属就整体搬家(归属稳定性测试在 0.46.4 补上)。文末「这套规则有多稳」对已展开的条目只留一句索引,不再贴一遍全文;被截掉的分歧条目也应进文末清单(0.46.4 修正:此处当时实际只列了前 4 条,另有 9 条及其 7 条原注被漏掉)。
604
- - **顺手**(`engine/interpret-plain.js`、`engine/interpret.js`):没填问题时抬头不再写「问题:(未填写)」,正文也不再假称「具体到你问的这件事」——改成「没指定问题,就按……的顺序往下看」。这是「读者视角」的最后一点漏:没问问题却硬答「你问的这件事」,最容易被当成模板腔(面板侧的回显与「先答所问」标题在 0.46.4 一并修正)。
605
- - **账面**:1996 盘解析文本 11862 → 9099 字(−23%),`knowledgeCount` 29 → 10,五维正文之间不再有整块复读。
606
- - **测试**:`test/interpret-knowledge.test.mjs` +5 条——同卡不重复、每维 ≤3、`knowledgeCount` 与实际挂载一致、无问题时抬头不写「未填写」、正文不假称「你问的这件事」。统计 **93 个测试文件 / 3600 条断言**,七道闸全绿。
607
-
608
- ## 0.46.2(已并入 0.46.5)
609
-
610
- 离线页的「验前事 / 生时校正」原来是原生控件:年份框 21px、按钮 31px 灰底;窄屏下三档判断按钮 22px,追问框 37px、导出按钮 39px,「点任一宫位看详情」只有 2.25:1。
611
-
612
- - **缺口在哪**:这两块由 `web-ui.js` 输出 `.mp-btn` / `.mp-input`,但基础样式只写在 DSH 宿主的 `src/app.js` 里(且用的是 `--dsw-*` 变量),离线页从没定义过——于是年份与类型退回 21px 原生输入框,「算贴合度 / 计算候选时辰」退回 31px 灰按钮,和整页的米色卡片明显不是一套。
613
- - **实测口径**:用无头 Chrome 通过 CDP 在 390px 视口、浅色/深色两套配色下逐个点开 19 个 tab,量 `#out` 内溢出、可点区域尺寸与文字对比度。修复前:验前事三档按钮 32×22、年份框 21px、按钮 31px;全页每个 tab 的追问框 37px、导出按钮 39px;紫微提示条 2.25:1。
614
- - **改动**(只碰页面层与结果区模板):`tools/build-html.mjs` 给页面补一套同变量的 `.mp-verify/.mp-rect` 按钮与输入框样式(含聚焦环),窄屏把三档按钮排成等分三列、标签独占一行,`.mp-chip` / 验前事按钮 / 年份与类型框 / 追问框 / 导出按钮统一抬到 44px,追问输入改 16px 避免 iOS 聚焦缩放;`src/panel-kit.js` 的 `.pp-soon` 由 `--faint` 改 `--muted`(浅色 4.77:1、深色 7.73:1);`src/web-ui.js` 删掉两处把按钮压到 12px/31px 的行内样式。
615
- - **口径不变**:颜色全走既有页面变量,深色仍是只换变量;`test/theme.test.mjs` 锁定的打印、深色、窄屏 tab 规则一条未动(50 条断言原样通过)。
616
- - **测试**:新增 `test/ui-controls.test.mjs`(15 条)——页面控件样式、无硬编码色、窄屏 44px、提示条对比度(从变量声明取色独立复算)。修复后复测:19 个 tab × 浅/深 0 处横向溢出、0 个 <44px 控件、0 处对比度 <3:1。统计 **93 个测试文件 / 3595 条断言**(+15),七道闸全绿。
617
-
618
- ## 0.46.1(已并入 0.46.5)
619
-
620
- 偏财格不再引《论正财》,七杀格补上三命对照:九个走月令的格,这才真正做到「子平在前、三命在后」各一条。
621
-
622
- - **缺口在哪**:三命通会此本正财、偏财分章,引擎却让两格共用 tag「财」——1996 示例盘就是偏财格,古籍节里挂的却是《三命通会·卷六·论正财》。七杀格更只有子平《论偏官》一条,没有三命对照,而 README 已写「同一个格,子平真诠在前讲怎么用,三命通会紧随作对照」。
623
- - **两条原文**(`engine/classics.js`):`smt-piancai`(卷六·论偏财 7650,「乃众人之财也……切忌有姊妹兄弟分夺」)与 `smt-guansha-liu`(卷五·官煞去留杂论 7599,「天干透者易去,月支所藏者难去」)。均按典藏网章页逐字核验(2/2 通过),照录不加省略号,plain 为白话自撰。
624
- - **七杀为何取「官煞去留杂论」**:该本三命通会没有单列「论偏官」章,硬凑一篇改名就是造出处;取同卷讲官煞混杂去留的这一篇作对照,章名照录,plain 写明「七杀格遇正官混杂,就按这一篇看取舍」。
625
- - **接线**:`GEJU_KEY` 把正财格、偏财格拆成两个 tag,子平《论财》同时标「正财」「偏财」,于是两格都是子平在前、三命本格章在后;七杀格 / 偏官格指向官煞篇。5 条上限、专旺从格先占位、总纲位三选一均未动,其余盘选条逐字节不变。
626
- - **文档与知识卡**:`bazi-sanming-duizhao` 补写「此本正财偏财分章、七杀无专章」;清单四·1 与 README 致谢的「十四篇」改对为十六篇;README 里写死的「90 个测试文件 / 3423 条断言」改为「取自断言基线」,避免每轮过期。
627
- - **测试**:`test/sanming.test.mjs` 的条目分组由「章名是否以论开头」改为显式 id 清单(官煞篇不是「论」字题),新增偏财 / 七杀配对与正反两向(偏财不引正财章、正财不误取偏财章);`test/classic-quotes.test.mjs` 用 1996 偏财盘钉住对照条;`test/tongguan.test.mjs` 的 1996 选条期望同步为 `smt-piancai`。统计 **92 个测试文件 / 3580 条断言**(+13),七道闸全绿。
628
-
629
- ## 0.46.0(已并入 0.46.5)
630
-
631
- 紫微补齐九类流派开关:此前只做了闰月三档,换派只能拿到默认盘;现在每一项都能单独切换,且不传时盘面与旧版完全一致。
632
-
633
- - **缺口在哪**:0.42.0 把参考项目的「其余九类流派开关」明确留作后续,引擎里亮度、庚干四化、天马、天空、截空旬空、魁钺、天伤天使、长生起点、晚子时都只有一种写法;工具 schema 也没有对应参数,模型侧无法要求「按全书派排」。
634
- - **改动**(`engine/ziwei.js`):新增 `ZIWEI_SCHOOL_DEFAULTS` / `ZIWEI_SCHOOL_OPTIONS` / `ziweiSchoolsOf`,九个开关逐个落到安星与起盘——`brightnessSchool` 四套亮度数值表按星逐年转中文(QS/XD1 七档、ZZ/XD2 五档);`gengYearSihua` 五个庚干四化变体;`tianmaSchool` 年支/生月三合;`tiankongSchool` 不排/年支顺行/加生时;`jiekongSchool` 不排/单星/正副/占验,启用时同时排旬空副旬;`kuiyueSchool` 四派魁钺(生年与流年同表);`tianshiTianshang` 中州派阴男阳女互换;`changshengSchool` 火土派把土五局长生起点从申改寅;`lateZishi` next-day 时 23:00 后起盘日顺延。
635
- - **接线**:`engine/index.js` 透传九个平铺参数与嵌套 `schools`(八字 × 紫微交叉验证同样生效);根 `index.js` 的 MCP schema 新增九个字段与枚举;摘要只在改动默认时补一行【流派】,默认盘不多噪音。
636
- - **口径**:不传或传非法值一律回默认,默认仍是 49 星盘面;庚干变体只作用于生年四化,宫干自化与大限/流年四化不随之改变(已写进 `rules.schools`)。
637
- - **测试**:新增 `test/ziwei-schools.test.mjs`(73 条)——默认盘逐字节不变、九项各自独立生效、非法值回退、嵌套参数、compute 透传与摘要。统计 **92 个测试文件 / 3567 条断言**(+73),七道闸全绿。
638
-
639
- ## 0.45.2(已并入 0.46.5)
640
-
641
- 玄空的 `period` 非整数不再静默落回九运,而是按入参错误报 `E_INPUT`。
642
-
643
- - **缺口在哪**:`engine/index.js` 只把 `Number.isInteger(period)` 传给引擎,`2.5` 或字符串 `"9"` 会被直接丢掉,`buildXuankong` 随后走缺省分支排九运——调用方拿到的是一张看似正常的盘,而不是「运写错了」。
644
- - **改动**:`buildXuankong` 先校验「显式给了 period 就必须是整数」(`null` / `undefined` 仍算未给),不符合与越界共用同一条 `E_INPUT` 文案;`index.js` 不再预先过滤 period,原样交给引擎判定。
645
- - **口径不变**:合法 1–9 的整数仍优先于 `fortuneYear`;未给 period 时仍按 `fortuneYear` 定运,再缺省九运并注明。
646
- - **测试**:`test/fengshui-xuankong.test.mjs` 补 4 条(非整数/字符串报错、错误码、`null` 仍缺省),`test/tool-fengshui.test.mjs` 补 2 条(两种非整数在工具层都显示 `[E_INPUT]`)。统计 **91 个测试文件 / 3494 条断言**(+6),七道闸全绿。
647
-
648
- ## 0.45.1(已并入 0.46.5)
649
-
650
- 风水引擎的入参校验改走统一错误工厂,工具层不再把「坐向写错」这类调用错误标成内部异常。
651
-
652
- - **缺口在哪**:`engine/fengshui.js` 的坐向、性别、生日、运越界都裸抛 `new Error`,到 `index.js` 的工具 catch 里没有 `code`,一律落到 `[E_INTERNAL]`;模型侧据此会把「参数该改」误判成「插件坏了」。
653
- - **改动**:六处入参校验改用 `fail('E_INPUT', …)`——非 24 山、命卦缺性别、命卦缺完整生日、缺坐向、坐向不对宫、运越界。`mingGua` 落中宫的「命卦计算异常:落中宫」是内部一致性守卫,不是入参错误,仍保持无码 → `E_INTERNAL`。
654
- - **口径不变**:文案、判定条件与结果字段均未改,只补错误码;工具层现有 `code || E_INTERNAL` 的透传逻辑不用动。
655
- - **测试**:`test/tool-fengshui.test.mjs` 补 7 条(+7)——运越界与坐向不对宫各加一条码断言,另表驱动五组入参错误,要求文案匹配且前缀恒为 `[E_INPUT]`。统计 **91 个测试文件 / 3488 条断言**(+7),七道闸全绿。
656
-
657
- ## 0.45.0(已并入 0.46.5)
658
-
659
- 把「通关」从一句取象变成可复核的结构判定:用神与忌神相战时,指出五行里唯一能接上的那一行,并如实报它在局中的分量。
660
-
661
- - **缺口在哪**:`engine/geju.js` 的文案一直写「身中和,先取调候与通关」,但引擎从未算过通关;`classics.js` 也只录了寒暖/燥湿等滴天髓条目,没有通神论「通关」原文。
662
- - **判定口径**(`engine/geju.js` 的 `tongguanOf`):只在「用神与克它的忌神两行在局中各 ≥1.5 分」时成立相战;通关行由五行生克唯一确定(克方所生、又生用神,金克木以水为关),按分量分「可通 / 关弱 / 为忌 / 未通」四档,`usable` 仅指「可通」。通关行若在本盘属忌神,只标「为忌」、不当桥用;只写进用神 detail、摘要与解释层,不折分数、不断吉凶,也不判通关之力够不够用。
663
- - **原文与选条**(`engine/classics.js`):新增 `dt-tongguan`(通神论·通关,典藏网 153091,原句照录「关内有织女,关外有牛郎,此关若通也,相邀入洞房」)。只在 `usable` 时占一位,并让泛论「用神配气候」让位;寒暖/燥湿的具体条目照留,整节仍以 5 条为限。未通的盘(如 1996 盘)经典选条保持原样。
664
- - **知识卡**(`engine/interpret-knowledge.js`):新增 `bazi-tongguan`,标 `variant` 并写明分歧——各家对「两神相战」取哪两神不一(日主与官杀 / 用神与忌神 / 局中最旺两行),本插件固定取用神与克它的忌神。知识库 50 条(15 / 34 / 1)。
665
- - **已知边界**:调候与扶抑可能给出同一行同时在喜在忌(扫射中约四分之一盘);本插件不改写喜忌表,通关判定按现表计算,并在清单里写明。
666
- - **测试**:新增 `test/tongguan.test.mjs`(58 条)——五组相克各给唯一通关行、1.4/1.5 阈值与四档分类、喜忌顺序与空结果、24 年逐月真实盘独立重算与确定性、可通/未通两盘的经典选条、摘要/解释层/面板可见性与知识卡。统计 **91 个测试文件 / 3481 条断言**(+58),七道闸全绿。
667
-
668
- ## 0.44.2(已并入 0.46.5)
669
-
670
- 补齐模型侧调用玄空的最后一环:工具 schema 声明 `action:'xuankong'` 与 `period`,并让「今年」只补进命卦。
671
-
672
- - **缺口在哪**:玄空下卦在引擎与两个界面都能用,但模型工具 `metaphysics_chart` 的 `action` 枚举只有 natal / advise / assess / generate,没有 `xuankong`,也没有 `period` 参数——对话里让模型排玄空,schema 层面就过不去。
673
- - **另一个隐患**:`run()` 原先把「没给 fortuneYear 就补今年」的规则写成「fengshui 且不是 advise」,玄空一旦可调用,缺省会得到 fortuneYear=今年,九运缺省提示永远不出现,按年定运与默认九运两种口径悄悄混在一起。现在只对 natal(含未写 action 的缺省)补年份,玄空严格走 `period` → `fortuneYear` → 九运并注明。
674
- - **改动**(`index.js`):`action` 枚举加 `xuankong`;新增 `period`(1–9,优先于 fortuneYear);`sitting` / `facing` / `fortuneYear` 与 `system` 的说明同步覆盖玄空;年份补全条件收窄到 natal。
675
- - **口径不变**:显式 `period` 优先;给了 `fortuneYear` 按该年定运并回运程起止;两者都没有才缺省九运(2024–2043)并写明提示。
676
- - **测试**:新增 `test/tool-fengshui.test.mjs`(19 条)——枚举与 period 声明、显式运不注入年份、按年定运的起止、缺省九运且不被今年顶替、命卦仍默认今年、非法运与坐向不自洽在工具层报错。统计 **90 个测试文件 / 3423 条断言**(+19),七道闸全绿。
677
-
678
- ## 0.44.1(已并入 0.46.5)
679
-
680
- 风水结果在 DSH 侧栏与独立页同步换了展示:从一段摘要文本变成方位网格,侧栏主按钮文案也按 tab 归位。
681
-
682
- - **为什么**:上一轮把玄空下卦算出来了,但结果只是 `renderText` 的文本墙——九宫运/山/向挤在方括号里,旺山旺向与表法只能逐字读。侧栏面板里这个问题更明显(没有等宽排版)。
683
- - **共用一份渲染**(`src/panel-kit.js` 的 `pp.fengshuiHTML`):侧栏(`src/app.js`)与独立页(`src/web-ui.js`)都挂到同一个函数,改一处两边同步。
684
- - **玄空**:按后天八卦三行九宫(巽离坤 / 震中兑 / 艮坎乾),每宫依次列运/山/向三数;与当运相同的数高亮(中宫运数本身即当运,故 9 运、8 运各 3 处高亮);卡头写山盘/向盘的入中星与顺逆,以及「盘面」「表法」两个独立 chip;下方事实行写当运落宫、合十、表法说明。
685
- - **八宅命卦**:八向格(中宫留空)标星名与吉/凶,四吉四凶各四;给了流年时加一行年紫白(入中星 + 八宫星名)。
686
- - **门主灶**:同一张八向格 + 门/灶/床/厕四行 + 命宅配(给了生辰才有)。
687
- - 所有文本走 `esc()`,布局文案或宅卦名里塞 `<img>` / `<script>` 不会变成标签。
688
- - **侧栏动作按钮**:速查类 tab(黄历/农历/择日/称骨/小六壬/星座/生命数字/人生K/风水/起名)由「起卦」改为「看结果」,奇门为「起局」,空状态提示同步改成「填好参数,点『看结果』」。
689
- - **没改什么**:引擎与输出字段未动,仍是展示层改动;`meta.scope` 与免责声明原文照旧。
690
- - **测试**:新增 `test/fengshui-ui.test.mjs`(43 条)——九宫顺序与 27 个数、当运高亮、9 运无局与 8 运乾巽到山到向两套盘、八宅四吉四凶与年紫白、门主灶四行与命宅配、转义、侧栏/独立页接线与按钮文案。统计 **89 个测试文件 / 3404 条断言**(+43),七道闸全绿。
691
-
692
- ## 0.44.0(已并入 0.46.5)
693
-
694
- 风水补上一直挂着的玄空飞星:不是只加一张表,而是把「运盘 → 山盘 → 向盘」的挨星规则真正跑通,并让盘面与通行旺山旺向表逐运对得上。
695
-
696
- - **缺口在哪**:README 的风水段一直明写「不含玄空各运盘」。八宅命卦、大游年、年紫白都是单星飞布,缺的正是玄空最核心的**下卦三盘**:当运星入中排运盘,再取坐宫/向宫的运星入中排山盘、向盘,最后看当运山星是否到坐、当运向星是否到向。
697
- - **关键口径(这一轮最容易踩错的地方)**:山盘/向盘的顺逆**不是**按坐山本身的阴阳,而是按「入中运星的本宫(本位卦)同元龙之山」的阴阳;五黄入中时按本山阴阳。按本山阴阳会把旺山旺向算成每运固定的六局,与通行二十四山旺山旺向表(一运、九运无局)对不上;改按本宫同元龙后,九运旺山旺向表与盘面逐运吻合。
698
- - **新增能力**(`engine/fengshui.js`):`periodOfYear`(1864 起一运、每运 20 年、九运 180 年一轮)、`MOUNTAIN_META`(24 山三元龙与阴阳)、`xuankongChart` 与 `action:'xuankong'`。输出九宫逐宫的 `运/山/向`、山盘与向盘的入中星与顺逆依据、当运星落宫、山星/向星合十宫位,以及**表法**旺山旺向(通行表)与**盘面**旺山旺向(当运星是否落坐/向)两套结论并列;两者口径不同,不合并、不互相覆盖,文案里写明差在哪。缺省运为九运(2024–2043)并给出提示,也可传 `period`(1–9)或 `fortuneYear`。
699
- - **没做什么**:替卦 / 兼向、年月日时飞星、形峦与现场勘舆、具体应期。`meta.scope` 与免责声明逐条写明。
700
- - **界面**:面板与独立页的风水速查加第三个模式「玄空」,坐山/朝向沿用 24 山输入,另加「运(1–9)」输入;结果仍走摘要文本,九宫按「巽离坤 / 震中兑 / 艮坎乾」三行排出。
701
- - **测试**:新增 `test/fengshui-xuankong.test.mjs`(119 条)——三元九运边界、24 山三元龙阴阳逐条、七张公开盘面数字(含双星会向、五黄入中)、每运 12 局三盘均为 1–9 排列、**盘面旺山旺向与通行表逐运一致**(两套独立数据互证)、坐向互通、216 局确定性、运的来源与输入边界、`compute` 接线与摘要。统计 **88 个测试文件 / 3361 条断言**(+119),七道闸全绿。
702
-
703
- ## 0.43.1(已并入 0.46.5)
704
-
705
- 专旺格与从格终于有原文可读:三命通会里其实有七篇专章,此前清单写的「三书没有可整段照录的专章」是错的。
706
-
707
- - **缺口在哪**:`docs/知识扩展与待核实清单.md` 四·1 一直写着「专旺格与从格暂无对应的单章原文条目(三书里没有可整段照录的专章),暂不硬凑」。核对典藏网目录后发现三命通会卷六有曲直、炎上、从革、润下、稼穑五篇,卷五有弃命从煞、卷六有弃命从财——正好对着引擎里已有的专旺五格与从财格、从杀格。于是这一轮不是「补口径」,是补上本可以早就有的原文。
708
- - **七条原文**(`engine/classics.js`):`smt-quzhi`(卷六·曲直 7630)、`smt-yanshang`(卷六·炎上 7631)、`smt-congge`(卷六·从革 7632)、`smt-runxia`(卷六·润下 7633)、`smt-jiasi`(卷六·稼穑 7634)、`smt-congsha`(卷五·弃命从煞 7598)、`smt-congcai`(卷六·弃命从财 7652)。原文取连续段落照录、不加省略号也不改写;白话自撰。原文里「多主眼疾」「破家不仁之人」这类旧说重话照录,但明确只记原文、不拿来断人。
709
- - **接线**(`classicsFor`):命中的专旺格 / 从财格 / 从杀格先取单章原文,排在月令格之前——专旺或从格是这张盘的定义性结构,先占位才不会被后面两条气候与总纲挤掉;整节仍以 5 条为上限,不额外放宽。从儿格(食伤)、从强格(印 / 比劫)三书里没有可整段照录的专章,`SPECIAL_CLASSIC` 不登记、不硬凑,测试里用两张真实盘反向核过「不误配」。
710
- - **知识库 49 条**:新增 `bazi-zhuanwang-yuanwen`(专旺五格的成格条件比「身强」细)与 `bazi-congge-yuanwen`(弃命相从、见根气即破格),均标 `variant`——专旺是否必须成方局、从格是否允许微根,各家宽严不一;只列结构与原文,不断贵贱,也不补专旺的破格条件。顺手把清单表格里漏登的三条历史条目(紫微三方四正复合飞化、六爻用神旺衰、六爻全卦逐爻旺衰)补齐,表格从 44 行对到 49 条。
711
- - **口径修正**:清单四·1 与 README 致谢里「三书没有专章 / 只取七条」的说法一并改对,写明「十四篇:论十神七篇 + 专旺五格与弃命从煞、从财七篇」,并注明从儿、从强仍未录。
712
- - **测试**:`test/classic-quotes.test.mjs` 新增七张真实盘(曲直 / 炎上 / 从革 / 润下 / 稼穑 / 从财 / 从杀)逐格核「命中的单章排第一、why 点名、仍守 5 条上限」,另加从儿 / 从强两条反向用例、limit 截断、摘要与解释层可见;`test/sanming.test.mjs` 条目数由 7 改为 14(并拆出「7 论十神 + 7 格局篇」两个计数),逐条核原文、章名、典藏网链接、链接互不重复、tag 不与月令十神混用,并钉住两张新知识卡。统计 **87 个测试文件 / 3242 条断言**(+57),七道闸全绿。
713
-
714
- ## 0.43.0(已并入 0.46.5)
715
-
716
- 解读从「五维度 + 若干节」升级成可读的报告:紫微补逐宫与分层格局,八字补命局框架、画像、流年叙述与专业建议;措辞收进两份独立词库,引擎与说法彻底分开。
717
-
718
- - **缺口在哪**:此前的解读只有五个维度和几张表——维度说得对,但不成篇。用户拿到紫微盘,看不到「这十二个宫各自是什么味道」;拿到八字盘,看不到「这个人的框架、长什么样、哪一年顺」,只能自己去拼盘面。对照市面上的成篇解读,差的是**结构与措辞**这两层,不是数据。
719
- - **紫微新增四块**(`engine/interpret.js`):① **命身底色**——命宫主星 + 亮度 + 双星组合 + 身宫落点一句话说清;② **逐宫分析**——十二宫各一条 `【宫·支】主星(亮度)|吉星|煞星|四化`,下接「读法」;③ **三层格局**——有利格局 / 结构提示 / 忌格提醒,每条写 `名称 · 人话 · 依据(盘面事实) · 做法`,按 tone 着色;④ **行动建议**四条。只把六煞(擎羊/陀罗/火星/铃星/地空/地劫)写进五个维度,其余杂曜留在逐宫,避免一眼看去全是星名。
720
- - **八字新增四节**:**命局框架**(日主/用神/格局三行,末尾一句命局基调)、**正面画像**(外在取象 / 性格底色 / 事业与家庭)、**流年时间轴**(近三年逐条给档位与理由,用「可能性」措辞并声明档位不是断语)、**专业建议**(喜用落地 / 忌神自觉 / 地支关系 / 调候四件可做的事)。
721
- - **两份词库**(新增 `engine/ziwei-words.js`、`engine/bazi-words.js`):紫微侧 12 宫取象、14 主星(别称/关键词/得地与失地两种语气/长处/要留意的点)、24 组双星、14 煞星、18 吉星、四化落宫、七档亮度、34 条格局读法;八字侧 10 天干取象、10 颗十神 + 5 组(十神权重底层给的是组名,组与单颗各有一套话)、旺衰 × 用神方向的六种命局基调、地支冲合刑害破的手感。**词库不含判断条件**——要不要说、说哪一条由引擎决定,换个排盘引擎结论也不会被说反。
722
- - **命局基调按权重取**:`frameToneOf(level, favorRoles)` 只看角色不动分数;调用方先把 `favorRoles` 按十神权重排好再传入,于是「身强喜食伤财官杀」取到的是分量最重那一支(泄),而不是固定顺序的第一条。强档没有对应基调时回落「泄」、弱档回落「生」,都写明理由。
723
- - **面板**:分节支持 tone(左框线 + 标题色:有利绿、提示橙、忌格红)与 `**加粗**`、换行分段(此前整节挤成一坨);逐宫、三层格局各有独立锚点,目录可跳。
724
- - **术语表**(`engine/interpret-plain.js`):补 庙旺 / 三方四正 / 命主 / 身主 / 五行局 / 自化 / 飞星 / 正曜 / 借对宫 / 双星 / 墓库 / 伏吟 / 反吟 十三条,仍按「正文里真的出现过」才展示,并按体系取不同释义。
725
- - **顺手改掉两处重复**:紫微「说人话」不再复述直答里的命宫与身宫,改说「你与环境怎么互动」与重心;八字性格底色的单颗十神只补「落在哪个角色上」,不再把组的那句抄一遍。
726
- - **测试**:新增 `test/ziwei-words.test.mjs`(55 条)与 `test/bazi-words.test.mjs`(46 条)——词库条目数与引擎表一一对应(34 条格局名与 `PATTERN_TONE` 双向零差集)、双星 key 必须能拆成两颗真实主星、亮度三档齐全、煞星不写成判决、基调优先序与回落、地支关系去重与「自刑优先于刑」、四节存在且引用本盘真实字段、面板把 `**` 与换行渲染成 `<b>` 与段落、全文无 undefined/NaN。**87 个测试文件 / 3185 条断言**,七道闸全绿。
727
- - **边界**:词库只给倾向与做法,不下断语;格局读法覆盖现有 34 条,新增格局未入词库时按 tone 回落成通用句而不是现编;逐宫只写星曜与四化,不叠大限流年的三层算力;健康维度只用煞星星情,不给脏腑诊断。
728
-
729
- ## 0.42.0(已并入 0.46.5)
730
-
731
- 紫微的闰月从两档补到三档,默认换成主流排盘的「按日切分」;顺手修掉流年斗君二次换月。
732
-
733
- - **缺口在哪**:此前只有「闰月按本月」与 `leapAsNext`(整月归次月)两档,默认按本月。闰月后半月出生的人,主流排盘按次月起盘,我们却按本月,命宫、身宫、五行局、十四主星位置、大限起运、流月斗君整条链都差一个月——盘看起来完整,宫位却系统性偏移。
734
- - **三档口径**(`engine/ziwei.js` 新增 `LEAP_POLICIES` / `leapPolicyOf` / `effectiveLunarMonth`):`split`(默认,1–15 归本月、16 起归次月,按日切分)、`next`(整月归次月)、`prev`(整月归本月);`leapAsNext: true` 保留为 `next` 的旧写法,`leapMonth` 优先于它。不认识的取值回落到默认,不抛错。工具参数同步成枚举,`rules.leapMonth` 写明三档与默认。
735
- - **为何改默认**:参考开源项目 [ziwei-doushu](https://github.com/Renhuai123/ziwei-doushu)(MIT)的流派配置与其 150 组金标准盘对照结论——主流排盘默认「月中分界」。我们不引入其引擎,只采纳这一条排盘口径,并把它做成可切回的开关;不想换的人传 `leapMonth: 'prev'` 即回到旧口径。
736
- - **盘里能看见**:`lunar` 保留 `monthRaw`(原始闰月)与换算后的 `month`、`leapPolicy`,闰月另给一句说明(「闰4月按日切分……本盘闰月21日按5月」);摘要的农历行写成「2020年闰4月21日(按5月起盘)」,不再把 21 日写成「闰5月21日」;面板宫盘抬头同样处理。
737
- - **修掉一个旧 bug**:`flowOf` 里的流年斗君此前用 `chart.lunar.month`(已是换算后的月)再按 `leapAsNext` 加一次月,闰月 + `leapAsNext` 会多推一个月。现在起盘时只换一次,流月/流日/流时全部直接读换算结果。
738
- - **边界**:闰十二月十六起回绕到正月只换月序、不老一岁(闰腊月极罕见,明写不猜);1–15/16–30 的分界按通行「月中」,不提供逐日自由配置;不引入参考项目的其余九类流派开关(庚年四化变体、亮度流派、安天马/天空/截空等),留作后续。
739
- - **测试**:新增 `test/ziwei-leap.test.mjs`(44 条)——2020 闰四月的初十/十五/十六/廿一四个边界、三档口径函数与默认/别名/未知值回落、起盘月与命宫紫微斗君逐项对照、前半月 split 与 prev 同盘、`leapAsNext` 与 `next` 等价、斗君只换一次月、非闰月三档排出同一张盘、compute 透传与摘要/面板文案。**85 个测试文件 / 3084 条断言**,七道闸全绿。
740
-
741
- ## 0.41.0(已并入 0.46.5)
742
-
743
- 起名补上一直被写在「不做」里的两层:**五格剖象**(天格/人格/地格/外格/总格 + 81 数理 + 三才)与**音韵检查**。此前 README 明写「不做五格(需康熙字典笔画)与音韵」,等于把最常被问的两件事推给用户;这一轮把笔画与读音数据补全,再按通行算法落地。
744
-
745
- - **数据层**(新增 `engine/name-data.js`):391 个用字逐字补**拼音、声调、康熙笔画**(按繁体字形与偏旁本字计:华→華14、马→馬10、静→静16、涛→濤18、灵→靈24、兰→蘭23、丰→豐18、书→書10、画→畫12、云→雲12、风→風9、阳→陽17;氵→水4、艹→艸6、辶→辵7、阝左→阜8、阝右→邑7);单姓笔画表约 120 个(王4/李7/张11/刘15/陈16/罗20/郑19),复姓 13 个逐字存(欧阳 15/17、司马 5/10、夏侯 10/9…);81 数理取通行本,分吉/半吉/凶三档。数据与字库由测试逐条对齐——391 条一一对应,多一个字少一个字都会红。
746
- - **五格**(`engine/name.js` 新增 `wuge`):单姓双名 天格=姓+1、人格=姓末+名首、地格=名两字和、外格=总−人+1、总格=全部;单姓单名 地格=名+1、**外格固定 2**(没有「外侧」,通行本记 2,不是 1);复姓 天格=两字和、外格=总−人+1(等价于复姓单名的「姓首字+1」)。数理超 81 按 −80 回绕(104→24),三才取天/人/地个位对五行,再按生克给一句「一路相生 / 相连相克 / 吉凶各派看法不一」,不折算分数。
747
- - **缺笔画不半算**:任一字查不到康熙笔画,整体返回 `available:false` 并点名是哪个字,提示用 `strokeOverrides`(逐字)或 `surnameStrokes`(按姓)补;补进来的字在结果与面板里都标「用户指定」。姓超两字、姓不在表、只给名不给姓,都走同一条「算不了」的路,不拿简体笔画或猜测顶上。
748
- - **音韵**(新增 `phonetics`):只报可数的事实——全名同调、相邻同声母、相邻同韵母、相邻同音(叠字),再按条数判「顺口 / 略拗 / 拗口」。声母先切 zh/ch/sh,y/w 按拼写当声母。**不做语义谐音**(需要词库),摘要与注释都写明「谐音、方言读法还得自己读三遍」。
749
- - **排序而非判定**:生成候选名把五格格数当第三顺位(合喜用 → 两字异行 → 五格 → 性别倾向 → 字库序),注释写清「是排序不是吉名判定」;姓的笔画不在表里时这一轮不按五格排序,也不伪造。
750
- - **四处可见**:摘要各加一行【五格】【音韵】;面板新增五格格阵(5 列,吉/半吉/凶各配色)、笔画行(用户指定标「(指定)」)、三才行与音韵行(拼音+调、声调序列、水平徽标、逐条问题),算不了时显示原因而不是空白;生成候选的每个名字带「五格 N/5 吉」与音韵水平 chip。
751
- - **顺手修掉一处静默丢参**:页面上「评名字」虽然显示出生日期,`src/web-ui.js` 与 `src/app.js` 却在提交前 `delete args.datetime`,于是填了生辰也永远得到「给出生年月日才能判断」;现在生辰填了就传、空着才删,评估能按喜用判,面板里的八字行也随之出现。
752
- - **测试**:新增 `test/name-wuge.test.mjs`(103 条)——数据完整性(读音表与字库双向零差集、声调 1–4、笔画 1–40、拼音正则、81 条数理档位)、康熙锚点(静16/涛18/灵24/兰23/丰18/书10/画12/云12/风9/阳17 等 16 字与 7 个姓)、81 回绕、四类姓氏结构的五格数与吉凶、三才、缺笔画/超长姓/无名的落点、笔画覆盖与来源标注、音韵四类问题与顺口反例(王沐宸)、compute 接线与面板渲染,以及两处入口不再丢生辰。**84 个测试文件 / 3040 条断言**,七道闸全绿。
753
- - **边界**:81 数理各派对少数数取法有出入,按通行本取一套;五格只是传统数理游戏,不参与喜用判定,也不改结论。
754
-
755
- ## 0.40.0(已并入 0.46.5)
756
-
757
- 六爻的伏神补上「出伏条件」:飞伏生克与月建日辰并列摆出,归成四档,只判条件、不出应期。
758
-
759
- - **缺口在哪**:知识卡 `liuyao-fushen` 一直写着伏神看「日月生扶」,引擎却只算飞伏生克(飞生伏 / 伏生飞 / 飞克伏 / 伏克飞 / 比和)——月建、日辰从未落到伏神那一爻上。卡上是口径、盘上没有实现,这一轮把这一层补上。
760
- - **四档判定**(`engine/liuyao.js` 新增 `fushenAccess`,挂 `result.fushenAccess`):先并列两栏——助(飞生伏、伏克飞、日辰生、日辰比和、月建旺、月建相)与压(飞克伏、日辰克、月破);有助无压为「可出」、有助有压为「有助有压」、有压无助为「受压难出」、两者都无为「未得助」;没有飞伏关系时记「飞伏未知」,不猜。
761
- - **四处可见**:摘要单列「伏神出伏:第2爻可出」;解析在飞伏段后逐条写该爻的月建(五行、五态、是否月破)、日辰(五行、五关系)与助压明细;白话按档位补一句(「出得来」是条件、不等于马上应验);面板在旺衰 chip 下单列一排(可出绿,有助有压 / 受压难出赭)。
762
- - **口径与边界**:四档只并列条件,不排「飞伏与日月谁先谁后」的各家优先级;月破算压、伏神旬空只标出而不并入档位,都是明写的取法,不假装是共识。**应期仍未做**——这一层只回答「现在出不出得来」,不给具体日期;`docs/知识扩展与待核实清单.md` 的四·3 与文末注同步写明「条件是条件、应期另算」。
763
- - **测试**:新增 `test/liuyao-chufu.test.mjs`(53 条)——用独立的五行生克与相冲表复算 64 卦 × 4 个询问方向 × 12 个月 × 12 日 = 6,048 组,要求逐组零不符、四档都出现、四种真实飞伏关系都覆盖;四条从真实盘里挑的边界(地雷复·学业 寅卯「可出」、亥卯「有助有压」、地火明夷·财 子子「受压难出」、地山谦·财 午辰「未得助」);缺月建只看日辰、飞伏关系未知、伏神旬空只标不改档、传 null 不抛四条兜底;摘要/解析/白话/面板四层可见、旧结果兼容、断言输出里没有应期字段。统计 **83 个测试文件 / 2937 条断言**,七道闸全绿。
764
-
765
- ## 0.39.0(已并入 0.46.5)
766
-
767
- 首屏从「19 个 tab 平铺」改成按目的分三组,并保留一键切回平铺。此前第一次来的人得先猜「梅花」「称骨」是什么;现在按「问一件事 / 看一个人 / 查日子」分组,每项带一句白话。同一轮还改了「问进对话」的提问模板:原来它只约束证据与口气,模型答出来是一串带引用的术语流,读的人不知道这张盘在说什么。
768
-
769
- - **三组入口**(`tools/build-html.mjs`):问一件事(六爻/梅花/塔罗/奇门/六壬/小六壬)、看一个人(八字/紫微/合盘/人格/称骨/数字/人生K)、查日子(黄历/择日/农历/星座/风水/起名)——19 项一个不落,顺序按用途重排,不按引擎模块排。
770
- - **每项一句白话**:「摇六次,问一件事」「四柱看一生格局」「挑个办事的好日子」,不用先懂术语再点。
771
- - **最近用过**(`src/web-ui.js`):只记入口名与时间,最多 3 条,存 `mp.recent.tabs`;点入口、点起卦/排盘、人格问卷提交时记录,首屏默认 tab 不记;`localStorage` 读写都包 try/catch,隐私模式下只是不记,不影响使用;读回的值先过「当前页面真实入口」白名单,不直接拼进选择器。
772
- - **平铺回退**:19 个 tab 原样保留在页面上,右上角「分组 / 平铺」一键切换并记住选择(`mp.first.view`),旧用户的肌肉记忆不受影响。
773
- - **手机端**:每组先露 4 项,其余折在「还有 N 个」后面(`nth-child(n+5)` + `.open`),三组铺完不再把表单推到第二屏以下;桌面三列、中屏一列。
774
- - **样式**:卡片沿用纸色 + 朱红(选中项实心),深色下文字反色;打印时首屏分组、视图开关与 tab 条一律不打印,纸面仍是「抬头 + 盘面 + 解读」。
775
- - **追问读不懂**(`engine/followup.js`、`test/ask-prompt.test.mjs`):此前「回答要求」只有三条——引到具体柱/宫/爻、没依据就说看不出来、别给绝对断言。这三条只管**证据**与**口气**,不管**可读性**,于是照它答出来的东西是一串带引用的术语流:知道「甲有问题、乙有问题」,却不知道这张盘到底在说什么。现在模板先交代一句「读者不懂命理」,再给一套骨架:**开头一句不用术语的结论**(只读这句也该有收获)→ 判断**最多两条、按重要性排序**,每条分 `盘面|白话|倾向|边界` 四行(盘面只引字段不掺解释;白话把上一行的术语当场翻掉,一个词只翻一次、不连续堆三个以上;倾向用「更可能……」讲清现实含义;边界写清何时不成立,盘面没给的直接写「这盘里看不出来」)→ 收尾一句「**如果只记一件事**」,给可核对、可动手的观察点并点明它出自哪条依据。`调候 / 化气 / 通关 / 空亡 / 争合` 单独点名要求落地;「格局很好」「运程不顺」这类没有信息的空话禁掉。
776
- - **默认问法也改口**:空问题时原来问「请先总览这张盘」,而「总览」本身就在邀请逐字段复述——模型当然照着摘要念一遍。改成「先用一句白话讲清这张盘的主线,再指出最值得注意的一两处,并说明每处的具体依据」。
777
- - **固定骨架有长度上限**:抬头 + 回答要求约 520 字,不随 `maxChars` 变;测试里那条「固定骨架本身不超过 900 字」专门盯它别长成小作文。顺带修掉一条会误报的旧断言——原来写「整段提问 < 800 字」,骨架一长就红,现在拆成「摘要正文真的截到 maxChars」与「骨架另有上限」两条,各盯各的。
778
- - **测试**:新增 `test/first-screen.test.mjs`(44 条)——三组名称与顺序、19 项与平铺集合逐一对齐、每项都有白话、记录时机(入口/主按钮/问卷)、存储上限与去重、读写失败降级、手机折叠与 aria、两套入口共用 `activate`、深色反色与打印隐藏。其中 `.recent[hidden]` 一条专盯「`display:flex` 盖掉 `[hidden]`」——首版就踩了,没记录时页头挂着一个空的「最近用过」。`test/ask-prompt.test.mjs` 由 46 条增至 54 条(骨架四行齐全、无术语结论、难词点名、收尾句、空话黑名单、默认问法改口)。统计 **83 个测试文件 / 2937 条断言**,七道闸全绿。
779
-
780
- ## 0.38.2(已发布 2026-10-29)
781
-
782
- 紫微格局修掉三处「写得像实现了、其实永远不成立」的判定:夹局的方向、羊陀夹忌、刑囚夹印;顺手把 34 条目录从 README 的 31 条补全,并用独立谓词逐条钉死。
783
-
784
- - **夹局不分左右**(`engine/ziwei.js` 的 `jia`):旧写法只认「A 在命宫前一宫、B 在后一宫」这一种顺序,但「夹」只要求两星分居命宫前后。实测 69,120 张盘:**昌曲夹命 0/8、羊陀夹命 0/1,474 从未命中**,日月夹命(237:231)、左右夹命(470:457)、魁钺夹命(283:292)各漏约一半。改为两向都认;`test/ziwei-patterns.test.mjs` 用镜像方向的真实盘(1955-01-02、1955-06-22、1956-02-14 等)钉住。
785
- - **羊陀夹忌**:擎羊恒在禄存 +1、陀罗恒在禄存 −1,两星只能夹**禄存**那一宫;旧判据要求「化忌两侧是羊陀」,几何上不可能(1,553 张符合的盘一次都没报)。改为「化忌与禄存同宫」,证据文本写明化忌落在哪一支。
786
- - **刑囚夹印**:廉贞与天相永远隔偶数宫,字面上的「廉贞、擎羊夹天相」同样不成立(17,568 张盘两向皆零)。按通行说法改为「廉贞天相同**守命宫**于子午、擎羊同宫」——源文说的是「守命」,所以判的是命宫那一宫,廉相羊同宫在别的宫位不报;evidence 写明三颗星同守哪一宫;命宫卯酉、廉贞天相对照遇擎羊的变体未纳入,写进 README 口径。三条来源:知乎「刑囚夹印」、sohu 格局文、ziwei-yun「天相不可能被廉贞和擎羊二星所夹」。
787
- - **34 条目录补齐**:README 原列 31 条,且把 武贪同行、火贪铃贪 归在吉格(引擎一直是中性)、`双禄交流 / 命无正曜 / 杀破狼` 完全没写。现按引擎口径分三组列出(吉 20 / 中性 5 / 忌 9),`PATTERN_TONE` 改为导出供测试比对;README 与目录的一致性由测试直接解析 README 断言。
788
- - **结构统计补中性**:`patternSummary` 增 `neutral`,摘要行改成「吉格 N、中性 K、忌格 M」——此前中性格计入 count 却不出现在统计里,count 会大于两档之和。
789
- - **不新增能力、不动知识库**:知识库仍 47 条(本轮是判定口径修正,不是新规则);格局仍只描述结构、不折吉凶分数。
790
- - **测试**:新增 `test/ziwei-patterns.test.mjs`(79 条)——34 条目录与 README 三组逐名对齐;312 张盘 × 34 条用独立谓词(只读星位与四化,不调引擎判定)复算,要求每条「零不符且至少命中一次」,专门防死规则;夹局镜像方向、羊陀夹命 ⇔ 禄存守命、羊陀夹忌 ⇔ 化忌同禄存、刑囚夹印守命(含「非命宫同宫不报」反向盘)、摘要计数与确定性各自钉住。故意把 `jia` 改回有序写法时该文件 11 条变红。统计 **81 个测试文件 / 2832 条断言**,七道闸全绿。
791
-
792
- ## 0.38.1(已并入 0.38.2)
793
-
794
- 古籍库补上《子平真诠》论格局成败的两章,并把「用神总纲」一位改成按盘取;顺手修掉 why 里拼出「论论财」的旧文案。
795
-
796
- - **两条原文**(`engine/classics.js`):`zp-chengbai`(九、论用神成败救应,「成中有败,必是带忌;败中有成,全凭救应」)与 `zp-bianhua`(十、论用神变化,「藏庚透壬,则化为财。凡此之类皆用神之变化也」),均照录中华典藏网 53629 / 53630,白话自撰。
797
- - **为什么是这两章**:0.37.0 起古籍节覆盖了「月令格 × 两书对照」与「调候」,但化气格只剩气候与总纲,组合(官印相生、伤官见官等)没有任何原文可读——这两章正是判「化气成不成」「成格有没有带忌」的出处。
798
- - **总纲位三选一,不另加位次**:`classicsFor` 的第五条仍是「用神总纲」位——有化气格取「论用神变化」,见组合取「论用神成败救应」,其余取「论用神」通用总纲。上限没有从 5 放宽,也没有让泛论挤掉针对这张盘的话;同盘同时有化气与组合时取「变化」,why 写明取舍。
799
- - **文案 bug**:此前 why 用 `${书名}论${章名}` 拼,而章名本身已带「论」,实际输出成「子平真诠论论财」「三命通会论论正财」。改为「书名「章名」一条 / 另取」,章节标题去掉序号与开头的「论」;测试加「why 不出现论论」的断言。
800
- - **知识库 47 条**:新增 `bazi-geju-chengbai`(成中带忌、败中有救)与 `bazi-huagi-bianhua`(月令藏干与合局改变取用),均标 `variant`——成格条件、化气成立条件各家宽严不一,只并列原文与方向,不逐盘判成破。`docs/知识扩展与待核实清单.md` 的条数、统计与注记同步;顺手把上一轮注记里写错的版本号 0.37.2 改回 0.38.0。
801
- - **口径边界**:专旺格、从格仍没有对应的单章原文(三书里没有可整段照录的专章),不硬凑;古籍节仍只负责「书上怎么说」,不把原文折算成吉凶分数。
802
- - **测试**:`test/classic-quotes.test.mjs` 新增 13 条(两章原文抽检与典藏网出处、why 无双「论」、三选一互斥、1996 盘取「变化」、化气/组合/无特格三种落点);`test/sanming.test.mjs` 新增 7 条(总纲换条后仍保住两书对照、两张知识卡的出处与「不当断语」口径)。统计 **80 个测试文件 / 2753 条断言**,七道闸全绿。
803
-
804
- ## 0.38.0(已并入 0.38.2)
805
-
806
- 补上知识卡里已经写了、引擎却一直没做的一层:**岁运并临与伏吟反吟的逐年提示**。此前 `bazi-suiyun` 卡说「只作变动提示」,但盘面里没有任何地方标出是哪一年,等于只有口径、没有实现。
807
-
808
- - **四类信号**(`engine/bazi.js` 给每条流年加 `suiyun`):**岁运并临**(当值大运与流年干支相同)、**运年反吟**(大运与流年天克地冲)、**流年伏吟**(流年与年/月/日/时柱干支相同)、**流年反吟**(流年与某柱天克地冲)。每条信号带 `type` / `target` / `detail`,另给 `note` 写明口径。
809
- - **当值大运怎么取**:流年按立春起算,取与「该年立春到次年立春」区间相交的大运;交运落在这一年里时,前后两步都在本年当过值,两条并列。没有用虚岁近似,也不把交运日抹平。
810
- - **天克地冲的判据**:天干相克 **且** 地支相冲,缺一不算。例如丙子年对丙午年柱是同干相冲,不标反吟;这条单独在测试里构造验证。
811
- - **口径与边界**:只标干支重复与对冲,不折分数、不判吉凶——「岁运并临主大凶」一说不采,摘要与解析都写明「只标变动,仍看该年是否动到用神」。大运与原局之间的伏吟反吟未逐年标,四柱十神的引化也未叠入;起运前只有流年这一侧能成立。
812
- - **四处可见**:摘要加一行「岁运提示(只标干支变动,不判吉凶):2030庚戌 岁运并临;…」;解析新增「岁运提示」节,逐年写清当值大运与每条的出处;白话只在最近一个命中处补一句「变化感强一点,不是好消息也不是坏消息」;面板在流年 chip 下方单列一排提示,chip 悬停给逐条依据。旧结果(没有 `suiyun` 字段)照常渲染,解析退回「近十年没有」的保守说法。
813
- - **账面口径修正**(`docs/知识扩展与待核实清单.md`):知识库实际已是 45 条(诸家一致 15 / 各家有异说 29 / 待核实 1),清单头部还写着 42 条、统计还停在 15/27/1,一并改对;「岁运并临吉凶」一行补上「已落引擎与界面」。
814
- - **测试**:新增 `test/suiyun.test.mjs`(102 条)——不复用引擎判定,按「月柱干支顺逆推八步」与「立春区间相交」两套独立写法复算 10 张盘 × 10 年;扫描全部样本核四类信号与事实一致(并临必然同干支、反吟必然天克地冲、伏吟必然同柱);构造同干相冲(丙子 vs 丙午)不算反吟、起运前无大运、年内交运两步并列三条边界;钉住确定性、摘要/解析/白话/面板四处可见、旧结果兼容与知识卡口径。统计 **80 个测试文件 / 2733 条断言**,七道闸全绿。
815
-
816
- ## 0.37.1(已并入 0.38.2)
817
-
818
- 界面深修一轮,重点在窄屏:19 个 tab 不再吃掉首屏,两列表单不再被按钮挤成 134px;六爻的化进/化退补上力重。
819
-
820
- - **桌面抬头改竖排**(`tools/build-html.mjs`):品牌一行、tab 条一行。tab 从右对齐的 flex 换行改为 `repeat(auto-fit,minmax(74px,1fr))` 等宽网格,每格同宽、末行左对齐,不再出现「起名 人格」两项孤零零挂在右边、与上一行错开半个身位。
821
- - **窄屏 tab 改单行横滑**:3 列网格是为六个 tab 写的,tab 涨到 19 个后要占七行(约 340px),首屏只剩输入框。改回单行横滑,44px 触摸目标、`scrollbar-width:none` + `::-webkit-scrollbar{display:none}` 藏掉滚动条、首尾各留 12px 呼吸位;切到靠后的 tab 时 `scrollTabIntoView()` 把当前项滚到可视区中间(`prefers-reduced-motion` 下用瞬时跳转),避免「页面变了、高亮停在屏幕外」。
822
- - **窄屏表单两列修好**:根因是 `.go{grid-column:4}`、`.go.ghost{grid-column:3}` 写死给桌面四列,窄屏两列时这两条会生成第 3、4 列隐式 auto 轨道,把两个正文列挤到 134px,性别与按钮全被压扁。窄屏改为「看示例/排盘」分别落在第 1、2 列,性别与出生地各占整行,三个勾选项两两成对,收尾不再留空格。
823
- - **人格页重做**(`src/panel-kit.js`):结果卡原本是「四行细条 + 段落堆叠」,字小、无层级;现在按「类型抬头(大字类型码 + 名称/关键词 + 已答题数)→ 四维瓦片(双极字母 + 取值条 + 一句取向)→ 一句 → 优势/留意(绿/赭左线两张卡)→ 认知功能链(主导高亮)→ 工作/关系/学习/课题分节」分层。问卷态改成两列编号清单,桌面一眼扫完 24 题。同时把卡片抬头从 `<header>` 改成 `<div>`:页面级 `header{flex-direction:column}` 会把卡片抬头也压成竖排。
824
- - **顶层卡片没拿到调色板**(根因):变量块只挂在 `.pp,.mp-it` 上,而人格、黄历、称骨、人生 K 线、起名、速查这些卡片是直接插进 `#out` 的兄弟节点,`var(--band)`/`var(--card)` 全部失效 → 卡片退化成没底色、没边框的一堆字,这正是人格页看着丑的主因。变量块扩到 `.mp-al/.mp-cg/.mp-kline/.mp-mb/.mp-nm/.mp-quick` 等全部顶层卡片,`test/theme.test.mjs` 的断言同步改为「各顶层卡共享同一份变量」。
825
- - **人格问卷改分页问答**(`src/web-ui.js`、`src/app.js`、`tools/build-html.mjs`、`src/panel-kit.js`):原来是一个「24 题分数」文本框——让用户自己数 24 个数字,像在填表格。现在照常见在线测评的做法:**4 题一页、共 6 页**,每题 1–5 五格单选(完全不像 / 不太像 / 说不准 / 有点像 / 很像我),顶部有进度条与「第 n / 6 页 · 已答 x / 24」,底部是上一页 / 下一页 / 看结果 / 清空。答满 12 题就能先出结果(与引擎的 `E_INPUT` 门槛一致),不够时按钮禁用并写明还差几题;最后一页收起「下一页」,「看结果」与原主按钮二选一,不再重复两个入口。题目与 1–5 的说法都从引擎的问卷态取(`compute({system:'mbti'})`),前端不抄一份;答案按题序存成数组,末尾连着没答的去掉再交给 `answers`,中途未答的按引擎口径算「跳过」。独立页与 DSH 面板共用同一套分页交互(面板是 `MbtiQuiz` 组件);结果不进「最近排过」——答案没存进历史,重放还原不了问卷。
826
- - **人格页输入区**:问卷与日期无关,起卦日期/时刻在人格 tab 下隐藏(面板与独立页同步);问卷整行独占,窄屏下 5 格缩字体与内边距、按钮整行、44px 触摸目标;深色下选中格文字随强调色反色(与 tab / 主按钮同一口径)。
827
- - **桌面副本可同步**:新增 `--desktop` 与 `npm run build:desktop`,一次把同一份页面写到仓库根和 `~/Desktop/命理排盘.html`。桌面那份是手工拷的产物,源码一改就旧;现在构建就能刷新,页面左上角的版本徽标用来核对。README 三处说明同步更新。
828
- - **变量补全与观感**:共享变量块补齐 `--ink3/--fx/--sans/--kai`(此前多条形同虚设的字体、次级色规则因此失效)与 `--shadow`,深色另给一套;盘面卡片统一 12px 圆角与外阴影,古籍引文块改为左侧朱线 + 楷体悬挂缩进,`:focus-visible` 统一描边,结果入场只做一次轻微上浮并尊重 `prefers-reduced-motion`。
829
- - **六爻 · 化进/化退力重**(`engine/liuyao.js` 新增 `jinTuiPower`,挂 `result.jinTuiPower`):此前只标方向,现在把每条进退放回月建五态落档——旺相 → 后劲足(退则退得缓)、休囚 → 后劲有限(退则退得实)、死 → 进得虚、逢月破 → 月破失据、缺月建 → 只报趋势;旬空只标出、不改结论。摘要单列「进退力重」一行;解析在「卦体关系」里逐条写清月建、日辰与档位,「未纳入」删去该项(保留用神两现权重与伏神出伏应期);白话加一句;面板单列一排 chip(后劲足/退得缓绿、其余赭)。只给档位、不折加权分数,吉凶仍落在用神/忌神那一层判。
830
- - **测试**:`test/theme.test.mjs` 第五节改为「单行横滑 + 藏滚动条 + 首尾呼吸位 + 44px 触摸目标 + 切 tab 自动滚入视野 + 两列内按钮不生成额外轨道」,共 50 条断言;`test/mbti.test.mjs` 新增分页问卷一节(25 条)——离线页容器/样式、web-ui 的每页 4 题与 12 题门槛、事件委托、面板 `MbtiQuiz` 单跑校验(一页 4 题、刻度来自引擎、进度文案、按钮禁用与末页无「下一页」)、题面不复制到页面/面板;`test/liuyao-jintui.test.mjs` 新增第六节(27 条)——五态两行档位逐档复算、月破与缺月建两条边界、旬空只标不改结论、摘要/解析/白话/面板四处可见、旧结果不出该排。统计 **79 个测试文件 / 2631 条断言**,七道闸全绿。
831
-
832
- ## 0.37.0(已并入 0.38.2)
833
-
834
- 古籍库从两本扩到三本:接入《三命通会》卷五、卷六论十神七条,与《子平真诠》同一格局并列对照。
835
-
836
- - **三命通会 7 条**(`engine/classics.js` 登记 `sanming` 书目):论正官、论正财、论印绶、论食神、论伤官、论阳刃、论建禄各一条,原文照录通行本、逐条给典藏网章节链接,白话释义自撰。选条标准只有一条——与「格局取用」直接相关;神煞、女命、六亲等卷暂不录入。
837
- - **同格两书并列**:同一个「月令格」,先取《子平真诠》那一条(讲怎么用:顺逆、成败、救应),再取《三命通会》同格一条作对照(讲怎么取、怕什么)。例如正官格:子平真诠讲「刑冲破害为忌、生之护之为喜」,三命通会讲「六格之首,止许一位,多则不宜」。两条各给一句 why,不合并、不调和成一句断语。
838
- - **条数上限 5**:格局两条 + 气候两条 + 用神总纲一条,正好把默认位占满;未匹配到两书同格时只出一条,不硬凑。
839
- - **面板书名修正**(`src/panel-kit.js`):此前面板把非子平真诠的条目一律标成「滴天髓」,接入第三本后会串成「滴天髓·卷六·论正财」;改为按书目映射书名,`test/sanming.test.mjs` 钉住这一点。
840
- - **知识库**:新增 `bazi-sanming-duizhao`(两书分工:一重「用」、一重「取」与「忌」,并列而不合并),全库 **45 条**。
841
- - **口径**:只录与格局取用直接相关的七条,不声称覆盖全书;两书成书年代与流派不同,用语有出入,照录通行本、不做校勘改字,也不替两家调和。
842
- - **测试**:新增 `test/sanming.test.mjs`(40 条)——书目与七条完整性、原文逐字抽检、七格「子平在前、三命在后」的对照选取、why 文案、上限与去重、确定性与 limit、摘要/解释层/面板三处可见、知识卡。`test/classic-quotes.test.mjs` 同步改为三书、条目 ≥26、单盘取 2–5 条。统计 **79 个测试文件 / 2571 条断言**,七道闸全绿。
843
-
844
- ## 0.36.0(已并入 0.38.2)
845
-
846
- 把 `docs/知识扩展与待核实清单.md` 里登记的两处缺口补上:紫微的「三方四正一起飞」、六爻的「全卦逐爻旺衰」。0.35.x 的面板修复随这一版一起发。
847
-
848
- - **紫微 · 三方四正复合飞化**(`engine/ziwei.js` 新增 `flyComposite`,挂 `chart.flyComposite`):单宫飞化只回答「这一宫自己去找谁」,这一层把本宫、对宫与两个三合宫共四宫的宫干四化一起摊开——四宫各化禄权科忌,共 16 条,按落宫归堆,落到同一宫就是会照。四类会聚单独成型:**双忌会**(同宫收到 ≥2 个忌)、**禄忌同宫**(禄随忌走)、**三化以上会宫**、**自化**(宫干化出去又落回本宫)。摘要加【三方四正飞化】行(会聚标签 + 四化去向按宫去重);解析新增「三方四正飞化」节,写清哪几股力会到哪一宫;白话加一句「N 股力最后挤在 X 这件事上」;面板并排 chip,悬停给飞入清单。
849
- - **紫微 · 口径**:会聚判定只看「落在同一宫」这一条结构事实,不折分数、不断吉凶,也未叠大限流年四化;星未上盘时只记星、不记落宫(`to: null`)。三方四正四宫由命宫 +4/+8/+6 推得,与格局识别用的那一套同源。
850
- - **六爻 · 全卦逐爻旺衰**(`engine/liuyao.js` 新增 `hexagramStrength`,挂 `result.hexStrength`):与用神旺衰同一套判定(月令五态、日辰五关系、月破/暗动/冲空),区别只在不挑用神——六爻每一爻都给一次,世应、动爻、旬空另标,并给出五态分布 `counts`、最旺/最弱爻与世应各自的状态。
851
- - **六爻 · 不依赖用神**:此前旺衰只在取到用神时才算,没指定所问之事就一片空白;现在 `hexStrength` 在 `buildLiuyao` 之后独立计算,没给 `direction` 也能看整张卦的气。
852
- - **六爻 · 口径**:只报状态、不折分数;「未纳入」删去「全卦逐爻的月建旺衰」,保留化进化退的实际力重、用神两现取舍、伏神出伏应期三项。
853
- - **知识库**:新增 `ziwei-sanfang-fei`(复合飞化的会照取法与各家分歧)与 `liuyao-quanggu-shuai`(全卦旺衰与「用神只是一处落点」),并把 `ziwei-feixing` 的 note 从「未做完整飞星串连」更正为「串连与复合飞化已做、未叠大限流年」。全库 **44 条**。
854
- - **自我介绍与讨论群(只在仓库页)**:README 文末新增「关于:一个人做的插件,欢迎来聊」——写明这是个人作品、能力有限,欢迎就断法口径、神煞取法、解析措辞进群讨论,报 bug 请带输入与结果;`docs/assets/dsh-metaphysics-group*.png` 放群二维码。**不进插件运行时**:面板与离线页不加这条提示,市场条目与 `locale` 描述也只说能力、不说作者(提醒只出现一次,在仓库 README)。市场条目与 `locale` 另补齐了 0.35–0.36 两项新能力。
855
- - **测试**:新增 `test/ziwei-fly-triad.test.mjs`(44 条)与 `test/liuyao-hex-shuai.test.mjs`(53 条)——四化表与五态五关系都用另一套写法逐格复算(16 条飞化、12 卦 × 3 月 × 6 爻)、归堆与会聚独立过滤比对、60 张盘结构自洽且会聚非死规则、四种冲法构造验证、摘要/解析/白话/面板四处可见、旧结果兼容、确定性。统计 **78 个测试文件 / 2531 条断言**,七道闸全绿。
856
-
857
- ## 0.35.1(已并入 0.38.2)
858
-
859
- 修一个会让整个命理面板白屏的崩溃,并让它以后能自己把错误说出来。
860
-
861
- - **崩溃根因**(`src/app.js`):为了给「问进对话」记住上一张盘,加了一个 `useEffect` 去写 `LAST`,但它落在 `const [result, setResult] = useState(null)` **之前**;React 首渲时读依赖数组撞上 TDZ,抛 `ReferenceError: Cannot access 'result' before initialization`,整个面板渲染失败——桌面端看到的就是「侧栏有『命理』、点开一片空白」。已把该 effect 移到 `result` 声明之后。
862
- - **渲染兜底**(新增 `PanelGuard`,`React.Component` 的错误边界):面板里任何一层组件抛错时,把错误原文与前 14 行栈直接铺在面板上,并附「__PP / Engine / React / 版本」环境行——不再白屏,也不用开 devtools 才能报错。
863
- - **版本可见**:构建时把 `package.json` 的版本注入 `window.__MP_VER`,侧栏标题显示为「命理 v0.35.1」;`__ModuleLoader__.load` 的模块描述里也带 `version`。以后一眼能确认应用加载的是哪份构建。
864
- - 测试与闸门不变:**76 个测试文件 / 2434 条断言**,七道闸全绿。
865
-
866
- ## 0.35.0(已并入 0.38.2)
867
-
868
- 面板可以直接把提问送进对话窗了:排完盘点「问进对话」,这张盘的摘要和你的问题会变成一条正常的用户消息,由对话里的模型接着答。
869
-
870
- - **提问模板**(`engine/followup.js` 新增 `askPrompt`):四段——一句说明(不用重排盘)、`体系 / 所问` 两行、`——盘面摘要——`(取 `compute` 的 `summary`,超 3000 字截断并标「摘要已截断」)、`——回答要求——`(引到具体柱/宫/爻、没依据就说「这盘里看不出来」、不给绝对化断言)。只做文本组装,不调模型、不改盘,返回 `{text, question, system, label, chars, truncated}`。
871
- - **对话桥**(`src/app.js`):往会话作用域槽位 `conversation.input.right` 注册一个不画界面的组件,从 slot props 取 `inputActions`;点按钮时 `setDraft(text)` 写草稿再 `submit()`,走输入框正常的回车路径——有回合在跑时排队,不打断当前回答。桥没挂上(插件刚装、还没重启,或 Harness 改了槽位名)时退回复制剪贴板并提示,不报错。
872
- - **按钮位置**:结果卡下方的追问行,「追问」(本地按盘面字段直接答)旁边多一个「问进对话」,两者共用同一个问题输入框。
873
- - **离线页不动**:`命理排盘.html` 没有 Harness 对话窗,所以只有「追问」,不出现这个按钮。
874
- - 测试:新增 `test/ask-prompt.test.mjs`(46 条:字段结构、体系名翻译、问题原样带入、摘要截断与占位、六套体系各跑一遍、无绝对化表述、传 null 不抛、确定性);`test/client-bundle.test.mjs` 增加对话桥注册与「提问 → setDraft → submit」源码通路的断言(现在注册三个槽)。
875
- - 统计:**76 个测试文件 / 2431 条断言**(当时),七道闸全绿。
876
-
877
- # 更新记录
878
-
879
- 版本按「一组可感知的改动」发,README 与市场条目描述随能力同步。
880
-
881
- 0.23.0–0.33.0 都只提交在本地、没有单独发到 npm;这些内容随 **0.34.0** 一并发布。npm 上的 latest 从 0.22.0 直接跳到 0.34.0,`npm i dsh-metaphysics` 装到的就是这一版。
882
-
883
- 0.35.0–0.38.1 同样只提交在本地;这些内容随 **0.38.2** 一并发布(2026-10-29),npm 上的 latest 从 0.34.0 直接跳到 0.38.2。
884
-
885
- 0.39.0–0.46.4 同样只提交在本地;这些内容随 **0.46.5** 一并发布(2026-10-30),npm 上的 latest 从 0.38.2 直接跳到 0.46.5。
886
-
887
- 0.47.0–0.50.0 同样只提交在本地;这些内容随 **0.50.1** 一并发布(2026-10-30),npm 上的 latest 从 0.46.5 跳到 0.50.1。
888
-
889
- ## 0.34.0(已发布)
890
-
891
- 六爻补上**用神旺衰**:月建给这一段时令的气,日辰给当天的扶克。此前用神只算到「落在哪一爻、与卦体怎么对」,旺不旺一律写「仍要月建日辰」,等于把最关键的一半留白。
892
-
893
- - **月令五态**:爻五行与月支五行同气为旺、受月令生为相、生月令为休、克月令为囚、被月令克为死(`monthStateOf`)。
894
- - **日辰五关系**:站在爻这一边说——日辰生我为「日生」、克我为「日克」、同气为「比和」,反过来是我泄日辰(「泄」)或我耗日辰(「耗」)(`dayRelationOf`)。
895
- - **三种冲法分开命名**:月建冲爻为**月破**,日辰冲静爻为**暗动**,日辰冲旬空之爻为**冲空**,日辰冲动爻为**逢日辰冲**;不再混成一句「被冲」。
896
- - **月建从哪来**:给了 `datetime`(或 `asOf`)就按节气换月、与八字同源(复用奇门的 `buildSnapshot`)取月支;没给时间就不编月建,只报日辰那一半,摘要里也看不出凭空多出的月份。
897
- - **四处可见**:摘要加「用神旺衰:月建 午(火) 用神月建相 · 用神与日辰比和」;解析「用神落位与卦体」节加「时令对用神」段(逐爻写月建态与日辰关系、冲法);面板加一排旺衰 chip(旺/相/得日辰生用 ok 色,死/囚/月破/受日辰克/泄/耗用 warn 色);白话加一句「眼下这阵子对这件事是帮着的/不太帮忙/有帮有压」。
898
- - **口径**:这一层只报状态标签,不折成分数、不断成败;全卦逐爻的旺衰仍未做(现在只算到用神那几爻),化进化退叠上月建日辰后的实际力重也仍未做。
899
- - **知识库**:新增 `liuyao-yongshen-shuai`(variant)讲五态、五关系与三种冲法,note 写明各家对月破/暗动/冲空取法不完全一致。全库 **42 条**。
900
- - **发版工具**:新增 `tools/verify-publish.mjs` 与 `--verify-only` 模式——核对以「tarball 能下载、字节与 registry 记的 shasum 一致、关键文件在包里」为准,因为 npm 会先让版本条目可见、附件晚几分钟才落盘(0.34.0 发布时就撞上过这段空窗,`npm publish` 的成功字样并不作数)。
901
- - **测试**:新增 `test/liuyao-shuai.test.mjs`(52 条)——地支五行 12 支、月令五态与日辰关系各 144 格逐格用另一套写法复算、12 张静卦 × 3 个月建逐爻复算、月破/暗动/冲空/逢日辰冲四种冲法各自构造验证、标签次序、缺月建与缺用神的退化路径、摘要/解析/面板/白话四处可见、旧结果(无 `useGodStrength`)不炸、确定性。统计 **75 个测试文件 / 2379 条断言**(含发布核对工具的 35 条自测)。
902
-
903
- ## 0.33.0
904
-
905
- 奇门补上**天盘干的两层**:干对月令的旺衰,以及干与所落宫的生克。此前旺衰只算门与星,干只出现在击刑/入墓这类硬条件里,落宫关系(干与宫谁克谁)完全没说。
906
-
907
- - **干宫生克**:新增 `stemPalaceRelation(stem, palace)`(`engine/qimen.js`),只吃「天干五行 + 洛书宫五行」,输出 干克宫 / 宫克干 / 干生宫 / 宫生干 / 比和 五种,附五行与一句说明;与门宫关系(门迫、宫制门)并列,**各说各的、不折成一个分数**,两者同时成立时分别列出。
908
- - **干旺衰**:`STEM_ELEMENT`(甲乙木、丙丁火、戊己土、庚辛金、壬癸水)并入同一套旺相休囚死判定;每宫多 `stemElement` / `stemRelation` / `stemState` 三个字段,中五宫同样有(无门但干与星照算),汇总到 `states.stem`。
909
- - **三处可见**:摘要【旺衰】行改为「门 … 星 … 干 …」;解读「月令旺衰」段加入天盘干一行与「干宫的落宫关系另算:宫克干 9宫辛、2宫癸;干生宫 7宫己…」;面板事实表新增**「干旺衰」「干宫生克」两行**,九宫格每格底部补干宫关系与干旺衰小字。
910
- - **口径**:天盘干只认三奇六仪(甲隐于六仪、盘面不出现),所以干旺衰实际覆盖 9 个符号;干宫生克是「天盘干对地盘宫」,不是天盘干对地盘干的**十干克应**——后者 100 组仍未做(各家措辞不一,需先定底本)。
911
- - **知识库**:`qimen-wangshuai` 扩写为「门、星与天盘干」;新增 `qimen-gan-shengke`(variant)讲干宫五态与「不折分数」,note 写明各家取象宽窄不一、十干克应未做。全库 **41 条**(诸家一致 15 / 各家有异说 25 / 待核实 1)。
912
- - **测试**:新增 `test/qimen-gan.test.mjs`(53 条)——用天干五行与宫五行重推 10 干 × 9 宫 = 90 组全部复算;合成盘验五侧与缺参;扫 60 个真实盘逐宫核 `stemElement` / `stemRelation` / `stemState`(含中五宫),要求 9 个天盘干、五种干宫关系、五种状态都出现(防死表);`states.stem` 与逐宫一致;三处可见 + 转义;旧结果(无 stemState/stemRelation)不炸;确定性。统计 **73 个测试文件 / 2292 条断言**。
913
-
914
- ## 0.32.0
915
-
916
- 八字大运补上**交运时刻(日 / 时辰级)**——此前只有「几岁几月起运」,交运年份在边界处可能差一年内;清单里的 `bazi-dayun-jiaoqi` 从「待核实」转成「各家有异说」。
917
-
918
- - **口径**:三日折一年。交运时刻 = 出生时刻 + 「出生 → 起运那一侧节令」的真实天数 × 365.2422/3(≈121.7474)。这一条比例同时兑现古法三条换算——3 日折 1 年、1 日折 4 个月(≈121.75 天)、1 时辰折 10 日(≈10.15 天);顺排数到下一节、逆排数到上一节。
919
- - **每步大运**:在「同月同日同时刻」换,公历闰日(2 月 29 日交运)十年后退到 2 月 28 日;每步带 `fromDate` / `toDate`,八步首尾相接。
920
- - **结果字段**:`dayun.jiao = { at, jd, scaleDaysPerDay, yearDays, spanDays, from:{name,time}, frame, offsetMinutes, note }`,旧的 `dayun.startAge` 与 `toNextJieDays` 原样保留(向后兼容);交运时刻与四柱同口径(真太阳时盘上就是真太阳时,`frame` 写明)。
921
- - **三处可见**:摘要「大运:… 起运;交运 1998-08-08 02:51(平太阳时,距芒种 24.7197 天,三日折一年)」;解读「时间窗」节首行给交运时刻与换算说明,大运表新增**「交运」列**;面板运势曲线头部与页脚写交运时刻,大运 chip 的悬停标题带该步交运日期。
922
- - **知识库**:`bazi-dayun-jiaoqi` 由 todo 改写为 variant——讲清放大口径、同月同日同时刻换、闰日退位,并注明各家对「一年折几日」取法不一(本插件固定 365.2422 日,与按 360 日折算的流派会差一两天)。全库仍 40 条(诸家一致 15 / 各家有异说 24 / 待核实 1)。
923
- - **测试**:新增 `test/bazi-jiaoyun.test.mjs`(58 条)——比例与三条换算、用 `partsToJd` 独立复算偏移、顺逆取节令、八步相接与每步 10 年、闰日退位(1987-10-10 盘交运 1988-02-29 → 1998-02-28)、22 个盘的全日期合法性扫描、真太阳时口径、四处可见、旧结果兼容、确定性。`test/report.test.mjs` 的大运表断言改为按表头取列号(加列不再让它失败)。统计 **72 个测试文件 / 2239 条断言**。
924
-
925
- ## 0.31.0
926
-
927
- 新增第十九套体系:**十六型人格(mbti)**——一份 MBTI **风格**的 24 题问卷。这不是命理,是用户点名要的「isfp / infp 这种问答判断」;口径上单独写清它**不是官方 MBTI 量表**(题目、计分、常模都是自建的,不与任何商业量表对齐),结果只作自我参照。
928
-
929
- - 新模块 `engine/mbti.js`(纯 ESM、零依赖、确定性计算):`DIMENSIONS`(EI/SN/TF/JP 四维,各带两侧白话与平手侧 I/N/F/P)、`QUESTIONS`(24 题,四维各 6 题,左右交错)、`FUNCTION_STACKS`(16 型 → 四功能码)、`FUNCTIONS`(八种认知功能各一句)、`TYPES`(16 型文案:称号、关键词、一句话、3 条优势、2 条留意、工作/关系/学习/课题)、`mbtiPaper()`(发卷)、`buildMbti({ answers })`(计分)。
930
- - **计分**:每题净分 =(分数 − 3)× 侧向(题目的 `side` 是该题「像我」时的加分侧),维度净分大于 0 取左字母、小于 0 取右字母、= 0 按平手侧取并标「临界」;强度按「净分 / (答数 × 2)」分四档(临界 ≤12%、轻微 ≤30%、明显 ≤60%、很强)。跳过某题传 `null`(也接受 `''`)不计入分母,**至少答 12 题**才出口径;非数组或超过 24 个报 `E_INPUT`,分值不是 1–5 整数报 `E_RANGE`。
931
- - **三处可见**:`compute({ system:'mbti' })` 不给 `answers` 时先返回 24 道题与量表说明;给了就返回类型 + 四维强度 + 认知功能栈 + 工作/关系/学习/课题;摘要分节写【十六型人格】【四维】【优势】【留意】【课题】【认知功能】【工作】【关系】【学习】与末行口径声明。
932
- - **面板与独立页**:侧栏新增「人格」tab(`src/app.js`),独立页新增 `data-tab="mbti"` 与 `#for-mbti` 输入块(`tools/build-html.mjs`),两处都是「24 个分数(1–5,空格或逗号分隔;留空先发问卷)」一个输入框;结果由 `pp.mbtiHTML` 渲染成四维强度条 + 双栏优势/留意 + 认知功能 chips + 四段白话,问卷态则列 24 题清单。tab 从 18 个变 19 个,`test/standalone.test.mjs` 的 tab 清单断言同步。
933
- - **工具 schema**:`system` enum 与描述加入 `mbti`,新增 `answers` 参数(24 个 1–5 整数,可含 `null`);`locale/en.json` 与 `zh.json` 的体系数从十八/十套速查改为十九/十一套,并点名十六型人格。
934
- - **不进知识库**:十六型人格不属命理体系、也没接解读层(`interpret()` 不处理它),所以 `engine/interpret-knowledge.js` 仍是 40 条;它的口径声明写在结果自身的 `note` 与 README「精度与口径」里。
935
- - 测试 `test/mbti.test.mjs` 63 条:问卷结构(24 题、四维各 6 题、左右两侧题数相同、题号唯一、平手侧齐全);试卷模式;**四组样例 × 四维独立复算**(另写「左分 − 右分」实现核净分、取值与类型);强度四档边界;全左=ESTJ、全右=INFP、全 3 分按平手取 INFP;16 型全覆盖且每型文案齐全(3 优势 / 2 留意 / 四场景)、功能栈 4 个合法码;入参校验 8 类;跳题按维度扣减答数、整维跳过标「未作答」;摘要与面板三处可见、转义、旧结果不炸;确定性与「同维同侧换题序不改分」。统计 **71 个测试文件 / 2181 条断言**。
936
-
937
- ## 0.30.0(待发布)
938
-
939
- 六爻的**用神落位与卦体联动**:以前解释层只有一句「问工作看官鬼」,并没有真的把用神取出来,所以「用神持世」「用神化退」「用神在六冲卦」这些话都无从对上。现在用神会真的落到某一爻上,再与卦体、动变、旬空串起来看。
940
-
941
- - `engine/liuyao.js` 新增 `YONGSHEN_RULES`(七档取用)、`yongshenOf(result, { direction, gender, liuqin })`、`PURE_BY_PALACE`(宫 → 首卦,供伏神取用)、飞伏生克表 `WUXING_SAY`/`RELATION_LABEL`。
942
- - **取用口径**:求财与男命妻缘看妻财、工作职位考核看官鬼、文书合同学历看父母、健康以官鬼为病(子孙为医药)、出行以世爻为用、感情男看妻财女看官鬼;未指明所问之事则不取用神,只给提示,不硬凑。
943
- - **用神不上卦就取伏神**:回到本宫首卦(八纯卦)找同六亲的爻位,列出伏神与飞神,并按五行标出「飞生伏 / 伏生飞 / 飞克伏 / 伏克飞 / 比和」;首卦同一六亲两现时标「伏神两现」,两句都列出来、**不代选**,也不出出伏日期。
944
- - **与卦体联动**:六冲卦(主散)、六合卦(主成)、变六冲、变六合、内外卦伏吟、内外卦反吟(并注明来源是地支全冲还是八卦正对)、用神化进 / 化退、用神旬空、用神持世 / 临应 / 发动。标签始终挂「用神」二字,避免把全卦的动势误当成用神的处境。
945
- - **四处可见**:摘要新增 `用神:官鬼(工作、职位、考核)→ 2爻甲寅木(内卦)` 与 `用神联动:…`;解析在「卦体关系」之后新增「用神落位与卦体」节;面板在卦体 chips 之后加用神 chip 行;白话直答与整段白话各带一句「你问的这件事,在卦里对应第 2 爻」。
946
- - 知识库按实现重写 `liuyao-yongshen`(七档取用,settled)与 `liuyao-fushen`(伏神取法与两现不代选,variant+note),全库 **40 条**(15 诸家一致 / 23 异说 / 2 待核实)。
947
- - 测试 `test/liuyao-yongshen.test.mjs` 54 条:七档取用与感情分男女、出行用世;64 卦 × 5 档取用位置逐一核;伏神用 classics.json 里 **56 条带「缺爻」标注的卦例**对拍(伏神位必须等于本宫首卦同位,且与典籍原录的缺爻一致,100 处命中);飞伏生克方向独立按五行复算;卦体联动标签两侧都验;旬空两侧都验;摘要/解析/面板/白话四处可见;旧结果(无 `useGod`)不炸。统计 **70 个测试文件 / 2118 条断言**(当时)。
948
-
949
- ## 0.29.0(待发布)
950
-
951
- 紫微的**四化飞星串连**:宫干定四化、四化定落宫,再顺着这条化从落宫接着飞下去——把「命宫化忌进父母宫,父母宫又化忌进福德宫」这种逐宫传递,一路跟到它绕回来为止。
952
-
953
- - `engine/ziwei.js` 新增 `FLY_TYPES`、`flyStarOf(stem, type)`、`flyStars(chart)`、`flyChain(chart, { from, type, maxSteps })`、`flyChains(chart, { from })`;`buildZiwei()` 结果新增 `fly`(12 宫 × 四化 = 48 条飞化)与 `flyChains`(命宫出发的四支链)。
954
- - **两条口径**:①飞化只认宫干四化表(中州派表,庚干作太阳禄、武曲权、太阴科、天同忌),星落在哪一宫就写哪一宫,落回本宫记**自化**;②串连只跟**同一支化**逐宫跳,最多 12 步,回到走过的宫即记「成环」。因为「一个宫 → 一个宫」是函数映射,完整盘上每条链必然成环——实测链长为 1、3、4、5、6 步。
955
- - **三处可见**:摘要新增 `【命宫飞星】禄:命宫→官禄→父母→命宫(成环)…`;解析在「四化」之后新增「四化飞星」节,逐跳写 `命宫(丙)化忌廉贞→父母`、点出成环与自化,并声明「这一层只描方向与牵引,不断吉凶」;面板在四化 chips 之后加四支飞化 chip(`飞忌 命→父母→福德→财帛→交友→父母↺`,title 给逐跳依据)。白话直答也带一句「这几件事是连着转的」。
956
- - 知识库新增 2 条:`ziwei-feixing`(飞星派 vs 三合派、庚干异说,标 `variant`)、`ziwei-jichuanji`(串连走几跳、借对宫飞化各派不一,本插件走满 12 宫或成环即停,标 `variant`)。
957
- - 测试 `test/ziwei-fly.test.mjs` 42 条:测试内**独立录入**十天干四化表核 40 条;固定盘 48 条飞化的落宫/地支/自化与盘面 `selfHua` 两处互证;四支链逐步核「宫干 → 化星 → 落宫」与首尾相接;换一张盘核 12 宫出发全成环;固定盘回归快照(禄/权/科/忌四条路径逐字);摘要/解读/白话/面板三处可见;旧结果(缺 `fly`)不炸。统计 **69 个测试文件 / 2064 条断言**。
958
-
959
- ## 0.28.0(待发布)
960
-
961
- 离线单文件页 `命理排盘.html` 改为**随 npm 包分发**:之前它只是本地产物(默认写到包目录之外),订阅者装完插件手里并没有这份页面;现在它就在包里。
962
-
963
- - `tools/build-html.mjs` 的默认输出从 `path.resolve(root, '..', '命理排盘.html')` 改为 `path.resolve(root, '命理排盘.html')`——写进包根,`--out <路径>` 仍可另存(例如同步桌面那份手边的拷贝)。
964
- - `package.json` 的 `files` 增加 `命理排盘.html`,`exports` 增加 `"./命理排盘.html"`:既会被 npm 发出去,也能用 `require.resolve('dsh-metaphysics/命理排盘.html')` 拿到绝对路径。
965
- - 重新生成一份进包:`node tools/build-html.mjs` → 689907 字符 / 887419 字节(UTF-8),单文件零依赖,十八个 tab 齐全。外部 URL 只有三类:仓库链接、典籍出处链接(点开才联网)、可选的地理编码在线查询。
966
- - **介绍同步**:`README.md` 特性表加「离线单文件页(随包分发)」并新增小节,写明包内路径、`require.resolve` 用法、与面板同源同版本、以及只在这两处会联网;`SUBMIT.md` 与市场条目 `submit/xuanfu-web__dsh-metaphysics.yml` 的 en/zh 描述都补上这一句。
967
- - 测试 `test/standalone.test.mjs` 新增 4 条:`files` 里带离线页、`exports` 能解析、**仓库根那份与 `page()` 逐字相同**(防止改了源码忘了重建、把旧页面发给订阅者)、构建默认目标在包根而不是包外。统计 **68 个测试文件 / 2022 条断言**。
968
-
969
- ## 0.27.0(待发布)
970
-
971
- 六爻的「化进神 / 化退神」:动爻变出的地支与本爻同五行、且在顺次上往前一步,这一爻就有后劲;倒着退一步则渐消。
972
-
973
- - `engine/liuyao.js` 新增 `jinTuiOf(from, to)`、常量 `JIN_TUI_PAIRS` 与 `JIN_OF`/`TUI_OF` 两张单向表;`bodyRelations()` 返回值新增 `jinTui: [{ position, from, to, type: '进'|'退' }]`。
974
- - **判定口径**:八对顺次——木 寅→卯、火 巳→午、金 申→酉、水 亥→子,土四支成环 丑→辰→未→戌→丑。同五行但不相邻(如寅→辰)不算;同支不变不算;跨五行不算。
975
- - `bodyLabels()` 在爻伏吟 / 爻反吟之后追加「化进神 5、6」「化退神 4」(进在前),面板 / 摘要 / 解读 / 白话读同一份标签。
976
- - **三处可见**:摘要「卦体:」行带化进 / 化退;「解读」的「卦体关系」节逐爻写清本支→变支并声明「同一爻化进,也得看用神旺不旺」;面板 chip 化进用 ok 色、化退用 warn 色。
977
- - 知识库新增 2 条:`liuyao-jintui`(settled,机制与八对表)、`liuyao-jintui-yong`(variant,讲用神化进为得力 / 忌神化进为患加剧,并注明土之进退次序各家不完全一致)。
978
- - 测试新增 `test/liuyao-jintui.test.mjs` 49 条:五行分组独立生成八对进神再与 12×12 全枚举重算比对、12 条语料卦例逐字对拍、静卦与跨五行不硬凑、摘要 / 面板 chip / 旧结果兼容。`test/liuyao-body.test.mjs` 的 23 条对拍改为只核卦体标签(化进 / 化退另由新测试负责)。统计 **68 个测试文件 / 2018 条断言**。
979
-
980
- ## 0.26.0(当时)
981
-
982
- 奇门的「月令旺衰」:八门与九星各自对月支五行分旺、相、休、囚、死,回答「这个符号当下有多少气」。
983
-
984
- - `engine/qimen.js` 新增 `monthState(element, monthElement)`、`monthElementOf(branch)`、`groupByState(items, monthElement)` 与只读表 `QIMEN_STATE_TABLES`(门/星/月支三张五行表)。
985
- - **判定口径**:与月令同气为旺、月令所生为相、生月令为休、克月令为囚、被月令克为死。以月支五行为尺(寅卯木、巳午火、申酉金、亥子水、辰戌丑未土),八门与九星各用自己的五行去对;月令取四柱月支,与节气月同一口径。
986
- - 排盘结果新增 `month: { branch, element }` 与 `states: { gate: {旺,相,休,囚,死}, star: … }`;每个宫多 `gateState` / `starState`(中五宫只有星的)。
987
- - **三处可见**:摘要多一行「【旺衰】月令 午(火) 门 旺 景门 相 死门/生门 …」;「解读」新增「月令旺衰」节,列出五态归属、五态定义,并声明这一层只说明力量强弱、不折吉凶(门旺而宫克门仍受制);面板奇门盘下方键值表加「月令」「门旺衰」「星旺衰」三行。
988
- - 知识库新增 2 条(`qimen-wangshuai` 为 settled,`qimen-wangshuai-yong` 标 variant 并写明「按时令/落宫论」的流派差异)。
989
- - 测试新增 `test/qimen-wangshuai.test.mjs` 36 条:三张表与传世说法对拍、五行对月令的组合全部用测试内独立生克表重算、归堆不重不漏、60 个真实盘逐宫核对门/星状态与月令来源、五态在真实盘里都能出现、摘要/解读/面板三处接线、旧结果缺字段不炸。统计 **67 个测试文件 / 1969 条断言**。
990
-
991
- ## 0.25.0(当时)
992
-
993
- 奇门的「宫位条件」补齐两块:六仪击刑、三奇入墓——和门迫一样,都是天盘干落到某个宫就成立的硬条件,只作条件、不打分。
994
-
995
- - `engine/qimen.js` 新增 `jiXingOf()` / `ruMuOf()` 与只读表 `QIMEN_CONDITION_TABLES`,排盘结果多一个 `conditions: { jiXing, ruMu }`(每项 `{palace, stem, zhi, basis}`)。
996
- - **判定口径**:
997
- - 击刑按地支相刑定宫:甲子戊震三(子刑卯)、甲戌己坤二(戌刑未)、甲申庚艮八(申刑寅)、甲午辛离九(午自刑)、甲辰壬巽四(辰自刑)、甲寅癸巽四(寅刑巳)。只判天盘六仪,地盘不计。
998
- - 入墓按五行墓库定宫:乙木墓未(坤二)、丙丁火墓戌(乾六)。只判天盘三奇;六仪、八门、九星的入墓说法不统一,留白。
999
- - **三处可见**:摘要多一行「【宫位条件】击刑 … 入墓 …」;「解读」的「宫位条件」段把门迫/宫制门/击刑/入墓并列,每条带依据(如「甲午辛,午自刑」),并声明不自动等同于用神受制;面板奇门盘下方键值表加「击刑」「入墓」两行。
1000
- - 知识库新增 2 条(`qimen-jixing` / `qimen-rumu`,均标 variant 并写明流派差异)。
1001
- - 测试新增 `test/qimen-rules.test.mjs` 49 条:表与「地支相刑 → 该支所在宫」的独立推导逐条对拍、合成宫位验成立/不成立两侧、60 个真实盘扫查(六仪与三奇都能触发,防表变死数据;所标之宫与盘中天盘干一致)、摘要/解读/面板三处接线、旧结果缺 `conditions` 不炸。统计 **66 个测试文件 / 1930 条断言**。
1002
-
1003
- ## 0.24.0(当时)
1004
-
1005
- 六爻多了「卦体」这一层:六冲卦、六合卦、卦伏吟、卦反吟、爻伏吟、爻反吟,全部由纳甲地支实配推导,并用《增删卜易》体例的 23 条带断语卦例逐条对拍。
1006
-
1007
- - `engine/liuyao.js` 新增 `hexBody()` / `bodyRelations()` / `bodyLabels()`:结果里多一个 `body` 字段(`ben` / `bian` 的六冲六合、`fuYin`、`fanYin.by: ['chong'|'pair']`、`yaoFuYin`、`yaoFanYin`),并挂 `body.labels` 供面板与文本共用同一份措辞。
1008
- - **判定口径(可复核)**:
1009
- - 六冲卦 = 六爻地支正好配成子午、寅申、辰戌三组对冲。按纳甲实排共 **10 支**:八纯卦 + 天雷无妄 + 雷天大壮(传统只认八纯,故知识条目按 variant 写并注明分歧)。
1010
- - 六合卦 = 配成子丑、寅亥、卯戌、辰酉、巳申、午未三组相合,正好 **8 支**,与传世名单完全吻合;六冲与六合无交集,重支之卦(如雷水解)不判。
1011
- - 卦伏吟 = 变卦某宫三支与本卦对应宫逐位相同,且**卦确实变了**;纳甲上只有乾震共用子寅辰/午申戌,所以只会出在乾↔震互换。
1012
- - 卦反吟 = 地支三爻全冲,或本卦之宫与变卦之宫在后天八卦上正对(乾巽/坎离/艮坤/震兑);爻伏吟、爻反吟按动爻本支与变支同支/相冲判。
1013
- - **三处可见**:摘要末尾「卦体:」一行;「解析与详解」新增「卦体关系」一节(讲聚散、原地、反复,并声明「标签只说明动势,吉凶仍归用神」),整体维度「依据」加一行卦体;面板六爻卡在爻线下方加 chip 行。
1014
- - 白话层(直答 / 说人话)各补一句卦体的话;知识库新增 4 条(`liuyao-liuchong` / `liuyao-liuhe` / `liuyao-fanyin` / `liuyao-fuyin`)。
1015
- - 测试新增 `test/liuyao-body.test.mjs` 63 条:六合 8 支与传世表对拍、六冲 10 支(含「只认八纯」的差异说明)、伏吟「卦未变不算伏吟」回归、反吟两路分判、23 条卦例逐字对拍;统计 **65 个测试文件 / 1881 条断言**(当时)。
1016
-
1017
- ## 0.23.0(未单独发布,并入 0.34.0)
1018
-
1019
- 八字结果里多了「古籍原文」:格局、十神喜忌、调候三条线,各引原书一句,并附白话释义与出处。
1020
-
1021
- - 新增 `engine/classics.js`:**19 条**原文摘句——`子平真诠` 10 章(论用神、论用神配气候得失、论正官、论财、论印绶、论食神、论偏官、论伤官、论阳刃、论建禄月劫)+ `滴天髓` 通神论 9 条(寒暖、燥湿、衰旺、中和、官杀、伤官、月令、体用、精神),照录中华典藏网通行本,逐条带章名与 url。
1022
- - **匹配规则明确**:先按月令格局取对应十神章(如偏财格 → 论财),再按气候取《滴天髓》寒暖 / 燥湿,再补《论用神配气候得失》,最后以《论用神》兜底;去重后限 4 条,每条写明「为什么取这条」。
1023
- - **三处可见**:八字摘要末尾【古籍】四行;「解析与详解」新增「古籍原文」一节;面板八字卡在寒暖/穷通之后新增古籍块(书名·章、原句、白话释义)。
1024
- - 口径:原文照录通行本(各本有异文),释义为白话自撰;不把原句改写成结论,也不合并不同流派的说法。
1025
- - 测试新增 `test/classic-quotes.test.mjs` 34 条(19 条完整性、10 处原文定值抽检、匹配规则、解释层/摘要/面板接线);统计 **64 个测试文件 / 1818 条断言**。
1026
-
1027
- ## 0.22.0(已发布)
1028
-
1029
- 起名不再只是「未收录」三个字:逐字给出五行、判定与可换字。
1030
-
1031
- - 字库 190 → **391 字**(常用名用字为主,按木/火/土/金/水五行分段):丰(火)、秋(金,秋收成熟)、林(木)这类常见字不再掉「未收录」。
1032
- - **逐字判定**:`assessName` 每个字返回五行、释义、性别倾向、来源(`lib` 自建字库 / `user` 你传入的 `charElements` / `none` 未收录)、是否合喜用;未收录的字不猜五行,但会给出**同喜用五行的可换字**(如「秋」不合喜用 → 可换坤(土)、垚(土))。
1033
- - **不替用户下判断**:没给生辰时 `favorable` 返回 `null`(不判合不合),结论分「无生辰 / 全未收录 / 全合 / 部分合 / 全不合」五档,并把统计(几个字、几个已知、几个合喜用、字库共几字)写出来。
1034
- - **候选去同质化**:`generateNames` 三轮选名(新字 + 新五行组合 → 新字 → 放开)× 字库顺序打散 × 两字异行优先,避免「清一色梓桐」。同一盘 8 个候选示例:李炎梓(火木)、李坤桐(土木)、李楠灿(木火)、李楷垚(木土)、李培炫(土火)、李炜城(火土)、李柏松(木木)、李煜烨(火火)。
1035
- - **面板**新增起名卡(`pp.nameHTML`):逐字大字 + 五行 chip + 来源徽标 + 合/不合喜用 + 可换字、八字与喜用一行、结论;生成卡按「名 + 五行 chips + 释义」逐行排,不再是纯文本块。
1036
- - 工具参数新增 `charElements`(`{字: 木|火|土|金|水}`,自定义字五行,未收录字也能参与判定);`name` 的出生信息允许省 `datetime` 用 `year/month/day`。
1037
- - 测试新增 `test/names.test.mjs` 39 条(字库规模与去重、丰秋林逐字判定、未收录字 + 可换字、charElements 生效与非法忽略、无生辰不判、候选全合喜用、面板结构与接线);统计 **63 个测试文件 / 1784 条断言**。
1038
-
1039
- ## 0.21.0(已发布)
1040
-
1041
- 《穷通宝鉴》120 格逐条入库:同一「日主 + 月令」该取什么,书上怎么写的,全都摆出来。
1042
-
1043
- - 新增 `engine/qiongtong.js`:十天干 × 十二月令共 120 格,每格含用神顺序(首取在前)、原文摘句、出处章号;
1044
- - 用神顺序据通行整理表(knowyourbazi 整理表,首格为首选),原文摘句照录 [luckclub.cn](https://www.luckclub.cn/bazi/004/)《穷通宝鉴》每章首段(去掉「徐乐吾曰」评注);
1045
- - 数据里的 `quoteStems` 是「原文首段依次提到的天干」,与整理表首取不同处可对照阅读(如正月庚金:表首取戊,原文先举丙);
1046
- - 原文全章未见某用神字时(丁酉缺「丙」、癸未缺「壬」)直接写 note「按整理表录入,待以善本核对」,不替它圆场。
1047
- - **取用**:调候优先时,寒暖判定定「这一盘缺什么」,穷通宝鉴定「这一格书上取什么」;两者不同向时以调候为先,界面与解释层把两套并列写出,不悄悄合并。
1048
- - **评分**:流年天干正落在该格首取时 +0.3,次取 +0.15,理由写明「天干丙正是丑月乙日的首取(穷通宝鉴)」;该干属忌神时不给这笔分。
1049
- - **解释层**新增「穷通宝鉴」一节:格(「乙日生于十二月」)+ 用神与首取 + 原文摘句 + 章号;「未纳入」一栏同步改成「已录 120 格,整理表口径、异文处已标 note」。
1050
- - **面板**寒暖卡下新增穷通宝鉴块:用神 chips(首取高亮)、原文引句、章号;文本摘要「寒暖:」一行后追加「穷通:十二月乙取丙(首取丙)」。
1051
- - 新增 `tools/qiongtong-scrape.mjs`(抓 113 章原文,缓存不入库)与 `tools/qiongtong-build.mjs`(生成 `engine/qiongtong.js`),数据可复现。
1052
- - 测试 `test/qiongtong.test.mjs` 31 条:120 格齐全、用神字合法、原文摘句非空、月令月名一致、定值(乙丑取丙、庚寅首取戊/原文先举丙、丁酉与癸未的 note、未知输入返回 null)、1996 寒湿盘接入(detail/评分/解释/面板)。
1053
- - 统计:62 个测试文件 / 1745 条断言;client.js 44 模块。
1054
-
1055
- ## 0.20.0(已发布)
1056
-
1057
- 调候(寒暖燥湿)不再是脚注:从「扶抑为主 + 一句提示」改成「调候优先 + 扶抑校验」的判定层。
1058
-
1059
- - 新增 `engine/tiaohou.js`:按月令基础温度、全局火水比例、湿土燥土给出 **寒 / 寒湿 / 寒燥 / 湿滞 / 平 / 燥 / 燥热 / 温热** 八档气候,附温度与燥湿量化值和依据(如「季冬丑月、火0、水1.8、湿土2处」);由此定调候所取(寒湿取丙火、燥热取壬水)与所忌。偏寒偏燥明显时判「调候优先」,否则「扶抑为主」。
1060
- - **用神仲裁**:调候所需与扶抑喜忌冲突时显式裁决并说明理由(「寒暖失衡时再补强弱也难受」),不冲突时写「两套取法同向,不必取舍」;`method` 字段改成「调候优先 + 扶抑校验」/「扶抑为主 + 调候校验」,读得出来用了哪套。
1061
- - **评分接入调候**:流年/大运评分里,调候优先时天干地支合调候所需加权,合所忌扣权,寒局再逢水再扣(「地支子水加重寒湿」)。以 1996-01-19 盘为例:2020 庚子由「平 0.5」改为「忌 −0.8」并写明水助寒湿;2026 丙午「大吉 4.0」写明「寒湿之局得丙火,解冻」。
1062
- - **解释层**新增「寒暖燥湿」一节:气候判定 + 体感白话(按日主五行各写一句)+ 调候取忌 + 仲裁;八字文本摘要加「寒暖:」一行。
1063
- - **面板**在「用神」下新增寒暖卡:气候标签、调候优先徽标、寒—平—热标尺、调候取/忌/依据、白话叙述;独立页与面板共用。
1064
- - 口径:调候由月令与全局寒暖燥湿判定,未逐条录入《穷通宝鉴》120 条;调候与扶抑的优先级各家有争论,界面与文档都写明采用的是「调候优先、扶抑校验」。
1065
- - 测试新增 `test/tiaohou.test.mjs`(32 条:寒/热两盘、仲裁同向与冲突、评分方向与上下限、解释节、摘要行、面板卡);统计 61 个测试文件 / 1714 条断言。
1066
-
1067
- ## 0.19.0(已发布)
1068
-
1069
- 黄历、择日、公农历互转三处按「吉历」的用法补齐(只吸收合适的那部分,不搬它的小工具):
1070
-
1071
- - **黄历增强**:值日十二神(黄道/黑道)、十二时辰吉凶(五鼠遁定干支 + 时家十二神,逐时标吉凶)、二十八宿(吉凶/七政/禽/宫)、胎神、财神/喜神/福神/阳贵/阴贵方位、日柱纳音、六合三合吉配生肖;值日神/二十八宿/胎神/吉神方位与 lunar-javascript 逐日对拍(60 天仅交节当日 1 处日界差异,已注明口径)。
1072
- - **择日扩充**:事项从 13 类扩到 27 类(领证/提亲/收送聘金/满月酒/交易/投资/签订合同/搬家入宅/装修建造/试车买车/旅行/赴任/访亲友/入学…),面板与独立页按「常用 / 婚嫁 / 生活 / 建造 / 工商」五组下拉归类;打分与冲属相排除口径不变。
1073
- - **公农历互转 `convert`**:新增体系。公历 → 农历(农历年月日、闰月、干支四柱、生肖)与农历 → 公历(闰月须显式指定,小月无三十报错),往返自洽;只知道农历生日时可先转公历再排盘。工具层与面板、独立页都已接入。
1074
- - 面板与独立页 tab 由 17 个扩到 **18 个**;黄历 tab 有专属卡片(值日徽标、宜忌、四格、吉神方位、十二时辰吉凶网格)。
1075
- - 测试新增 `test/tools3.test.mjs`(14 条:黄历新增字段定值、五鼠遁、十二时辰吉凶、公农历往返/闰月/报错、择日分组与冲属相排除、渲染与接线)。
1076
-
1077
- ## 0.18.4(已发布)
1078
-
1079
- 称骨补上**称骨歌原文**与白话释义(此前只有自撰的分档批语):
1080
-
1081
- - 新增通行本《称骨歌》52 首(二两一钱 … 七两二钱),`CHENGGU_SONG` 按骨重(钱)索引,原文照录;
1082
- 各版本有异文,断句标点统一为「,;,。」
1083
- - `buildChenggu` 新增 `song` 字段:`{ text, plain, title, source }`;`plain` 是白话释义(自撰,明确不是原文),
1084
- 超出 21–72 钱时给出「未见通行本歌诀」而不是编一首
1085
- - 文本摘要把「歌诀」与「释义」分两段;口径里写明歌诀为通行本、释义为白话自撰
1086
- - 新增 `PP.chengguHTML`:四项骨重表格 + 合计与分档徽标 + 歌诀(两行竖排大字)+ 释义 + 口径;
1087
- 面板与独立页的称骨 tab 改用它(原先落到通用文本块)
1088
- - 新增 `test/chenggu.test.mjs`(18 条):52 档齐全且都是四句、关键档位不串行、白话不是原文、
1089
- summary 两段、渲染器四项与口径、两处界面接线
1090
- - 统计:59 个测试文件 / 1668 条断言
1091
-
1092
- ## 0.18.3(已发布)
1093
-
1094
- K 线的第二轮打磨(0.18.2 之后的可读性修正):
1095
-
1096
- - 大运段名从图顶挪到图下的条纹带里,不再和「最高/最低岁」标记抢位置;段名居中,条带随大运交替着色
1097
- - 5 年 / 10 年均线在右缘标出末端数值,两条贴太近时自动上下错开
1098
- - 纵轴补 0/25/50/75/100 刻度,横轴补「年龄(岁)」与「每岁一分 · 满分 100」;影线用 `clipPath`
1099
- 夹在绘图区内,贴边的影线不再溢出
1100
- - 新增统计条:全段均值、最好大运、最差大运、波动幅度。旺衰落在换档阈值附近时只给均值与波动,不给
1101
- 「最好/最差大运」的顺位
1102
- - 图高由 300 提到 322,给刻度与段名条留位
1103
- - `test/kline.test.mjs` 增到 29 条(段名条、均线末端值、纵轴刻度、统计条、最好/最差大运)
1104
- - 统计:58 个测试文件 / 1650 条断言
1105
-
1106
- ## 0.18.2(已发布)
1107
-
1108
- 人生 K 线从「等宽文本 + ASCII」升级成真正的蜡烛图,并嵌进八字结果:
1109
-
1110
- - 新增 `PP.trendChart` / `PP.trendHTML`:实体=该岁相对上一岁的涨跌、影线=±4 分;叠 5 年 / 10 年均线、
1111
- 大运交替底色与分界虚线(段名标顶部)、0–100 固定量程网格、年龄刻度、最高/最低岁标记;悬停看逐年
1112
- 「多少岁 / 哪一年 / 什么干支 / 多少分 / 落在哪步大运」。颜色全走 CSS 变量,深浅色与打印跟随
1113
- - 「人生K线」tab 不再输出纯文本摘要,直接给图 + 大运分段 chips + 高低年份;数据不足或空值时安全退回文本
1114
- - **八字结果底部直接嵌同一张 K 线**(面板与独立页在排八字时顺带算一次 `trend`),与原有的
1115
- 「人生运势曲线」(大运阶梯 + 流年折线)并存:曲线看趋势形态,K 线看逐年涨跌
1116
- - 新增 `test/kline.test.mjs`(23 条):结构、坐标不越界、无 NaN、空/单点安全、旺衰边界不出高低结论、
1117
- 两处嵌入点都在源码里
1118
- - 统计:58 个测试文件 / 1644 条断言
1119
-
1120
- ## 0.18.1(已发布)
1121
-
1122
- 元数据与检索入口同步,**无运行时行为变化**:
1123
-
1124
- - 把「玄学 / 算命 / 占卜 / 运势」加进 `package.json` 关键词与描述、`locale/*.json`、市场条目描述、README 与工具描述——之前只写「命理排盘」,用户搜「玄学」搜不到;现在搜「玄学」应能命中
1125
- - 工具描述补一条触发条件:用户只搜「玄学」或问「有什么玄学工具」时也应介绍本插件
1126
- - 排盘逻辑、输出与测试断言不变;仅 UA 随版本号更新(`dsh-metaphysics/0.18.1`)
1127
-
1128
- ## 0.18.0(已发布)
1129
-
1130
- 吸收同生态另一款命理插件「玄机阁」(dsh-xuanji,MIT)的能力:**按行为规格独立实现,不 vendor 源码、
1131
- 不引入 iztro / lunar-javascript 依赖**,引擎仍为零外部依赖的纯 ESM。
1132
-
1133
- ### 九套速查体系(新增)
1134
-
1135
- 每套都有 `engine/*.js` + 工具分支 + 面板/独立页入口 + 测试,口径固定、同日同结果:
1136
-
1137
- - **黄历 almanac**:农历、四柱干支(年柱按立春、月柱按节)、建除十二神、宜忌简表、冲煞与财喜神方位、
1138
- 上一/下一节气、每日一卦。与 lunar-javascript 对拍四组日期(日柱/月柱/年柱/农历/建除全一致);
1139
- 唯一差异是交节当日「上一节气」的日界口径(我们按正午判已交节),已记入 `meta.scope`
1140
- - **择日 zeri**:13 类事项 × 建除适配打分,逐日分「推荐 / 可用 / 回避」,当事人属相冲煞日直接排除,
1141
- 每条回避都带理由;明确是「排序引导」,不是吉凶断语
1142
- - **称骨 chenggu**:年/月/日/时四项骨重求和与分档批语。年表按 `(农历年-4)%60` 查 60 甲子,
1143
- 月日时各一张表;对拍公开黄历页修正了初版错表(1990-08-15 巳时应为**五两六钱**,不是五两五钱)
1144
- - **小六壬 xiaoliuren**:时间起课(农历月/日/时三掐)与报数起课(三个 1–99),六宫吉凶与白话断语
1145
- - **星座 star**:太阳星座档案 + 当日四维基调;基调由日期哈希确定性生成,同一天同一星座永远一致,
1146
- 明写「不是随机数,也不是模型编的」
1147
- - **生命数字 numerology**:生命路径数 / 生日数 / 态度数,11/22/33 主数保留,逐数给数义与课题;
1148
- 与八字是两套口径,混问时会说明不可互相印证
1149
- - **人生 K 线 trend**:复用八字的旺衰、大运、流年十神,按固定计分表给 1–100 岁逐年分与 K 线形态、
1150
- 分大运 ASCII 走势、最佳/最差年份。旺衰恰好落在换档阈值(±0.3)时只给提示、不给顺位结论
1151
- - **风水 fengshui**:八宅命卦(1900s/2000s 男女公式、立春界)、大游年四吉四凶、流年九宫飞星
1152
- (2026 一白入中为锚)、24 山门主灶布局倾向、命宅配调停文案;`scope` 明写不含玄空各运盘与现场勘舆
1153
- - **起名 name**:评估现有名字或生成候选名;按八字喜用五行(偏强喜克泄耗、偏弱喜生扶)匹配 241 字
1154
- 自建字库,未收录的字如实标「未收录」。**不做五格剖象**(需康熙字典笔画)与音韵判断
1155
-
1156
- ### 1986–1991 夏令时自动校正
1157
-
1158
- `engine/dst.js`:中国 1986–1991 年夏季行夏令时,钟面时间比标准时快 1 小时。八字/紫微/合盘/验前事/
1159
- 生时校正/人生 K 线/风水在排盘前统一校正,跨日时回退到前一天 23:xx 并给出 `dst.note`;
1160
- `dst: false` 可显式关闭(出生证已是真实太阳口径时用)。修正了「夏令时出生按钟面时间排盘差一个时辰」的口径错误。
1161
-
1162
- ### 合婚明细层(hepan 增强)
1163
-
1164
- 原有总分与三维度**不动**,新增 `detail`:属相六合/三合/六冲/相害/相刑、天干五合、双向十神、
1165
- 跨盘地支关系、年命纳音生克、吉凶象计数分档(上 / 中上 / 中 / 需磨合)。冲刑害一律中性叙述,不断「必分」。
1166
-
1167
- ### 界面
1168
-
1169
- - 面板与独立页 tab 由 8 个扩到 **17 个**:九套速查体系各有自己的最小输入;速查结果走通用 `pp.quickHTML`
1170
- (等宽文本 + 标题),不套命盘模板
1171
- - 八字面板补传 `verifyPast`,验前事区块终于会在面板里出现(此前只有独立页有)
1172
- - 独立页「方法页」同步体系清单与已知边界
1173
-
1174
- ### 视觉升级三项(沿用本次工作树)
1175
-
1176
- 视觉升级三项,均不改计算口径、不新增判断:
1177
-
1178
- - **色板拉开层级**:`--bg` 压深作「桌面」(`#fffdf8 → #f6f1e6`),`--card` 提到近白(`#fffefb → #fffdf8`),
1179
- band / tri / soul / sel / link 一并拉开。`--hair` 随底色同步加深(`#efe9dc → #e9e2d3`),否则比背景还亮、
1180
- 发丝线会变成高光。深色块用同一套逻辑(底更沉、卡片更亮)。
1181
- 改动前 `--bg` 与 `--card` 只差 1/255,卡片与底色几乎同色,一切「卡片」都浮不起来。
1182
- 前景色(ink / muted / red / lu / 十神组)一个未动,对比度、打印样式、可访问性不受影响
1183
- - **人生运势曲线**:新增 `pp.curveHTML()`(渲染在八字盘「大运」节内)——大运作阶梯、流年作折线,
1184
- 叠在同一坐标系;背景五条档位色带(绿=吉 / 灰=平 / 红=忌),标出全程最高运与最低运,
1185
- 今年流年点加粗描边,悬停看逐年「年份(年龄)干支 档位 分值」。
1186
- 纯内联 SVG、零依赖,颜色走 CSS 变量,深浅色自动跟随
1187
- - 纵轴固定量程 −2.2 ~ 3.2(引擎实测 score ∈ [−2, 3.2]):固定而非自适应,不同盘之间才可比
1188
- - 数据不足两步大运则不画(不画半张图);缺 `luck` 字段、传 null / 空对象均不崩
1189
- - 新增 `test/curve.test.mjs` 36 条:几何不越界、色带无缝、阶梯形态、点与引擎数据对齐、
1190
- 刻度不重叠、安全与无障碍、边界不崩
1191
- - **三套内联 SVG 符号**(零依赖、零外部请求,一律 `currentColor` 跟随主题):
1192
- - **爻线**:原先 span + 背景色拼接、靠 `flex gap:18%` 留阴爻间隙,字号一变间隙就飘;
1193
- 改为 104×12 内联 SVG,间隙按画布坐标固定(两段各 43 + 间隙 18 = 104)。三种尺寸共用一份几何
1194
- - **动爻标记**:沿用传统老阳 ○ / 老阴 ×,非动爻留同宽空位,六列对齐不抖;爻线列由 112px 放宽到 128px
1195
- - **五行符号**:12×12 描边图标,形状取各元素最易辨识的意象(木=树 / 火=焰 / 土=「土」字骨 /
1196
- 金=菱形 / 水=波纹),接入五行分类 chip 与用神喜忌行
1197
- - **八卦小象**:14×10 三爻 SVG,接在梅花上下卦标题前;爻位由 `TRI_BITS` 自下而上翻转后渲染
1198
- - 新增 `test/symbols.test.mjs` 79 条:三种尺寸几何、阴爻两段+间隙恰为满宽、八个卦逐爻位校验、
1199
- 五条元素路径互不相同、整合到六爻/梅花/八字盘、既有结构回归护栏、无脏值无注入面
1200
- - 全量 57 文件 / 1621 条 PASS(原 1362),`test:ci` 七道闸全绿
1201
- - 新增 `test/tools.test.mjs` 65 条 + `test/tools2.test.mjs` 68 条:黄历对拍、择日排除冲属相、
1202
- 称骨四项和、小六壬递推、星座边界、生命数字主数、DST 开关、人生 K 线边界、风水坐向、起名未收录字
1203
-
1204
- ## 0.17.1(已发布)
1205
-
1206
- 同步更新,**无运行时行为变化**:
1207
-
1208
- - README 与仓库现状对齐:补齐奇门 / 合盘(八套体系)、0.16–0.17 的报告化与可核验能力、安装示例版本
1209
- - CI 自检加固:新增 `tools/check-bundle.mjs` 产物自检闸(逐模块编译 client.js、核对与源码一致),`test:ci`
1210
- 先构建再检查;`ask.test` 不再读取仓库外的生成物
1211
- - 仅 UA 字符串随版本号更新(`dsh-metaphysics/0.17.1`),排盘逻辑与输出不变
1212
-
1213
- ## 0.17.0(已发布)
1214
-
1215
- 对应「晚子时开关 / 验前事 / 生时校正」三条用户反馈:
1216
-
1217
- - **晚子时开关**:面板与独立页新增「晚子时换日」(八字/紫微/合盘)与奇门「归当日/归次日」;
1218
- 之前引擎已支持 `lateZi` / `lateZiHourMode`,但 UI 没有暴露,用户无法自己调
1219
- - **验前事**:工具参数 `verifyPast`(年数)+ 面板/独立页「验前事」区块——列出过去若干年的
1220
- 流年信号(冲/合/刑、档位、十神),用户自评「准/不准/不确定」,用 `verifyFit` 算贴合度并给建议;
1221
- **只读,不重排、不改盘**;贴合度低时先提示核对出生时间/时区/晚子时
1222
- - **生时校正**:`engine/rectify.js` + 工具参数 `rectify`/`events`——对候选时辰逐一排盘,
1223
- 按固定规则(事件类别 × 当年十神/关系/档位)打分,返回候选排序与并列说明;
1224
- 规则显式可复核,明确「只缩小范围、不替代出生记录」
1225
- - 测试:新增 `test/verify.test.mjs` 25 条;全量 53 个文件 / 1362 条 PASS
1226
-
1227
- ## 0.16.0(已发布)
1228
-
1229
- 报告化改版,对应与 Seeself 对比后的 R1–R8:
1230
-
1231
- - **R1 报告骨架**:解析顶部新增「一页读懂」五条摘要(整体 / 事业 / 财富 / 感情 / 节奏);
1232
- 目录锚点跳转;新增三张表——八字「大运表 / 流年表 / 触发事件表」、紫微「大限表 / 流年表 / 触发事件表」,
1233
- 全部由已有引擎字段摊平,不新增判断;打印加 `break-inside:avoid` 与表格换行规则
1234
- - **R2 证据卡**:每个维度的「依据」从一行灰字升级为可展开的 `<details>` 证据卡
1235
- (盘面事实 + 技法标签),并给每个维度打「置信度 强/中/弱」(只按证据条数分档,不引新算法);
1236
- 文本输出同步:依据行尾附 `置信度:…`
1237
- - **R3 追问模式**:新增 `engine/followup.js` 与工具参数 `ask`——围绕已算好的盘回答
1238
- 「某一年 / 某方面」的问题(如「2027 年事业怎么样」),只取盘面已有字段,不重排、不猜测;
1239
- 找不到年份/未识别方面时明确说找不到并给出可问范围。面板与独立页都加了追问输入框
1240
- - **R4 示例报告**:面板与独立页各加「看示例」,固定示例盘(1990-05-12 14:30 男 石家庄)
1241
- 走与真实排盘完全相同的渲染路径,无示例专用分支
1242
- - **R5 交叉验证层**:新增 `engine/crosscheck.js` 与工具参数 `cross`——八字 × 紫微对
1243
- 事业/财富/感情/身体/节奏五项并列对照,标注「同向 / 有张力 / 互补」;只作对照,不合并数值
1244
- - **R6 量化表达**:八字/紫微各加「量化口径」分节——明确量化只到档位(十神权重、宫位计数),
1245
- 不换算金额、不给疾病诊断;新增 `test/report-extra.test.mjs` 断言不出现金额区间
1246
- - **R7 方法与验证页**:独立页内置静态「方法与验证」(体系、对拍 128 条、测试与闸门、口径、已知边界),
1247
- 离线可开
1248
- - **R8 导出与分享**:面板与独立页加「导出 .md」(盘面 + 解析 + 交叉验证 + 追问),
1249
- 独立页保留打印/存 PDF
1250
- - 测试:新增 `test/report.test.mjs` 36 条、`test/report-extra.test.mjs` 31 条;
1251
- 全量 52 个文件 / 1335 条 PASS
1252
-
1253
- ## 0.15.0(已发布)
1254
-
1255
- - **性能**:节气按需计算、牛顿初值用回归年、容差放宽;八字单盘 2.70ms → 1.60ms
1256
- - **口径差异对照**:`engine/diff.js` + `tools/caliber-diff.mjs`,区分根因字段与连带变化
1257
- - **白话四层**:直答 / 说人话 / 每维一句话 / 追问建议;术语按体系区分
1258
- - **规则知识库**:28 条(出处 + 可信度 + 尚未实现清单)
1259
- - **卦例对拍扩容**:《卜筮正宗》从 19 条扩到 **128 条**(93 成对 + 35 静卦),
1260
- 新增核对动爻个数、缺爻(伏神)、旬空;排除的 5 条连同理由留在
1261
- `tools/data-boshizhengzong.mjs` 的 `excluded`
1262
- - **引擎入参守卫(P0)**:新增 `engine/validate.js` 的 `assertCivil()`,`buildBazi / buildZiwei /
1263
- buildDaliuren / buildQimen / buildHepan / buildZiweiHepan / buildSnapshot` 入口统一校验;
1264
- 坏入参从裸 `TypeError` 改为 `E_INPUT`,文案写清「该传什么」(15 类坏输入有契约测试)
1265
- - 统一错误工厂 `engine/fail.js`;梅花的 datetime / 数字起卦错误也改为 `E_INPUT`
1266
- - **缓存层统一(P0)**:新增 `engine/lru.js`(上限 + TTL + 命中率),节气瞬时/单年/三年窗口/
1267
- 地址四处缓存改为同一工厂;`DSH_METRICS=1` 时 `renderText` 打印各缓存命中率
1268
- (实测紫微盘 `termInstant` 命中 75%)
1269
- - **规则表单一真源(P0 收尾)**:`engine/nayin.js`(六十甲子纳音,bazi/ziwei 共用)、
1270
- `engine/sanhe.js`(三合四局 + 单支归属,bazi/hepan/daliuren 共用);纳甲本就在 `liuyao.js` 一份
1271
- - `test/tables.test.mjs`:纳音 60 项与八字导出逐项一致、三合同局判定与五行等价、
1272
- 乾为天纳甲起例,并用静态检查防止有人再把表复制回各模块
1273
-
1274
- ## 0.14.3(已发布)
1275
-
1276
- - **经典通例对拍**:新增 `test/fixtures/classics.json` 与 `test/classics.test.mjs`,把典籍里的规则表当作期望值来验实现——
1277
- - 六爻:京房八宫卦序的宫属与世应(八纯上爻、一至五世依次、游魂四爻、归魂三爻),64 卦全表
1278
- - 六壬:日干寄宫(甲寅乙辰丙戊巳丁己未庚申辛戌壬亥癸丑)、中气换将(雨水登明亥将起,12 个中气抽样)
1279
- - 紫微:纳音定五行局、紫微天府以寅申为轴相照
1280
- - 出处与录入方式写在 fixture 的 `meta.sources`,由 `tools/gen-classics-fixture.mjs` 生成,不从引擎输出反推
1281
- - 说明:录入的是**通例表**(规则级),不是某本书的例课原文;例课需要可引用的原文,见 README「对拍」
1282
- - **卦象/牌阵类也给出「依据」**:六爻列本卦/变卦、世应爻位与六亲六神、动爻、日辰、卦宫;梅花列本卦/互卦/变卦、体用与生克、动爻;六壬列课体、三传、月将、旬空与青龙/朱雀/六合/天后/白虎/子孙是否出现;塔罗列牌阵与牌位、主轴牌、正逆位计数与元素分布
1283
- - 至此六个有维度的体系(八字/紫微/六爻/梅花/六壬/塔罗)都能核对依据;奇门走分节形态,事实本就写在 section 正文里
1284
- - **《增删卜易》卦例对拍**:从 PDF 电子本(有文字层)录入 9 条原文卦例——「月建 + 日干支 + 本卦 → 变卦」,出处精确到章(元神忌神衰旺章第十、月将章第十六、日辰章第十七、独发章第三十一、星煞章第三十三、用神元神忌神仇神章第九)。引擎须按 64 卦表还原这一对(名字、翻爻、变卦生成)
1285
- - 《卜筮正宗》(复城道长精校)此前是**扫描版 PDF、无文字层**;这次拿到同一版本的 **docx**(有文字层),从中提取 138 条带「占事」的卦例,99 条卦名可唯一解析,收 19 条进 `boshizhengzong`
1286
- - 每条核对:本卦 → 变卦、卦宫(宫 + 五行,与八宫表互证)、有日期的样本还核旬空
1287
- - 书中「空亡」与通用旬空不一致的例子(丙辰日作戌亥,应为子丑)只记卦名卦宫、不断言空亡;1 条卦宫与八宫表冲突(表格串行)不收,原因写在 fixture 的 `meta.sources`
1288
- - 原文用字保留异体(遯/遁、干/乾),动爻**不录**——原书卦象图在 PDF 里被压成一行,位置不可靠,硬录等于造数据
1289
- - **六爻补旬空**:`buildLiuyao` 现在输出 `xunShou`(旬首)与 `xunKong`(旬空两位),文本摘要多一行「旬首:甲午 旬空:辰巳」;六旬表与「丙辰日空子丑」都有断言
1290
- - **双 UI 收口(第一步)**:新增 `src/core.js`,把「爻值解析」「问事体系」「数字输入」三条规则收成单一来源,`app.js` 与 `web-ui.js` 都改为调用 `window.__MPCore`;构建脚本把 core 一并打进 `client.js` 与独立 HTML
1291
- - 单测 `test/core.test.mjs`(21 条)直接加载浏览器文件验证;`ask.test.mjs` 改为检查「单一来源 + 两端委托」
1292
- - 表单编排(参数拼装)仍各留一份,下一步再收
1293
- - **修合盘面板**:合盘的主方性别/出生地被漏在 `bazi|ziwei` 分支之外——0.14.1 起引擎把性别改为必填,面板点「合盘」会直接报 `你(主方)的gender 必须是 male 或 female`,看起来像"合盘不对"。现在三体系共用同一分支,合盘四柱与单盘一致(实测 庚午 辛巳 丁丑 丁未 对 庚午 辛巳 丁丑 丁未)
1294
- - **奇门进面板**:新增「奇门」tab,起局时刻 + **换局规则**(fieldset + legend + `role="radiogroup"` 的原生 radio:拆补 / 超神接气 / 置闰,附 `details` 说明),`juMethod` 透传给引擎;盘面下新增 `qimenFactsHTML`,用 `dl > div > dt/dd` 列出局数、节气、四柱、值符、值使、旬首、空亡、驿马、换局规则、晚子时——事实与解读区的结论分开,全部走 `esc()`
1295
- - 尚未做(下一步):三栏 Grid 布局、`<template>` 渲染、显式状态机(idle/missing_input/…)、960/1200 断点的布局断言
1296
- - **独立页补齐合盘 / 奇门**:`命理排盘.html` 由六个 tab 变八个
1297
- - 合盘:对方出生日期/时刻/性别/出生地 + 「合盘方式」八字/紫微切换;主方同样带性别与真太阳时,四柱与单盘一致
1298
- - 奇门:换局规则用 `fieldset + legend + role="radiogroup"` 的原生 radio(拆补/超神接气/置闰,附 `details`),加「询问方向(定用神)」;结果 = 九宫盘 + `dl` 事实表 + 分节解读;换规则重起局、换方向只重出解读
1299
- - `build-html` 导出 `page()` 且直接运行时才写盘,`test/standalone.test.mjs` 直接对生成源码做结构断言(24 条)
1300
- - **解析深化:把"怎么推出来的"也写出来**
1301
- - 八字 / 紫微新增四段:**看盘顺序**(月令→旺衰→用神→格局→大运→流年/命宫→三方→四化→大限,逐步引用实际值)、**时间窗**(当前与后续大运 + 近五年流年,带档位与理由)、**交叉校验**(喜忌分量对比、大运与流年同向/反向、调候与扶抑是否一致)、**未纳入**(没算什么、哪些流派差异会改变轻重)
1302
- - 六爻 / 六壬补**看卦/看课顺序**(卦宫→世应→动爻→用神→日辰→变卦;月将→四课→三传→课体→神将)与**未纳入**
1303
- - 这些段落全部由盘面数据推出,不新增断语;`test/deep.test.mjs` 41 条断言校验结构、关键步骤与"无占位值"
1304
- - 测试:44 个文件 / 1147 条 PASS
1305
-
1306
- ## 0.14.2 —— 口径、复现与性能(已发布)
1307
-
1308
- - **1929 年前的节气改用当时的地方时**:`termInstantJd` 与农历共用同一套换算(1929-01-01 前为北京地方平时 UTC+7.7611,之后东八区),并顺手修正切点常量的半天偏移。此前农历切换、节气一律 +8,1929 年前出生者在交节前后约 14 分钟内可能月柱整柱错位
1309
- - **晚子时口径统一**:`lateZi`(八字/六壬)与 `lateZiHourMode`(奇门)互为别名,一个概念不再有两个参数名;四套体系的摘要都会写明实际采用的口径(换日 / 不换日)。默认值保持原样(八字/六壬换日、奇门不换日),不偷偷改盘
1310
- - **无经度必须告警**:没给出生地/经度时,八字与紫微摘要首行出现 ⚠(此前只在一行括号里提一句,海外出生很容易被忽略)
1311
- - **可复现**:塔罗/六爻新增 `seed`(同 seed 同结果,可回放、可对拍);塔罗 `castAt` 由 `asOf` 决定;八字流年可用 `asOf` 钉死基准年(此前锚在"当前年份",隔年重算结论就变了);六爻的日辰(六神起法)也可用 `asOf` 固定,不再随本机日期漂移
1312
- - **默认离线**:工具新增 `geocode: 'offline' | 'online'`,默认 `offline`——内置坐标表已到地级市,足够真太阳时;只有显式开启才会把出生地原文发给 Nominatim。地址解析加 6 小时缓存,UA 补上版本与仓库地址
1313
- - **性能**:`termInstantJd` / `termWindow` 按年缓存(农历换算一次要问几百次中气,而 VSOP87 是全引擎最贵的一段)
1314
- - 紫微盘 10.9ms → **0.5ms**,奇门 8.1ms → **0.07ms**,八字 2.4ms → **0.4ms**
1315
- - 全量回归 15.8s → **3.3s**
1316
- - **无障碍**:结果区补 `role="region"` + `aria-live="polite"`,错误提示 `role="alert"`,通知 `role="status"`
1317
- - **工具层**:`geocode` / `seed` 进 schema,`asOf` 说明覆盖紫微/八字/塔罗三个体系;非法 `geocode` 值报 `E_INPUT`
1318
- - **CI**:新增 `tools/check-html-sinks.mjs`(innerHTML 拼接必须经过白名单转义函数)与 `tools/check-patterns.mjs`(engine 纯净性、日志、`var`、`debugger`、`new Date()`/`Math.random` 白名单),正/负向都验证过
1319
- - **稳定性扫射**:`test/fuzz.test.mjs` —— 用固定种子随机 12 组生日跑遍八个体系,覆盖参数矩阵、边界日期(1600/2400/闰年/1929 切换点)、解析层与"同参数两次结果字节一致"
1320
- - **自刑补齐**:辰午酉亥两柱同见判「自刑」,大运/流年支与原局同支也按自刑处理。此前 `buildRelations` 遇到同支直接跳过,四柱里 3 个辰也不会报刑
1321
- - **权重口径显式化**:五行占比(1/0.5/0.3)与日主通根(1.2/0.6/0.3)各自命名并注明用途——数值未变,只是不再像"同一件事写了两份"
1322
- - **解析加「依据」**:八字与紫微的五个维度各附一行盘面事实(日主旺衰、月令、喜忌、大运流年、宫位主星、煞星),面板渲染 `mp-it-dev`、文本渲染「 依据:…」;卦象类的依据行在 0.14.3 补齐
1323
- - **解析失败不再变空壳**:builder 抛错时面板显示「⚠ 解析生成失败」并把原因转义后带出,文本摘要同样标出;此前只返回一个空 dimensions 的对象,用户看到的是"没有解析"
1324
- - **结构不变量**:`test/invariants.test.mjs` —— 不依赖外部样盘,用"盘面自身必须成立"的性质守算法:紫微 12 宫支互异/大限连续覆盖、奇门八门八神各一次、六十四卦一一对应、四柱纳音与世应合法。金标准只能覆盖少量样盘,不变量对每张盘都成立
1325
- - 测试:39 个文件 / 1011 条 PASS(新增 historical-tz、repro、caliber、tool-geo、fuzz、relations、evidence、invariants 八组)
1326
-
1327
- ## 0.14.1 —— 先让「通过」可信
1328
-
1329
- 这一版不加新体系,只补三件会静默出错的地基:测试的失败信号、渲染层的转义、入参的拒绝。
1330
-
1331
- - **测试不再假绿**:`test/_harness.mjs` 统一断言,任何一条 FAIL 都让进程非零退出。此前 bazi / calendar / liuyao / lunar / shensha / tarot / ziwei / e2e / layout 九个文件只 `console.log`,断言写错也 exit 0,`npm test` 恒报 27/27
1332
- - `tools/check-assertions.mjs`:每个文件的 PASS 条数锁进 `test/assertion-baseline.json`,删断言即失败(`npm run test:baseline` 显式重建)
1333
- - `tools/verify-tests-can-fail.mjs`:故意写错一条断言,必须变红——保护「测试本身」
1334
- - **两处 XSS**:塔罗面板的「所问」与解读段落回显(`src/panel-kit.js`)、独立页错误提示(`src/web-ui.js`)此前把用户原文拼进 `innerHTML`;现改为 `esc()` 与 `textContent`,并加 `test/security.test.mjs` 回归
1335
- - **入参校验与错误码**:`compute()` 新增 `E_INPUT / E_RANGE / E_LINES / E_COUNT / E_ASOF / E_PARTNER / E_SYSTEM`
1336
- - 日期按月份天数与闰年校验(`1990-02-30`、`2026-04-31` 不再静默滚到下个月)
1337
- - `bazi / ziwei / hepan` 的 gender 改为必填(缺省按男命排会让大运/大限方向整个反掉)
1338
- - 六爻爻数 ≠ 6 时报错(不再悄悄换成随机卦);塔罗张数非 1/3/5 时报错;`asOf` 非法时报错(不再静默用「此刻」)
1339
- - 工具层 `execute()` 统一包上 `[错误码]` 前缀,内部异常不再以堆栈式文案直出
1340
- - **合盘口径与单盘对齐**:合盘现在把 `address / longitude / trueSolar / lateZi` 分别透传给双方(工具层也会为 `partner.address` 解析经度)。此前合盘完全忽略地址,同一次出生在单盘是 丁丑 日、在合盘里却是 戊寅 日
1341
- - 新增 `test/hepan.test.mjs`:断言「合盘里的你 == 单盘的你」,八字与紫微两条链路都覆盖
1342
- - **解析文案修复**:`命局身身强`(level 已含「身」)、`调候上还初夏`(硬拼连接词)、同一段两次「调候上…」、大运与流年档位并成一句导致建议前后矛盾
1343
- - 新增 `test/interpret-copy.test.mjs`:对 8 个体系的实际输出做病句/重复/未定义值扫描
1344
- - 测试新增 `test/args.test.mjs`(40 条)、`test/security.test.mjs`(10 条)、`test/hepan.test.mjs`(7 条)、`test/interpret-copy.test.mjs`(63 条),全量 31 个文件 893 条 PASS
1345
- - CI 增加「断言数不低于基线」与「测试自检」两步
1346
-
1347
- ## 0.14.0 —— 奇门、合盘与节气精度(此前只存在于工作树,本版一并落库)
1348
-
1349
- - 新增**奇门遁甲**(时家转盘:拆补 / 超神接气 / 置闰三派取局、值符值使、九宫、空亡驿马)与对应解读
1350
- - 新增**合盘**:八字合盘(日主关系 / 夫妻宫 / 五行互补)与紫微合盘(命宫、夫妻宫、五行局)
1351
- - 节气计算改用 **VSOP87B 截断级数 + 岁差 + 章动 + 光行差**,与 NAOJ 历要项对拍偏差降到 1 分钟内
1352
- - `parseDateTime` 对 ΔT 覆盖范围(1900–2100)之外的年份给出精度提示,摘要顶部标 ⚠
1353
- - `geocodeAddress` 支持地址更细时联网(Nominatim)兜底,失败退回内置坐标表
1354
- - 六壬补神煞与格局文案;紫微补流月/流日/流时并接入盘面与解读
1355
- - `tools/qimen-divergence.mjs`:枚举三派取局的分裂样本,供排盘差异核对
1356
-
1357
- ## 0.13.6
1358
-
1359
- - 修 `npm run release` 的发布后核对:npm 的发布是异步的(PUT 返回 202,registry 生效实测要 1–4 分钟),脚本原来 30 秒就判定失败
1360
- - 改为对 tarball 轮询 HEAD,最多等 6 分钟;超时只提示「已提交,稍后自查」而不报错
1361
- - 顺手核对 `dist-tags`,`latest` 不指向新版本时给出 `npm dist-tag add` 的建议
1362
-
1363
- ## 0.13.5
1364
-
1365
- - 新增 `npm run release`(`tools/release.mjs`):一条命令走完「测试 → 构建 → 校验产物 → 发 npm」,token 只从环境变量 `NPM_TOKEN` 读,临时 `.npmrc` 用后即删
1366
- - 发布前会拦下三种情况:git 工作区不干净、`client.js` 与源码不同步、registry 上已有同版本
1367
- - `-- --dry-run` 只跑到校验;本机没装 npm CLI 时用 `NPM_CLI=/path/to/npm-cli.js` 指定
1368
-
1369
- ## 0.13.4
1370
-
1371
- - 新增 `npm run build` / `npm run build:html` / `npm test`:`tools/test-all.mjs` 顺序跑完 20 个测试文件并汇总退出码,省掉手敲一长串 `node test/*.mjs`
1372
- - `daliuren` / `meihua` 两处旧测试统一成 `PASS/FAIL` 计数风格(此前只打印 `all pass`,CI 里数不出断言数)
1373
- - 补 `CHANGELOG.md`;`engines.node` 声明 `>=18`;SUBMIT 文档补提交状态与阻塞说明
1374
- - 新增 GitHub Actions(`.github/workflows/test.yml`):先构建并校验 `client.js` 与源码一致,再跑全部回归
1375
-
1376
- ## 0.13.3
1377
-
1378
- - **工具层打通「解析与详解」**:`compute()` 把 `question` / `direction` 透传给 `interpret()`;工具 schema 新增 `withInterpret`、`direction`(综合/财运/事业/感情/健康/学业/出行)与 `asOf`(流月流日流时的基准时刻);`renderText()` 在带解析时附上解析正文与免责声明
1379
- - 修 `layout` 测试沿用旧类名 `.pn`(0.13.2 已改 `.ft-pn`)导致的假失败
1380
- - 未知体系报错改为列出六种体系(原文案仍写着「紫微斗数尚未接入」)
1381
- - `package.json` 补 `author` / `repository` / `homepage` / `bugs`;中英文案重写
1382
- - 市场条目描述同步到当前能力(主星庙旺、流月流日流时、解析)
1383
- - README 注明真太阳时只按经度修正、未含历史时区与夏令时
1384
-
1385
- ## 0.13.2
1386
-
1387
- - 叶子类名按语义补前缀(`bz-` / `dt-` / `flow-` / `ft-` / `ct-` / `hb-` / `ss-` / `ask-` 等 192 处),消除泛词类名复用隐患
1388
-
1389
- ## 0.13.1
1390
-
1391
- - 修三个潜伏的结构性缺陷:孤立「身」角标残骸、解析详解块调色板失效、320px 下六爻盘横向溢出
1392
- - 打印时折叠的详解自动展开;宫格补 `aria-expanded` 同步
1393
-
1394
- ## 0.13.0
1395
-
1396
- - 八字四柱表按专业排盘版式重排(四列并排、无竖线、干支大字、十神分组着色、藏干逐行)
1397
- - 末行新增五行旺相休囚死;修 `td.big` 选择器长期失效
1398
-
1399
- ## 0.12.0
1400
-
1401
- - 紫微补流月 / 流日 / 流时(斗君逐级下推),接入盘面与解读
1402
-
1403
- ## 0.11.0
1404
-
1405
- - 深色主题(盘面颜色全变量化)、存为 PDF / 打印、修 390px 下塔罗 tab 被裁
1406
-
1407
- ## 0.10.0
1408
-
1409
- - 紫微宫位可点击展开详情、三方四正联动;修「身宫整格消失」的类名撞车
1410
-
1411
- ## 0.9.0
1412
-
1413
- - 紫微十四主星加庙旺得利平不陷亮度标注;塔罗面板可选 1/3/5 张牌阵
1414
-
1415
- ## 0.8.x
1416
-
1417
- - 0.8.0 起卦 tab 新增「所问之事 + 询问方向」,解读按问题展开;解析区可折叠
1418
- - 0.8.1 紫微解读补化科、流年四化不再截断
1419
- - 0.8.2 手机竖屏紫微盘恢复 4×4 宫盘
1420
- - 0.8.3 竖屏布局改用容器查询,修窄侧栏下盘面挤成一团
1421
-
1422
- ## 0.7.0
1423
-
1424
- - 新增「解析与详解」模块:五维度解析、卦象卦辞爻辞动爻、塔罗连贯解读,带免责提示
1425
-
1426
- ## 0.6.0
1427
-
1428
- - 六爻 / 梅花 / 六壬面板重绘(真爻线、体用标注、天地盘方盘);输入区区分出生时间与起卦时刻
1429
-
1430
- ## 0.5.0
1431
-
1432
- - 八字 42 神煞(七类、双查法)+ 格局 / 用神 / 大运流年评分
1433
- - 紫微 34 格局、大限一览、流年四化
1434
- - 塔罗模块重写:78 张牌、牌阵位义、6–8 段解读、体系声明
1435
- - 首个进入插件市场投稿流程的版本(awesome-dsh-plugin PR)
1
+ ## 0.61.0(2026-11-03)
2
+
3
+ > 本版主题(续):择日不再只数建除宜忌——按《协纪辨方书》卷十一「用事」的逐条神煞计分,再按卷十「宜忌」的六等与德神制化定轻重,起法逐条可回溯。随 0.61.0 发布。
4
+
5
+ - **择日神煞宜忌层**(新增 `engine/zeri-shensha.js`,约 15KB):
6
+ - 数据分两层:卷十一「用事」16 条事项的宜/忌神煞名单逐字照录;起法分散在卷四(建除十二神、月建、月厌、厌对、阴阳不将)、卷五(天德、月德、天德合、月德合、月空、天恩、天赦、天愿、母仓、月恩、四相、时德、王官守相民日、四击、九空、五墓、四耗、四废、四忌四穷、九坎九焦、五虚、八风触水龙、宝义制专伐日、八专、无禄、重日五合五离、解神、复日、鸣吠、鸣吠对)、卷六(三合、临日、驿马、劫煞、灾煞、月煞、月刑、月害、大时、游祸、天吏、六合、兵吉、五富、天仓、天贼、要安、玉宇、金堂、敬安、普护、福生、圣心、益后、续世、阳德、阴德、天马、兵禁、地囊、土符、大煞、归忌、往亡、月忌日)与卷九「立成」。
7
+ - 27 个择日事项全部映射到卷十一的 16 条事项;无对应条的走建除简表,映射依据写在 `ZERI_SHENSHA_BASIS`。
8
+ - 没有可靠起法的条目(土王用事后、血忌、伏社日、八风、气往亡、专日、伐日、四离、四绝、上朔)逐日 `shensha.unsupported` 列出,不猜、不计分。
9
+ - 条件神煞按原文条件:天狗只作「申月戌日」;阴阳不将按十二月逐支表;归忌按孟仲季月;三合按局;解神按冲月建(与紫微按月安的解神区分)。
10
+ - **打分口径**(`engine/zeri.js`):
11
+ - 建除宜 +2、建除忌 −2;神煞宜每颗 +2(单类封顶 +4);神煞忌、日忌、农历日忌各每颗 −2(各封顶 −4);当事人属相逢冲 −2 并径直排除。
12
+ - 结果逐日新增 `shensha`(月支、建除神、当日神煞名单、宜/忌分组、未实现条目),顶层新增 `shenshaRef`(底本、卷次、未实现清单)。
13
+ - `meta.scope` 与 `disclaimer` 明写:六等判词与德神制化取自卷十,吉/凶权重与比值阈值是本仓校准(不是古籍常数),等第表未逐格数字化。
14
+ - **接线(全链路)**:`engine/index.js` 摘要加「神煞依据/起法/未实现起法」一行;`src/panel-kit.js` 择日面板同步显示;`index.js` 工具描述改写为「宜忌依卷十一逐条」。
15
+ - **闸门**(新增 `test/zeri-shensha.test.mjs` 11 条 + `test/fixtures/zeri-sources.json`):
16
+ - 原文锁:夹具里的卷十一原文按最长优先词典切词,逐条等于 `SHENSHA_LISTS` 的宜/忌数组——表被「顺手补齐」即红;夹具条数与库的条目数必须一致。
17
+ - 27 事项映射完整性;2026-10-29(戌月丙子,满/民日/灾煞)、12-01(亥月己酉,开/灾煞)、12-15(子月癸亥,闭/四穷)、12-22(子月庚午,破/月破/大耗、冲鼠)四组逐日落星;天狗只申月戌日;土王用事后只进未实现清单。
18
+ - 打分锁见下条「卷十」;`compare.best` 落在 12-01。
19
+ - **审查修掉一个展示 bug**:余忌命中时 `verdictOf` 把对象数组直接 `join`,逐日断语渲染成「…的余忌之列([object Object])」;改为取神煞名,并补两条回归断言(点名「灾煞」、全文无 `[object Object]`)。
20
+ - 断言基线 7496 → 7518(151 → 152 个文件;新增 22 条卷十测试)。
21
+ - **卷十「宜忌」六等与德神制化**(继续 `engine/zeri-shensha.js`):
22
+ - 六等判词逐字取卷十 4853 行:上(吉足胜凶)、上次(吉足抵凶,遇德从宜、不遇从宜亦从忌)、中(吉不抵凶,遇德则吉胜,不遇从忌)、中次(凶胜于吉,遇德始相抵)、下(凶又逢凶,遇德从忌、不遇诸事皆忌)、下下(凶叠大凶,遇德仍诸事皆忌),另立「平」(吉凶相抵)。原文「参」在底本误作「防」,`GRADE_TEXT` 按文义还字,夹具注明。
23
+ - 德神制化按卷十各条按语分三类:`keJie` 德神可解(月建、满日、闭日、劫煞、灾煞、月煞、月刑、月害、月厌、大时、天吏、厌对、复日)、`buJie` 德神犹忌(月破、天狗、游祸、四忌、四穷、往亡)、`wuShe` 与德义不相属(九坎、九焦、土符、地囊、归忌、血忌)。「止忌……」的余忌按事项落回 `residualEntries`(灾煞等止忌求医疗病、月厌止忌婚嫁出行等、月建止忌兴造破土)。
24
+ - 月日条件按原文:满日值守日/相日、闭日值王日/官日、劫煞/灾煞/大时/天吏按孟仲季月值某建除、月刑「巳月值平日」、月害「卯酉月值除日守日、丑未月值执日大时」、月厌「寅申月值成日、丑未月值开日」。德神名单不满足条件或不在名单内,仍按不遇德处理。
25
+ - 月厌叠月破或灾煞时直接判下下·诸事皆忌,遇德也不解。
26
+ - 输出:逐日新增 `grade`(等第、判词、宜忌方向、德神、吉/凶合分、比值、可解/仍忌/犹忌清单、是否叠凶),顶层 `shenshaRef` 新增 `juan10`;`meta.scope` 与 `disclaimer` 明写权重/阈值是本仓校准、等第表未逐格数字化。
27
+ - 接线:`engine/index.js` 摘要逐日附「卷十等第·宜忌方向」并新增一行卷十依据;`src/panel-kit.js` 候选表新增「卷十等第」列与依据脚注;`test/fixtures/zeri-juan10.json` 存判词与 25 条德神制化关键词。
28
+ - 评分锁随六等改写:10-29 开业 +4 推荐·上、12-01 +3 推荐·上、12-08 0 平平·平、12-15 −5 回避·下·诸事皆忌、12-22 排除;灾煞遇德对开业可解,对求医仍落余忌。
29
+
30
+ > 本版主题:紫微的杂曜不再只有 49 颗简盘——十二颗缺的星按安星诀逐颗落地,诀文一并交给使用者和别家模型。随 0.61.0 发布。
31
+
32
+ - **杂曜安星库**(新增 `engine/ziwei-zuoyao.js`,11KB):
33
+ - 补上通行简盘长期缺的十二颗:解神、天巫、天月、阴煞(按生月);天官、天福、天厨(按生年干);蜚廉(按生年支);天德、年解(按生年支起宫顺/逆);天才(命宫+生年支)、天寿(身宫+生年支)。八颗走十干/十二月明表,四颗走起宫顺逆公式;分类为吉星 7、煞星 3、杂曜 2。
34
+ - 三条硬口径:**至少两处独立站点同表才收**(37 条链接去重后 9 个来源,每颗都有 ≥2 个不同站点);**诀文照录不改写**,转抄例子与自家诀文相抵时以诀文为准(天才一例三源同诀、转抄却写「巳宫安天才」,判为笔误);**同名异星绝不合并**——蜚廉(年支)≠ 博士十二神的飞廉、按年安的天德 ≠ 岁前十二神的天德、年解 ≠ 按月安的解神(月解),三组在盘上各处其位。
35
+ - 龙德、月德刻意不入表,`ZUOYAO_SKIPPED` 逐颗写明 20 字以上理由(与岁前十二神同名同宫、并入即重复安星),面板与复制提问都看得到这份「没收清单」。
36
+ - **新开关 `zuoyaoSchool`(默认 `minimal`,盘面一字不变)**(`engine/ziwei.js`、`engine/index.js`、`index.js`、`engine/diff.js`):
37
+ - `minimal` 仍是通行简盘 49 颗;`full` 按上面的诀补入十二颗,共 61 颗。默认不排的理由写在开关表注释里:星数一变,旧盘的宫位句柄与已存命盘会静默变盘。
38
+ - 结果新增 `zuoyao` 层:`mode / starTotal / placed[]`(星名、地支、宫名、定宫依据、基本义、入庙标记)`/ verses`(一行一颗的诀文块)`/ skipped`;`rules.schools` 并列入杂曜口径,`rules.zuoyao` 两档各给一句该怎么打开。
39
+ - 口径并排(紫微 12 → 13 组)新增「杂曜:49 颗简盘 / 61 颗全表」;`【流派】` 行只在显式改动时出现。
40
+ - **修掉一个真 bug**:`zuoyaoBranch` 的公式曜原先只挡命宫/身宫,缺生年支时 `fix(NaN)` 照样返回「一个宫」,天德、年解会带着 NaN 落宫被塞进盘里(面板宫名渲染成空)。现在四颗公式曜都先验生年支,并对非有限值兜底返回 null——缺依据就整颗不排,绝不安到默认宫。
41
+ - **接线(全链路)**:`engine/followup.js` 复制提问在全表盘后附「紫微杂曜安星诀」段(本盘落宫 + 诀文 + 未另立清单,并明写属通行说、不是《全书》原文),简盘不塞这段;`src/panel-kit.js` 宫位与详情两处加「庙」标,盘下方新增可折叠的诀文块,默认档另给一句白话说明怎么开全表;独立页 `命理排盘.html` 同源带出。
42
+ - **口径落成知识卡**(`engine/interpret-knowledge.js` 新增 `ziwei-zaoyao`):挂 `overall / work / health`——`overall` 已被三方四正、破格、四化三张占满(每维最多 3 张),而天官、天福、天厨主贵显与俸禄(事业/公职),天月、解神、阴煞主病符与消灾(疾厄),落宫实质就落在这两维。`engine/citations.js` 记为 `general`(通行说):维基文库本《紫微斗数全书》卷一是赋文与格局、卷二是安身命例,未见这套安星诀,故不署《全书》原文。
43
+ - **体积**:杂曜库随紫微引擎进 `ziwei / bazi / hepan` 三块(+11KB 源码 / +6.5KB gzip),三块原本就贴着 220KB 的 gzip 分块线(最紧一块 213KB),加完变 219.6 / 223.7 / 222.9KB → `test/chunks.test.mjs` 的上限抬到 228KB,并把「再加库就该拆块」写进注释;入口 `client.js` 不受影响。18 块合计 gzip 2.38MB。
44
+ - **闸门**(新增 `test/ziwei-zuoyao.test.mjs` 96 条):
45
+ - 期望值全部由诀文里的地支字重导(`byBranch`),不复制引擎表内数字——表被人「顺手补齐」就红;解神另用第二式(月建对冲)逐月独立互核;新库反过来反查旧表(破碎/华盖/咸池三组三合位)。
46
+ - 面板不靠源码 grep 交差:用 `vm` 把真 `src/panel-kit.js` 载进沙箱、拿真 `compute` 渲两档盘,逐条数「已排 12 颗/12 个 chip/入庙标记/诀文折叠且写明属通行说/11 行诀文/龙德月德未另立/简盘无诀文块/全页无 `undefined`·`NaN`」;撤掉模板里的 `${zyHTML}` 即 4 条红。
47
+ - `placeZuoyao` 缺依据整颗跳过(12/8/9/11/0 五档)、入庙标记只在庙地名单内出现、诀文块一行一颗;开关默认与两档盘面(49 vs 61、简盘星名必为全表子集、盘上落宫 = 库复算落宫)、三组同名异星并存不合并。
48
+ - **新增「接线漏检锁」**(`test/ziwei-schools.test.mjs`):每个流派开关都必须同时出现在工具 schema、`compute` 平铺透传与口径并排三处——本轮先只加了引擎侧,正是这条能拦住「AI 传了参数但服务端不认」;开关计数由「10」改为键名清单,规则行由「列全九项」改为十一类逐条。
49
+ - 连带更新:`citations.test.mjs` 通行说计数 7 → 8(有意设的锁),并按 `npm run build:citations` 重建 `docs/citations.html`。断言基线 7350 → 7496(150 → 151 个文件)。
50
+
51
+ > 本版主题(续):起名字库从「够用」扩到「常见姓名基本不缺字」。随 0.61.0 发布。
52
+
53
+ - **字库扩容:391 → 1062 字**(`engine/name-extra.js`、`engine/name.js`、`engine/name-data.js`):
54
+ - 新增 671 个常用名用字,按五行分组:木 210、火 89、土 89、金 143、水 140;原 391 字一字未删,`CHAR_LIB` 与 `READING` 用展开合并,原有调用方与数据形状不变。
55
+ - 补上此前大面积缺字的真实姓名常用字:伟、杰、军、强、丽、娜、秀、英、敏、娟、凯、豪、虎、兵、仪、喆、靖、翊、芯等;`李伟杰`、`王丽娜`、`王秀英`、`张建国` 这类名字不再出现「未收录」。
56
+ - 读音与康熙笔画由 Unihan `kRSUnicode` + 康熙部首笔画 + `kTraditionalVariant` 复算,不是手敲;繁体映射会串义的字按人名通行取法覆盖:千 3、才 3、发 12(發)、钟 17(鍾)、苏 22(蘇)、采 8、万 15、镌 18;长/兴/种按人名读法取 chang2/xing1/zhong4。
57
+ - 未收录字仍不猜五行;扩库只增加「可判断」的字,不改变任何五行归类口径。
58
+
59
+ - **候选排序加「常用字优先」**(`engine/name.js`):
60
+ - 字库变大后,笔画讨巧的生僻字可能挤进候选;排序在「合喜用 → 两字异行」之后新增常用字档(两字都常用 > 一字常用 > 都不常用),再看五格与性别倾向。`suggestFor` 给未收录字的替换建议同样先挑常用字。
61
+ - 常用字集合只用于加权排序,不参与五行判定;`notes` 里的排序说明同步改写。
62
+
63
+ - **闸门**(`test/names.test.mjs`、`test/name-wuge.test.mjs`):
64
+ - 字库规模改为 1000–1200 字双边界;新增 50 个真实姓名样本的覆盖率门槛(逐字查,缺字率 ≤5%,当前 123/123)。
65
+ - 新增扩充字笔画锚点(千/才/发/钟/苏/采/万/镌/伟/丽/杰/凯/娟)与长/兴/种的读音锚点,防生成脚本回退。
66
+
67
+ > 本版主题(续):六爻与梅花不再只有白话大意,盘面直接给出《周易》经文原文。
68
+
69
+ - **《周易》经文原文库**(`engine/yijing-text.js`):64 卦辞 + 384 爻辞 + 乾用九 / 坤用六,共 386 条爻辞。
70
+ - 原文照录,不改写、不意译;〔一作…〕标出 20 处古籍异文,只在原句后加括注,不动正文。
71
+ - 三份公开底本互校生成(npm `@freizl/yijing`、npm `iching-shifa`、GitHub `liujuntao123/yijing`),逐条折叠简繁异体后投票:三源一致直采,两源一致取多数,三源互异与已知讹字逐条裁定,裁定只用《周易》本书互证(《彖》《小象》《系辞》引文)与通行注疏本,不引外书。
72
+ - 投票确实抓到底本自身的错:`@freizl/yijing` 姤九五整句重复一次、大有九二误置同人六二「同人于宗,吝」;`iching-shifa` 把大有九二的爻题标成「六二」。爻题因此不抄底本,一律由卦画推出。
73
+ - 取辞按京房体系:动爻取该爻爻辞,六爻皆变且为乾坤时补用九 / 用六,无动爻只给卦辞并写明「六爻皆静」。
74
+ - **六爻 / 梅花结果新增「经文原文」节**(`engine/liuyao.js`、`engine/meihua.js`、`engine/interpret.js`):本卦卦辞 → 动爻爻辞 → 互卦卦辞(梅花)→ 变卦卦辞,排在白话大意之后、「落到生活里」之前;面板逐行转义渲染,无需新增样式,CLI 摘要(`interpretText`)自动带上。
75
+ - **复制提问把原文一起带走**(`engine/followup.js`):交给别家模型的那段话里,盘面摘要之后新增「《周易》经文原文」段——只读结果里已算好的 `jing`,ASK 栈不多背这 12KB;非卦象体系不多塞一段。
76
+ - **体积**:这张表只进 `client.liuyao.js` 一块(gzip +12KB,该块 178KB),不进解释栈;其余 17 块体积不变,分块合计 2.33MB。
77
+ - **闸门**(`test/yijing-text.test.mjs` 64 条、`tools/check-bundle.mjs`):
78
+ - 结构自证:384 爻的爻题「九 / 六」逐位比对引擎卦画,爻题写法(初/上位在前、二三四五题在前)全部合京房例;386 条爻辞正文与 64 条卦辞两两不同——大车型错置永远回不来。
79
+ - 接线:跑构建产物 `client.liuyao.js` 的 factory 出盘,锁住「漏配 `tools/build-client.mjs` 时分块静默没有经文」这一类;再加体积锁(表 ≤40KB、不得混进无关分块)。
80
+ - 新闸门「模块顺序」:打包按 `ORDER` 顺序执行 IIFE,被依赖的模块必须排在前,否则取到 `undefined` 且不报错——本次踩到两次,现在由 `check-bundle` 拦。断言基线 7146 → 7213。
81
+
82
+ > 本版主题(续):姓氏库从 129 姓扩到 998 姓 + 82 复姓,生僻姓的五格不再整块「算不了」。
83
+
84
+ - **姓氏库扩容**(新增 `engine/surname-data.js`,`engine/name-data.js` 改为从它摊开):
85
+ - 单姓 129 → **998**,复姓 13 → **82**;每行是「字 + 康熙笔画 + 拼音 + 声调」,`SURNAME_STROKES / SURNAME_READING / DOUBLE_SURNAMES` 三个旧出口的形状与调用方一字未改,`engine/name.js` 与面板不需要跟着改。
86
+ - 笔画不是手敲:三份独立资料互证(康熙笔画表 / 起名用字表 / 姓氏词典),都缺时用 Unihan 的康熙部首结构值(部首本字画数 + 剩余画数)复算,两条独立路径对上才收;三份资料与旧表四票不一致时逐字人工裁定,理由写进模块头部注释(温 13、万 15(繁体萬)、赖 16(貝部九画,旧表作 20 是错的)、钟 17、迟 19、沈 8、岳 8、板 8、御 11 等 25 字)。瓮(瓮/甕差 10 画)取不定,宁缺不猜。
87
+ - 71 个姓只给得出笔画、给不出唯一读法(乐 Lè/Yuè、查 Zhā/Chá、区 Ōu/Qū 这类多音),拼音一律留空——音韵检查照旧落空并点名缺哪个字,不拿一个可能错的读音去判「顺口」。覃/蔚/隗/柏/乐/能/查/石/尉九个姓另存又读,主读照算,盘面与摘要并列显示「姓又读 覃tan2」。
88
+ - 复姓读音同样由姓氏词典连写(万俟 mòqí、单于 chányú、尉迟 yùchí、澹台 tántái、乐正 yuèzhēng),笔画按逐字康熙值:旧表 诸葛[15,15]、令狐[5,8]、慕容[14,10] 三处按资料改为 [16,15] / [5,9] / [15,10]。
89
+ - **修掉一个真 bug**:`phonetics(fullName)` 原先只把全名第一个字当姓,复姓的第二字(诸葛的「葛」、尉迟的「迟」)走起名用字库,字库没有就整体报「没有读音数据」。现在 `phonetics(fullName, surnameLen)` 由调用方给出姓的字数,复姓逐字都能从姓氏表取读。
90
+ - **接线**:`engine/index.js` 摘要的【音韵】行带出又读;面板名字卡音韵行同样并列(`src/panel-kit.js`);`tools/build-client.mjs` 把 `surname-data` 排在 `name-data` 之前、只挂进 `name` 一块(该块 gzip 143KB,其余 17 块体积不变)。
91
+ - **闸门**(新增 `test/name-surname-lib.test.mjs` 48 条):
92
+ - **常见姓覆盖 100%**:把三份姓氏资料并集里的 521 个常见姓**冻结成测试内的锚点串**(不拿本轮抓取结果当标准答案),逐个要求入表;扩容失败或日后删表都会红。
93
+ - 形状与取值:4 列、笔画 1–40、拼音只含小写字母、**拼音为空 ⇔ 声调为 0**、无重复字;又读必须与主读不同且该姓已有主读。
94
+ - 康熙笔画与读音锚点各一组(含被推翻的旧值 赖 20),复姓逐字笔画齐全、`万俟=moqi`、`单于=chanyu` 锚点。
95
+ - 症状回归锁:撒/蹇/冼/戏/蒉/訾/昝/厍 这些原先五格「算不了」的姓现在都排得出天格 = 姓画 + 1;`compute` 端到端(生僻姓出五格、摘要带又读、候选按五格排序)。断言基线 7213 → 7261。
96
+
97
+ > 本版主题(续):塔罗从「78 个名字 + 几个关键词」补成一套有底本、有出处、敢留空的牌义库。
98
+
99
+ - **78 张牌义库**(新增 `engine/tarot-cards.js`,16KB):
100
+ - 底本声明为 Rider-Waite-Smith(1909)系,牌义按黄金黎明一脉(Liber 777 公开对应表)取,三处独立资料互核;三源一致才入库,不一致的逐条裁定并把理由写进模块头注释。不同体系的牌义(托特/马赛)不并进同一句话。
101
+ - 每张牌七个字段:英文名、牌面图像(中文白描 15–60 字,78 张全)、核心寓意(小阿卡纳 56 张各写一句,不复用通用句式)、元素、行星、星座、生命树源质。大阿卡纳 22 张全部给行星+星座,小牌 2–10 共 36 张按三分相定星座(权杖=白羊/狮子/射手,圣杯=巨蟹/天蝎/双鱼,宝剑=天秤/水瓶/双子,星币=摩羯/金牛/处女):2-4、5-7、8-10 依次落进这三个星座,同组三张各占该星座的第一/二/三旬,旬主星按迦勒底连续序(白羊一旬起火星)落定(例:权杖二=火星在白羊第一旬,权杖四=金星在白羊第三旬,圣杯九=木星在双鱼第二旬)。
102
+ - **三处明写的「不给」**:四张首牌只归源质不配单一星座;16 张宫廷牌不给占星对应——公开资料里两套映射(国王=本位宫一派 vs 黄金黎明四元素层级一派)在多数花色上把国王与王后对调,本插件不合并两派,只给元素与角色定位(学徒与消息 / 推进与风格 / 滋养与吸引 / 掌控与承担);22 条希伯来字母路径层整体不录入,因为它与牌义无关却最容易被抄错。
103
+ - 占星对应全部由规则表算出(`SUIT_SIGNS` / `DECAN_PLANETS` / `SEPHIROTH` / `DECAN_CN`),不逐张手敲;手写的只有中文图像与核心寓意。生成脚本收进 `tools/gen-tarot-cards.mjs`,`node tools/gen-tarot-cards.mjs` 一条命令重生成,Temp 目录不再是这份数据的一部分底稿。
104
+ - **接线(全链路)**:`engine/tarot.js` 牌库与抽牌结果逐张带出新字段;`engine/index.js` 摘要每张牌补 `[英文名]` 与「牌面:…」一行;`engine/plain-summary.js` 顶部人话总结带出牌面图像与占星对应(宫廷牌改说「它在盘上顶的是「…」那个角色」);`engine/event-prompt.js` 与 `engine/followup.js` 复制提问把核心义、占星对应/牌位角色、牌面图像一并带走;`src/panel-kit.js` 面板卡新增英文名牌与牌面白描段(配套两条样式);`engine/interpret.js` 逐牌解读改写为「牌面上…,它对应的占星位置是…/它在这里顶的是「…」那个角色」。
105
+ - **口径落成知识卡**(`engine/interpret-knowledge.js` 新增 `tarot-correspondence`,`engine/citations.js` 同步收录):塔罗解析文末「这套规则有多稳」会点名本盘涉及的旬位取法与「宫廷牌两派冲突故留空」,状态标签「文本·各家有异说」;`engine/tarot.js` 的 `systemNote` 同步说明,`engine/followup.js` 的追问骨架改为「逐牌(正逆/牌面/元素对应)」。
106
+ - **体积**:逐张牌库只挂在 `client.tarot.js` 一块(该块 gzip 176KB,未触 260KB 上限),不进公共解释栈——其余体系不背这 16KB。18 块合计 gzip 2.36MB。
107
+ - **闸门**(新增 `test/tarot-cards.test.mjs` 86 条):
108
+ - 数据自证:78 行形状、英文名纯 ASCII、图像 15–60 字、小牌核心 8–30 字且 **56 句互不相同**(防止回退成套话)、花色与元素逐张对 `SUITS` 一致。
109
+ - 规则闸门:36 张小牌的星座/旬主星逐个按 `SUIT_SIGNS × DECAN_PLANETS` 反算比对,**旬位标注另用一张手抄的迦勒底旬主星表(12 星座 × 3 旬)独立反查**——牌上的行星在该星座实际主第几旬,标注就必须是第几旬;首牌与宫廷牌的「留空」本身是断言(配了星座就红);22 张大牌的行星与星座逐张过庙旺规则(守护星落在本命宫)。另有 30 条冻结锚点(权杖四=金星在白羊第三旬、圣杯九=木星在双鱼第二旬等)与 5 条英文名、3 条源质锚点——换底本或改表都会红。
110
+ - **修掉一个自相矛盾的标注**:旬位原先按「二三四→第一旬、五六七→第二旬、八十→第三旬」分组算,于是权杖三(太阳)与权杖二(火星)同标「白羊座第一旬」——而白羊第一旬的旬主是火星。实际口径是同组三张分居该星座的一/二/三旬,改为按组内序号取模;三源互核的是行星与星座,这一层错的只是标注文案。
111
+ - 端到端:`compute` 摘要两行格式、`brief.sections`、逐牌解读文案、`buildEventPrompt`、面板 HTML(`vm` 里跑)五处都验;`systemNote` 必须提到宫廷牌。
112
+ - 连带更新:`citations.test.mjs` 的通行说计数 6 → 7(这条计数是有意设的锁,新增卡片要显式改),并按 `npm run build:citations` 重建 `docs/citations.html`。断言基线 7261 → 7350。
113
+
114
+ ## 0.60.0(2026-11-02,已发布)
115
+
116
+ > 已发布:npm `dsh-metaphysics@0.60.0`,shasum `6e126e8d84348f10945faa5e5759b454858d8f59`,94 个文件;tag `v0.60.0` 已推(指向发版提交 `3c92da1`,其后仅文档回写),GitHub release 已建。
117
+
118
+ > 本版主题:从「算得对」推进到「用得顺」。新增**我的命盘**(本机档案)与**复制提问**两条日常路径,并把历算、输入守卫、异步竞态、发布闸门里查出来的问题逐条修掉。新增能力不改变既有排盘口径;同一输入、同一 asOf 仍产出同一张盘。
119
+
120
+ - **我的命盘:一次录入,下次点卡出盘**(`src/panel-kit.js`、`src/app.js`、`src/web-ui.js`):
121
+ - 面板与离线单页共用一套实现与同一个存储键 `dsh-metaphysics/profiles-v1`:存的是出生日期、时刻、性别、出生地这些**输入**,不是结果;只落本机,不上传。
122
+ - 卡片照市面排盘 App 的命盘列表:一张卡一个人,点卡直接出盘;改名、置顶、删除收在卡片右上角,悬停或键盘聚焦才出现,触屏常驻。置顶在前,其余按最近排过排序;最多 24 张,超出时淘汰最久没排的那张。
123
+ - 档案来自 localStorage,按外部输入对待:逐字段验一遍,日期要真过日历,坏条目整条丢弃,不把 `undefined` 渲染进卡片;同 id 只留第一条。
124
+ - 删除点两次才算;改名会把原称呼读回输入框,改完点「更新这张档案」覆盖原档,创建时间、使用次数与置顶状态不变。
125
+ - 写入失败不再假装成功:`profilesPut` 报失败,删除/置顶/记次数也回滚到存储里的真实状态;浏览器完全没有 localStorage 时同样按失败回报——否则卡片从界面消失、下次进来又复活。
126
+ - 旧版本或手改存储留下的「有日期没时刻」卡不再拿表单里现成的时刻顶上(那会排成另一个人),而是提示先补时刻;这种卡也不算「排过一次」。
127
+ - 称呼框是裸 DOM:面板重绘与单页重绘都先把已输入的字存起来,翻置顶、切视图不会把称呼抹掉。
128
+
129
+ - **复制提问:把盘面和问题整理成一段话,交给任意 AI**(`engine/followup.js`、`engine/bridge.js`、`src/app.js`、`src/web-ui.js`):
130
+ - 追问框优先于「所问之事」:只读主问题时,命盘类没有这个输入框,复制出去的「所问」会永远是默认开场句。
131
+ - 包里带上面板已算好的开场结论(直答/说人话),别的模型开场沿用同一口径;盘面摘要与回答骨架一并带上。
132
+ - 打包失败时按钮给出「暂无可复制内容」并自动复原,不再毫无反应;切方向 / 重绘结果时追问框里已经输入的字保留。
133
+
134
+ - **输入守卫:坏参数不再静默变成另一张盘**(`engine/index.js`、`index.js`、`engine/handle.js`):
135
+ - 经度统一整形并校验:数字串转数字;非有限值或超出 −180…180 报 `E_RANGE`,不再走到真太阳时里炸成裸异常,也不再静默少一次修正。
136
+ - 地址、问题、revise、ask、姓名等自由文本设长度上限——这些串会整段进句柄,不设限等于允许一次调用把结果撑到几百 KB。
137
+ - `datetime` 的秒位真正校验;`asOf` 的小时与分钟必须在范围内,非法值不再被折回另一天。
138
+ - 句柄增量拒绝 `__proto__` / `constructor` / `prototype` 键,避免改掉结果对象的原型。
139
+ - 联网解析失败不写缓存:不会连着六小时把「解析失败」当成答案;风水不再请求出生地解析(经度对盘面没有影响,发给第三方是纯外泄)。
140
+ - `detail` 只接受 `full` / `lean`,写了别的值不再被当成缺省静默放过。
141
+
142
+ - **历算修正**(`engine/calendar.js`、`engine/lunar.js`、`engine/dst.js`、`engine/ziwei.js`、`engine/trend.js`、`engine/random.js`、`engine/rectify.js`、`engine/zeri.js`):
143
+ - `jdToParts` 的分钟进位会让 23:59:45 塌回「当日 00:00」,日柱退一天;改为先归到整秒再向下取整分,拆出的那一天永远就是这一刻所在的那一天。
144
+ - 农历的节气时刻被移了两次时(净偏移约 −12 分),节气落在午夜前后十几分钟内会少算一天,置闰整月错位;修正后 1917 年由「闰三」回到真历表「闰二」、1922 年由「闰六」回到「闰五」。
145
+ - 夏令时换表日给出明确说明:起算日 02:00–03:00 的钟面读数在当年不存在,终止日 01:00–02:00 同一读数对应两个真实时刻——按哪种读法折算写进提示。
146
+ - 紫微流年改用调用方的 `asOf` 作基准年,同一句柄跨年不再排出不同的流年表;人生 K 线按交运年份切段,与虚岁轴对齐,不再整条线提前一年。
147
+ - 随机种子把高位与小数位折进状态:相差 2^32 的种子(如隔 49.7 天的毫秒时间戳)不再摇出同一卦。
148
+ - 生时校正的事件限 200 条、年份限 1600–2400、候选时辰去重后最多 24 个;择日事项错误统一带 `E_INPUT`,`days` 的数字串会被规范化,越界或非数字一律报错,不再静默改成 30 天。
149
+
150
+ - **输出档位与上下文**(`engine/index.js`、`index.js`、`engine/handle.js`):
151
+ - 新增 `detail: "lean"`:只给结论、所问方向那一条与三张表,长论述与「规则·出处」折成一行指针(省约一半文本);盘面、句柄与解析对象不变,影子盘与口径对照也不会把档位当成盘面差异。
152
+ - 工具 schema 把梅花与小六壬的 `mode` 合并进同一个字段并写明三组取值,避免同名字段被后定义覆盖。
153
+
154
+ - **客户端稳定性**(`src/engine-lazy.js`、`src/app.js`):
155
+ - 分块在途请求去重:并发打开两个体系共享同一次下载;失败也清掉在途记录,一次网络抖动不会把分块永久钉在「正在加载」。
156
+ - 面板连续排盘 / 连点 tab 时用序号丢弃过期结果:旧请求不再覆盖新盘,也不再在 await 之后把 tab 拨回去。
157
+
158
+ - **闸门与发布**(`tools/`):
159
+ - `check-html-sinks` 重写:逐插值判定,补上四类旧版漏检(裸变量赋值、一个 `esc(` 救全条、`insertAdjacentHTML` 的第二个实参、`dangerouslySetInnerHTML`),并带可自证的漏检用例。
160
+ - 发布脚本不再 `git add -A`:按目录白名单与扩展名逐路径暂存,点开头的运行痕迹不收,重命名记录正确跳过来源路径。
161
+ - 新增凭据扫描、对拍报告新鲜度校验、分块体积预算(单块 gzip ≤260KB、18 块合计 ≤2.75MB)。
162
+ - `npm test` 现有 147 个测试文件 / 7139 条断言;新测试覆盖档案存储、分块预算、客户端竞态、细节档位、DST 歧义、输入守卫、HTML 注入面、凭据闸。新增断言均通过「把旧实现改回去必须变红」的反向验证。
163
+
164
+ - **真机回归**:`e2e-dom` 137 项、`e2e-panel` 89 项全过,覆盖档案存入/回填/改名/置顶/两次删除/缺时刻拦截、复制提问的所问与开场结论、切方向后追问框保留、深色与窄屏布局、全程无 JS 报错。
165
+
166
+ ## 0.59.1(2026-11-02,已发布)
167
+
168
+ > 已发布:npm `dsh-metaphysics@0.59.1`,shasum `43817f74d114121bbbe947c91abc10a825a287b9`,94 个文件。
169
+
170
+ > 本版主题:把「先说结论」从八字/紫微推到全部九个体系,并且堵住三个会让第一屏**说错话**的坑。不新增断法,不改算法;改的是「第一屏能不能读、说的是不是真的」。
171
+
172
+ - **九个体系都有第一屏了**(`engine/plain-summary.js`、`engine/index.js`、`src/panel-kit.js`):
173
+ - 之前只有八字与紫微在盘面上方给一段人话;六爻、梅花、六壬、奇门、塔罗、合盘、走势七个体系点开就是一整屏术语。
174
+ - 现在每个体系一个 `xxxSummary`,统一返回 `{title,chips,lead,sections,advice,caveat,footer}`;`plainSummary()` 分派,`compute()` 统一挂在 `r.brief` 上(生成失败只记 `briefError`,绝不拖垮排盘)。面板侧收成一个 `pp.briefHTML(r)`,九个盘面都只写一行前缀,不再各自判一次、也不会漏一个。
175
+ - 各体系讲各自的结构:六爻讲世应/用神/月日/卦体,梅花讲体用,六壬讲三传(起手—转折—落点),奇门讲日干宫与时干宫的门星神,塔罗逐张给位置义,合盘讲日主关系/夫妻宫/五行互补,走势讲「这一步的基调、最亮最闷、怎么用」。
176
+ - 证据:`test/plain-summary.test.mjs` 从 63 条扩到 149 条。新增一组「七体系×五项」:给得出、字段里不许漏 `undefined`、每段有实质、至少一条可做的事、结尾写明不是断语、问事的要回显用户那句话。渲染侧另测九个盘面:方框在最前、只渲染一次、带免责尾句、结果无 `undefined`。
177
+
178
+ - **六爻停在「综合」:没有用神也给第一屏,并说清为什么**(`engine/plain-summary.js`):
179
+ - 问题:用神由「询问方向」定,而方向默认是「综合」。默认状态下卡片一片空白——恰好是大多数第一次点开六爻的人看到的样子。
180
+ - 改法:走「世应版」——只讲与问题无关的世爻、应爻、卦体(六冲/六合/伏吟/反吟)与动爻,并在补充说明里写明「不是算不出来,是取用神要先知道问什么」,第一条建议就是让用户补选方向。选定方向后自动切回用神版,两种版本不会同时出现。
181
+ - 顺带修一句措辞:动爻原来写「4、5、6 爻动」,会被读成「六个爻都在动」;改成「第 4、5、6 爻动」,标签里的「3 爻动」是数量。
182
+
183
+ - **修:选「财运/学业」时,建议那一段是空的**(`engine/plain-summary.js`):命盘的「询问方向」是 wealth/career/love/health/study/travel/general 七档,问事提示的六类是 career/love/business/action/day/other,两套键只有两个重合。不转这一道,「财运」取不到现实核对清单。新增 `DIR2KIND` 映射(财运→生意、学业→工作、健康→其他、出行→推进)。
184
+
185
+ - **修:合盘标签渲染成 `undefinedundefined × undefinedundefined`**(`engine/plain-summary.js`):合盘结果里 `dayMaster` 是「丁火」这样一整串,不是 `{stem,element}` 对象——两种写法现在都接住。
186
+
187
+ - **修:紫微同一段里既说「成」又说「破」**(`engine/plain-summary.js`):被判冲破的格局原先同时出现在「结构上成的是…」与「被冲破的格局有…」两句里,读的人只会觉得自相矛盾。被冲破的一律不计入「成」,措辞也从「被判为被冲破」改成「冲不等于毁,说的是它不如完好时那么顶用」。
188
+
189
+ - **修:奇门宫位写「6宫」**(`engine/plain-summary.js`):读奇门的人认的是乾宫、巽宫,不是阿拉伯数字。宫名从 `PALACE_FIELD` 释义里取,并补上方位(乾宫(西北));中宫仍按寄宫说明。
190
+
191
+ - **修:塔罗的「关节牌」取得随机**(`engine/plain-summary.js`):原来取「第一张逆位」,同一副牌换个抽牌顺序结论就换位置。改成取「现在/现况/核心/建议」那一张,没有就取中间一张;标签里也去掉重复的「3 张」。
192
+
193
+ - **走势不再读挂钟**(`engine/trend.js`、`engine/index.js`、`engine/plain-summary.js`、`src/core.js`、`src/app.js`、`src/web-ui.js`):
194
+ - 原来 `trendSummary` 用 `new Date().getFullYear()` 找「你现在在哪一步」,过了元旦同一条线会自己改口,也过不了 `check-patterns` 的时间约定。
195
+ - 改成:`buildTrend` 接受 `nowYear`,`compute` 从 `asOf` 取年,写进 `meta.nowYear`;引擎侧一律不读挂钟。界面(面板与离线页)用 `Core.todayStamp()` 传当天,内嵌在八字页里的 K 线也带上。没给 `asOf` 时不假装知道现在,改说「没给当前日期,所以不标现在在第几步」。
196
+ - 顺带多给一句有用的:「走到这一步的第 N 年,再过 M 年换下一步」。
197
+
198
+ - **修(最严重的一条):新增模块漏进分块构建,八个体系的产物里静默变成 `briefError`**(`tools/build-client.mjs`):
199
+ - `plain-summary` 只挂在八字/紫微的栈上。另外八个分块(六爻、奇门、六壬、塔罗、黄历、择日、称骨、起名…)里 `plainSummary` 是 `undefined`,`compute` 一调就抛,被 try/catch 收进 `briefError`——源码测试全绿,打包后第一屏直接消失。这正是 0.59.0 记过的同一个坑(`limits` 那次)。
200
+ - 改法:抽出 `BRIEF` 组,所有会调 `compute` 的分块都带上。`chunks.test.mjs` 的 19 体系逐字节比对当场抓到(报压缩名 `Fe is not a function`)。
201
+
202
+ - **修:八字页会同时出现两个「先说结论」**(`src/panel-kit.js`、`src/app.js`、`src/web-ui.js`):K 线随八字页渲染时也带上了自己的人话方框,两个方框抢第一屏。`trendHTML(r, { brief:false })` 用于内嵌,单独看走势时仍然保留。
203
+
204
+ - **口径对照不把「人话总结」当盘面差异**(`engine/diff.js`):`brief` 是从盘面派生的叙述,换一档口径必然改写;不剔掉的话,奇门晚子时那一项会从「1 处差异」变成 3 处。
205
+
206
+ - **时辰未知:八字三柱模式,紫微/合盘阻断,趋势降级**(`engine/bazi.js`、`engine/index.js`、`src/app.js`、`src/web-ui.js`、`tools/build-html.mjs`):
207
+ - 问题:没填时刻就按页面默认时刻排盘,时柱、紫微命宫、起运日照常出现——**看起来像算过,实际是拿占位值算的**。这比算错更糟:错得看不出来。
208
+ - 做法:`buildBazi` 接受 `hourUnknown`,内部仍按「正午」跑完整条管线(大运、旺衰要有个基准),但对外把不该被当成已知的东西全部收回——`pillars.hour = null`、命宫/身宫置空(依赖生时支)、输入回显不带钟点、`civilText`/`trueSolarText` 只留日期、大运与交运去掉时刻并标 `precision: 'day'`、五行不含时柱重算、只落在时柱上的神煞整条去掉。**全文不出现 `12:00`**,内部只用语义标记 `provisionalHour: 'noon'`。
209
+ - 下游分三类处理:紫微(命宫由生月+生时支定,时支未知整盘不成立)与合盘(夫妻宫、大运依赖时支)→ `HOUR_UNKNOWN` 阻断并给一句可执行引导;趋势 → 降级,顶层带 `hourPrecision: 'day'` 且首行写明「起运按日估算」。
210
+ - 摘要第一行固定句:「时柱按正午暂算,涉及时柱的结论仅供参考」——用户先看到「这不是一张完整盘」,才不会被下面的时柱/命宫误导。
211
+ - 界面:八字与人生 K 线的时间框旁多一个「时辰未知」勾选(勾上即收起时刻框),面板与独立页同一套行为;紫微/合盘不提供这个勾选,因为给了等于诱导出一个假盘。
212
+ - 证据:`test/hour-unknown.test.mjs` 47 条。三条硬断言——全文(JSON + 渲染文本 + 摘要)不得出现 `12:00`;时柱及依赖项必须为空且不得写成已知;提示必须是摘要第一行(无出生地、远期 ΔT 精度提示都不得把它挤到第二行);工具 schema 必须暴露 `hourUnknown`;面板 `pp-warn` 必须逐字含固定句。另有五条守下游:紫微/合盘必须抛 `HOUR_UNKNOWN`、趋势必须带按日标记、默认路径逐字节不变。
213
+
214
+ - **修:无地址时固定提示被挤到第二行**(`engine/index.js`、`test/hour-unknown.test.mjs`):地警告与 ΔT 精度提示也在往摘要最前插——固定句先插、后警告再插,「时柱按正午暂算…」就被压到第二行(命中精度提示时第三行)。改为最后再插固定句,并补「无出生地」「2150 远期盘」两条断言:现在无论有没有地址、精度如何,首行都是它。
215
+
216
+ - **补:工具 schema 也支持 `hourUnknown`**(`index.js`、`test/hour-unknown.test.mjs`):原先只有面板与离线页能勾三柱,`metaphysics_chart` 的 schema 里没这个参数,Agent 要不到。补上布尔参数与说明(八字三柱、趋势按日、紫微/合盘阻断),并加断言防回退。
217
+
218
+ - **面板三柱提示改用固定句**(`src/panel-kit.js`):`pp-warn` 文案统一为「时柱暂缺:只排年/月/日三柱,起运与交运按日估算。时柱按正午暂算,涉及时柱的结论仅供参考。」,与摘要首行逐字一致(有断言)。
219
+ - **证据与门禁**:`test:ci` 138 文件全过,断言基线 6737 条(0.59.0 为 6620);真机回归 `e2e-dom` 103 项、`e2e-panel` 43 项(含「方框只渲染一次」);`stress` 200 盘 14 项(p95 2ms、堆增长 +0.46MB)。
220
+
221
+ ## 0.59.0(2026-11-01,已发布)
222
+
223
+
224
+ > 已发布:npm `dsh-metaphysics@0.59.0`,shasum `4712088541c06b112792c9249fe64d0dbe0dd38d`,93 个文件。
225
+
226
+ > 本版主题:把「算得更准」这条路主动停下,改走「不骗人」。三件事——知识标签不再冒充「已验证」、分歧按「本盘涉及」分组、新增「本插件不回答什么」清单。都不碰算法:0.58.0 的应期回测已经说明,51.7% 对 29.6% 的随机基线,靠调规则优先级补不上来;能补上来的是「别让用户以为它比实际更可靠」。
227
+
228
+ - **知识标签不再冒充「已验证」**(`engine/interpret-knowledge.js`、`engine/interpret.js`、`src/panel-kit.js`):
229
+ - 问题:三个标签原写作「诸家一致 / 各家有异说 / 待核实」。前两个在用户眼里约等于「可靠」,而实际含义只是「各书都这么写」。「文本里一致」和「世界里成立」共用一个词,是产品在无意中骗人。
230
+ - 改法:标签写全为「文本·诸家一致 / 文本·各家有异说 / 文本·未录入」,前两个强制带前缀;知识区块末尾加一句统一声明——「以上标签只说明典籍文本的一致程度,不表示该技法经过验证;本插件不对任何技法的预测效度作保证」,全报告只出现一次(挂在最后一个带知识卡的维度下,逐维重复反而会被跳过不看)。
231
+ - 证据:`test/interpret-knowledge.test.mjs` 新增 4 条,其中一条是**防止被改回去**的——任何标签不以「文本·」开头即失败;另三条盯声明本身(存在、点明「不表示经过验证」、点明「不作保证」)。
232
+
233
+ - **分歧按「本盘涉及」分组**(`engine/interpret.js`):
234
+ - 问题:文末「这套规则有多稳」把本盘踩到的分歧和「这派别来就吵的」混成一锅,八字一张盘能列十几条,用户看不出哪几条跟自己有关。
235
+ - 改法:按 `seen` 分成两组——先列「本盘涉及 N 处」(只留条目名,正文里已展开过),再列「本体系另有 M 处通行分歧(本盘未涉及,附原注备查)」;两者都没有时写明「本盘未踩到,结论是按一派一路算下来的」。开头与结尾各一句把这层定性钉死:这是**文本层**的分歧,不是谁对谁错的判定,插件不替它们裁决。
236
+ - 证据:`test/interpret-knowledge.test.mjs` 新增 2 条——分组标记必须存在;「本盘涉及」里列出的条目必须真在这张盘的知识卡里出现过(防虚标)。
237
+
238
+ - **新增「本插件不回答什么」清单**(`engine/limits.js`、`engine/interpret.js`、`engine/index.js`、`src/panel-kit.js`):
239
+ - 为什么不做成免责声明:「可能不准」这种句子没有信息量,用户看完还是不知道该信哪部分。有用的写法是——这条为什么做不到、做到哪一步就停了、依据是什么。
240
+ - 通用三条:技法效度未经检验(能复核的只有形式层)、同盘不同命(模型硬缺陷,不是样本不够)、不给医疗法律投资建议。按体系各 1–3 条:六爻不给公历日期且用神两现不代选、八字不预测具体年份事件且旺衰是分档不是评分、紫微飞星层只报路径不判吉凶、梅花不取外应、大六壬应期未做、奇门八门九星入墓未做、塔罗只给通行牌义。
241
+ - 走公共收尾 `withReportMeta` 注入,所以奇门那条不经过正文组装的支路也带得上。面板在报告最末折叠显示(与免责声明分工不同:免责声明是「别全当真」,这里是「具体哪几件不答、为什么」);对话侧全量输出给调用方,不截成标题——模型知道「为什么不答」,才不会自己补一个答案。
242
+ - 证据:`test/limits.test.mjs` 27 条(字段完整 / id 不重复 / 文案 ≥40 字且有实质 / 无绝对化用词 / 七个体系都有专属条目 / 通用三条覆盖三个死穴 / 八字不带六爻条目 / 奇门支路也带上)。其中最关键一条是**清单不能和实现矛盾**:既然写着「应期不给公历日期」,六爻解析全文就不得匹配出 `YYYY年M月D日`;哪天有人在应期里加了日期,这条会先挂。
243
+
244
+ - **修:新增引擎模块漏进构建清单,打包后静默变成 `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` 和它所属的模块组,否则源码测试全绿、产物静默坏掉。**
245
+
246
+ - **B1 六爻应期收尾:规则顺序纠错 + 补统计显著性**(`engine/yingqi.js`、`tools/backtest-yingqi.mjs`、`test/yingqi.test.mjs`):
247
+ - **发现一个实质错误**:代码里规则的排列几乎是把原文倒过来排的,而注释声称「状态互斥优先级照应期总注的排列:空 → 破 → 动 → 墓 → 太旺 → 衰绝 → 静」。把《各門類應期總注章第又二十六》19 条逐条对下来,真实次序是「静 → 动 → 太旺 → 衰绝 → 入墓 → 六合 → 月破 → 旬空 → 大象吉受克 → 大象凶受克 → 元神总纲 → 化进 → 化退 → 独发独静 → 变爻动爻 → 远近当分 → 再占 → 世空元动 → 世衰元静」。**那句「空 → 破 → … → 静」原文里没有,是编的。**
248
+ - 改法:新增 `RULE_ORDER` 照原文罗列次序,`primary` 重新定义为「按原文次序第一条生效的规则」,不再是「最可能应验的那条」。同时把 `yingqiState` 上那句「状态互斥优先级」的错注释删掉——那里没有选择逻辑,各项独立计算。
249
+ - **对拍补了二项单尾检验,把「百分比」变成「结论」**(`tools/backtest-yingqi.mjs`):并集 15/29=51.7%,随机基线 29.6%,**p=0.0102(显著)**;主规则 8/29=27.6%,按主规则自身支数算基线 17.0%,**p=0.1047(不显著)**。两者一正一反说明:规则集合确实覆盖了原文所记的应验支,但条文之间没有可用的优先次序——这正是面板继续不出日期的依据。
250
+ - **逐规则统计**(新增):`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 中,都低于自身基线。**但这只是报告,不据此调规则**——按这些数字重排就是拿对拍集调参,命中率会变成自己喂出来的。脚本头部与测试注释都写死了这条边界。
251
+ - 新增能力边界 `liuyao-liuyue`:不推演流月推进后的二次变化。依据是一条实占反例(用神伏藏、本可靠日辰冲开,进入下月建后一冲解掉原月建对制它之爻的合,制者复起,出伏失败),这类跨月推演还没做,所以应期只能作「该留意哪几支」。
252
+ - 证据:`test/yingqi.test.mjs` 28 条(+3)。新增两条是防回归的关键——「规则顺序照原文罗列」把 15 个 id 的顺序钉死,改排序必须给原文依据;「同时命中按原文次序取主规则」用「入墓 5 < 月破 7」的用例验证排序真的生效。另修正两个旧用例的日辰(原来取辰,正好是水墓,会把「入墓」拉进来抢主位,测的就不是月破/旬空了)。
253
+
254
+ - **真机回归:用本机浏览器把 19 个 tab 逐个点一遍**(`tools/e2e-dom.mjs`、`package.json`):
255
+ - 补的是最后一层:冒烟测试跑在 node 里,测得到引擎与渲染函数,测不到事件绑定、表单显隐、勾选后的重渲染、深链落地。这一层用 Chrome 真开页面点。
256
+ - 19 个 tab 各查:切得到、有主按钮、能出结果、结果无脏串、**全程无 JS 报错**(监听 `pageerror` 与 `console.error`)。共 103 项断言。
257
+ - 另测三条只有真浏览器能测的:① 八字勾「时辰未知」后,结果里必须出现「时柱暂缺」且不含 `12:00`;② 深链 `#mp=…` 直接打开能自动落地出结果;③ 深色主题下扫描全页文字对比度(含渐变背景取平均色)、390px 窄屏无横向溢出且能出结果。
258
+ - 用 `playwright-core` + 本机已装的 Chrome/Edge,**不下载浏览器**;找不到浏览器时打印跳过并返回 0,不会把 CI 弄红。
259
+ - 过程中修掉两处**误报**(不是产品问题,但值得记):渐变背景只读 `backgroundColor` 会拿到透明、把「浅底深字」判成同色;父容器(`button.tool`)的文字都在子节点里,拿父容器的 `color` 算对比度必然误判——改成只看「直接含文字节点的元素」且渐变取平均色。
260
+
261
+ - **全体系稳定性复查:新增冒烟 + 修掉 K 线 id 不稳定**(`test/smoke-all.test.mjs`、`tools/smoke-all.mjs`、`src/panel-kit.js`):
262
+ - 为什么加:单测各自盯一块,但整页能出结果的路径有几十条,一条崩就是白屏——上次「时辰未知」崩在 `p.stemTenGod`,引擎 6253 条断言全绿、页面全崩。这次把 19 个 tab 的 36 个用例逐个跑「排盘 → 渲染 → 文本 → 解析」四条链,共 300 条断言。
263
+ - 每项查五件事:不抛异常;成品里不留 `undefined / NaN / null / [object Object]`;**同一张盘渲染两次必须字节一致**;关键结构词在(四柱/命宫/值符/世爻/宜忌…);无 `<script>` 与事件属性。
264
+ - 另外覆盖:边界日期(1900/1929 时区切换、2024-02-29、2100)、立春前后年柱必须换、晚子时开关必须改日柱、三柱盘与完整盘的年月日柱必须一致、10 条参数错误路径必须给「带错误码的中文提示」、句柄往返、八字×紫微交叉、40 个随机日期采样、以及**交付物自身**——把单页里的 4 段内联脚本各过一遍编译器(产物语法坏了,跑源码的单测永远发现不了)。
265
+ - **修掉一个真 bug**:人生 K 线的 `clipPath` id 原来用全局自增(`klineSeq`),导致同一张盘两次渲染出不同 id——截图对拍、快照测试永远对不上。改成盘面内容的短哈希(FNV-1a):不同盘不同 id,同盘永远同 id。
266
+ - 用法:`npm run smoke`(也进 `test:ci`,断言数进基线)。
267
+
268
+ - **盘面顶部「先说结论」:一段人话总结**(`engine/plain-summary.js`、`engine/index.js`、`src/panel-kit.js`):
269
+ - 起因:排完盘先给的是四柱表和一堆术语,普通人第一屏读不动——就算下面写了解析,也读不到第二屏。要的是「先给一段能看懂的话,再给依据」。
270
+ - 内容:一个方框,四件事——总纲(日主+生月+冷暖+最需要什么)、你的底色(十神权重前两位翻成人话)、感情这件事(配偶星落在哪、配偶宫坐什么、有没有破冲合)、最容易卡住的地方;末尾给 2–4 条可以立刻做的事,再加一句补充说明与「不是断语」的尾句。
271
+ - 硬规矩:**只做「结构 → 人话」的翻译,不下吉凶断语**。「官杀混」可以说成「你容易遇到两种类型的人」,不能说成「你婚姻不好」。同一张盘每次生成的文字逐字相同(有断言钉死确定性)。
272
+ - 八字与紫微都有:紫微那版讲命宫主星、身宫落宫、夫妻宫与格局(格局只描述形状,不作吉凶判词)。
273
+ - 位置:方框在盘面之前、每份结果只渲染一次;对话侧 `renderText` 也把这段放在最前(`【先说结论】`),模型照它复述就不会一开口是术语表。
274
+ - 证据:`test/plain-summary.test.mjs` 38 条。含确定性(两次生成 JSON 全等)、不越界(不许出现「一定会/必然/注定/肯定会」)、时辰未知时必须在补充说明里讲清「只有六个字、约七成信息」、男命取财星不套女命说法、渲染顺序(方框 index < 盘面 index)。
275
+
276
+ - **面板一键「复制问事提示」**(`src/panel-kit.js`、`src/web-ui.js`、`src/app.js`、`src/core.js`、`engine/index.js`、`tools/build-client.mjs`):
277
+ - 六爻 / 梅花 / 大六壬 / 奇门 / 塔罗五个体系的结果页,问题行下方出现「复制问事提示」按钮:点一下,当前盘面 + 所问之事打包成一段完整提示,粘到任何对话里都能用。`core.js` 加 `kindOfDirection` 把命盘的七向(财运/事业/感情…)映射到问事的六类(business/career/love…)。
278
+ - 命盘类(八字 / 紫微 / 合盘 / 趋势 / 起名 / 风水 / 称骨 / 星座 / 数字 / 人格)不渲染这个按钮——它们回答的是「这个人是什么结构」,不是「这件事成不成」,给了按钮就是诱导误用。小六壬结果是单行落宫、没有解析报告,按钮也不在它那边,提示走命令行。
279
+ - 引擎侧 `engine/index.js` 导出 `buildEventPrompt` / `ASK_KINDS`;`build-client` 给五个问事分块加 `EVENT_PROMPT` 栈(`qimen-prompt` + `event-prompt`),命盘分块不带,避免无谓体积。本仓 esbuild 不接受 `export {} from`,改为先 `import` 再 `export`。
280
+ - 证据:`test/ask-copy.test.mjs` 14 条——五个问事体系都渲染且只渲染一次、两个命盘类不渲染、引擎确实导出构建器。
281
+
282
+ - **问事解读提示:把「先问清事 → 取用神 → 回到现实」推广到全部问事体系**(`engine/event-prompt.js`、`engine/qimen-prompt.js`、`tools/event-prompt.mjs`、`docs/问事解读提示.md`):
283
+ - 起因:奇门那套要求(先答他所问、不堆术语、每个符号说得出为什么、结论回到现实核对)不该只对奇门成立。六爻、梅花、六壬、塔罗、小六壬一样会被读成「符号念一遍」——世爻旺相所以好、用生体所以吉、这张是死神所以完蛋。
284
+ - 做法:骨架共用(时间确认 → 问事分类 → 取用神给理由 → 读状态 → 三追问自检 → 现实核对 → 表达要求 → 禁止 → 输出格式),**取用神各体系自己给**:六爻世应 + 六亲按事类取(工作官鬼、财妻财、感情男财女官、文书父母)、梅花体用、六壬日干日支 + 三传、塔罗牌位决定含义、小六壬明确说明「没有独立的我,别硬补」。奇门委派给 `qimen-prompt.js`,两套提示内容逐字一致(有断言钉住)。
285
+ - 时间不明一律拦住:问事体系靠起课那一刻定盘,没时刻就没有盘。`timeKnown:false` 时返回「先别起课」的拦截文本,且**不得出现任何盘面符号**(有断言:全文不许匹配世爻/应爻/四柱/值符)。
286
+ - 把「说不清」写进提示,而不是糊过去:六爻用神两现必须标「两现未定」;小六壬必须说明它给不了「我 vs 对方」;梅花体用标了「大吉」也要提醒「吉是条件好,不是结果已经发生」。
287
+ - 用法:`npm run prompt:event -- --system liuyao --kind career --question "…" --lines 9,7,8,8,7,6`,输出一段填好盘面的完整提示;`--no-time` 只出「先问时间」。长文档见 `docs/问事解读提示.md`。
288
+ - 证据:`test/event-prompt.test.mjs` 61 条。含**空话检测**(现实核对里不许出现「结合现实 / 具体情况具体分析 / 视情况而定」)、**自洽检测**(禁止清单里写的,提示自己不能犯)、问题超 200 字截断。
289
+
290
+ - **报告内置「数 / 象 / 辞」三层导读**(`engine/guide.js`、`engine/interpret.js`、`src/panel-kit.js`):
291
+ - 为什么做进插件而不是只放文档:读不懂命盘的人不会去翻 README,他只在结果页划两下就关了。所以导读必须「一进来就看见、但不挡路」——折叠,默认收起,排在「一页读懂」之前。
292
+ - 内容只讲一件事:这份报告里哪部分是算出来的(可复核)、哪部分是命名(可商量)、哪部分是判断(要自己拿主意)。三层各带一句「这一层在本报告里长什么样」,再接三问检验法(坐标 / 关系 / 唯一读法),最后点明纳甲、十神、宫位都是中间件。
293
+ - 数据与渲染分开:`guide.js` 只存文案(纯数据,vm 可测),`panel-kit` 负责画。两套 UI 共用 `resultWithInterpret`,所以面板与离线页同时生效,不用改两处。
294
+ - 证据:`test/guide.test.mjs` 25 条。最要紧的三条是**内容自洽**:三层与三问必须齐(少一层就退化成鸡汤)、问句必须以问号结尾(是提问不是结论)、**全文不得出现效度承诺词**(这段本身就是「效度未验证」的说明,出现「一定」「精准」即自相矛盾)。另有渲染契约:只渲染一次、排在结论之前、默认收起、转义无注入面。
295
+ - 这一版把 `docs/象与数-要义导读.md`(长文)里的核心判准压缩成 90 秒版放进报告,长文留作延伸阅读。
296
+
297
+ - **修:深色主题下选中高亮块的字看不见**(`src/app.js`、`src/core.js`):
298
+ - 症状:深色模式下打开侧栏面板,被点中的那个体系(tab / 分组里的工具项 / 视图开关 / 主按钮 / 分段控件)文字是白的,压在同样浅的品牌色块上,对比度约 1.2:1 —— 等于没有字。
299
+ - 根因不是「颜色没调好」,是**写死了白色**:选中态一律 `background:var(--dsw-alias-brand-primary);color:#fff`,八处都是这么写的。而品牌色在深色主题里通常反而变浅(深色底上才看得见),白字落上去必然糊掉。同一个 `#fff` 在浅色主题下是对的,在深色下是错的,说明它本来就不该被写死。
300
+ - 改法:不再猜一个颜色,改成**运行时量一次宿主真实的品牌色**——往 body 插一个透明探针,`getComputedStyle` 取回解析后的 `backgroundColor`,按 WCAG 相对亮度算出白字与近黑字各自的对比度,挑高的那一侧写进 `:root` 的 `--mp-on-brand`,CSS 只读 `var(--mp-on-brand,#fff)`。系统主题切换(`prefers-color-scheme`)与宿主换 `class` / `data-theme` 时各重算一次;量不到就回落到 `#fff`,不会比改动前更差。
301
+ - 为什么不用媒体查询硬编码两套色:宿主的深色品牌色是什么值,插件无从得知(它可能仍是深蓝,也可能是浅青),猜错一次就是同一个 bug 换个方向复发。
302
+ - 证据:`test/core.test.mjs` 新增 12 条,其中一条走遍 RGB 步长 51 的全色域(216 个底色),断言「挑出来的那侧对比度永远不低于另一侧」,并给出最差值 4.19:1 —— 满足大字号 AA(3:1);中灰如 `#7f7f7f` 两侧都到不了 4.5,这是色彩本身的极限,不是选错。`test/theme.test.mjs` 新增 8 条静态守卫:**品牌色块后到规则结束为止不得再出现写死的白字**,谁改回去谁先挂。
303
+
304
+ - **滴天髓·下篇六亲论录入:家庭这一块从「通行说」升到「可核原文」**(`engine/citations.js`、`engine/interpret-knowledge.js`、`test/fixtures/citation-sources.json`):
305
+ - 起因是「能不能用八字对家庭生活给方向」这个问题。查下来发现,六亲这块在库里只有一条 `smt-liuqin`(三命通会条列名目),夫妻、子女、父母三处的原文一句没录——用户看到的「家庭」解释,实际上没有底本支撑。
306
+ - 补法:从底本(`diancang.xyz/.../ditiansui/153092.html`,下篇六亲论)逐字录入 5 条——夫妻「夫妻因缘宿世来,喜神有意傍天财」、子女「子女根枝一世传,喜神看与杀相连」、父母「父母或降与或替,岁月所关果非细」、女命章、何知章(富/贵/贫/贱四条判据)。原文进 fixture,CI 离线可复验,`test/citations.test.mjs` 的「每条引文的来源正文都在 fixture 里」逐条比对。
307
+ - 关联:`bazi-liuqin` 由 1 条引文扩到 4 条(夫妻/子女/父母各有落点),`bazi-geju-chengbai` 加何知章(成破格 → 富贵贫贱有了原文判据),引文总数 94 → 99。
308
+ - **意外收获,也是本版最硬的一条**:女命章原文「三奇二德虚好语,咸池驿马半推详」——三奇、二德是空口说好话,咸池(桃花)、驿马顶多参考一半。**「神煞不主吉凶」不是今人的现代意见,是《滴天髓》自己说的。** 以前 `bazi-shensha` 只引三命通会(条列名目)+ 子平真诠(主张不主吉凶),只引前者会让人以为插件在给神煞背书;现在两书合看,立场有原文兜底。
309
+ - 边界:六亲论这一篇是韵语提纲,各家注解发挥分歧很大,所以只录原文、不把某家注解当原文引(`dt-liuqin-fuqi` 的 note 写明了这一点)。
310
+
311
+ - 门槛:131 个测试文件 / 6104 条断言全过(较 0.58.0 增 33 条);client.js 256KB / gzip 78KB;产物自检 18 个分块 / 逐模块编译 58 个;性能 29 项在限内。
312
+
313
+ > 下列两条是 0.58.0 之后、本版之前的工作,随本版一并发布。再往下的 C3 对话桥替代 / §5.8 自动发布加固 / push-tag 三条的详细记录属 0.58.0,保留于此备查。
314
+
315
+ ## 0.58.0(2026-11-01,已发布)
316
+
317
+ > 本版主题:把「盘送不进对话」这条路补成三条不依赖宿主的通道(C3),顺手让自动发布可观测、可自愈,再把引文里两句长期误署的话改回原书。
318
+ >
319
+ > 包含:C3 对话桥替代(深链 / 复制 / 结构化参数)、§5.8 自动发布加固、B6 通行说复核、B6 通根透干复核(误署纠正)、B6 第五批(大六壬 3 条)、C4-a 三方合盘、C4-b 择日候选日比较、C4-c 同盘多口径并排、D1+ 首屏耗时回显、A1+ 推导链出处、D4 发布回滚、自检修复(见下)。
320
+
321
+ ## 未发布
322
+
323
+ - **凭据扫描进约定闸:token 形态的字符串提交不进去**(`tools/check-patterns.mjs`):
324
+ - 起因:npm / GitHub 的发布凭据存在 `<用户目录>/.dsh/metaphysics-autopublish.json`,只从环境变量喂给 `tools/release.mjs`;它一旦被贴进对话、写进文档或提交到仓库,撤回版本也撤不回已推送的历史。
325
+ - 新增第 8 条规则:全仓(跳过 `node_modules` / `.git` / `.workbuddy`)扫 `npm_xxx`、`gh[pousr]_xxx`、`github_pat_xxx`、PEM 私钥头。**命中只打印「文件:行」与原因,绝不回显匹配到的内容**——检查本身不能变成泄露通道。
326
+ - 自检:往仓库根放一个 `npm_` + 40 位的假串,闸门退出码 1 并指出 `_leak-probe.js:1`;删掉后恢复通过。当前 299 个文件无命中。
327
+
328
+ - **面板(宿主侧栏)真机回归:补上最后一层没测过的 UI,并抓到一个三柱盘必崩的 bug**(`tools/e2e-panel.mjs`、`src/app.js`、`package.json`):
329
+ - 缺口在哪:单页 E2E 跑的是 `src/web-ui.js`,面板跑的是 `src/app.js`——两条渲染链只有 `panel-kit` 共用。面板自己的状态(勾选联动、本地历史、深链落地、首屏卡片)此前只有静态字符串断言,等于没跑过。
330
+ - 怎么测:真 Chrome + **真 React 18**,配一个最小宿主——假 `slots` 注册表(`register` / `inject` / `spec`)、假 `ctx.effect`、`assemble()` 打出的全量 client(含引擎),本机 http 起服务(`file://` 下 localStorage 会抛 SecurityError)。把 `PanelIcon` 画进侧栏、主面板画进 `#main`,然后照用户顺序点:切体系 → 排盘 → 勾「时辰未知」→ 起卦 → 切深色 → 缩到 520px → 带 `#mp=` 深链重开。43 项断言。
331
+ - **抓到的真 bug**:`HISTORY_LABEL` 对 `pillars` 逐项取 `.ganzhi`,时柱为 `null` 时抛 `Cannot read properties of null`——表现是「三柱盘一点排盘就报错」,而引擎 6620 条断言全绿(那段代码在面板里,不在引擎里)。已修:过滤空柱,并在文案末尾写「(时柱暂缺)」,别让历史条目看起来像四柱。
332
+ - 顺带验了面板独有的几处:勾选后时刻框被禁用、排过的盘进 `localStorage` 并出现在「最近用过」、连点 10 次不崩也不膨胀、深色下选中卡片对比度 8.13:1、520px 容器无横向溢出、深链把面板切到对应体系并带回问题。
333
+ - `test/hour-unknown.test.mjs` 补 6 条把 `HISTORY_LABEL` 的逻辑本身钉住(从 `app.js` 取出函数独立求值,不依赖浏览器),免得下次又只有真机才暴露。
334
+ - 用法:`npm run e2e:panel`(没有 Chrome/Edge 时打印跳过并返回 0);`npm run e2e` 现在同时跑单页与面板两层。
335
+
336
+ - **连续 200 次压测:不崩、不漂、不涨、不串**(`test/stress.test.mjs`、`package.json`):
337
+ - 冒烟测「每条路能走通」,压测测「一直走会不会变形」。200 份**不同日期**的输入(八字/紫微/六爻/奇门轮转,逼缓存真的淘汰),预热 20 次后再跑。
338
+ - 四条断言:① 200 次零抛错、结果里没有 NaN/undefined/[object Object];② 同一份输入在压测前后**逐字节一致**(抓隐藏计数器、缓存污染);③ 日历三个 LRU 都不超上限,且确实踩到过上限(`termInstant 899/4096`、`termYear 32/32`、`termWindow 8/8`——踩不到说明压测没打中热点);④ 后 50 次不比前 50 次慢(0.5ms vs 0.8ms),p95 ≤40ms。
339
+ - 内存单独起一个 `--expose-gc` 子进程量:强制 GC 后堆增长 **+0.44MB**(9.55 → 10.00MB)。同进程量只会量到未回收的垃圾,是噪声不是泄漏。
340
+ - 实测:200 次共 127ms,平均 0.61ms/次。用法 `npm run stress`。
341
+
342
+ - **B1 六爻应期:样本不再等用户,改从《增删卜易》里取;规则层落地,命中率公开且不好看**(`engine/yingqi.js`、`tools/gen-zengshan-cases.mjs`、`tools/backtest-yingqi.mjs`、`test/fixtures/zengshan-cases.json`、`test/yingqi.test.mjs`):
343
+ - 为什么不等用户给卦例。应期对拍要「月建日辰 + 完整六爻 + 断语 + 应期口径 + 实际应验」五样齐,这类样本在《增删卜易》里本来就是成批的(野鹤老人自己拿实占卦例成书)。本地已缓存全书 12.4 万字,170 处「X月Y日占」起式,够用,且不必麻烦用户现编。
344
+ - 收录标准四条全过才收:起式能定位月建日辰;六爻能按行解析;**解析出的六亲/地支/五行与引擎纳甲逐爻一致**(这一条同时充当解析正确性校验——纳甲+六亲由卦宫五行唯一决定,六爻全对基本等于卦没错);断语点名用神(「寅木官星持世」「未土父母動化進神」「財爻持世」「世爻寅木」「X为用神」五种句式);应验句里有可解析的年月日。结果 **29 条收录 / 141 条排除**,每条排除都写了理由(`excluded`),不静默丢弃。变卦名按「原文缩写还原成候选,候选唯一才核」处理(写「之兌」即兑为泽、写「之夬」即泽天夬,「大」这种可指大过/大壮的当未能核验),避免拿缩写误判。
345
+ - 规则层照《各門類應期總注章第又二十六》19 条落成 15 条可判规则;落不到「某支」上的 4 条(独发独静、远近换尺、再占、元神总纲)列进 `NOT_IMPLEMENTED`,不假装做了。取支一律只给地支、不换算公历日期——与既有 `yingqiWindow` 的契约一致。
346
+ - **对拍结果(公开,不好看)**:并集命中 15/29=**51.7%**,平均 3.55 支、随机基线 29.6%;主规则命中 8/29=**27.6%**,与基线持平。结论:按条文取支集合比瞎猜强约 22 个百分点,但目前的规则优先级排序**没有预测力**;逐条看还能看到「化进神」「化退神」各 1 例全落空。因此面板**仍不出日期**,`test/yingqi.test.mjs` 25 条一律用构造盘断言(不拿对拍集调参,否则命中率是自己喂出来的)。
347
+ - 复现:`npm run gen:zengshan` → `npm run backtest:yingqi`。
348
+ - **F 真化改为「判例对齐」**(方案文档同步):公开古籍没有「已验证人生」的化气格命例,做真化命中率等于在没有答案的地方造分;改为取古籍明确判「化气格成」的四柱,只比对条件清单口径,不做命中率宣称。
349
+
350
+ - **发版最后一步补成工具:`tools/push-tag.mjs`**(`package.json` 增 `push:tag` 脚本,`release.mjs` 的提示改指它):
351
+ - 起因:0.58.0 发完 npm,脚本提示 `git tag v0.58.0 && git push origin v0.58.0`,而这台机器 GitHub 443 整段不通(`Connection reset` / 连不上),tag 只能落在本地,远端 release 页面上永远缺一个。
352
+ - 做法:默认取 `package.json` 版本;缺 tag 就建 annotated tag;推送连续三次失败且错误像「连不上」时,自动临时 ed25519 → 注册 deploy key → 走 `ssh.github.com:443` 推 `refs/tags/…` → 无论成败都删 key 与私钥。`--dry-run` 只报告不动手,`--no-create` 只推不建。与自动发布用同一个配置文件,不额外落盘凭据。
353
+ - 证据:`test/push-tag.test.mjs` 22 条(dry-run 不建 tag 也不碰远端、默认 tag 跟版本号、tag 名不合法直接拒绝、SSH 兜底接线与删 key、凭据只从配置文件读)。实测 v0.58.0 走 SSH 兜底推成功,临时 deploy key 168375084 已删。
354
+
355
+ - **C3 对话桥替代**(`engine/bridge.js`、`src/app.js`、`src/web-ui.js`):会话槽位 `conversation.input.right` 不稳,桥一断就没路把盘送进对话;这一版给出三条不依赖宿主的通道。
356
+ - 深链:`#mp=<句柄>&q=<问题>`,参数走 C1 句柄编码,截断或改字报 `E_HANDLE` 而不是静默排成另一张盘。面板首屏先读链接再排盘(表单状态下一帧才生效,同一批值经 `run` 的 over 直传,不会先闪一张旧盘);独立页在 `setTab` 之后填表单再排,并在结果顶部写「已按链接还原:体系|问题」,没填回表单的参数(如合盘对方)如实列出,不悄悄丢。
357
+ - 复制:完整提问(与桥发出去的是同一份)、一句话精简(体系 + 句柄 + 问题,≤200 字)、结构化参数(`{"tool":"metaphysics","args":{handle,…}}`,助手可直接照 args 调 compute)。
358
+ - 面板在追问框下加一排芯片「复制提问 / 复制精简 / 复制参数 / 复制深链」,桥可用时保留、桥缺席时就是主通道;独立页在追问区加「复制提问」、导出栏加「复制深链」。
359
+ - 证据:`test/bridge.test.mjs` 88 条(深链往返与四柱复现、四种写法可解析、六类坏链接不抛异常且带 code、表单还原与未还原提示、三档文本与 JSON、无句柄不编链接、不改盘面对象、面板与独立页接线、bridge 进公共栈);无头 Chrome 实测 `命理排盘.html#mp=…` 打开后四柱与问题一致、坏句柄回落到默认盘。
360
+
361
+ - **§5.8 自动发布加固**(`tools/autopublish.mjs`、计划任务):把「定时跑但出了问题看不出来」补成可观测、可自愈。
362
+ - 每天 23:00 与 23:30 双跑:第二跑在指纹未变时只写一行日志,等于给第一跑的一次兜底重试。
363
+ - 每次运行开头写 `运行开始(auto/dry-run/init/force,pid …)`;**无改动也写一行**(原来是完全静默,事后查不出任务跑没跑);日志超过 512KB 自动裁到最近 800 行。
364
+ - 失败写 `tools/.autopublish-error`(内容含失败原因与时间),成功一次自动删掉;未捕获异常也留痕。该文件进 `.gitignore`。
365
+ - GitHub HTTPS 连续失败且报错像「连不上」(443 / timeout / SSL / RPC failed)时,自动生成临时 ed25519 → 调 API 注册 deploy key → 走 `ssh://git@ssh.github.com:443/...` 推一次 → 无论成败删 key、删本地私钥;「推被拒」不触发兜底。
366
+ - 证据:`test/autopublish.test.mjs` 28 条(未知参数仍立即拒绝且不碰状态文件、加固项接线、dry-run 写运行开始、配置缺失时退出码 1 且写错误文件、失败后不留锁也不改状态)。
367
+
368
+ - **B6 通行说复核(8 张逐张过一遍底本)**(`engine/citations.js`、`engine/interpret-knowledge.js`):
369
+ - `liuyao-jintui-yong` 由通行说改为 refs:《增删卜易》卷二·進神退神章第二十九「進神退神者,爻之動而化也,化進化退,吉凶禍福有喜忌之分,所喜者宜於化進,所忌者宜化退神。」底本已经把喜忌落在进退上;把「喜/忌」具体落到用神/忌神两档仍标为本插件引申(写进知识卡 note)。
370
+ - 其余七张维持通行说,但把「查过什么」写进理由:紫微飞星三张——`《紫微斗數全書》`卷一、卷三全文检索「宮干/飛星/三方同飛/忌轉忌」均无命中,底本只有生年四化;奇门干宫生克——统宗已抓四卷只有「星相克/仪相克/门相克」与「时干克日干」;十干克应——检索到的「十干克應歌訣」署诸葛亮、释意者为近人,属现代韵语,不能当原文;通根透干——当时没定位到,留待联网复核(下一轮已改判,见「B6 通根透干复核」);塔罗逆位——韦特《Pictorial Key to the Tarot》1911 已入公有领域,但原书对逆位态度含混,未给「逆位=受阻/内化」这套固定读法。
371
+ - 53 张卡:45 张已定位原文(+1)、7 张通行说(−1)、1 张待补。`docs/citations.html` 同步重建。
372
+ - 证据:`test/citations.test.mjs` 59 条(新增 3 条:用神化进退落到進神退神章、source 为 verified、通行说剩七张且待补一张)。
373
+
374
+ - **B6 通根透干复核:通行说是误署,改引《滴天髓·干支总论》**(`engine/citations.js`、`engine/interpret-knowledge.js`):
375
+ - 说法查证。常被引作《滴天髓》的「地支所藏之干,本静以待用,透出干头,则显其用矣。故干以通根为美,支以透出为贵」,在**滴天髓底本全文**里检索「本静以待用/干以通根为美/透出干头」零命中;在**《子平真诠》沈孝瞻原文**(论十干十二支,中华典藏本 984 字)里同样零命中。它实际出现在《子平真诠》**评注本**卷一·论十干十二支的注文(附支藏人元图、十二月令人元司令分野表之后的按语)。也就是说:网络通行写法「《滴天髓》云:地支所藏之干……」把注文署给了原书。
376
+ - 改判依据。该注文自身引的才是《滴天髓》:「天全一气,不可使地德莫之载;地全三物,不可使天道莫之容」——这句在本地所收滴天髓底本「干支总论」里逐字可对上,语义正好是「天干要地支承载(通根)、地支藏干要透出天干(透出)」。故本卡只引这句可核的原文,注文那两句写进 `note` 作说明,不冒充原文。
377
+ - 结果:`bazi-tonggen-tougan` 由通行说改为 refs(新增引文 `dt-yiqi-tonggen`,《滴天髓·干支总论》);引文库 93→94 条;**46 张已定位 / 6 张通行说 / 1 张待补**。`docs/citations.html` 现在也会把 `note` 显示在已定位条目下,误引纠正看得见。
378
+ - 证据:`test/citations.test.mjs` 62 条(新增 3 条:改引干支总论、引文确为原句、note 写明误署;通行说计数 7→6)。
379
+
380
+ - **D4 发布回滚**(`tools/release.mjs` + `tools/release-rollback.mjs`):发版失败、或发布后附件核对没通过时,打印一套可照抄的回滚步骤,不自动动 registry。
381
+ - `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 两步。
382
+ - `release.mjs` 在发布前记住 registry 上的 `dist-tags.latest`,作为回退目标;`npm publish` 失败与 `verifyPublish` 失败都自动打印这套步骤,并给出单独跑的等价命令。
383
+ - 新增 `node tools/release-rollback.mjs`(`npm run rollback:plan`):默认只打印;`--apply dist-tag` 需要 `NPM_TOKEN`,只代为把 latest 指回上一版;`unpublish` / `deprecate` / 删远程 tag 一律只打印,由人确认后执行。
384
+ - 证据:`test/release-rollback.test.mjs` 40 条(两种原因的步骤与命令、无上一版时不猜号、tagged 两步、未知 reason 回落、排版与不打印 token、CLI 退出码与 `--apply` 限制、release.mjs 接线与 verify-only 不把问题版本当上一版)。
385
+
386
+ - **自检修复**(`engine/index.js`、`src/web-ui.js`):两处只在真实浏览器/连续操作下才暴露的一致性问题。
387
+ - `partner2: null` 在排盘前归一化为未传:原先 compute 当它没给,句柄却把 `partner2:null` 编进去,同一对盘会拿到两个句柄。
388
+ - 独立页耗时行改存 `last.perf`,由 `paint()` 末尾补回:切询问方向等重绘会换掉整段结果区,原先那一行随之消失;现在重绘后仍在且只有一行。
389
+ - 证据:`test/hepan-triple.test.mjs` 新增 2 条(null 不出三方、与省略同句柄);`test/perf-instrumentation.test.mjs` 增至 41 条(耗时行入状态、paint 末尾补回);headless Chromium 实测切方向后 `.mp-perf` 仍为 1 行。
390
+
391
+ - **B6 第五批:大六壬原文录入**(`engine/citations.js`):《大六壬大全》维基文库四库全书本,新增 3 条,`daliuren-sike` 由通行说改为 refs。
392
+ - 卷一·起例「十干寄宫」:`甲课寅兮乙课辰,丙戊课巳不须论。丁己课未庚申上,辛戌壬亥是其真。癸课原来丑宫坐,分明不用四正神。`——四课起手。
393
+ - 卷一·起例「贼克法」:`取课先从下贼呼,如无下贼上克初。初传之上名中次,中上加临是末居。三传既定天盘将,此是入式法第一。`——九宗门取初传。
394
+ - 卷二·神将释「月将」:`逆布者谓之月将,其实即十二神也。`——月将定义;加时布盘仍标通行口诀、不标卷次。
395
+ - 引文库合计 **93 条**(八字经典 41 + 引文索引 52),53 张卡里 44 张已定位原文、8 张通行说、1 张待补;`test/fixtures/citation-sources.json` 增至 58 个章页,`docs/citations.html` 同步重建。
396
+ - 证据:`test/citations.test.mjs` 新增 6 条(书目登记、四课三传带 refs、三章定位、无省略号),共 56 条;`test/trace-sources.test.mjs` 同步把大六壬三层的出处改为已核验卷次。
397
+
398
+ - **A1+ 推导链出处**(`engine/trace.js`):16 层的 `source` 统一成「出处;实现:engine/…」,能对上已录入篇名的才写书名卷次。
399
+ - 六爻:六亲对读《增删卜易》卷一·用神章第八;伏神引卷二·飛伏神章第二十八;旺衰引卷一·月將章第十六、日辰章第十七。纳甲、世应明写「规则表 / 通行动诀,本仓未录入古籍章页」。
400
+ - 八字:格局引《子平真诠》八、论用神(专求月令),调候参《穷通宝鉴》五行总论;旺衰**明写本仓量化规则、非古籍定数**;四宫标 Tyme 1.5.4 口径与 704 组对拍、未照录古籍章页。
401
+ - 紫微:格局引《紫微斗数全书》卷三·论人命入格、谈星要论(与引文索引同源)。
402
+ - 奇门:盘面事实引《奇门遁甲统宗》卷一·奇门秘诀总赋;旺衰引卷三;宫位引卷二与卷十一·玄机赋(中);用神表与十干克应明写「本仓表,非古籍原文」。
403
+ - 大六壬:本环境没有可稳定核验的公有领域章页,三层只标「通行口诀,未标卷次」,不拿别书条文冒充。
404
+ - 证据:`test/trace-sources.test.mjs` 35 条(16 层都有实现位置、书名只能在已登记的五本里、所引篇名能在引文库找到、各体系「有据 / 无据」的措辞、Markdown 导出原样保留);`test/trace.test.mjs` 同步文本断言。
405
+
406
+ - **D1+ 首屏耗时回显**(`src/engine-lazy.js`、`src/app.js`、`src/web-ui.js`、`src/panel-kit.js`):
407
+ - `__mpEnsureEngine` 记录每次取块耗时与是否命中缓存(`window.__MP_LAST_LOAD`),不埋点上报、不发网络请求。
408
+ - 面板从点击到两帧后记「首屏」,并拆出引擎取块与排盘两段;连续点两次时旧回调按 `perfSeq` 丢弃,不会把上一次的数字盖到新结果上。
409
+ - 独立页记「排盘」与「渲染(组 HTML + 写 DOM 的同步时间)」,明确不把浏览器真正绘制的那一帧算进来。
410
+ - 结果顶部缝一行灰色小字:`首屏 42ms|引擎 18ms(首次加载)· 排盘 9ms`,悬停说明「本机实测,不含网络与服务端」。缺哪段省略哪段,不编数字、不出 NaN。
411
+ - 证据:`test/perf-instrumentation.test.mjs` 39 条(三种组合的排版、缓存标注与缺省、NaN/负数、懒加载两次调用与缓存、面板/独立页计时接线、无上报调用)。
412
+
413
+ - **C4-a 三方合盘**(`engine/hepan.js · tripleOf` + `engine/index.js`):`hepan` 新增可选 `partner2`(字段同 `partner`),结果多一个 `triple`——
414
+ - `pairs`:三对(你×对方 / 你×第三方 / 对方×第三方)各给 `total`、`level` 与三维度分数,顺序固定;`a-b` 与顶层 `score` 完全一致,另两对与「单独拿这两人排合盘」逐分相同,翻过来排也一样。
415
+ - `best` / `hardest` / `spread` / `focus`:最顺、最需磨合、最高最低分差、三对之间分歧最大的那一维。**分差不足 3 分时不点名**,摘要改说「三对分数接近,不排名」,避免假精确。
416
+ - **不合成「三人总分」**:三方只把三对两两关系并列——和不同的人相处是不同的事,合成一个数会把差异抹平。
417
+ - 八字与紫微两种合盘都支持;`partner2: null` 视同未传,非对象或缺 `datetime` 报 `E_PARTNER` 并点名 `partner2`。
418
+ - 第三人进排盘句柄与影子盘指纹(换第三人=另一组盘,`baseId` 随之改变),下一轮只传 `handle` 即可复现同一组三方。
419
+ - 面板与独立页:合盘 tab 勾「三方合盘(加入第三人)」后展开第三方日期/时刻/性别/出生地;结果区在三维度后加三对并列小表(分数 + 三维度),只在该勾选时出现。
420
+ - 证据:`test/hepan-triple.test.mjs` 54 条(结构、与单独合盘/颠倒顺序一致、最顺与最需磨合、分歧维度、null 与坏输入、文本、紫微、句柄与影子盘、面板表与转义、面板/独立页/模板/宿主 schema 接线)。
421
+
422
+ - **C4-b 择日候选日比较**(`engine/zeri.js` + 面板/独立页):`zeri` 新增可选 `candidates`(2–12 个真实公历日期)。
423
+ - 给了就只比这几天(去重、保持输入顺序),不再按 `startDate` 扫区间;逐日分数与区间模式同一套公式,同一批日子逐分一致。
424
+ - 结果多一个 `compare`:`best`(这一组最高分与结论、同分者)、`spread`(最高与最低分差)、`note`(「胜出只表示更合所问事项,不代表好多少」)。全部因冲属相被排除时 `best` 为 `null`,摘要如实写「都因冲属相被排除」,不硬推一个。
425
+ - 入参守卫:不是数组、少于 2 个、超过 12 个、去重后不足 2 天、`2026-02-30` 这类不存在的日期,一律 `E_INPUT` 并说清改法;区间模式仍必须给 `startDate`。
426
+ - 面板与独立页:择日表单新增「候选日(可空,只比这几天)」,逗号/顿号/空格分隔;结果区在候选模式下画逐日表(日期+农历 / 干支+建除 / 分数 / 结论 / 理由),最优行标「最优」,下方并列推荐、可用、回避与比较口径;区间模式仍用原文案,不铺 60 行表。
427
+ - 候选日进句柄,下一轮只传 `handle` 即可复现同一组比较。
428
+ - 证据:`test/zeri-candidates.test.mjs` 48 条(与区间模式同分、去重、冲煞排除、全排除、五类坏输入、文本、句柄、面板表与转义、四处接线)。
429
+
430
+ - **C4-c 同盘多口径并排**(`engine/diff.js · CALIBER_VIEWS`):口径对照的每一行多回 `views`——只挑会影响结论的几项做两列并排,不改盘、不重算、不判优劣。
431
+ - 八字:日柱 / 时柱 / 旺衰 / 格局(`frame.primaryName`)/ 喜用 / 起运;紫微:命宫 / 身宫支 / 五行局 / 身主 / 起大限;奇门:日柱 / 局数 / 值符 / 值使。字段取两张盘里已有的值,缺省写 `—`,不把对象硬串成 JSON。
432
+ - 摘要里每行多一句「并排:日柱 丙辰 → 乙卯;…」,只列变化项;面板与独立页在根因后加 `mp-cview` 表(列名用档位名,例如「换日 / 不换日」),同样只列变化项。
433
+ - 紫微身宫取 `body.branch`;原先写的 `body.ganzhi` 不存在,会一直显示 `—`。
434
+ - 证据:`test/caliber-diff.test.mjs` 新增 21 条(视图键与行数、单元格格式、子年身主 火星 → 铃星、午年无变化项、奇门晚子时落日柱、文本并排、面板表与转义)。
435
+
436
+ ## 0.57.0(2026-11-01,已发布)
437
+
438
+ > 本版主题:排盘句柄与一句话改参、推导链 Markdown 导出、喜忌中性档、引文索引三批补录、性能门槛。
439
+
440
+ - **B6 第二/三/四批原文录入**(`engine/citations.js`):知识卡的「已定位原文」由 17 张增至 **43 张**,通行说由 35 张降至 **9 张**,待补仍 1 张。
441
+ - 第二批 7 条,均取自中华典藏网公有领域底本、逐字核验后照录:《三命通会》卷二「论五行旺相休囚死并寄」(旺相休囚死)、卷三「总论诸神煞」(神煞取用)、卷三「论空亡」(空亡)、卷二「论大运」(起运)、卷七「论六亲」(六亲)、卷二「论三刑」(刑冲),以及《穷通宝鉴》「五行总论」(调候)。《穷通宝鉴》该本页首未标卷次,条目只写篇名、不替它补卷号。`bazi-tonggen-tougan` 仍留通行说——《滴天髓》只有「壬水通根透癸」的单条,没有泛论通根透干的段落,不拿个案冒充通则。
442
+ - 第三批 6 条:《奇门遁甲统宗》卷一「奇门秘诀总赋」(阴阳遁与超神接气)、卷十一「玄机赋(中)」(六仪击刑、三奇入墓)、卷三(旺相休囚)、卷二(八门迫制与有气无气),以及《梅花易数》卷二「体用生克」。奇门章节只标页面实有的卷次与篇题,`qimen-gan-shengke`(干与落宫生克)留通行说——底本只有「奇仪对日干」的十神条,未见单列干宫生克条,不拿十神条文冒充。
443
+ - 第四批 13 条:《增删卜易》(维基文库本,**繁体照录**)——卷一用神、月将、日辰、动变生克冲合、六神、六合、六冲、反伏、各门类应期总注,卷二飞伏神与进神退神;覆盖 `liuyao-yongshen`、`liuyao-fushen`、`liuyao-wangshuai`、`liuyao-yongshen-shuai`、`liuyao-quanggu-shuai`、`liuyao-dongbian`、`liuyao-liushen`、`liuyao-liuhe`、`liuyao-liuchong`、`liuyao-fanyin`、`liuyao-fuyin`、`liuyao-jintui`、`liuyao-yingqi` 十三张卡。`liuyao-jintui-yong` 仍留通行说:底本把进退落在「動而化」的吉凶喜忌与应期上,未见单列「用神化進/化退」条,按用神与忌神分档是本插件引申。
444
+ - 引文库合计 **90 条**(八字经典 41 + 引文索引 49:紫微 23、三命通会 6、增删卜易 13、奇门 5、穷通宝鉴 1、梅花 1)。`test/fixtures/citation-sources.json` 同步到 56 个章页快照,`test/citations.test.mjs` 累计 50 条断言(书目登记、卡片带 refs、各条取书与章名、无省略号)。大六壬仍标通行说:本环境无可稳定核验的公有领域章页(ctext 明示禁止抓取、中华典藏网未收)。
445
+ - **D3 性能门槛**(`tools/check-perf.mjs`):`tools/bench.mjs` 拆出 `runBench()` 与 `CASES` 供复用(CLI 行为不变,`--json` 仍可用),新增门槛脚本对八体系样本逐项判超限——首次 150ms、p50 10ms、p95 25ms、带解析 250ms、1000 盘 4000ms、RSS 800MB。阈值按文档目标(bazi p50 < 1.5ms、1000 盘 < 400ms)留 5–10 倍余量,拦的是数量级回退而非毫秒级抖动;`DSH_PERF_SCALE=3` 可按倍数为慢机放大上限,不改代码。`npm run bench` 只测不判,`npm run check:perf` 判超限,`test:ci`、GitHub Actions 与 `tools/autopublish.mjs` 的发布闸门都串上。证据:`test/perf.test.mjs` 29 条(八体系基准形状、真实样本判定、超限样本必红、阈值余量与放大、npm/CI/自动发布/README/方案接线);本机实测 bazi 首次约 20ms、p50 0.78ms、1000 盘约 355ms、RSS 约 80MB、带解析 <8ms。
446
+ - **自动发布参数校验**(`tools/autopublish.mjs`):只认 `--dry-run` / `--init` / `--force`,其余参数(例如误写 `--dry`)立即以退出码 1 拒绝并列出可用参数,不再静默忽略后照常提交推送;未知参数不触碰状态文件。证据:`test/autopublish.test.mjs` 8 条。
447
+ - **C2 一句话改参**(`engine/revise.js`):把「换成紫微看 2030 年事业」「女命」「晚子时算次日」「出生在成都」「不用真太阳时」「详细解读一下」这类原话翻成参数补丁再排盘,可配合 `handle` 使用——上一轮的出生信息不必重报。**只认明确句式**:换体系必须有切换词(换成 / 改成 / 看 / 用 / 按…),单提一句「紫微里怎么说」不换盘;出生年份与时辰一句话给不出分秒,不猜,改为在 `ignored` 里明说改不了、请直传 `datetime`。识别不到时盘面一字不动,`applied` 为空。结果 `revision` 回传 `text` / `applied`(`key`、`label`、`value`、`display`、`from`、`fromDisplay`、`ignored`),旧值翻成中文(`system: bazi → 八字`、布尔 → 开 / 关、`asOf` → 年份),没设过的记「(未设)」而不是编默认值。改参先生效、后跑地址解析与日期补全,换体系会连带改走另一套默认值;句柄记的是改后参数、不含 `revise` 原文,所以同一张盘换个说法得到同一句柄。摘要末尾给「【改参】原话 + 逐条 旧 → 新 + 未处理」,面板与独立页给改参卡(先改动、后句柄)。`revision` 属请求回显,影子盘指纹与口径对照均忽略。
448
+ - **C1 排盘句柄**(`engine/handle.js`):每次排盘在结果里回一个自包含短句柄 `mc1.<base64url>.<8 位校验>`,下一次只传 `handle` + 增量参数(`asOf`、`direction`、`question`、换 `system` 看同一时刻另一套盘)即可,不必重报出生信息。句柄把参数本身编码进去而不是存在内存里——宿主一次工具调用可能落在不同进程,内存句柄拿不到下一轮。只收影响盘面的参数:`trace` / `shadow` / `withInterpret` / `cross` / `ask` / `caliber` / `geocode` 这些输出开关不进句柄,所以要不要解析、要不要推导链都不改变句柄;`seed` / `asOf` / 各流派开关必须留下,否则复现不出同一张盘。键序固定(键名排序),参数写法不同也得到同一句柄;校验位用 FNV-1a,截断、改字、错前缀都报 `E_HANDLE` 并给修复提示,不会静默排成另一张盘。base64url 与 UTF-8 均为自带实现(不依赖 Buffer / btoa / TextEncoder),引擎在 Node、浏览器与 vm 沙箱里都能跑。`compute` 入口先 `resolveHandle` 再排盘,显式 `undefined` 不覆盖句柄字段;宿主工具新增 `handle` 参数,并在地址解析、日期补全之前先并回参数,避免追问时漏掉出生地导致真太阳时不同。结果摘要末尾附「【排盘句柄】+ 用法」;面板与独立页给句柄卡与「复制句柄」按钮,并写明「是编码不是加密,含出生时间与出生地,别公开贴出」。影子盘指纹与口径对照忽略 `handle`(它反映的是另一次请求,不是盘面差异)。随机抽牌 / 起卦:句柄复现参数、不复现牌面,要复现须带 `seed`。
449
+ - **F 喜忌中性档**(`engine/geju.js`):忌神里全局分量不足 0.5 的另列 `neutral`(含 `element` / `role` / `verb` / `weight`),摘要、解析层、白话层与面板 chip(`中性偏忌 X 0.3 分`)都写明「近零,不作实忌」。**只是展示分档,`avoid` 不变**——局中没有不等于运里不来,大运/流年遇之仍按忌计,评分与调候结论一律不动。
450
+ - **A5 推导链导出**(`engine/trace.js`):`trace: true` 时结果同时给 `traceText`——同一份层的 Markdown(标题 + 每层结果/规则/输入表/出处),可直接贴进对话或文档;表格单元格转义 `|` 与换行。面板推导链抽屉加「复制 Markdown」按钮(内容取自隐藏 textarea,与引擎同源,不在前端重排)。五个体系(六爻 / 八字 / 紫微 / 奇门 / 大六壬)共用同一份导出逻辑。
451
+ - **测试**:新增 `test/handle.test.mjs`(70 条:往返、增量、换体系、键序、输出开关不进句柄、截断/改字/错前缀、中文与表情、影子盘不受影响、宿主 schema 与执行、面板与独立页接线)、`test/revise.test.mjs`(68 条:九条改参规则的命中与不命中、改参后盘面真变化、未设原值回显、忽略项提示、句柄配合、宿主执行、改参卡转义与接线)、`test/trace-export.test.mjs`(60 条)、`test/yongshen-neutral.test.mjs`(29 条)、`test/citations.test.mjs`(50 条,含 B6 第二/三/四批 23 条)、`test/perf.test.mjs`(29 条)、`test/autopublish.test.mjs`(8 条:未知参数直接拒绝、白名单固定)。当前 **122 个测试文件 / 5653 条断言**,七道闸 + 性能门槛全绿。
452
+
453
+ ## 0.56.0(2026-11-01,已发布)
454
+
455
+ - **邮件反馈 2026-10-31(三条)**:输入区错位、八字旺衰与喜忌、紫微子年身主。逐条处理记录见 `docs/用户反馈记录.md`。
456
+ - **面板输入区对齐**(`src/app.js`):① `.mp-input` / `.mp-textarea` 补 `box-sizing:border-box`——Chrome 下 select 默认 border-box、input 默认 content-box,同为 36px 时 input 实高 50px,底对齐后「性别」下拉比日期框低 14px;② 「晚子时换日」改成与「真太阳时」「联网精确到区县」同构的普通勾选,去掉误加的 `mp-field mp-checks`(继承 `margin-top:13px` 后比同行低 7px),并补 title 说明;③ 降列由视口 `@media` 改为 `.mp-wrap` 容器查询(860px 两列、480px 一列)——侧栏宽度不等于窗口宽度,面板拖到约 600px 而窗口仍是 1200px 时原来照排四列、输入框被压到 117px;「八字 × 紫微 交叉验证」勾选独占一行。无头 Chrome 以面板实际 CSS 在 600/940px 两档复测:同行输入框顶底一致、三项勾选中线一致。独立页本有全局 `*{box-sizing:border-box}`,不受影响。
457
+ - **八字旺衰 · 合会折根与虚透减半**(`engine/bazi.js`):地支通根前先看会合——三会成方时同类支不折、印局按 6 成、他局按 1 成;三合成局同类不折、印局 6 成、他局 2 成;六合同类不折、印 8 成、他 5 成,且只折局外那一支(已入会/合局的支归该局);半合/半会不折。天干比劫/印透出而折根后同类藏干不足 0.3 的作**虚透**,帮扶按半计。`strength.parts` 新增 `structure`(折根说明)与 `virtualHelpers`,`detail` 追加「合会折根:…」「虚透X帮扶减半」,`method` 改为「…(三会/三合/六合折根)+ 天干帮扶(虚透减半)…属简化算法,非唯一流派」;推导链旺衰层同步新增「合会折根」「虚透」两行。亥月戊土、年子时丑、日坐寅这一型,旧算法把丑中己土与寅中戊土当足根、天干己土当实帮,判「偏强」并忌土;现判偏弱/身弱、喜火土、忌金水木。416 张盘的五档分布由 52/82/56/114/112(偏弱/中和/身弱/偏强/身强)变为 68/87/69/96/96,偏强与身强各降约 15%。
458
+ - **紫微身主两派**(`engine/ziwei.js`):新增第十个流派开关 `shenzhuSchool`——`common`(默认,子午皆火星,与 iztro 及通行排盘一致)/ `verse`(安身主诀「子午安身铃火宿」逐字:子铃星、午火星;维基文库本《紫微斗数全书》卷一、卷三未见此诀,故不标作《全书》原文)。**默认行为变化:子年身主由铃星改为火星**;午年两派都是火星,其余十支不变。子午年盘带 `bodyMasterSchool` 与 `bodyMasterNote`,文本 `【身主】火星(子午皆火星)`、面板 `*` 悬停说明出处;`rules.schools` 列入身主口径。工具 schema、`engine/index.js` 平铺透传、口径对照(紫微 11 → 12 组)同步;`bodyMasterSchool` / `bodyMasterNote` 属口径回显,不计盘面差异。
459
+ - **测试**:新增 `test/bazi-strength-structure.test.mjs`(32 条:同型盘偏弱与喜火土、三会/三合/六合/局内支不重复折、同类局与印局、无合会盘不受影响、推导链两行、五档分布不塌缩)、`test/ziwei-shenzhu.test.mjs`(29 条)、`test/panel-form-align.test.mjs`(11 条);`test/caliber-diff.test.mjs` 补子年身主能检出、午年无差异与 12 行渲染;`test/ziwei-schools.test.mjs` 开关数 9 → 10;`test/trace.test.mjs` 的争议样本换成 1962-03-22。当前 **116 个测试文件 / 5366 条断言**,七道闸全绿。
460
+ - **自动发布改为只推送**(`tools/autopublish.mjs`):定时任务只跑七道闸、重建产物、提交并推送 `main`,不再自动升版本号、打 tag 或发 npm;push 失败重试 3 次(15s / 30s 退避)。发版仍走 `tools/release.mjs`。
461
+ - **B5 玄空替卦与年月日时飞星**(`engine/fengshui.js`):`action:'xuankong'` 新增兼向替卦与年月日时紫白。兼向按「坐山偏离本山中心超过 4.5°」判定,接受 `sittingOffset` / `sittingDegree` / `facingOffset` / `facingDegree`(坐向都给须一致);替星取《沈氏玄空学》坤壬乙诀 24 山全表(1/2/6/7/9 五星),山星/向星改以替星入中,顺逆仍按替星本宫同元龙;同卦兼/出卦兼、原运星与「用替而未替」都在结果里标明,替卦不再套正向旺山旺向表。年月日时紫白按公式派:年逐年退一位;月按年支三组起 8/5/2、逐月退一位;日按冬至–夏至三段起 1/7/4 与 9/3/6,阳遁顺飞、阴遁逆飞;时按日支三组子时起 1/7/4 与 9/3/6,阳遁顺行顺飞、阴遁逆行逆飞;月取节气月、日按公历日且 23:00 后归次日。新增 `fortuneDate` / `fortuneTime` 入参;只给年份时只排年星并提示补日期。摘要、面板九宫卡、独立页表单(兼向度数/飞星日期/时刻)同步;口径异说写进 note,不与「日星一律顺飞」「月按农历月」等派别合并。
462
+ - **测试**:新增 `test/fengshui-tigua-zibai.test.mjs`(102 条)——替星表 24 山、4.5° 阈值、同卦兼/出卦兼、8 运子午替星改盘、5 运用替而未替、度数输入与边界、年月日时六个分段锚点、时家冬夏×日支三组、晚子时、中宫文案、摘要/面板/compute 接线;`test/fengshui-ui.test.mjs` +5 条替卦卡与飞星事实;原玄空测试的 scope 与来源条数同步。当前 **113 个测试文件 / 5286 条断言**,七道闸全绿。
463
+ - **信息层次与 AI 解读可读性**(`engine/followup.js`):给 8 个体系登记「阅读层次」(八字:基本信息 → 四柱 → 旺衰/格局/用神 → 合冲/神煞 → 大运流年 → 古籍依据;紫微、六爻、梅花、大六壬、奇门、塔罗、风水各有顺序,未知体系走通用兜底)。`askPrompt` 先列层次、再给摘要;回答要求由 4 条改为 5 条:结论 → **骨架事实**(按层次 2–4 行,不掺倾向)→ 最多两条判断(盘面/白话/倾向/边界)→ 只记一件事 → 边界与禁语,并写明「上一层没交代清楚,不要跳到下一层」。层次顺序参考 ziwei.pub/bazi 的分区,只借层次、不复制文案;固定骨架由约 520 字增至约 700 字,仍受 `test/ask-prompt.test.mjs` 的 900 字上限约束。
464
+ - **参考资料登记**(`docs/参考资料与对拍来源.md`):记录 ziwei.pub/bazi 的访问日期、采用的命宫/身宫/胎元/胎息口径与信息层次、704 组日期对拍证据,以及未采用的文案/视觉/AI 内容;另列 tyme4ts 与历法、卦例、紫微、八字、奇门对拍入口。约定「先登记再改代码、采用范围必须能指向测试或对拍证据」。
465
+ - **测试**:`test/ask-prompt.test.mjs` 由 67 条扩到 81 条——层次顺序、不跳层、骨架段、5 条编号、8 体系非空不重复、未知体系兜底;当前 **112 个测试文件 / 5179 条断言**,七道闸全绿。
466
+ - **B4 奇门十干克应 + 六仪入墓**(`engine/qimen-ganying.js`):新增通行 100 组「天盘干加地盘干」表(格名 + 断语 + 底本链接),每宫与中宫随盘带 `ganYing`。底本取 daoisms 通行表,《奇门遁甲元灵经》卷二只存甲、乙、丙三组且措辞不同,作为异文并列、不合并;底本个别讹字按文义校正(么→私、病病→病、得→行、磋砣→蹉跎)。新增六仪入墓(戊墓戌乾六、己庚墓丑艮八、辛壬墓辰巽四、癸墓未坤二),与三奇入墓并列进 `conditions.liuYiRuMu`。摘要、解读层「十干克应」段、面板九宫格与事实行、推导链关系层、知识卡 `qimen-ganying` 与引用索引同步;克应只作取象与读盘线索,与门宫/干宫生克并列,不自动折吉凶。
467
+ - **测试**:新增 `test/qimen-ganying.test.mjs`(46 条)——100 组完整无重、抽样条目、六仪入墓映射、60 个时辰 × 480 宫逐宫有克应、全链路显示;`test/trace.test.mjs` 宫位条件断言补十干克应与六仪入墓。当前 **112 个测试文件 / 5165 条断言**,七道闸全绿。
468
+ - **B6 引文索引补齐**:知识卡 53 张(新增 `qimen-ganying`),已定位原文 17 张、通行说 35 张、待补 1 张;`docs/citations.html` 重新生成。
469
+ - **A1+ 奇门四层推导链**(`engine/trace.js`):新增 `facts → yongshen → states → relations`,依次摊开盘面事实(四柱、节气局数、旬首、值符值使、空亡驿马)、按询问方向取的用神落宫、门/星/天盘干按月令的五态、门迫/宫制门/干宫生克与击刑入墓空亡。用神表由 `engine/qimen-interpret.js` 的 `qimenYongshen()` 单源导出,解读与推导链不再各写一份。
470
+ - **A1+ 大六壬三层推导链**(`engine/trace.js`):新增 `tiandipan → sike → sanchuan`,给出月将加时后的十二支天地盘与天将、四课上下神与生克、三传的干支/六亲/天将/旬空与课体。只读结果,不改盘面。
471
+ - **接线**:面板与独立页对奇门 / 大六壬默认请求 `trace`;奇门把「询问方向」传入 compute,改方向时只重建用神落宫层,不重新起局。
472
+ - **D1+ 拆分 chart 块**(`tools/build-client.mjs`):原 `chart` 拆成 `bazi` / `ziwei` / `hepan` / `trend` 四块,分块总数 15 → 18。八字块内含人生 K 线索与紫微交叉验证,紫微块带八字交叉验证,合盘块同时带两套引擎与紫微合盘模板,人生 K 线块不再背紫微。各块 gzip:bazi 178KB、ziwei 174KB、hepan 177KB、trend 154KB(原 chart 183KB);入口仍为 71KB。分块之间不共享代码,代价是重复的公共栈,换来每个 tab 只取自己需要的块。
473
+ - **测试**:`test/chunks.test.mjs` 由 102 条扩到 121 条——18 块注册/自包含/体积、八字与紫微在各自块内开交叉验证、紫微合盘在 hepan 块内复算、切块后缓存不重复拉取;统计 **107 个测试文件 / 4978 条断言**,七道闸全绿。
474
+ - **B2 紫微破格**(`engine/ziwei.js`):34 条格局逐条给 `status`(`formed` / `broken` / `n/a`)、`breaks`(哪颗星落在哪一宫)与 `breakRule`。吉格与武贪、双禄交流、火贪铃贪再判破格:三方四正见羊陀火铃、空劫或化忌即破;石中隐玉另判「三方无科禄」、火贪铃贪按「三方有凶杀」、武贪按「武贪化忌」、机月同梁/昌曲/魁钺夹命各按本条原文判。忌格与命无正曜、杀破狼不判破格,明确标 `n/a`。摘要、文本、解读层与面板 chip 同步显示破格数与理由;`test/ziwei-poge.test.mjs`(25 条)扫 312 张盘复核。
475
+ - **B6 引文索引**(`engine/citations.js` + `docs/citations.html`):新增《紫微斗数全书》23 条原文(维基文库,卷一/卷三,含卷章与链接),与既有 41 条八字原文合成 64 条引文库;53 张知识卡逐张登记出处(B4 新增 `qimen-ganying`),17 张已定位到可核验原文,其余标「通行说」或「待补」并写清理由,不冒充原文。`test/citations.test.mjs`(27 条)核验「原文子串确实出现在来源正文里」,重建索引页并与磁盘逐字比对;`docs/citations.html` 由 `npm run build:citations` 生成。
476
+ - **测试**:新增 2 个测试文件(52 条),当前 **109 个测试文件 / 5030 条断言**,七道闸全绿。
477
+ - **B3 四宫口径修正**(`engine/bazi.js`):新增**胎息**(日干五合、日支六合),并把命宫/身宫由「命宫对宫」改为 ziwei.pub 同款 Tyme 1.5.4 口径——命宫=27 减生月与生时支、取模后加二,身宫=11 加两支、取模后加二,干支并入六十甲子。旧口径在 1990-05-12 14:30 得丙戌/庚辰,与紫微派页面(辛巳/己丑)不符;修正后四宫为壬申/壬子/辛巳/己丑。已用 tyme4ts 1.5.4 对 1950–2020 的 **704 组日期逐组对齐,0 处不符**。摘要、解读层「胎命身」、面板 chip、独立页与八字推导链第 3 层(`palaces`)同步;`test/bazi-palaces.test.mjs`(57 条)锁 6 组日期与「胎息=五合六合」「命宫+身宫支序=6」两条结构不变量。
478
+ - **B3 专旺成格 / 真从假从**(`engine/geju.js`):专旺补 `status`(成格/待定/破格)与 `breaks`——月令助旺且不见官杀/财星为成格,月令不助为待定,官杀 >1.2 逆势或财 >1.8 耗旺为破格;三合局全另记 `ju`。从格补 `rootWeight`(地支藏干同类/印 + 天干透出)与真假:完全无根、无比劫印绶透出为**真从**,有中气/余气微根或虚透为**假从**;见一个本气根(≥1 分)就不作从格。摘要、解读层「格局依据」、面板 chip(破格虚线、假从/待定警示色)与原文取条同步;破格不再挤占专旺单章,化气与假从同盘时化气优先。`test/bazi-special.test.mjs`(28 条)锁成/待/破与真/假从各档及全链路显示。
479
+ - **测试**:新增 2 个测试文件(85 条),当前 **111 个测试文件 / 5119 条断言**,七道闸全绿。
480
+
481
+ ## 0.55.0(2026-10-31,已发布)
482
+
483
+ 补齐口径对照里的紫微九派,并把邮件反馈里的两处显示口径收紧:五合不再直接写「合化」,自化与生年/大限/流年四化分三层显示。
484
+
485
+ - **口径对照补全**(`engine/diff.js`):紫微由闰月、真太阳时两组扩到 11 组,新增亮度表、庚干四化、天马、天空、截空旬空、魁钺、天伤天使、长生、晚子时九类流派开关。默认档与另一档都取自引擎枚举,平铺参数与 `schools` 嵌套都能读;非法值回落默认。切换后 `schools` / `rules.schools` 只是口径回显,不再计入盘面差异。
486
+ - **同一张表**:面板折叠卡、独立页、`tools/caliber-diff.mjs` 与工具 `diff: true` 仍共用 `CALIBER_SWITCHES`;紫微卡一次列 11 行,summary 先给「几组影响此盘」。`shadow` / `trace` 属于派生展示,不再参与对照,避免面板里每组开关都被影子盘回显误报成「有变化」。
487
+ - **五合措辞**(`engine/bazi.js`):干支关系只标「有合」,摘要与面板写「戊癸合(化火待定)」;是否真化仍由化气格条件另判,不把「合」直接说成「化」。
488
+ - **四化分层**(`src/panel-kit.js`):生年四化实心、大限/流年四化空心、自化改为彩色字 + 虚下划线,图例补「虚下划线=自化」,宫位详情同步;自化块带读屏说明。
489
+ - **公开对拍补奇门**(`tools/verification.mjs`):接入 `test/fixtures/qimen-20.json` 的 20 个时辰 × 9 宫 = 180 个宫位,逐宫核四柱、局数、值符、值使、星门神与天盘干;报告从 457 行增到 **477 行**,新增「奇门」筛选与卡片。徽章改为披露「128 例 · 5 剔除 · 312 紫微 · 20 奇门 · 12 交运」。
490
+ - **CI 同源加固**:构建产物与对拍报告的 `git diff` 前先 `git add -N`,新增的 `client.*.js`、报告页或徽章不再因 untracked 而漏检;`release` 走同一套判据。自动发布指纹补入报告生成器与两份对拍 fixture。
491
+ - **工具输出克隆**(`engine/index.js`):`jsonSafe` 不再 `JSON.parse(JSON.stringify())`,改为等价递归深拷贝(NaN→null、-0→0、Date→ISO、数组空位→null、对象内 undefined/函数丢键、循环引用抛错),省掉每次 `compute` 建一遍几百 KB 中间字符串。21 个体系 21 组样本改动前后输出逐字节相同、影子盘 ID 不变。
492
+ - **三合表单源**(`engine/shensha.js` / `engine/almanac.js`):将星/驿马/桃花的 `trioKey` 与黄历「三合吉配」「煞方」原本各自维护的三合成员表,改为从 `engine/sanhe.js` 的 `SANHE_GROUPS` 派生,全仓只剩一份三合成员表。
493
+ - **测试**:`test/caliber-diff.test.mjs` 由 129 条扩到 205 条——11 组开关、默认档/另一档枚举、嵌套读取、回显忽略、九派逐项能改盘、shadow/trace 不参与对照、11 行渲染;`test/relations.test.mjs` 补五合「待定」与五组干合;`test/layout.test.mjs` 补自化分层与图例;`test/verification.test.mjs` 补奇门 20 例与改坏值符的检出。统计 **107 个测试文件 / 4925 条断言**,七道闸全绿。
494
+ - **文档**:README 口径对照、精度与口径、公开对拍三处同步;独立页「方法与验证」补奇门 20 例。
495
+ - **版本说明**:0.51.0–0.54.0 未单独发布,能力均并入 0.55.0。已于 2026-10-31 发布:npm latest 从 **0.50.5** 跳到 **0.55.0**(80 个文件,shasum `a8640df32d5451078bd15bf94d7b95da0547f698`),tag 与 GitHub release 同为 `v0.55.0`。
496
+
497
+ ## 0.54.0(2026-10-31)
498
+
499
+ 把「验了什么、差在哪」做成公开页:新增 `docs/verification.html` 与 README 顶部徽章,报告数字与 CI 共用 `tools/verification.mjs` 一个数据源。
500
+
501
+ - **128 条卦例**:《卜筮正宗》成对 93 条 + 静卦 35 条,逐条核本变卦、动爻数、卦宫、缺爻、旬空;源 138 条中被剔除的 5 条连同原书理由逐条列出(动爻标记冲突、缺爻冲突、卦宫冲突、静卦核对失败)。
502
+ - **312 张紫微盘 × 34 条格局 = 10,608 条判定**:沿用 `test/ziwei-patterns.test.mjs` 的扫描盘(1950–2025、月日时错开)与独立谓词——只读星位与四化,不调用引擎格局函数;34 条每条至少命中一次,命中分布列在报告折叠区。
503
+ - **12 个交运案例**:覆盖阳年男女顺逆、闰日 02-29、真太阳时、立春/晚子时边界、长间隔与 ΔT 近似区间;独立复算取节、三日折一年比例、`jiao/startAge` 同源、闰日十年后退位与口径标注。
504
+ - **报告页**:`docs/verification.html` 自包含,无外链脚本 / 样式;可按「一致 / 剔除 + 理由 / 不一致」与体系(六爻 / 紫微 / 交运)筛选,附搜索与 34 格局命中分布;窄屏表格横向滚动,深色跟随系统。README 顶部徽章 `docs/assets/verification-badge.svg` 由同一生成器写出,0 处不符时为绿色。
505
+ - **CI 同源**:新增 `test/verification.test.mjs`(23 条)直接 import 生成器,断言 128 / 312 / 12 / 0 不符、剔除项带理由、报告与徽章和生成结果逐字节一致;并故意改坏一条卦宫判定,要求校验器立刻标「不一致」。CI 增加「重建报告 + `git diff`」步骤,`release` 也会重建并校验报告;任何判定变化或忘记重建,CI 都会红。
506
+ - **测试**:统计 **107 个测试文件 / 4836 条断言**,七道闸全绿。报告页 390×844 深色无横向溢出,筛选按钮与表格可读。
507
+
508
+ ## 0.53.0(2026-10-31)
509
+
510
+ 把 `client.js` 按 tab 拆开:入口只留界面与懒加载器,引擎落到 15 个自包含分块,首屏 gzip 从 0.52 的 334KB 降到 71KB(目标 < 100KB)。
511
+
512
+ - **拆包协议**:DSH 客户端模块支持 `require.async("./client.<name>.js")`,分块用 `__ModuleLoader__.load({ id, chunk, factory })` 注册。入口 `client.js` 不再内联 `engine/*.js`,只保留 panel-kit / app / core;新增 `src/engine-lazy.js`,按当前 tab 取分块,并把该块统一入口的导出合并到同一个 `Engine` 对象。分块自包含,宿主与入口都缓存已加载的块。
513
+ - **分组**:chart(八字 / 紫微 / 合盘 / 人生 K 线)、name、fengshui、liuyao(六爻 / 梅花)、qimen、daliuren、tarot、almanac、convert、zeri、chenggu、xiaoliuren、star、numerology、mbti,共 15 块,覆盖全部 19 个 tab。互相依赖的体系(如合盘双方、八字交叉紫微)落在同一块,避免运行时同步 require 另一个分块。
514
+ - **安全降级**:`buildModule` 的 import 解构改为 `(__mods.x || {})`,统一入口对未随块加载的体系引用能安全落空,只有实际被调用的体系需要在场。入口在 `require.async` 缺失时给出明确的宿主版本提示,不静默白屏。
515
+ - **界面**:`run()` 与切到人格 tab 前先 `await ensureEngine(k)`,加载期间显示「正在加载本页需要的引擎…」;MBTI 题面不再在未加载时缓存空问卷;独立页与旧宿主没有分块加载器时回退到现成的完整 `Engine`,离线页行为不变。
516
+ - **构建与自检**:`tools/build-client.mjs` 生成入口 + `client.<name>.js`,并清理已下线分块的旧文件;`tools/check-bundle.mjs` 现在同时校验入口与每个分块的编译、注册名、返回 `Engine`、与源码逐字节一致,并守住入口 gzip < 100KB;`release` 的产物 diff 与 tarball 关键文件加入分块。构建日志按 UTF-8 字节数报告,不再用字符串长度低估中文体积。
517
+ - **体积**:入口 `client.js` 239KB(UTF-8)/ gzip 71KB;最大分块 chart 179KB gzip,六爻 128KB、奇门 123KB、塔罗 122KB、六壬 118KB、起名 98KB,速查类 46–68KB、人格 55KB。首次打开只下载入口,排盘时才取当前 tab 的块。
518
+ - **测试**:新增 `test/chunks.test.mjs`(102 条):19 个 tab 全映射、15 个分块的注册名 / 自包含 / 体积、入口体积与懒加载、19 个体系的分块引擎与源码逐字节一致、切回 chart 仍能排紫微、分块缓存不重复拉取、无 interpret 的分块不抹掉 DIRECTIONS。统计 **106 个测试文件 / 4813 条断言**,七道闸全绿。
519
+ - **界面验证**:CDP 真机视口 390×844 深色:`innerWidth = scrollWidth = 390`、结果区 366px、`prefers-color-scheme: dark = true`、正文底色 `rgb(18,17,13)`、推导链入口在;无横向溢出。940×900 浅色 `scrollWidth = 940`、结果区 888px。
520
+
521
+ ## 0.52.0(2026-10-31)
522
+
523
+ 把「结论怎么来的」摊开:新增 A1 推导链 `trace: true`,六爻 / 八字 / 紫微逐层返回 `{field, rule, inputs, result, source}`,面板用右侧抽屉逐级展开。
524
+
525
+ - **六爻五层**:纳甲(本卦上下卦 → 六爻干支)→ 六亲(卦宫五行 → 逐爻六亲)→ 世应(八宫世位 → 世 / 应爻)→ 伏神(用神不上卦时取本宫首卦同位,附飞伏生克与出伏判定)→ 旺衰(月建 / 日辰 → 用神五态与全卦逐爻状态)。未选询问方向时明确写「未选询问方向(综合),未取用神」,不再误写成「未指定所问之事」。
526
+ - **八字两层**:旺衰分值(日主 / 月令权重 / 通根 / 天干帮扶耗泄 → 分值、档位与 detail)与格局取用(月令格与取格依据、十神分量、调候 → 主格 / 兼格、喜忌、有争议五行)。
527
+ - **紫微一层**:格局命中条件(命宫、五行局、命主身主、命中数 → 逐条命中的格局与 evidence;未命中时写明只是不在已收录清单内)。
528
+ - **只读与可复现**:`buildTrace` 只读 `compute` 结果,不重算、不读时间与随机,`trace` 开关前后盘面逐字节一致、影子盘 ID 不变;生成失败只挂 `traceError`,不影响主结果。`renderText` 追加【推导链】段,宿主 `metaphysics_chart` 同步暴露 `trace` 布尔参数。
529
+ - **界面**:结果顶部新增「推导链」入口(显示层级链与层数),点开为右侧抽屉;每层用 `<details>` 逐级展开,先给规则与结构化输入,再给结果与出处。关闭按钮 44px、遮罩与 Esc 可关、关闭后焦点回入口;窄屏抽屉占满 100vw,深色只换变量,打印隐藏。六爻的询问方向一开始就参与 compute(否则用神会退成综合),改方向时只按新方向重算用神 / 旺衰 / 伏神三层,不重摇一卦。独立页 `#out` 的入场动画从「位移 + 淡入」改为纯淡入——`transform` 动画会为 fixed 子元素建立 containing block,曾把抽屉关在结果卡片里。
530
+ - **测试**:新增 `test/trace.test.mjs`(61 条):五层 / 两层 / 一层的字段与顺序、每层 rule / inputs / result / source、伏神在爻上与不上卦两种分支、未选方向说明、改方向 refresh 不重摇也不改原结果、trace 不改盘与不改影子盘 ID、文本层、面板抽屉与转义、面板 / 独立页接线、宿主 schema 与执行。统计 **105 个测试文件 / 4711 条断言**,七道闸全绿。
531
+ - **界面验证**:390×844 深色下抽屉贴视口右侧(`rect = 0,0,390,844`)、5 层、首层展开、关闭按钮 44px、无横向溢出;关闭后 `aria-hidden=true`。900px 浅色与既有结果卡均无溢出。
532
+
533
+ ## 0.51.0(2026-10-31)
534
+
535
+ 给每张盘一个可复制的「影子盘」ID,并把 `client.js` 真正压缩(路线图 A4 + D1)。
536
+
537
+ - **A4 影子盘(引擎)**:新增 `engine/fingerprint.js`(规范化 JSON + 35 位短哈希,纯函数)。`compute({ shadow: true })` 在结果上挂 `shadow: { id, baseId, version, system, payload, reproducible, asOfPinned }`。`id` 含版本,`baseId` 不含版本;同一组归一化参数(键序无关、默认值等价、地址与等值经度等价)在任何机器上得到同一 ID,版本升级只改 `id`、不改 `baseId`。
538
+ - **版本 diff**:`shadowDiff(previous, current)` 只在 `baseId` 相同时比对,复用 `engine/diff.js` 的标签 / 根因 / 分类,返回「几处变化、根因字段旧值→新值、连带分类」;`compute({ shadow: true })` 的结果可直接比,也可以比 `shadowSnapshot()` 存下的轻量快照。面板与独立页把快照写进本地存储(最多 24 张盘),同盘重排时自动与上次比对,升级后展开就能看到字段级差异。
539
+ - **随机起卦不撞 ID**:塔罗 / 六爻未给 `seed` 时,实际抽到的牌面 / 六爻值会算进指纹,两次不同抽牌得到不同 ID,并标「不可复算」;给定 `seed` 或六爻值时同参数同 ID。八字 / 紫微未固定 `asOf` 时提示「流年随此刻变化」。
540
+ - **界面**:结果上方新增影子盘卡(ID 等宽、一键复制、版本与基础指纹),有跨版本 / 跨次变化时展开「与上次同盘比对」;共享调色板,深色只换变量,窄屏复制按钮 44px、无横向溢出,打印时强制展开并隐藏复制按钮。面板与独立页同一渲染路径。
541
+ - **工具**:宿主 `metaphysics_chart` 新增 `shadow` 布尔参数,版本从 `package.json` 注入;`renderText` 追加【影子盘】行。独立页由 `build-html` 注入 `window.__MP_VER`,不再落到 `dev`。
542
+ - **D1 压缩**:`tools/build-client.mjs` 用 esbuild(`minify + target es2020 + charset utf8`)压缩,未安装时退回保守去注释;`client.js` 从 **983KB → 640KB**,gzip **329KB**。`check-bundle` 改为在未压缩源码上逐模块定位、对真实文件做整文件与宿主形态执行,并与压缩重建结果逐字节比对;CI 增加 `npm ci`;`client-bundle` 新增体积断言(低于源码 80%、gzip < 360KB),并改走统一断言工具(失败会真正退出非零)。路线图原定 gzip < 100KB,不做内容拆分与懒加载无法达到,这里按实际体积设闸并写明。
543
+ - **界面验证**:390×844 深色下 `scrollWidth = 390`、卡片宽 366、复制按钮 44px、卡片底色 `rgb(33,31,24)`;900px 浅色下卡片 848、复制按钮 40px;模拟旧版本存档后自动 diff 正确显示「版本变化 + 1 处字段」。
544
+ - **测试**:新增 `test/shadow.test.mjs`(55 条):ID 确定性 / 键序 / 默认值 / 参数敏感性 / 体系 / asOf、地址与经度等价、版本只改 id、随机牌面不撞 ID、diff 根因与分类、文本层、面板转义与复制按钮、localStorage 自动对盘、宿主 schema 与版本注入。统计 **104 个测试文件 / 4650 条断言**,七道闸全绿。
545
+
546
+ ## 0.50.5(已发布 2026-10-31)
547
+
548
+ 修 GitHub issue #1:「身弱喜火土,给分析成忌火土了」——顺带修掉同源的「同一五行同时出现在喜用与忌神」。
549
+
550
+ - **问题在哪**:`engine/geju.js` 的 `yongshenOf` 先按扶抑定喜忌,再让调候在「调候优先」时把 `climate.avoidElement` 插进 `avoid`;如果这个五行本来就在扶抑的 `favor` 里(例:偏弱己土燥盘,火为印、喜火,调候又忌火),两份列表就会重叠。摘要行仍写「喜水火土……忌金木」,但面板、解读、喜忌筛选各取一份,用户看到的就是「一会儿喜火、一会儿忌火」。身强寒湿盘的水同理。
551
+ - **修法**:调候所忌若已在 `favor`,不再插入 `avoid`,改记入 `disputed`(元素、扶抑角色、调候气候),喜用保留该行;调候所需要素仍按原逻辑从 `avoid` 移除。新增 `disputedTenGods`;`detail`、摘要「用神」「寒暖」行、解读「用神」「寒暖」节、白话、面板用神行与寒暖卡都标「有争议」,并说明「保留在喜用,不列入忌」。没有冲突的盘不出现该标记。
552
+ - **口径**:这是「两派并存」的显式标注,不改旺衰、不改调候判断、不替用户选边;扶抑与调候仍然各自成立,只是不允许同一行同时被判喜与忌。
553
+ - **界面验证**:390px 宽度下,争议行在 366px 内折 2 行,喜忌行与寒暖卡(338/338)均无横向溢出;浅色正文对比度 4.77:1、深色 7.73:1。
554
+ - **测试**:新增 `test/yongshen-disputed.test.mjs`(23 条):两张真实争议盘(1962-03-22 偏弱燥火、2000-01-01 偏强寒湿水)的 favor/avoid/disputed/disputedTenGods、无冲突盘不误报、216 盘扫描喜忌无交集、文本 / 解读 / 白话 / 面板四处可见、白话与解读内嵌一致。统计 **103 个测试文件 / 4593 条断言**,七道闸全绿。
555
+ - **讨论群二维码**:GitHub README 的外部图片会被改写成 `camo.githubusercontent.com`,部分网络下断链;改挂 GitHub Release 附件直链(不经 camo / raw),并保留微信邀请链接兜底。Chrome 内实测 1161×1623 正常加载,README-only,不改运行时与断言数。
556
+
557
+ ## 0.50.4(已并入 0.50.5)
558
+
559
+ 把「口径对照」从命令行搬到结果下面:同一个盘只换一个开关(晚子时 / 真太阳时 / 闰月归月 / 奇门取局 / 晚子时归日),差在哪几个字,现在展开就能看见。
560
+
561
+ - **缺口在哪**:`engine/diff.js` 与 `tools/caliber-diff.mjs` 0.24 起就有,但只停在 CLI;面板与独立页切口径后只给新盘,用户不知道变的是日柱、命宫还是起运。紫微与奇门的差异还落成 `soul.ganzhi`、`siZhu.day` 这种原始路径,读不出来。
562
+ - **引擎**(`engine/index.js`):新增 `caliberCompare(args)`,按 `CALIBER_SWITCHES` 把**当前口径**与**另一档**各排一次,返回 `{currentLabel, altLabel, total, summary, roots, categories}`;对照前剔掉 `cross / verifyPast / question / direction` 等只影响解析与附加模块的参数。`renderText` 在 `result.caliber` 存在时追加【口径对照】段。
563
+ - **标签与根因**(`engine/diff.js`):补紫微(命宫 / 身宫 / 宫位 / 星曜 / 大限 / 飞星 / 格局)与奇门(四柱 / 局数 / 阴阳遁)的标签;`soul.ganzhi`、`siZhu.day`、`ju`、`dayun.jiao.at` 等进入根因表。口径回显字段(`juMethod / juMethodNote / lateZiHourMode / leapPolicy`)不再算差异——此前奇门两张完全相同的盘会被报成「2 处」,非闰月紫微也会凭空多 1 处。
564
+ - **界面**(`src/panel-kit.js` / `src/app.js` / `src/web-ui.js`):结果下新增折叠的「口径对照」卡;summary 先用一句话说「几组开关中几组影响此盘」,展开后逐行给「当前 · A → 换成 · B」、根因旧值→新值、连带分类计数。只对八字 / 紫微 / 奇门出现;对照失败时不影响主结果。卡内走共享调色板,深色只换变量;窄屏隐藏「展开」提示、summary 保持 44px 触摸目标;打印时强制展开。
565
+ - **工具与 CLI**:根 `index.js` 新增 `diff: true`(默认关,每次多排 2–3 张盘);`tools/caliber-diff.mjs` 改用同一个 `caliberCompare`,开关表只维护一份;`tools/build-client.mjs` 把 `diff` 模块打进 `client.js`。
566
+ - **口径**:只列同一组输入下的逐字段差异与根因,不判哪套口径更准,不改盘、不折吉凶;没有根因时如实写「无单一根因」(例如真太阳时只改起运时刻、不改柱)。`total` 是变化字段数,不是分数。
567
+ - **验证**:390×844 同源 iframe 实测(1996-01-19 23:40 · 安徽池州):`scrollWidth 375 < innerWidth 390`,对照卡 351px,展开后无横向溢出;强制展开深色媒体块后卡底 `#211f18`、正文与注 6.74:1、标题 6.49:1。
568
+ - **测试**:`test/caliber-diff.test.mjs` 由 19 条扩到 129 条——开关表、标签 / 根因、口径回显忽略、八字 / 紫微 / 奇门真实盘独立复算(当前→另一档方向、`total / summary / roots` 与 `diffObjects` 对拍)、无变化与无根因边界、XSS 转义、面板 / 独立页 / 工具接线。统计 **102 个测试文件 / 4570 条断言**,七道闸全绿。
569
+ - **文档**:讨论群二维码换新图(`docs/assets/dsh-metaphysics-group.jpg`,11 月 6 日前有效),README 有效期同步;旧 PNG 删除、改用新文件名,避免旧图缓存继续命中。不涉及运行时与断言数。
570
+
571
+ ## 0.50.3(已并入 0.50.5)
572
+
573
+ 给「岁运提示」补上最后一段干支关系:大运与本命四柱的伏吟 / 反吟。以前只比「大运 × 流年」和「流年 × 本命柱」,大运压到本命柱上的那一步一直空着,知识卡的 note 也明写着「未逐年标注」。
574
+
575
+ - **引擎**(`engine/bazi.js`):逐年 `suiyun.signals` 新增 `大运伏吟`(当值大运与本命某柱干支相同)与 `大运反吟`(天克地冲),对年 / 月 / 日 / 时四柱逐柱比对;target 写成「第N步大运·某柱」,detail 写明具体干支。整步大运都在,随每年重复列出,note 与解析层都写明「不当成逐年加重」。原四类信号与顺序不变,`岁运并临` 仍优先于同一组大运的 `运年反吟`。
576
+ - **接线**:摘要、解析层、面板沿用旧路径;摘要与面板 chip 对「大运」类信号也带柱位(`大运反吟(第8步大运·日柱)`),面板 chip 悬停仍给完整依据。`suiyunClassicOf` 口径不变:任一类信号出现就附《三命通会·卷二·总论岁运》原文。
577
+ - **口径**:仍只标干支重复与对冲,不折分数、不判吉凶;大运伏吟/反吟是整步十年的背景,不是逐年加码。选这一条而不是六爻应期具体日期,是因为后者在清单里明确要先建 20 条以上《卜筮正宗》应验日期对拍集,缺语料时输出日期等于拍脑袋。
578
+ - **文档与知识卡**:`bazi-suiyun` 由「四类」改「六类」,note 改为交代「连续多年出现、不逐年加重」;README「岁运提示」、清单 §3 与 0.50.3 说明块同步。
579
+ - **测试**:`test/suiyun.test.mjs` 的独立参照补上两类(六类信号逐条复算),新增 1950 盘钉住「大运伏吟整步重复 2026–2028」、同年 type+target 不重复、摘要与面板柱位、知识卡六类与 note;`test/sanming.test.mjs` 的无信号样例改用 1996-02-18(1984-10-18 在新口径下已有大运信号)。统计 **102 个测试文件 / 4460 条断言**,七道闸全绿。
580
+
581
+ ## 0.50.2(已并入 0.50.5)
582
+
583
+ 给 0.49.0 的「人元司权」补上原文出处:录入《三命通会》卷二·论人元司事(典藏网 7529),并如实并列该本与本插件不同的日数分法。
584
+
585
+ - **缺口在哪**:0.49.0 起每张八字盘都会算「生在本月第几日、哪一干当权」,知识卡却只写「之说见《渊海子平》」,没有卷次、没有链接,解释层也没有一句原文——这是全插件少数「有算法、无出处」的地方。
586
+ - **原文**(`engine/classics.js`):新增 `smt-renyuan`,照录「故支吕所藏者主命,谓之人元……寅中有艮土用事五日,丙火长生五日,甲木二十日;二月建卯,卯中有甲木用事七日,乙木二十三日」,81 字逐字核验通过;来源本写作「支吕」,按「异文不改字」原样保留,不替它改字或圆场。
587
+ - **口径分歧**:该本寅月作 5/5/20、卯月作 7/23,本插件通行 30 日表作 7/7/16、10/20;`plain` 与解析层都写明「不是同一套分法、不改取格」,两表并列。新增 scene「人元」,与「岁运」一样不进五条取条表:`compute` 在有 `renyuan` 时挂 `r.renyuanClassic`,摘要人元行加「原文见《三命通会·卷二·论人元司事》」、解析层人元节附原文与白话、面板经通用 section 渲染自动出现;`RENYUAN_TABLE`、旺衰与取格一行未改。
588
+ - **知识卡**:`bazi-yueling-siquan` 的 detail/source/note 补上 7529 与 5/5/20,状态仍为 `variant`。
589
+ - **文档**:README「古籍原文」「人元司权」「致谢」三处、清单 §二.1 / §三表 / §四.1 与 0.50.2 说明块同步。
590
+ - **测试**:`test/classic-quotes.test.mjs` +4(scene 枚举加「人元」、原文/出处/plain、不进五条),`test/sanming.test.mjs` 由 17 条改为 18 条并 +11(结果层/摘要/解析层/面板/知识卡),`test/renyuan.test.mjs` +11(用 `RENYUAN_TABLE` 独立对照原文日数、结果层接线、5/5/20 可见)。统计 **102 个测试文件 / 4432 条断言**,七道闸全绿。
591
+
592
+ ## 0.50.1(已发布 2026-10-30)
593
+
594
+ 宿主侧栏面板的首屏与独立页并轨:三组卡片、最近用过、分组↔平铺、窄屏收纳,全部从同一份数据生成,不再「页面一套、侧栏一套」。
595
+
596
+ - **缺口在哪**:0.39.0 给独立页做了分组首屏(问一件事 / 看一个人 / 查日子、最近用过、分组↔平铺),面板一直是 19 个 tab 平铺加自己那套 `.mp-tabs`——既没有最近用过,也没有「每组先露 4 项」的收纳;窄侧栏里 tab 条先吃掉大半屏,卡片与表单被推到下面。
597
+ - **唯一数据源**(新增 `src/groups.mjs`):三组标题、白话提示与 19 个入口(含「人生K」铺满整行)只写一份。`tools/build-html.mjs` 用它在构建时生成页面分组 HTML;`tools/build-client.mjs` 用 `JSON.stringify` 注入 `window.__MPGroups` 给面板。页面产物与面板不再各抄一份,`test/panel-first-screen.test.mjs` 逐项对拍页面生成的入口与数据源。
598
+ - **面板首屏**(`src/app.js`):React 版分组卡片(`.mp-tgroup` / `.mp-tool`)、最近用过(`mp.recent.tabs`,最多 3 条,先过 TABS 白名单)、分组↔平铺开关(`mp.first.view`,默认分组)、窄屏折叠(「还有 N 个」/「收起」,带 `aria-expanded`)。两套入口共用 `activate` → `recordRecent` + `switchTo`,排盘参数与结果路径不变。
599
+ - **平铺 tab 重构**:19 个 tab 从「分段控件」改为圆角胶囊网格(与独立页同形),窄屏单行横滑、44px 触摸目标;分组视图下 tab 条整体隐藏(`.mp-tabs.hide`)。
600
+ - **收纳用容器查询**:侧栏宽度不等于窗口宽度,`@container (max-width:560px)` 让 420px 侧栏与 390px 手机都按「每组 4 项 + 还有 N 个」收,不再用窗口媒体查询猜。
601
+ - **口径**:分组只是另一套入口——19 个 tab 原样保留,不改变任何默认值、排盘参数与结果;存储不可用(隐私模式)只少记「最近用过」,面板照常可用。
602
+ - **测试**:新增 `test/panel-first-screen.test.mjs` 40 条——分组数据、唯一数据源、页面产物对拍、面板接线、折叠与降级。统计 **102 个测试文件 / 4406 条断言**,七道闸全绿。
603
+
604
+ ## 0.50.0(已并入 0.50.1)
605
+
606
+ 知识卡 `liuyao-yingqi` 一直写着「应期只作时间窗口的提示」,引擎却一行都没给:用神旺衰算了、伏神出伏算了,轮到「什么时候见分晓」只剩「未做」。这一版把诚实的那一半补上——列出该留意的地支与快慢方向,仍不给具体日期。
607
+
608
+ - **引擎**(`engine/liuyao.js`):新增 `yingqiWindow(result, useGod, { monthBranch })`。用神在卦上取用神、不上卦取伏神,每支列出逢值(本支)、逢冲(对支)、逢合(六合支)三支;用神旬空时本支追加「出空填实」、对支追加「冲空」。快慢按月建五态:旺 / 相 → 偏速,休 / 囚 / 死 → 偏缓,月破或旬空 → 待解,缺月建 → 未定;用神两现时逐支归并去重,快慢不一致记未定。结果挂在 `r.yingqi`。
609
+ - **四处可见**:摘要加「应期线索:偏缓 · 逢值/逢冲辰 · …(只列地支,不出日期)」;解析层新增「应期线索」一节,逐条写月态与触发支;白话加一句「应期上大体偏远……不换算成具体哪天」;面板在伏神与进退之间加一排 chip(偏速绿、待解琥珀)。
610
+ - **口径**:只做「该留意哪一支」与快慢方向——不换算日期、不排先后、不判忌神受制、不叠动变连环;近事以日计、远事以月计,用哪把尺由事情远近决定,不代选。知识卡 `liuyao-yingqi` 仍为 `variant`,`liuyao-yingqi-exact` 仍为 `todo`(具体日期未做)。
611
+ - **口径变更连带**:解析层「未纳入」原写「应期仍未做」,现改为「应期的具体日期未做」;`test/liuyao-chufu.test.mjs` 第 212 行同步改断言(从锁旧句改为锁新句),不涉及伏神判定本身。
612
+ - **文档**:README「六爻」「精度与口径」两条、清单 §3.1 / §4.3 与 0.50.0 说明块同步;package description 补「应期线索」。
613
+ - **测试**:新增 `test/liuyao-yingqi.test.mjs` 73 条——12 支冲合独立复算、64 卦 × 13 组月建(12 支 + 缺月建)× 4 方向 3328 盘逐条复算(月态 / 月破 / 旬空 / 快慢 / 归并去重)、旬空 / 月破 / 用神两现 / 伏神 / 缺月建 / 两现快慢不一六条边界、四处可见与不出现日期、旧结果兼容、确定性。统计 **101 个测试文件 / 4366 条断言**,七道闸全绿。
614
+
615
+ ## 0.49.3(已并入 0.50.1)
616
+
617
+ 离线页(`命理排盘.html`)的「农历」tab 一直是坏的:转换方向那条分段控件从来没显示出来,农历日期怎么填都被判格式错;同一次真机检查还量出深色主题下「选中态实心底上的白字」只有约 3:1。这一版把断链接通,把强调面文字换成变量(两套配色各自过 WCAG),并顺手收掉窄屏闰月勾选框被拉高的毛病。
618
+
619
+ - **断链**(`src/web-ui.js`):① `setTab` 的速查子表单显隐漏了 `#qk-convert`,只有「公历 → 农历」的默认分支能跑,切到「农历 → 公历」的入口根本看不到;② 农历日期正则写成 `/^(d{4})-(d{1,2})-(d{1,2})$/`(少反斜杠),`d` 被当字面量,任何输入都匹配失败;③ 日期标签用硬编码名单判「起卦」,convert 漏在名单外被标成「起卦日期(公历)」。现改为与面板同一套正则,标签跟随 `TIME_KIND` 的 date 类写成「日期(公历)」。
620
+ - **深色强调面**(`tools/build-html.mjs`):深色块里的 `.tab.on,.seg button.on,.go{color:#14130f}` 写在基础规则之前,同优先级被后面的 `color:#fff` 盖掉——深色下实际是白字压浅珊瑚底,约 3:1。改为 `--accent-bg / --accent-bg2 / --on-accent / --on-accent-soft` 四个变量,7 处实心强调面(印章、选中 tab、分组卡片、评分格、主按钮、分段按钮、追问/chip)统一走变量。浅色仍是白字压 `#a72c23 → #7d1f18`(6.9 / 9.8:1),深色改为深字压 `#f0a38e → #e2755f`(9.1 / 6.1:1),渐变两端都 ≥4.5:1;页面样式里不再出现 `color:#fff`。
621
+ - **口径**:这是一次设计口径变更,先把 `test/theme.test.mjs` 第三节改成锁变量与逐端对比度(含副文字按 alpha 叠色后复算),再改实现;`test/first-screen.test.mjs` 里锁旧元素规则的一条同步换成 `--on-accent` 规则。
622
+ - **窄屏(≤640px)**:`#qk-convert` 独占整行,方向分段按钮不再折行;闰月改用 `.field.check`,勾选框保持 18px,触摸区由外层 label 撑到 44px(此前继承输入框的 `min-height:44px`,变成 18×44 长条)。
623
+ - **验证**:真 390×844(CDP 设备模拟)浅/深各跑一遍——无横向溢出(scrollW=390)、`农历2026年九月十七 ⇄ 2026-10-26` 正常出结果、日期标签为「日期(公历)」、勾选框 18×18、tab 与主按钮触摸目标 44/48px。
624
+ - **测试**:新增 `test/convert-ui.test.mjs` 31 条(两个入口同一套正则、2026-9-17 与闰六月前后边界、每个 `#qk-*` 都有显隐接线、闰月与 datetime 透传、格式错误文案走 textContent);`test/theme.test.mjs` 现为 65 条。统计 **100 个测试文件 / 4293 条断言**,七道闸全绿。
625
+
626
+ ## 0.49.2(已并入 0.50.1)
627
+
628
+ 黄历卡片里的二十八宿,把「壁水貐」写成了「壁水獝」、「胃土雉」写成了「胃土彘」——两个字都只是动物名,不影响排盘、宜忌与宿值日,但它是用户每天在摘要和面板上能看到的原文。这一版按通行二十八宿名逐字改正,并把整张表在测试里独立重录一遍,逐字对拍。
629
+
630
+ - **数据**(`engine/almanac.js`):`MANSIONS` 的壁宿动物 `獝` → `貐`、胃宿动物 `彘` → `雉`;宿名仍按「宿·五行·动物」写法,其余 26 宿未动。四宫、吉凶、五行、值日轮转规则一行未改。
631
+ - **口径**:值日宿仍按「日支 + 星期」定,28 日一循环;壁宿落周三(水)、胃宿落周六(土),与七曜一致。本次只改动物名,不改任何日期落到哪一宿。
632
+ - **文案**:`engine/almanac.js` 顶部「诚实边界」注释同步——二十八宿、胎神、值日神、吉神方位已收录,未收录的只剩逐日全量吉凶神煞与彭祖百忌(旧注释把已收录项也写成了「未收录」,与返回值的 `scope` 打架)。
633
+ - **测试**:新增 `test/almanac-xiu.test.mjs` 60 条——通行表在测试里独立录 28 行逐字对拍(含壁水貐、胃土雉)、四宫各七、动物不重、12 支 × 7 日的七曜顺序、13 段 56 天的 28 日循环与 28 日不重不漏、2026 全年不再出现「獝」「彘」、壁/胃的星期锚点、结果层/文本摘要/面板三处可见、同日两次逐字段一致、400 天宿五行与星期七曜一致。统计 **99 个测试文件 / 4262 条断言**,七道闸全绿。
634
+
635
+ ## 0.49.1(已并入 0.50.1)
636
+
637
+ 「岁运提示」是引擎里唯一一节没有原文支撑的能力:逐年标出岁运并临 / 运年反吟 / 流年伏吟反吟,读法却是自己写的;知识卡 `bazi-suiyun` 的出处只写「见《三命通会》《渊海子平》」,没有卷次也没有链接。这一版补上《三命通会》卷二「总论岁运」原文,并顺手记下一处口径分歧。
638
+
639
+ - **原文**(`engine/classics.js`):新增 `smt-suiyun`(卷二·总论岁运,典藏网 7539),照录「行运以生月为运元,最怕行运与太岁冲克,若岁运冲月必祸;若岁运与日相对,谓之返吟,岁运压日,谓之伏吟,二者不利六亲,非横破财,不为吉兆。」——用 `verify-quotes.pl` 对章页逐字核验通过(67 字,连续子串),白话自撰。
640
+ - **口径分歧写进 plain**:原文的「返吟」指岁运与日柱相对、「伏吟」指岁运压日;本插件按通行用法取「干支相同为伏吟、天克地冲为反吟」,两者并列、不合并。末句「不利六亲、破财」是旧说的重话,只作变动提示。新增 `scene: '岁运'`,不挂格局 tag。
641
+ - **不进五条上限**(`suiyunClassicOf`):`classicsFor` 仍是「格局两条 + 气候两条 + 总纲一条」;岁运原文只在 `liunian` 真有信号时随该节出现——原文讲的正是冲克,没冲没克时挂出来只会误导。结果挂 `r.suiyunClassic`。
642
+ - **三处可见**:摘要「岁运提示」行末加「古籍见《三命通会·卷二·总论岁运》」;解析层「岁运提示」节补原文与白话;面板岁运 chip 下加一行原文(悬停看白话,样式只走 `--muted`),无信号时三处都不出现。
643
+ - **知识卡**(`engine/interpret-knowledge.js`):`bazi-suiyun` 的 source 换成带链接的《三命通会》卷二·总论岁运,detail 写明返吟/伏吟的定义分歧;状态仍 `variant`。
644
+ - **口径**:只补出处与定义对照,四类信号的判定、分档与「不判吉凶」的边界一行不动。
645
+ - **文档**:README「古籍原文」「岁运提示」与致谢、清单 §二·7 与文末注同步;三命通会条目 16 → 17。
646
+ - **测试**:`test/sanming.test.mjs` +14 条(原文抽检、章名/链接、scene 与 tag、不进五条表、有/无信号两向的结果层/摘要/解析层/面板表现、知识卡出处),条目计数 16 → 17;`test/classic-quotes.test.mjs` +4 条(原文、出处、plain 口径)并把 scene 枚举加入「岁运」。统计 **98 个测试文件 / 4202 条断言**,七道闸全绿。
647
+
648
+ ## 0.49.0(已并入 0.50.1)
649
+
650
+ 「月令是什么」此前只答到月支本气:知识卡 `bazi-yueling-siquan` 写着「月内分日轮值」,引擎却一个字段都没给,面板与摘要里也看不到「生在本月第几日、哪一干当权」。这一版把《渊海子平》的人元司权分日落进引擎与解释层,补上清单 §3.3 里挂得最久的争议项。
651
+
652
+ - **引擎**(`engine/bazi.js`):新增 `RENYUAN_TABLE` 与 `renyuanOf(monthBranch, birthJdn, termJd)`——固定通行 30 日表(余气 → 中气 → 本气,合计 30 日,如寅月戊7丙7甲16),从「节」的当日算第 1 日,日差取本盘所用时刻(含真太阳时)所在日;第 31 日以后不硬分摊,按本气算并标 `beyond`。返回当权干与五行、所在日段、下一段距今天数、是否在本柱藏干表内。结果挂在 `bazi.renyuan`,并带 `term`(起算的节与时刻)。
653
+ - **摘要**(`engine/index.js`):节气行后加一行「人元:X月第N日,干+五行司权(各段日数)」,超出 30 日表时注明。
654
+ - **解析层**(`engine/interpret.js`):新增「人元司权」一节,说明从哪个节起算、这一日谁当权、下一段几日起交;同时写明分日只作解释层细节,**不改取格**;司权表比本柱藏干表宽的地方(子月壬、卯月甲、午月丙、酉月庚、亥月戊只出现在司权表)两表各照原样。
655
+ - **知识卡**(`engine/interpret-knowledge.js`):`bazi-yueling-siquan` 的 detail 与 note 补齐实现口径,状态仍为 `variant`——7/7/16、9/3/18 等分法未并列实现,轮值不参与旺衰与取格。
656
+ - **口径**:只认「节」不认「气」;节当日为第 1 日;30 日表固定,不按流派切换;第 31 日起按本气;司权与取格、旺衰解耦,删掉该字段后 `primary` / `favor` 逐字不变。
657
+ - **文档**:README「人元司权」一条;清单 §3.3 与 §4.1 同步,并补实现说明块。
658
+ - **测试**:新增 `test/renyuan.test.mjs` 361 条——逐支核表(合计 30、连续、五行、末段为本气、2–3 段)、纯边界(首日/末日/下一段/第 31 日/第 0 日夹取)、12 张真实盘独立复算日差、已知盘 1990-05-12(巳月第 7 日庚)与 1990-11-08(亥月第 1 日戊,不在藏干表)、2023-06-05(第 31 日按本气)、立春前后 30 分钟切换、删字段不改格、确定性、摘要/解析层/知识卡口径,并禁绝「一定/必然/注定/百分百」。统计 **98 个测试文件 / 4185 条断言**,七道闸全绿。
659
+
660
+ ## 0.48.0(已并入 0.50.1)
661
+
662
+ 在 390×844 的真视口(无头 Edge + DevTools 协议,浅色与系统深色各跑一遍)里把「交叉验证」和三张表量了一遍:大运表六列排到 748px,屏幕只露出左半边,右边界既没有渐隐也没有「还能滑」的提示;交叉验证是五段「八字——…;紫微——…;判断:…」的长句连读;表头 11px 的 `--label` 对 `--band` 只有 3.51:1;目录链接 22px、证据摘要 33px、名词解释 22px,都够不着 44px 的触摸目标。这一版按测量结果改样式与结构,`test/theme.test.mjs` 锁的深色/打印/窄屏规则一条没动,七道闸全绿。
663
+
664
+ - **交叉验证改对照卡**(`engine/crosscheck.js`、`src/panel-kit.js`):新增 `crossSection(cross)`,把文本和 `items` 一起交给面板——同一份数据两个去处,面板不用再拆文本。每个方面一张卡:标题行带「同向 / 有张力 / 互补」语气标签(绿 / 琥珀 / 蓝),八字、紫微各占一栏,注释放最后一行;≤640px 改单列,标签跟正文走。Markdown 与工具输出仍是原来的五行文本,口径不变。
665
+ - **三张表不再横着截断**:渲染时给每个 `td` 打 `data-label`、表头加 `scope="col"`;≤640px 隐藏表头,一行一张卡、每格用列名当行标,首列抬成卡头。390px 下大运表从 748px 横滑变成 342px 宽的可读卡片,触发事件表同理(418px → 342px);宽屏与打印仍是原表格。
666
+ - **对比度**:表头从 `--label` 改 `--ink2`(浅色 3.51 → 10.53:1,深色 9.98:1);卡内标签与备注用 `--muted`(5.29 / 6.74:1)。三档标签、目录链接、正文在两套变量下逐对算 WCAG 亮度比,全部 ≥4.5:1。
667
+ - **触摸目标**:窄屏目录改单行横滑胶囊(隐藏滚动条、首尾留 11px),链接与证据摘要、名词解释摘要统一 `min-height:44px`;390px 实测全部 44px,折叠标题 ≥46px。正文宽度不变,页面横向溢出为 0。
668
+ - **入口统一**:独立页与面板都改用 `Engine.crossSection`,不再各自拼 `crossText`。
669
+ - **侧栏也生效**:dsh 侧栏是「窗口宽、报告窄」,`@media` 不触发;`.mp-it` 声明为查询容器,同一批窄屏规则另挂一份 `@container (max-width:640px)`。实测把报告放进 420px 容器(窗口 1280px):表格 1092px → 396px 且不再横滑、目录链接 44px、对照卡单列,与 390px 视口下的结果一致。
670
+ - **测试**:新增 `test/narrow-report.test.mjs` 52 条——结构(五张卡、十个分栏、`data-label` 数量、转义)、窄屏样式规则(含容器查询版)、触摸目标、两套调色板逐对对比度,并反向锁住「表头若改回 label 会掉到 3.51:1」。统计 **97 个测试文件 / 3824 条断言**,七道闸全绿。
671
+
672
+ ## 0.47.1(已并入 0.50.1)
673
+
674
+ 交叉验证是 README 里挂了很久的能力,但测试只在外围点了六下(条目数、三档词、文本出现),五项判定的阈值、性别分支与节奏真值表一条没锁;顺手查出两处「说得比数据多」的文案。
675
+
676
+ - **测试补真**(新增 `test/crosscheck.test.mjs`,71 条):把交叉验证当纯函数测——事业「官杀 + 食伤 ≥ 2」、财富「财 ≥ 2」、感情按性别取「妻星(财)/ 夫星(官杀)」的 1.9 / 2.0 边界;节奏用 5 档 × 煞星轻重共 10 组真值表逐格核判断与说明;再用 10 张真实盘 × 男女共 20 组,从原始 `godStats` / 宫位星曜 / 大运档位独立复算五项判断与文案;另锁条目恰好五项、次序固定、只带六个字段(没有合并分数)、输入不被改写、两次调用同结果、八字入口与紫微入口的对照逐字节一致、`crossText` 五行结构。用「事业阈值 2 改成 3」做过变异检查:2 条立即变红,恢复后 71 条全绿。
677
+ - **文案与实现对齐**(`engine/crosscheck.js`):① 节奏一项原先只有一句「一边顺、一边压」,但八字大运为「平」时也会套用——1980-03-05、2005-01-13 等盘就是「平 + 紫微煞星 2 颗」。现在按实情分三句:八字顺而紫微煞星多、八字偏紧而紫微平静、八字为平而紫微煞星多,各写各的处理方式。② 大限没取到时,紫微侧原来写成「大限未取到;无煞星」,把缺数据说成了没有问题;现在只写「大限未取到」。③ 任一侧当前阶段缺失(八字未起运、紫微大限不在范围)时,判断由「同向 / 有张力」改为「互补」,说明里点名缺的是哪边,并写明「不下两边对照的结论」——不再拿「没取到」冒充「没问题」。
678
+ - **口径**:五项仍只并列、不合并成总分;三档仍是同向 / 有张力 / 互补,「互补」现在也明确承担「只有一边有信号」这一情形。健康项固定「互补」不变。
679
+ - **文档**:README「精度与口径」补一条,写明缺一侧时的标法与节奏说明的分档。
680
+ - **测试**:96 个测试文件 / 3772 条断言,七道闸全绿。
681
+
682
+ ## 0.47.0(已并入 0.50.1)
683
+
684
+ 四墓月(辰戌丑未)此前只取月令本气,藏干透了也用不上、三合会成了局也看不见;同一段代码还把戊辰、戊戌、己丑、己未当成建禄,把透干/会支取到的劫财写成「劫财格」。这一版把《子平真诠》十六「论杂气如何取用」落进引擎与原文库。
685
+
686
+ - **取格三级**(`engine/geju.js`):杂气月按「透干 → 三合会支 → 本气」取格。藏干透到年/月/时干仍优先;没有透干时,若其余三支与月支凑齐同一三合局,取局中五行对应的那一藏干(甲生辰月、年支申日支子 → 取水印);三合不齐才回本气。依据里写明走的是哪一条(透于某干 / 某某会成某局 / 以月令本气取格),会支只认三合、不认三会方。
687
+ - **两处误标**:`base.god === '比肩'` 原先一律给建禄格,戊辰、戊戌、己丑、己未这类「本气比肩但不在禄位」的杂气月因此冒称建禄——现加禄位校验,改判比肩格并在依据里点明「禄在巳、不在辰」;杂气月由透干或会支取到劫财时,按原文「透乙则用月劫」改判月劫格,不再落到「劫财格」。
688
+ - **原文与知识卡**(`engine/classics.js`、`engine/interpret-knowledge.js`):新增 `zp-zaji`(十六、论杂气如何取用,典藏网 53636),原文照录「何谓透干……透而又会,则透与会并用」、白话自撰。用神总纲位由三选一改为四选一:化气 > 四墓杂气 > 组合 > 通用总纲,杂气与组合同现时取杂气;位次不增,整节仍以 5 条为限。知识卡 `bazi-zaji-quyong` 补一条,标「各家有异说」。
689
+ - **口径**:原文「兼透则兼用」只给原则,落到单一格名必须择一,本插件取最先透出的那一干;会支只认三合、不认三会方;不判原文所说的「有情 / 无情」。这几点写进 README 与清单,不替分歧圆场。
690
+ - **测试**:新增 `test/zaji.test.mjs` 52 条,用 9 张真实盘正反两向钉住——透干压会支(1996-01-19)、会支取用(1985-02-03 / 2005-01-13 / 2002-10-13)、三合不齐回本气(1992-04-05)、非杂气月不启用会支(1979-11-13 / 1985-09-15)、建禄不误标(1989-03-05 / 1983-08-20 / 1990-04-13)、月劫三路(1985-04-05 / 1996-08-05 / 1990-10-28),并核总纲位次序、上限、确定性、摘要/解释层/面板与知识卡。`test/classic-quotes.test.mjs` +5 条,把总纲位改判为四选一并加原文抽检。统计 **95 个测试文件 / 3701 条断言**,七道闸全绿。
691
+
692
+ ## 0.46.5(已发布 2026-10-30)
693
+
694
+ 「问进对话」只把盘面摘要和问题送进对话,模型得自己再推一遍结论——同一张盘,面板里读到的「说人话」和对话开场可能不是一套口径。这一版把面板已算好的白话结论一并交给模型。
695
+
696
+ - **缺口在哪**(`engine/followup.js`):`askPrompt` 只读 `r.summary`,而 `interpret(r, ask)` 产出的 `answer`(直答)与 `plain`(说人话)只存在于面板结果对象 `it` 里。用户点「问进对话」后,模型看到的是原始盘面,开场结论全靠现场发挥;问法或流派稍有出入,就会与面板上的结论打架。
697
+ - **改动**:`askPrompt(r, { interpret })` 新增可选解析对象;有 `interpret` 时,在「所问」与「盘面摘要」之间插入「开场结论」小节,原样带上 `answer`(直答)与 `plain`(说人话),并把回答要求第 1 条改成「先沿用上面的开场结论,再用一句不用术语的话说清主线」。调用方没传时回退读 `r.interpret`(`compute({ withInterpret: true })` 的结果);两者都没有就完全不加这一节,固定骨架保持原样。
698
+ - **接线**(`src/app.js`):面板两处调用都带 `interpret: result.it`;`LAST` 增加 `it` 字段,输入框右侧的「命理·问」也能拿到同一份白话底稿,而不是只带摘要。
699
+ - **账面**:1996 盘(所问「今年考运」)提问文本 2353 → 2669 字,底稿只多 316 字(直答 106 + 说人话 144 + 小节标题),没有把提问撑成小作文;未传解析时逐字不变。
700
+ - **口径**:底稿只做「同一口径」的搬运,不改写、不摘要;模型仍被要求压成一句无术语的话,避免直接复读盘面术语。
701
+ - **测试**:`test/ask-prompt.test.mjs` +13 条——底稿小节存在且排在摘要之前、直答/说人话原样带入、回答要求指向底稿、未传解析时不加小节、`r.interpret` 自动回退、空解析对象不加空小节、无问题时底稿不说「先答所问」、带底稿仍逐字确定;`test/client-bundle.test.mjs` +2 条锁住面板两处调用都带 `interpret`、桥的 `LAST` 保留解析对象。统计 **94 个测试文件 / 3643 条断言**,七道闸全绿。
702
+
703
+ ## 0.46.4(已并入 0.46.5)
704
+
705
+ 0.46.3 有三处「写进了文案、没落进代码」:文末分歧清单只列前 4 条、面板仍显示「问题:(未填写)/先答所问」、归属稳定性测试并不存在。这一版把三处补齐,并把它们钉进断言。
706
+
707
+ - **分歧清单不再截断**(`engine/interpret.js`):`caveats.slice(0, 4)` 让 1996 盘的 13 条分歧只显示 4 条,另有 9 条不在任何段落、其中 7 条原注整份报告都读不到——与 0.46.3 写的「信息不丢」相反。现在按状态拆开:「待核实」仍归「尚未实现(不猜)」并附原注;其余分歧逐条列出(已展开的只留条目名,未展开的附原注),同一句原注不会出现两遍。
708
+ - **没问事就别喊「答所问」**(`src/panel-kit.js`、`engine/index.js`):奇门只选方向时,面板回显原来是「问题:(未填写)|询问方向:财运」,直答标题也固定写「先答所问」。现在没填问题只回显方向,标题改为「先看结论」;填了问题仍用「先答所问」。奇门的直答也从泛泛的「五个维度」改为「排盘事实、用神、宫位条件几节」,并点明所选方向。
709
+ - **测试补真**(`test/interpret-dedupe.test.mjs`,28 条):归属稳定性按 7 个方向 × 有事/无事 逐一对拍「卡片→维度」签名;分歧清单断言行数等于条目数、未展开条目的原注必须在、已展开的不重复贴;`knowledgeCount` 同时与「唯一卡片数」「逐维挂载总数」独立核对;面板侧用源码锁住旧「(未填写)」串已删除。0.46.3 里那句没有测试支撑的说法,至此才有对应断言。
710
+ - **口径**:信息完整优先于尾部紧凑——文末清单从 4 行回到 13 行,1996 盘解析文本 9099 → 9965 字(无问题)/ 10051 字(有问题),`knowledgeCount` 仍为 10,正文五维没有新增复读。
711
+ - **测试**:新增 94 个文件 / 3628 条断言,七道闸全绿。
712
+
713
+ ## 0.46.3(已并入 0.46.5)
714
+
715
+ 同一段「规则注解」在报告里复读了两三遍:1996 示例盘的 29 条注解里,只有 16 张是不同的卡。这次把注解改成「一张卡全报告只挂一次、每维最多 3 条」,没填问题时也不再假称「你问的这件事」。
716
+
717
+ - **缺口在哪**(`engine/interpret.js` 的 `enrichPlain`):知识卡按维度静态挂载,而 `knowledgeFor(system, dimKey)` 对「整体运势 / 事业发展 / 健康」会返回同一批通用条目,于是「月令不是一个月」「大运管十年基调」「同一个格,子平真诠怎么用、三命通会怎么取」这类解释在正文里出现 2–3 次,把五段判断冲散。实测 1996 盘:整体 14 条、事业 10 条(9 条重复)、感情 3 条(2 条重复)、健康 2 条(两条全重复)——29 条里 16 张不同,段落被复读切成碎片。
718
+ - **改动**:先按固定维度次序(整体 → 工作 → 事业 → 感情 → 健康)分派,已出现过的 id 跳过,每维再截到 3 条。次序用固定表而不是显示顺序,是因为「所问之事」会把某一维提前——按显示顺序先到先得的话,同一张盘换个问法,注解归属就整体搬家(归属稳定性测试在 0.46.4 补上)。文末「这套规则有多稳」对已展开的条目只留一句索引,不再贴一遍全文;被截掉的分歧条目也应进文末清单(0.46.4 修正:此处当时实际只列了前 4 条,另有 9 条及其 7 条原注被漏掉)。
719
+ - **顺手**(`engine/interpret-plain.js`、`engine/interpret.js`):没填问题时抬头不再写「问题:(未填写)」,正文也不再假称「具体到你问的这件事」——改成「没指定问题,就按……的顺序往下看」。这是「读者视角」的最后一点漏:没问问题却硬答「你问的这件事」,最容易被当成模板腔(面板侧的回显与「先答所问」标题在 0.46.4 一并修正)。
720
+ - **账面**:1996 盘解析文本 11862 → 9099 字(−23%),`knowledgeCount` 29 → 10,五维正文之间不再有整块复读。
721
+ - **测试**:`test/interpret-knowledge.test.mjs` +5 条——同卡不重复、每维 ≤3、`knowledgeCount` 与实际挂载一致、无问题时抬头不写「未填写」、正文不假称「你问的这件事」。统计 **93 个测试文件 / 3600 条断言**,七道闸全绿。
722
+
723
+ ## 0.46.2(已并入 0.46.5)
724
+
725
+ 离线页的「验前事 / 生时校正」原来是原生控件:年份框 21px、按钮 31px 灰底;窄屏下三档判断按钮 22px,追问框 37px、导出按钮 39px,「点任一宫位看详情」只有 2.25:1。
726
+
727
+ - **缺口在哪**:这两块由 `web-ui.js` 输出 `.mp-btn` / `.mp-input`,但基础样式只写在 DSH 宿主的 `src/app.js` 里(且用的是 `--dsw-*` 变量),离线页从没定义过——于是年份与类型退回 21px 原生输入框,「算贴合度 / 计算候选时辰」退回 31px 灰按钮,和整页的米色卡片明显不是一套。
728
+ - **实测口径**:用无头 Chrome 通过 CDP 在 390px 视口、浅色/深色两套配色下逐个点开 19 个 tab,量 `#out` 内溢出、可点区域尺寸与文字对比度。修复前:验前事三档按钮 32×22、年份框 21px、按钮 31px;全页每个 tab 的追问框 37px、导出按钮 39px;紫微提示条 2.25:1。
729
+ - **改动**(只碰页面层与结果区模板):`tools/build-html.mjs` 给页面补一套同变量的 `.mp-verify/.mp-rect` 按钮与输入框样式(含聚焦环),窄屏把三档按钮排成等分三列、标签独占一行,`.mp-chip` / 验前事按钮 / 年份与类型框 / 追问框 / 导出按钮统一抬到 44px,追问输入改 16px 避免 iOS 聚焦缩放;`src/panel-kit.js` 的 `.pp-soon` 由 `--faint` 改 `--muted`(浅色 4.77:1、深色 7.73:1);`src/web-ui.js` 删掉两处把按钮压到 12px/31px 的行内样式。
730
+ - **口径不变**:颜色全走既有页面变量,深色仍是只换变量;`test/theme.test.mjs` 锁定的打印、深色、窄屏 tab 规则一条未动(50 条断言原样通过)。
731
+ - **测试**:新增 `test/ui-controls.test.mjs`(15 条)——页面控件样式、无硬编码色、窄屏 44px、提示条对比度(从变量声明取色独立复算)。修复后复测:19 个 tab × 浅/深 0 处横向溢出、0 个 <44px 控件、0 处对比度 <3:1。统计 **93 个测试文件 / 3595 条断言**(+15),七道闸全绿。
732
+
733
+ ## 0.46.1(已并入 0.46.5)
734
+
735
+ 偏财格不再引《论正财》,七杀格补上三命对照:九个走月令的格,这才真正做到「子平在前、三命在后」各一条。
736
+
737
+ - **缺口在哪**:三命通会此本正财、偏财分章,引擎却让两格共用 tag「财」——1996 示例盘就是偏财格,古籍节里挂的却是《三命通会·卷六·论正财》。七杀格更只有子平《论偏官》一条,没有三命对照,而 README 已写「同一个格,子平真诠在前讲怎么用,三命通会紧随作对照」。
738
+ - **两条原文**(`engine/classics.js`):`smt-piancai`(卷六·论偏财 7650,「乃众人之财也……切忌有姊妹兄弟分夺」)与 `smt-guansha-liu`(卷五·官煞去留杂论 7599,「天干透者易去,月支所藏者难去」)。均按典藏网章页逐字核验(2/2 通过),照录不加省略号,plain 为白话自撰。
739
+ - **七杀为何取「官煞去留杂论」**:该本三命通会没有单列「论偏官」章,硬凑一篇改名就是造出处;取同卷讲官煞混杂去留的这一篇作对照,章名照录,plain 写明「七杀格遇正官混杂,就按这一篇看取舍」。
740
+ - **接线**:`GEJU_KEY` 把正财格、偏财格拆成两个 tag,子平《论财》同时标「正财」「偏财」,于是两格都是子平在前、三命本格章在后;七杀格 / 偏官格指向官煞篇。5 条上限、专旺从格先占位、总纲位三选一均未动,其余盘选条逐字节不变。
741
+ - **文档与知识卡**:`bazi-sanming-duizhao` 补写「此本正财偏财分章、七杀无专章」;清单四·1 与 README 致谢的「十四篇」改对为十六篇;README 里写死的「90 个测试文件 / 3423 条断言」改为「取自断言基线」,避免每轮过期。
742
+ - **测试**:`test/sanming.test.mjs` 的条目分组由「章名是否以论开头」改为显式 id 清单(官煞篇不是「论」字题),新增偏财 / 七杀配对与正反两向(偏财不引正财章、正财不误取偏财章);`test/classic-quotes.test.mjs` 用 1996 偏财盘钉住对照条;`test/tongguan.test.mjs` 的 1996 选条期望同步为 `smt-piancai`。统计 **92 个测试文件 / 3580 条断言**(+13),七道闸全绿。
743
+
744
+ ## 0.46.0(已并入 0.46.5)
745
+
746
+ 紫微补齐九类流派开关:此前只做了闰月三档,换派只能拿到默认盘;现在每一项都能单独切换,且不传时盘面与旧版完全一致。
747
+
748
+ - **缺口在哪**:0.42.0 把参考项目的「其余九类流派开关」明确留作后续,引擎里亮度、庚干四化、天马、天空、截空旬空、魁钺、天伤天使、长生起点、晚子时都只有一种写法;工具 schema 也没有对应参数,模型侧无法要求「按全书派排」。
749
+ - **改动**(`engine/ziwei.js`):新增 `ZIWEI_SCHOOL_DEFAULTS` / `ZIWEI_SCHOOL_OPTIONS` / `ziweiSchoolsOf`,九个开关逐个落到安星与起盘——`brightnessSchool` 四套亮度数值表按星逐年转中文(QS/XD1 七档、ZZ/XD2 五档);`gengYearSihua` 五个庚干四化变体;`tianmaSchool` 年支/生月三合;`tiankongSchool` 不排/年支顺行/加生时;`jiekongSchool` 不排/单星/正副/占验,启用时同时排旬空副旬;`kuiyueSchool` 四派魁钺(生年与流年同表);`tianshiTianshang` 中州派阴男阳女互换;`changshengSchool` 火土派把土五局长生起点从申改寅;`lateZishi` next-day 时 23:00 后起盘日顺延。
750
+ - **接线**:`engine/index.js` 透传九个平铺参数与嵌套 `schools`(八字 × 紫微交叉验证同样生效);根 `index.js` 的 MCP schema 新增九个字段与枚举;摘要只在改动默认时补一行【流派】,默认盘不多噪音。
751
+ - **口径**:不传或传非法值一律回默认,默认仍是 49 星盘面;庚干变体只作用于生年四化,宫干自化与大限/流年四化不随之改变(已写进 `rules.schools`)。
752
+ - **测试**:新增 `test/ziwei-schools.test.mjs`(73 条)——默认盘逐字节不变、九项各自独立生效、非法值回退、嵌套参数、compute 透传与摘要。统计 **92 个测试文件 / 3567 条断言**(+73),七道闸全绿。
753
+
754
+ ## 0.45.2(已并入 0.46.5)
755
+
756
+ 玄空的 `period` 非整数不再静默落回九运,而是按入参错误报 `E_INPUT`。
757
+
758
+ - **缺口在哪**:`engine/index.js` 只把 `Number.isInteger(period)` 传给引擎,`2.5` 或字符串 `"9"` 会被直接丢掉,`buildXuankong` 随后走缺省分支排九运——调用方拿到的是一张看似正常的盘,而不是「运写错了」。
759
+ - **改动**:`buildXuankong` 先校验「显式给了 period 就必须是整数」(`null` / `undefined` 仍算未给),不符合与越界共用同一条 `E_INPUT` 文案;`index.js` 不再预先过滤 period,原样交给引擎判定。
760
+ - **口径不变**:合法 1–9 的整数仍优先于 `fortuneYear`;未给 period 时仍按 `fortuneYear` 定运,再缺省九运并注明。
761
+ - **测试**:`test/fengshui-xuankong.test.mjs` 补 4 条(非整数/字符串报错、错误码、`null` 仍缺省),`test/tool-fengshui.test.mjs` 补 2 条(两种非整数在工具层都显示 `[E_INPUT]`)。统计 **91 个测试文件 / 3494 条断言**(+6),七道闸全绿。
762
+
763
+ ## 0.45.1(已并入 0.46.5)
764
+
765
+ 风水引擎的入参校验改走统一错误工厂,工具层不再把「坐向写错」这类调用错误标成内部异常。
766
+
767
+ - **缺口在哪**:`engine/fengshui.js` 的坐向、性别、生日、运越界都裸抛 `new Error`,到 `index.js` 的工具 catch 里没有 `code`,一律落到 `[E_INTERNAL]`;模型侧据此会把「参数该改」误判成「插件坏了」。
768
+ - **改动**:六处入参校验改用 `fail('E_INPUT', …)`——非 24 山、命卦缺性别、命卦缺完整生日、缺坐向、坐向不对宫、运越界。`mingGua` 落中宫的「命卦计算异常:落中宫」是内部一致性守卫,不是入参错误,仍保持无码 → `E_INTERNAL`。
769
+ - **口径不变**:文案、判定条件与结果字段均未改,只补错误码;工具层现有 `code || E_INTERNAL` 的透传逻辑不用动。
770
+ - **测试**:`test/tool-fengshui.test.mjs` 补 7 条(+7)——运越界与坐向不对宫各加一条码断言,另表驱动五组入参错误,要求文案匹配且前缀恒为 `[E_INPUT]`。统计 **91 个测试文件 / 3488 条断言**(+7),七道闸全绿。
771
+
772
+ ## 0.45.0(已并入 0.46.5)
773
+
774
+ 把「通关」从一句取象变成可复核的结构判定:用神与忌神相战时,指出五行里唯一能接上的那一行,并如实报它在局中的分量。
775
+
776
+ - **缺口在哪**:`engine/geju.js` 的文案一直写「身中和,先取调候与通关」,但引擎从未算过通关;`classics.js` 也只录了寒暖/燥湿等滴天髓条目,没有通神论「通关」原文。
777
+ - **判定口径**(`engine/geju.js` 的 `tongguanOf`):只在「用神与克它的忌神两行在局中各 ≥1.5 分」时成立相战;通关行由五行生克唯一确定(克方所生、又生用神,金克木以水为关),按分量分「可通 / 关弱 / 为忌 / 未通」四档,`usable` 仅指「可通」。通关行若在本盘属忌神,只标「为忌」、不当桥用;只写进用神 detail、摘要与解释层,不折分数、不断吉凶,也不判通关之力够不够用。
778
+ - **原文与选条**(`engine/classics.js`):新增 `dt-tongguan`(通神论·通关,典藏网 153091,原句照录「关内有织女,关外有牛郎,此关若通也,相邀入洞房」)。只在 `usable` 时占一位,并让泛论「用神配气候」让位;寒暖/燥湿的具体条目照留,整节仍以 5 条为限。未通的盘(如 1996 盘)经典选条保持原样。
779
+ - **知识卡**(`engine/interpret-knowledge.js`):新增 `bazi-tongguan`,标 `variant` 并写明分歧——各家对「两神相战」取哪两神不一(日主与官杀 / 用神与忌神 / 局中最旺两行),本插件固定取用神与克它的忌神。知识库 50 条(15 / 34 / 1)。
780
+ - **已知边界**:调候与扶抑可能给出同一行同时在喜在忌(扫射中约四分之一盘);本插件不改写喜忌表,通关判定按现表计算,并在清单里写明。
781
+ - **测试**:新增 `test/tongguan.test.mjs`(58 条)——五组相克各给唯一通关行、1.4/1.5 阈值与四档分类、喜忌顺序与空结果、24 年逐月真实盘独立重算与确定性、可通/未通两盘的经典选条、摘要/解释层/面板可见性与知识卡。统计 **91 个测试文件 / 3481 条断言**(+58),七道闸全绿。
782
+
783
+ ## 0.44.2(已并入 0.46.5)
784
+
785
+ 补齐模型侧调用玄空的最后一环:工具 schema 声明 `action:'xuankong'` 与 `period`,并让「今年」只补进命卦。
786
+
787
+ - **缺口在哪**:玄空下卦在引擎与两个界面都能用,但模型工具 `metaphysics_chart` 的 `action` 枚举只有 natal / advise / assess / generate,没有 `xuankong`,也没有 `period` 参数——对话里让模型排玄空,schema 层面就过不去。
788
+ - **另一个隐患**:`run()` 原先把「没给 fortuneYear 就补今年」的规则写成「fengshui 且不是 advise」,玄空一旦可调用,缺省会得到 fortuneYear=今年,九运缺省提示永远不出现,按年定运与默认九运两种口径悄悄混在一起。现在只对 natal(含未写 action 的缺省)补年份,玄空严格走 `period` → `fortuneYear` → 九运并注明。
789
+ - **改动**(`index.js`):`action` 枚举加 `xuankong`;新增 `period`(1–9,优先于 fortuneYear);`sitting` / `facing` / `fortuneYear` 与 `system` 的说明同步覆盖玄空;年份补全条件收窄到 natal。
790
+ - **口径不变**:显式 `period` 优先;给了 `fortuneYear` 按该年定运并回运程起止;两者都没有才缺省九运(2024–2043)并写明提示。
791
+ - **测试**:新增 `test/tool-fengshui.test.mjs`(19 条)——枚举与 period 声明、显式运不注入年份、按年定运的起止、缺省九运且不被今年顶替、命卦仍默认今年、非法运与坐向不自洽在工具层报错。统计 **90 个测试文件 / 3423 条断言**(+19),七道闸全绿。
792
+
793
+ ## 0.44.1(已并入 0.46.5)
794
+
795
+ 风水结果在 DSH 侧栏与独立页同步换了展示:从一段摘要文本变成方位网格,侧栏主按钮文案也按 tab 归位。
796
+
797
+ - **为什么**:上一轮把玄空下卦算出来了,但结果只是 `renderText` 的文本墙——九宫运/山/向挤在方括号里,旺山旺向与表法只能逐字读。侧栏面板里这个问题更明显(没有等宽排版)。
798
+ - **共用一份渲染**(`src/panel-kit.js` 的 `pp.fengshuiHTML`):侧栏(`src/app.js`)与独立页(`src/web-ui.js`)都挂到同一个函数,改一处两边同步。
799
+ - **玄空**:按后天八卦三行九宫(巽离坤 / 震中兑 / 艮坎乾),每宫依次列运/山/向三数;与当运相同的数高亮(中宫运数本身即当运,故 9 运、8 运各 3 处高亮);卡头写山盘/向盘的入中星与顺逆,以及「盘面」「表法」两个独立 chip;下方事实行写当运落宫、合十、表法说明。
800
+ - **八宅命卦**:八向格(中宫留空)标星名与吉/凶,四吉四凶各四;给了流年时加一行年紫白(入中星 + 八宫星名)。
801
+ - **门主灶**:同一张八向格 + 门/灶/床/厕四行 + 命宅配(给了生辰才有)。
802
+ - 所有文本走 `esc()`,布局文案或宅卦名里塞 `<img>` / `<script>` 不会变成标签。
803
+ - **侧栏动作按钮**:速查类 tab(黄历/农历/择日/称骨/小六壬/星座/生命数字/人生K/风水/起名)由「起卦」改为「看结果」,奇门为「起局」,空状态提示同步改成「填好参数,点『看结果』」。
804
+ - **没改什么**:引擎与输出字段未动,仍是展示层改动;`meta.scope` 与免责声明原文照旧。
805
+ - **测试**:新增 `test/fengshui-ui.test.mjs`(43 条)——九宫顺序与 27 个数、当运高亮、9 运无局与 8 运乾巽到山到向两套盘、八宅四吉四凶与年紫白、门主灶四行与命宅配、转义、侧栏/独立页接线与按钮文案。统计 **89 个测试文件 / 3404 条断言**(+43),七道闸全绿。
806
+
807
+ ## 0.44.0(已并入 0.46.5)
808
+
809
+ 风水补上一直挂着的玄空飞星:不是只加一张表,而是把「运盘 → 山盘 → 向盘」的挨星规则真正跑通,并让盘面与通行旺山旺向表逐运对得上。
810
+
811
+ - **缺口在哪**:README 的风水段一直明写「不含玄空各运盘」。八宅命卦、大游年、年紫白都是单星飞布,缺的正是玄空最核心的**下卦三盘**:当运星入中排运盘,再取坐宫/向宫的运星入中排山盘、向盘,最后看当运山星是否到坐、当运向星是否到向。
812
+ - **关键口径(这一轮最容易踩错的地方)**:山盘/向盘的顺逆**不是**按坐山本身的阴阳,而是按「入中运星的本宫(本位卦)同元龙之山」的阴阳;五黄入中时按本山阴阳。按本山阴阳会把旺山旺向算成每运固定的六局,与通行二十四山旺山旺向表(一运、九运无局)对不上;改按本宫同元龙后,九运旺山旺向表与盘面逐运吻合。
813
+ - **新增能力**(`engine/fengshui.js`):`periodOfYear`(1864 起一运、每运 20 年、九运 180 年一轮)、`MOUNTAIN_META`(24 山三元龙与阴阳)、`xuankongChart` 与 `action:'xuankong'`。输出九宫逐宫的 `运/山/向`、山盘与向盘的入中星与顺逆依据、当运星落宫、山星/向星合十宫位,以及**表法**旺山旺向(通行表)与**盘面**旺山旺向(当运星是否落坐/向)两套结论并列;两者口径不同,不合并、不互相覆盖,文案里写明差在哪。缺省运为九运(2024–2043)并给出提示,也可传 `period`(1–9)或 `fortuneYear`。
814
+ - **没做什么**:替卦 / 兼向、年月日时飞星、形峦与现场勘舆、具体应期。`meta.scope` 与免责声明逐条写明。
815
+ - **界面**:面板与独立页的风水速查加第三个模式「玄空」,坐山/朝向沿用 24 山输入,另加「运(1–9)」输入;结果仍走摘要文本,九宫按「巽离坤 / 震中兑 / 艮坎乾」三行排出。
816
+ - **测试**:新增 `test/fengshui-xuankong.test.mjs`(119 条)——三元九运边界、24 山三元龙阴阳逐条、七张公开盘面数字(含双星会向、五黄入中)、每运 12 局三盘均为 1–9 排列、**盘面旺山旺向与通行表逐运一致**(两套独立数据互证)、坐向互通、216 局确定性、运的来源与输入边界、`compute` 接线与摘要。统计 **88 个测试文件 / 3361 条断言**(+119),七道闸全绿。
817
+
818
+ ## 0.43.1(已并入 0.46.5)
819
+
820
+ 专旺格与从格终于有原文可读:三命通会里其实有七篇专章,此前清单写的「三书没有可整段照录的专章」是错的。
821
+
822
+ - **缺口在哪**:`docs/知识扩展与待核实清单.md` 四·1 一直写着「专旺格与从格暂无对应的单章原文条目(三书里没有可整段照录的专章),暂不硬凑」。核对典藏网目录后发现三命通会卷六有曲直、炎上、从革、润下、稼穑五篇,卷五有弃命从煞、卷六有弃命从财——正好对着引擎里已有的专旺五格与从财格、从杀格。于是这一轮不是「补口径」,是补上本可以早就有的原文。
823
+ - **七条原文**(`engine/classics.js`):`smt-quzhi`(卷六·曲直 7630)、`smt-yanshang`(卷六·炎上 7631)、`smt-congge`(卷六·从革 7632)、`smt-runxia`(卷六·润下 7633)、`smt-jiasi`(卷六·稼穑 7634)、`smt-congsha`(卷五·弃命从煞 7598)、`smt-congcai`(卷六·弃命从财 7652)。原文取连续段落照录、不加省略号也不改写;白话自撰。原文里「多主眼疾」「破家不仁之人」这类旧说重话照录,但明确只记原文、不拿来断人。
824
+ - **接线**(`classicsFor`):命中的专旺格 / 从财格 / 从杀格先取单章原文,排在月令格之前——专旺或从格是这张盘的定义性结构,先占位才不会被后面两条气候与总纲挤掉;整节仍以 5 条为上限,不额外放宽。从儿格(食伤)、从强格(印 / 比劫)三书里没有可整段照录的专章,`SPECIAL_CLASSIC` 不登记、不硬凑,测试里用两张真实盘反向核过「不误配」。
825
+ - **知识库 49 条**:新增 `bazi-zhuanwang-yuanwen`(专旺五格的成格条件比「身强」细)与 `bazi-congge-yuanwen`(弃命相从、见根气即破格),均标 `variant`——专旺是否必须成方局、从格是否允许微根,各家宽严不一;只列结构与原文,不断贵贱,也不补专旺的破格条件。顺手把清单表格里漏登的三条历史条目(紫微三方四正复合飞化、六爻用神旺衰、六爻全卦逐爻旺衰)补齐,表格从 44 行对到 49 条。
826
+ - **口径修正**:清单四·1 与 README 致谢里「三书没有专章 / 只取七条」的说法一并改对,写明「十四篇:论十神七篇 + 专旺五格与弃命从煞、从财七篇」,并注明从儿、从强仍未录。
827
+ - **测试**:`test/classic-quotes.test.mjs` 新增七张真实盘(曲直 / 炎上 / 从革 / 润下 / 稼穑 / 从财 / 从杀)逐格核「命中的单章排第一、why 点名、仍守 5 条上限」,另加从儿 / 从强两条反向用例、limit 截断、摘要与解释层可见;`test/sanming.test.mjs` 条目数由 7 改为 14(并拆出「7 论十神 + 7 格局篇」两个计数),逐条核原文、章名、典藏网链接、链接互不重复、tag 不与月令十神混用,并钉住两张新知识卡。统计 **87 个测试文件 / 3242 条断言**(+57),七道闸全绿。
828
+
829
+ ## 0.43.0(已并入 0.46.5)
830
+
831
+ 解读从「五维度 + 若干节」升级成可读的报告:紫微补逐宫与分层格局,八字补命局框架、画像、流年叙述与专业建议;措辞收进两份独立词库,引擎与说法彻底分开。
832
+
833
+ - **缺口在哪**:此前的解读只有五个维度和几张表——维度说得对,但不成篇。用户拿到紫微盘,看不到「这十二个宫各自是什么味道」;拿到八字盘,看不到「这个人的框架、长什么样、哪一年顺」,只能自己去拼盘面。对照市面上的成篇解读,差的是**结构与措辞**这两层,不是数据。
834
+ - **紫微新增四块**(`engine/interpret.js`):① **命身底色**——命宫主星 + 亮度 + 双星组合 + 身宫落点一句话说清;② **逐宫分析**——十二宫各一条 `【宫·支】主星(亮度)|吉星|煞星|四化`,下接「读法」;③ **三层格局**——有利格局 / 结构提示 / 忌格提醒,每条写 `名称 · 人话 · 依据(盘面事实) · 做法`,按 tone 着色;④ **行动建议**四条。只把六煞(擎羊/陀罗/火星/铃星/地空/地劫)写进五个维度,其余杂曜留在逐宫,避免一眼看去全是星名。
835
+ - **八字新增四节**:**命局框架**(日主/用神/格局三行,末尾一句命局基调)、**正面画像**(外在取象 / 性格底色 / 事业与家庭)、**流年时间轴**(近三年逐条给档位与理由,用「可能性」措辞并声明档位不是断语)、**专业建议**(喜用落地 / 忌神自觉 / 地支关系 / 调候四件可做的事)。
836
+ - **两份词库**(新增 `engine/ziwei-words.js`、`engine/bazi-words.js`):紫微侧 12 宫取象、14 主星(别称/关键词/得地与失地两种语气/长处/要留意的点)、24 组双星、14 煞星、18 吉星、四化落宫、七档亮度、34 条格局读法;八字侧 10 天干取象、10 颗十神 + 5 组(十神权重底层给的是组名,组与单颗各有一套话)、旺衰 × 用神方向的六种命局基调、地支冲合刑害破的手感。**词库不含判断条件**——要不要说、说哪一条由引擎决定,换个排盘引擎结论也不会被说反。
837
+ - **命局基调按权重取**:`frameToneOf(level, favorRoles)` 只看角色不动分数;调用方先把 `favorRoles` 按十神权重排好再传入,于是「身强喜食伤财官杀」取到的是分量最重那一支(泄),而不是固定顺序的第一条。强档没有对应基调时回落「泄」、弱档回落「生」,都写明理由。
838
+ - **面板**:分节支持 tone(左框线 + 标题色:有利绿、提示橙、忌格红)与 `**加粗**`、换行分段(此前整节挤成一坨);逐宫、三层格局各有独立锚点,目录可跳。
839
+ - **术语表**(`engine/interpret-plain.js`):补 庙旺 / 三方四正 / 命主 / 身主 / 五行局 / 自化 / 飞星 / 正曜 / 借对宫 / 双星 / 墓库 / 伏吟 / 反吟 十三条,仍按「正文里真的出现过」才展示,并按体系取不同释义。
840
+ - **顺手改掉两处重复**:紫微「说人话」不再复述直答里的命宫与身宫,改说「你与环境怎么互动」与重心;八字性格底色的单颗十神只补「落在哪个角色上」,不再把组的那句抄一遍。
841
+ - **测试**:新增 `test/ziwei-words.test.mjs`(55 条)与 `test/bazi-words.test.mjs`(46 条)——词库条目数与引擎表一一对应(34 条格局名与 `PATTERN_TONE` 双向零差集)、双星 key 必须能拆成两颗真实主星、亮度三档齐全、煞星不写成判决、基调优先序与回落、地支关系去重与「自刑优先于刑」、四节存在且引用本盘真实字段、面板把 `**` 与换行渲染成 `<b>` 与段落、全文无 undefined/NaN。**87 个测试文件 / 3185 条断言**,七道闸全绿。
842
+ - **边界**:词库只给倾向与做法,不下断语;格局读法覆盖现有 34 条,新增格局未入词库时按 tone 回落成通用句而不是现编;逐宫只写星曜与四化,不叠大限流年的三层算力;健康维度只用煞星星情,不给脏腑诊断。
843
+
844
+ ## 0.42.0(已并入 0.46.5)
845
+
846
+ 紫微的闰月从两档补到三档,默认换成主流排盘的「按日切分」;顺手修掉流年斗君二次换月。
847
+
848
+ - **缺口在哪**:此前只有「闰月按本月」与 `leapAsNext`(整月归次月)两档,默认按本月。闰月后半月出生的人,主流排盘按次月起盘,我们却按本月,命宫、身宫、五行局、十四主星位置、大限起运、流月斗君整条链都差一个月——盘看起来完整,宫位却系统性偏移。
849
+ - **三档口径**(`engine/ziwei.js` 新增 `LEAP_POLICIES` / `leapPolicyOf` / `effectiveLunarMonth`):`split`(默认,1–15 归本月、16 起归次月,按日切分)、`next`(整月归次月)、`prev`(整月归本月);`leapAsNext: true` 保留为 `next` 的旧写法,`leapMonth` 优先于它。不认识的取值回落到默认,不抛错。工具参数同步成枚举,`rules.leapMonth` 写明三档与默认。
850
+ - **为何改默认**:参考开源项目 [ziwei-doushu](https://github.com/Renhuai123/ziwei-doushu)(MIT)的流派配置与其 150 组金标准盘对照结论——主流排盘默认「月中分界」。我们不引入其引擎,只采纳这一条排盘口径,并把它做成可切回的开关;不想换的人传 `leapMonth: 'prev'` 即回到旧口径。
851
+ - **盘里能看见**:`lunar` 保留 `monthRaw`(原始闰月)与换算后的 `month`、`leapPolicy`,闰月另给一句说明(「闰4月按日切分……本盘闰月21日按5月」);摘要的农历行写成「2020年闰4月21日(按5月起盘)」,不再把 21 日写成「闰5月21日」;面板宫盘抬头同样处理。
852
+ - **修掉一个旧 bug**:`flowOf` 里的流年斗君此前用 `chart.lunar.month`(已是换算后的月)再按 `leapAsNext` 加一次月,闰月 + `leapAsNext` 会多推一个月。现在起盘时只换一次,流月/流日/流时全部直接读换算结果。
853
+ - **边界**:闰十二月十六起回绕到正月只换月序、不老一岁(闰腊月极罕见,明写不猜);1–15/16–30 的分界按通行「月中」,不提供逐日自由配置;不引入参考项目的其余九类流派开关(庚年四化变体、亮度流派、安天马/天空/截空等),留作后续。
854
+ - **测试**:新增 `test/ziwei-leap.test.mjs`(44 条)——2020 闰四月的初十/十五/十六/廿一四个边界、三档口径函数与默认/别名/未知值回落、起盘月与命宫紫微斗君逐项对照、前半月 split 与 prev 同盘、`leapAsNext` 与 `next` 等价、斗君只换一次月、非闰月三档排出同一张盘、compute 透传与摘要/面板文案。**85 个测试文件 / 3084 条断言**,七道闸全绿。
855
+
856
+ ## 0.41.0(已并入 0.46.5)
857
+
858
+ 起名补上一直被写在「不做」里的两层:**五格剖象**(天格/人格/地格/外格/总格 + 81 数理 + 三才)与**音韵检查**。此前 README 明写「不做五格(需康熙字典笔画)与音韵」,等于把最常被问的两件事推给用户;这一轮把笔画与读音数据补全,再按通行算法落地。
859
+
860
+ - **数据层**(新增 `engine/name-data.js`):391 个用字逐字补**拼音、声调、康熙笔画**(按繁体字形与偏旁本字计:华→華14、马→馬10、静→静16、涛→濤18、灵→靈24、兰→蘭23、丰→豐18、书→書10、画→畫12、云→雲12、风→風9、阳→陽17;氵→水4、艹→艸6、辶→辵7、阝左→阜8、阝右→邑7);单姓笔画表约 120 个(王4/李7/张11/刘15/陈16/罗20/郑19),复姓 13 个逐字存(欧阳 15/17、司马 5/10、夏侯 10/9…);81 数理取通行本,分吉/半吉/凶三档。数据与字库由测试逐条对齐——391 条一一对应,多一个字少一个字都会红。
861
+ - **五格**(`engine/name.js` 新增 `wuge`):单姓双名 天格=姓+1、人格=姓末+名首、地格=名两字和、外格=总−人+1、总格=全部;单姓单名 地格=名+1、**外格固定 2**(没有「外侧」,通行本记 2,不是 1);复姓 天格=两字和、外格=总−人+1(等价于复姓单名的「姓首字+1」)。数理超 81 按 −80 回绕(104→24),三才取天/人/地个位对五行,再按生克给一句「一路相生 / 相连相克 / 吉凶各派看法不一」,不折算分数。
862
+ - **缺笔画不半算**:任一字查不到康熙笔画,整体返回 `available:false` 并点名是哪个字,提示用 `strokeOverrides`(逐字)或 `surnameStrokes`(按姓)补;补进来的字在结果与面板里都标「用户指定」。姓超两字、姓不在表、只给名不给姓,都走同一条「算不了」的路,不拿简体笔画或猜测顶上。
863
+ - **音韵**(新增 `phonetics`):只报可数的事实——全名同调、相邻同声母、相邻同韵母、相邻同音(叠字),再按条数判「顺口 / 略拗 / 拗口」。声母先切 zh/ch/sh,y/w 按拼写当声母。**不做语义谐音**(需要词库),摘要与注释都写明「谐音、方言读法还得自己读三遍」。
864
+ - **排序而非判定**:生成候选名把五格格数当第三顺位(合喜用 → 两字异行 → 五格 → 性别倾向 → 字库序),注释写清「是排序不是吉名判定」;姓的笔画不在表里时这一轮不按五格排序,也不伪造。
865
+ - **四处可见**:摘要各加一行【五格】【音韵】;面板新增五格格阵(5 列,吉/半吉/凶各配色)、笔画行(用户指定标「(指定)」)、三才行与音韵行(拼音+调、声调序列、水平徽标、逐条问题),算不了时显示原因而不是空白;生成候选的每个名字带「五格 N/5 吉」与音韵水平 chip。
866
+ - **顺手修掉一处静默丢参**:页面上「评名字」虽然显示出生日期,`src/web-ui.js` 与 `src/app.js` 却在提交前 `delete args.datetime`,于是填了生辰也永远得到「给出生年月日才能判断」;现在生辰填了就传、空着才删,评估能按喜用判,面板里的八字行也随之出现。
867
+ - **测试**:新增 `test/name-wuge.test.mjs`(103 条)——数据完整性(读音表与字库双向零差集、声调 1–4、笔画 1–40、拼音正则、81 条数理档位)、康熙锚点(静16/涛18/灵24/兰23/丰18/书10/画12/云12/风9/阳17 等 16 字与 7 个姓)、81 回绕、四类姓氏结构的五格数与吉凶、三才、缺笔画/超长姓/无名的落点、笔画覆盖与来源标注、音韵四类问题与顺口反例(王沐宸)、compute 接线与面板渲染,以及两处入口不再丢生辰。**84 个测试文件 / 3040 条断言**,七道闸全绿。
868
+ - **边界**:81 数理各派对少数数取法有出入,按通行本取一套;五格只是传统数理游戏,不参与喜用判定,也不改结论。
869
+
870
+ ## 0.40.0(已并入 0.46.5)
871
+
872
+ 六爻的伏神补上「出伏条件」:飞伏生克与月建日辰并列摆出,归成四档,只判条件、不出应期。
873
+
874
+ - **缺口在哪**:知识卡 `liuyao-fushen` 一直写着伏神看「日月生扶」,引擎却只算飞伏生克(飞生伏 / 伏生飞 / 飞克伏 / 伏克飞 / 比和)——月建、日辰从未落到伏神那一爻上。卡上是口径、盘上没有实现,这一轮把这一层补上。
875
+ - **四档判定**(`engine/liuyao.js` 新增 `fushenAccess`,挂 `result.fushenAccess`):先并列两栏——助(飞生伏、伏克飞、日辰生、日辰比和、月建旺、月建相)与压(飞克伏、日辰克、月破);有助无压为「可出」、有助有压为「有助有压」、有压无助为「受压难出」、两者都无为「未得助」;没有飞伏关系时记「飞伏未知」,不猜。
876
+ - **四处可见**:摘要单列「伏神出伏:第2爻可出」;解析在飞伏段后逐条写该爻的月建(五行、五态、是否月破)、日辰(五行、五关系)与助压明细;白话按档位补一句(「出得来」是条件、不等于马上应验);面板在旺衰 chip 下单列一排(可出绿,有助有压 / 受压难出赭)。
877
+ - **口径与边界**:四档只并列条件,不排「飞伏与日月谁先谁后」的各家优先级;月破算压、伏神旬空只标出而不并入档位,都是明写的取法,不假装是共识。**应期仍未做**——这一层只回答「现在出不出得来」,不给具体日期;`docs/知识扩展与待核实清单.md` 的四·3 与文末注同步写明「条件是条件、应期另算」。
878
+ - **测试**:新增 `test/liuyao-chufu.test.mjs`(53 条)——用独立的五行生克与相冲表复算 64 卦 × 4 个询问方向 × 12 个月 × 12 日 = 6,048 组,要求逐组零不符、四档都出现、四种真实飞伏关系都覆盖;四条从真实盘里挑的边界(地雷复·学业 寅卯「可出」、亥卯「有助有压」、地火明夷·财 子子「受压难出」、地山谦·财 午辰「未得助」);缺月建只看日辰、飞伏关系未知、伏神旬空只标不改档、传 null 不抛四条兜底;摘要/解析/白话/面板四层可见、旧结果兼容、断言输出里没有应期字段。统计 **83 个测试文件 / 2937 条断言**,七道闸全绿。
879
+
880
+ ## 0.39.0(已并入 0.46.5)
881
+
882
+ 首屏从「19 个 tab 平铺」改成按目的分三组,并保留一键切回平铺。此前第一次来的人得先猜「梅花」「称骨」是什么;现在按「问一件事 / 看一个人 / 查日子」分组,每项带一句白话。同一轮还改了「问进对话」的提问模板:原来它只约束证据与口气,模型答出来是一串带引用的术语流,读的人不知道这张盘在说什么。
883
+
884
+ - **三组入口**(`tools/build-html.mjs`):问一件事(六爻/梅花/塔罗/奇门/六壬/小六壬)、看一个人(八字/紫微/合盘/人格/称骨/数字/人生K)、查日子(黄历/择日/农历/星座/风水/起名)——19 项一个不落,顺序按用途重排,不按引擎模块排。
885
+ - **每项一句白话**:「摇六次,问一件事」「四柱看一生格局」「挑个办事的好日子」,不用先懂术语再点。
886
+ - **最近用过**(`src/web-ui.js`):只记入口名与时间,最多 3 条,存 `mp.recent.tabs`;点入口、点起卦/排盘、人格问卷提交时记录,首屏默认 tab 不记;`localStorage` 读写都包 try/catch,隐私模式下只是不记,不影响使用;读回的值先过「当前页面真实入口」白名单,不直接拼进选择器。
887
+ - **平铺回退**:19 个 tab 原样保留在页面上,右上角「分组 / 平铺」一键切换并记住选择(`mp.first.view`),旧用户的肌肉记忆不受影响。
888
+ - **手机端**:每组先露 4 项,其余折在「还有 N 个」后面(`nth-child(n+5)` + `.open`),三组铺完不再把表单推到第二屏以下;桌面三列、中屏一列。
889
+ - **样式**:卡片沿用纸色 + 朱红(选中项实心),深色下文字反色;打印时首屏分组、视图开关与 tab 条一律不打印,纸面仍是「抬头 + 盘面 + 解读」。
890
+ - **追问读不懂**(`engine/followup.js`、`test/ask-prompt.test.mjs`):此前「回答要求」只有三条——引到具体柱/宫/爻、没依据就说看不出来、别给绝对断言。这三条只管**证据**与**口气**,不管**可读性**,于是照它答出来的东西是一串带引用的术语流:知道「甲有问题、乙有问题」,却不知道这张盘到底在说什么。现在模板先交代一句「读者不懂命理」,再给一套骨架:**开头一句不用术语的结论**(只读这句也该有收获)→ 判断**最多两条、按重要性排序**,每条分 `盘面|白话|倾向|边界` 四行(盘面只引字段不掺解释;白话把上一行的术语当场翻掉,一个词只翻一次、不连续堆三个以上;倾向用「更可能……」讲清现实含义;边界写清何时不成立,盘面没给的直接写「这盘里看不出来」)→ 收尾一句「**如果只记一件事**」,给可核对、可动手的观察点并点明它出自哪条依据。`调候 / 化气 / 通关 / 空亡 / 争合` 单独点名要求落地;「格局很好」「运程不顺」这类没有信息的空话禁掉。
891
+ - **默认问法也改口**:空问题时原来问「请先总览这张盘」,而「总览」本身就在邀请逐字段复述——模型当然照着摘要念一遍。改成「先用一句白话讲清这张盘的主线,再指出最值得注意的一两处,并说明每处的具体依据」。
892
+ - **固定骨架有长度上限**:抬头 + 回答要求约 520 字,不随 `maxChars` 变;测试里那条「固定骨架本身不超过 900 字」专门盯它别长成小作文。顺带修掉一条会误报的旧断言——原来写「整段提问 < 800 字」,骨架一长就红,现在拆成「摘要正文真的截到 maxChars」与「骨架另有上限」两条,各盯各的。
893
+ - **测试**:新增 `test/first-screen.test.mjs`(44 条)——三组名称与顺序、19 项与平铺集合逐一对齐、每项都有白话、记录时机(入口/主按钮/问卷)、存储上限与去重、读写失败降级、手机折叠与 aria、两套入口共用 `activate`、深色反色与打印隐藏。其中 `.recent[hidden]` 一条专盯「`display:flex` 盖掉 `[hidden]`」——首版就踩了,没记录时页头挂着一个空的「最近用过」。`test/ask-prompt.test.mjs` 由 46 条增至 54 条(骨架四行齐全、无术语结论、难词点名、收尾句、空话黑名单、默认问法改口)。统计 **83 个测试文件 / 2937 条断言**,七道闸全绿。
894
+
895
+ ## 0.38.2(已发布 2026-10-29)
896
+
897
+ 紫微格局修掉三处「写得像实现了、其实永远不成立」的判定:夹局的方向、羊陀夹忌、刑囚夹印;顺手把 34 条目录从 README 的 31 条补全,并用独立谓词逐条钉死。
898
+
899
+ - **夹局不分左右**(`engine/ziwei.js` 的 `jia`):旧写法只认「A 在命宫前一宫、B 在后一宫」这一种顺序,但「夹」只要求两星分居命宫前后。实测 69,120 张盘:**昌曲夹命 0/8、羊陀夹命 0/1,474 从未命中**,日月夹命(237:231)、左右夹命(470:457)、魁钺夹命(283:292)各漏约一半。改为两向都认;`test/ziwei-patterns.test.mjs` 用镜像方向的真实盘(1955-01-02、1955-06-22、1956-02-14 等)钉住。
900
+ - **羊陀夹忌**:擎羊恒在禄存 +1、陀罗恒在禄存 −1,两星只能夹**禄存**那一宫;旧判据要求「化忌两侧是羊陀」,几何上不可能(1,553 张符合的盘一次都没报)。改为「化忌与禄存同宫」,证据文本写明化忌落在哪一支。
901
+ - **刑囚夹印**:廉贞与天相永远隔偶数宫,字面上的「廉贞、擎羊夹天相」同样不成立(17,568 张盘两向皆零)。按通行说法改为「廉贞天相同**守命宫**于子午、擎羊同宫」——源文说的是「守命」,所以判的是命宫那一宫,廉相羊同宫在别的宫位不报;evidence 写明三颗星同守哪一宫;命宫卯酉、廉贞天相对照遇擎羊的变体未纳入,写进 README 口径。三条来源:知乎「刑囚夹印」、sohu 格局文、ziwei-yun「天相不可能被廉贞和擎羊二星所夹」。
902
+ - **34 条目录补齐**:README 原列 31 条,且把 武贪同行、火贪铃贪 归在吉格(引擎一直是中性)、`双禄交流 / 命无正曜 / 杀破狼` 完全没写。现按引擎口径分三组列出(吉 20 / 中性 5 / 忌 9),`PATTERN_TONE` 改为导出供测试比对;README 与目录的一致性由测试直接解析 README 断言。
903
+ - **结构统计补中性**:`patternSummary` 增 `neutral`,摘要行改成「吉格 N、中性 K、忌格 M」——此前中性格计入 count 却不出现在统计里,count 会大于两档之和。
904
+ - **不新增能力、不动知识库**:知识库仍 47 条(本轮是判定口径修正,不是新规则);格局仍只描述结构、不折吉凶分数。
905
+ - **测试**:新增 `test/ziwei-patterns.test.mjs`(79 条)——34 条目录与 README 三组逐名对齐;312 张盘 × 34 条用独立谓词(只读星位与四化,不调引擎判定)复算,要求每条「零不符且至少命中一次」,专门防死规则;夹局镜像方向、羊陀夹命 ⇔ 禄存守命、羊陀夹忌 ⇔ 化忌同禄存、刑囚夹印守命(含「非命宫同宫不报」反向盘)、摘要计数与确定性各自钉住。故意把 `jia` 改回有序写法时该文件 11 条变红。统计 **81 个测试文件 / 2832 条断言**,七道闸全绿。
906
+
907
+ ## 0.38.1(已并入 0.38.2)
908
+
909
+ 古籍库补上《子平真诠》论格局成败的两章,并把「用神总纲」一位改成按盘取;顺手修掉 why 里拼出「论论财」的旧文案。
910
+
911
+ - **两条原文**(`engine/classics.js`):`zp-chengbai`(九、论用神成败救应,「成中有败,必是带忌;败中有成,全凭救应」)与 `zp-bianhua`(十、论用神变化,「藏庚透壬,则化为财。凡此之类皆用神之变化也」),均照录中华典藏网 53629 / 53630,白话自撰。
912
+ - **为什么是这两章**:0.37.0 起古籍节覆盖了「月令格 × 两书对照」与「调候」,但化气格只剩气候与总纲,组合(官印相生、伤官见官等)没有任何原文可读——这两章正是判「化气成不成」「成格有没有带忌」的出处。
913
+ - **总纲位三选一,不另加位次**:`classicsFor` 的第五条仍是「用神总纲」位——有化气格取「论用神变化」,见组合取「论用神成败救应」,其余取「论用神」通用总纲。上限没有从 5 放宽,也没有让泛论挤掉针对这张盘的话;同盘同时有化气与组合时取「变化」,why 写明取舍。
914
+ - **文案 bug**:此前 why 用 `${书名}论${章名}` 拼,而章名本身已带「论」,实际输出成「子平真诠论论财」「三命通会论论正财」。改为「书名「章名」一条 / 另取」,章节标题去掉序号与开头的「论」;测试加「why 不出现论论」的断言。
915
+ - **知识库 47 条**:新增 `bazi-geju-chengbai`(成中带忌、败中有救)与 `bazi-huagi-bianhua`(月令藏干与合局改变取用),均标 `variant`——成格条件、化气成立条件各家宽严不一,只并列原文与方向,不逐盘判成破。`docs/知识扩展与待核实清单.md` 的条数、统计与注记同步;顺手把上一轮注记里写错的版本号 0.37.2 改回 0.38.0。
916
+ - **口径边界**:专旺格、从格仍没有对应的单章原文(三书里没有可整段照录的专章),不硬凑;古籍节仍只负责「书上怎么说」,不把原文折算成吉凶分数。
917
+ - **测试**:`test/classic-quotes.test.mjs` 新增 13 条(两章原文抽检与典藏网出处、why 无双「论」、三选一互斥、1996 盘取「变化」、化气/组合/无特格三种落点);`test/sanming.test.mjs` 新增 7 条(总纲换条后仍保住两书对照、两张知识卡的出处与「不当断语」口径)。统计 **80 个测试文件 / 2753 条断言**,七道闸全绿。
918
+
919
+ ## 0.38.0(已并入 0.38.2)
920
+
921
+ 补上知识卡里已经写了、引擎却一直没做的一层:**岁运并临与伏吟反吟的逐年提示**。此前 `bazi-suiyun` 卡说「只作变动提示」,但盘面里没有任何地方标出是哪一年,等于只有口径、没有实现。
922
+
923
+ - **四类信号**(`engine/bazi.js` 给每条流年加 `suiyun`):**岁运并临**(当值大运与流年干支相同)、**运年反吟**(大运与流年天克地冲)、**流年伏吟**(流年与年/月/日/时柱干支相同)、**流年反吟**(流年与某柱天克地冲)。每条信号带 `type` / `target` / `detail`,另给 `note` 写明口径。
924
+ - **当值大运怎么取**:流年按立春起算,取与「该年立春到次年立春」区间相交的大运;交运落在这一年里时,前后两步都在本年当过值,两条并列。没有用虚岁近似,也不把交运日抹平。
925
+ - **天克地冲的判据**:天干相克 **且** 地支相冲,缺一不算。例如丙子年对丙午年柱是同干相冲,不标反吟;这条单独在测试里构造验证。
926
+ - **口径与边界**:只标干支重复与对冲,不折分数、不判吉凶——「岁运并临主大凶」一说不采,摘要与解析都写明「只标变动,仍看该年是否动到用神」。大运与原局之间的伏吟反吟未逐年标,四柱十神的引化也未叠入;起运前只有流年这一侧能成立。
927
+ - **四处可见**:摘要加一行「岁运提示(只标干支变动,不判吉凶):2030庚戌 岁运并临;…」;解析新增「岁运提示」节,逐年写清当值大运与每条的出处;白话只在最近一个命中处补一句「变化感强一点,不是好消息也不是坏消息」;面板在流年 chip 下方单列一排提示,chip 悬停给逐条依据。旧结果(没有 `suiyun` 字段)照常渲染,解析退回「近十年没有」的保守说法。
928
+ - **账面口径修正**(`docs/知识扩展与待核实清单.md`):知识库实际已是 45 条(诸家一致 15 / 各家有异说 29 / 待核实 1),清单头部还写着 42 条、统计还停在 15/27/1,一并改对;「岁运并临吉凶」一行补上「已落引擎与界面」。
929
+ - **测试**:新增 `test/suiyun.test.mjs`(102 条)——不复用引擎判定,按「月柱干支顺逆推八步」与「立春区间相交」两套独立写法复算 10 张盘 × 10 年;扫描全部样本核四类信号与事实一致(并临必然同干支、反吟必然天克地冲、伏吟必然同柱);构造同干相冲(丙子 vs 丙午)不算反吟、起运前无大运、年内交运两步并列三条边界;钉住确定性、摘要/解析/白话/面板四处可见、旧结果兼容与知识卡口径。统计 **80 个测试文件 / 2733 条断言**,七道闸全绿。
930
+
931
+ ## 0.37.1(已并入 0.38.2)
932
+
933
+ 界面深修一轮,重点在窄屏:19 个 tab 不再吃掉首屏,两列表单不再被按钮挤成 134px;六爻的化进/化退补上力重。
934
+
935
+ - **桌面抬头改竖排**(`tools/build-html.mjs`):品牌一行、tab 条一行。tab 从右对齐的 flex 换行改为 `repeat(auto-fit,minmax(74px,1fr))` 等宽网格,每格同宽、末行左对齐,不再出现「起名 人格」两项孤零零挂在右边、与上一行错开半个身位。
936
+ - **窄屏 tab 改单行横滑**:3 列网格是为六个 tab 写的,tab 涨到 19 个后要占七行(约 340px),首屏只剩输入框。改回单行横滑,44px 触摸目标、`scrollbar-width:none` + `::-webkit-scrollbar{display:none}` 藏掉滚动条、首尾各留 12px 呼吸位;切到靠后的 tab 时 `scrollTabIntoView()` 把当前项滚到可视区中间(`prefers-reduced-motion` 下用瞬时跳转),避免「页面变了、高亮停在屏幕外」。
937
+ - **窄屏表单两列修好**:根因是 `.go{grid-column:4}`、`.go.ghost{grid-column:3}` 写死给桌面四列,窄屏两列时这两条会生成第 3、4 列隐式 auto 轨道,把两个正文列挤到 134px,性别与按钮全被压扁。窄屏改为「看示例/排盘」分别落在第 1、2 列,性别与出生地各占整行,三个勾选项两两成对,收尾不再留空格。
938
+ - **人格页重做**(`src/panel-kit.js`):结果卡原本是「四行细条 + 段落堆叠」,字小、无层级;现在按「类型抬头(大字类型码 + 名称/关键词 + 已答题数)→ 四维瓦片(双极字母 + 取值条 + 一句取向)→ 一句 → 优势/留意(绿/赭左线两张卡)→ 认知功能链(主导高亮)→ 工作/关系/学习/课题分节」分层。问卷态改成两列编号清单,桌面一眼扫完 24 题。同时把卡片抬头从 `<header>` 改成 `<div>`:页面级 `header{flex-direction:column}` 会把卡片抬头也压成竖排。
939
+ - **顶层卡片没拿到调色板**(根因):变量块只挂在 `.pp,.mp-it` 上,而人格、黄历、称骨、人生 K 线、起名、速查这些卡片是直接插进 `#out` 的兄弟节点,`var(--band)`/`var(--card)` 全部失效 → 卡片退化成没底色、没边框的一堆字,这正是人格页看着丑的主因。变量块扩到 `.mp-al/.mp-cg/.mp-kline/.mp-mb/.mp-nm/.mp-quick` 等全部顶层卡片,`test/theme.test.mjs` 的断言同步改为「各顶层卡共享同一份变量」。
940
+ - **人格问卷改分页问答**(`src/web-ui.js`、`src/app.js`、`tools/build-html.mjs`、`src/panel-kit.js`):原来是一个「24 题分数」文本框——让用户自己数 24 个数字,像在填表格。现在照常见在线测评的做法:**4 题一页、共 6 页**,每题 1–5 五格单选(完全不像 / 不太像 / 说不准 / 有点像 / 很像我),顶部有进度条与「第 n / 6 页 · 已答 x / 24」,底部是上一页 / 下一页 / 看结果 / 清空。答满 12 题就能先出结果(与引擎的 `E_INPUT` 门槛一致),不够时按钮禁用并写明还差几题;最后一页收起「下一页」,「看结果」与原主按钮二选一,不再重复两个入口。题目与 1–5 的说法都从引擎的问卷态取(`compute({system:'mbti'})`),前端不抄一份;答案按题序存成数组,末尾连着没答的去掉再交给 `answers`,中途未答的按引擎口径算「跳过」。独立页与 DSH 面板共用同一套分页交互(面板是 `MbtiQuiz` 组件);结果不进「最近排过」——答案没存进历史,重放还原不了问卷。
941
+ - **人格页输入区**:问卷与日期无关,起卦日期/时刻在人格 tab 下隐藏(面板与独立页同步);问卷整行独占,窄屏下 5 格缩字体与内边距、按钮整行、44px 触摸目标;深色下选中格文字随强调色反色(与 tab / 主按钮同一口径)。
942
+ - **桌面副本可同步**:新增 `--desktop` 与 `npm run build:desktop`,一次把同一份页面写到仓库根和 `~/Desktop/命理排盘.html`。桌面那份是手工拷的产物,源码一改就旧;现在构建就能刷新,页面左上角的版本徽标用来核对。README 三处说明同步更新。
943
+ - **变量补全与观感**:共享变量块补齐 `--ink3/--fx/--sans/--kai`(此前多条形同虚设的字体、次级色规则因此失效)与 `--shadow`,深色另给一套;盘面卡片统一 12px 圆角与外阴影,古籍引文块改为左侧朱线 + 楷体悬挂缩进,`:focus-visible` 统一描边,结果入场只做一次轻微上浮并尊重 `prefers-reduced-motion`。
944
+ - **六爻 · 化进/化退力重**(`engine/liuyao.js` 新增 `jinTuiPower`,挂 `result.jinTuiPower`):此前只标方向,现在把每条进退放回月建五态落档——旺相 → 后劲足(退则退得缓)、休囚 → 后劲有限(退则退得实)、死 → 进得虚、逢月破 → 月破失据、缺月建 → 只报趋势;旬空只标出、不改结论。摘要单列「进退力重」一行;解析在「卦体关系」里逐条写清月建、日辰与档位,「未纳入」删去该项(保留用神两现权重与伏神出伏应期);白话加一句;面板单列一排 chip(后劲足/退得缓绿、其余赭)。只给档位、不折加权分数,吉凶仍落在用神/忌神那一层判。
945
+ - **测试**:`test/theme.test.mjs` 第五节改为「单行横滑 + 藏滚动条 + 首尾呼吸位 + 44px 触摸目标 + 切 tab 自动滚入视野 + 两列内按钮不生成额外轨道」,共 50 条断言;`test/mbti.test.mjs` 新增分页问卷一节(25 条)——离线页容器/样式、web-ui 的每页 4 题与 12 题门槛、事件委托、面板 `MbtiQuiz` 单跑校验(一页 4 题、刻度来自引擎、进度文案、按钮禁用与末页无「下一页」)、题面不复制到页面/面板;`test/liuyao-jintui.test.mjs` 新增第六节(27 条)——五态两行档位逐档复算、月破与缺月建两条边界、旬空只标不改结论、摘要/解析/白话/面板四处可见、旧结果不出该排。统计 **79 个测试文件 / 2631 条断言**,七道闸全绿。
946
+
947
+ ## 0.37.0(已并入 0.38.2)
948
+
949
+ 古籍库从两本扩到三本:接入《三命通会》卷五、卷六论十神七条,与《子平真诠》同一格局并列对照。
950
+
951
+ - **三命通会 7 条**(`engine/classics.js` 登记 `sanming` 书目):论正官、论正财、论印绶、论食神、论伤官、论阳刃、论建禄各一条,原文照录通行本、逐条给典藏网章节链接,白话释义自撰。选条标准只有一条——与「格局取用」直接相关;神煞、女命、六亲等卷暂不录入。
952
+ - **同格两书并列**:同一个「月令格」,先取《子平真诠》那一条(讲怎么用:顺逆、成败、救应),再取《三命通会》同格一条作对照(讲怎么取、怕什么)。例如正官格:子平真诠讲「刑冲破害为忌、生之护之为喜」,三命通会讲「六格之首,止许一位,多则不宜」。两条各给一句 why,不合并、不调和成一句断语。
953
+ - **条数上限 5**:格局两条 + 气候两条 + 用神总纲一条,正好把默认位占满;未匹配到两书同格时只出一条,不硬凑。
954
+ - **面板书名修正**(`src/panel-kit.js`):此前面板把非子平真诠的条目一律标成「滴天髓」,接入第三本后会串成「滴天髓·卷六·论正财」;改为按书目映射书名,`test/sanming.test.mjs` 钉住这一点。
955
+ - **知识库**:新增 `bazi-sanming-duizhao`(两书分工:一重「用」、一重「取」与「忌」,并列而不合并),全库 **45 条**。
956
+ - **口径**:只录与格局取用直接相关的七条,不声称覆盖全书;两书成书年代与流派不同,用语有出入,照录通行本、不做校勘改字,也不替两家调和。
957
+ - **测试**:新增 `test/sanming.test.mjs`(40 条)——书目与七条完整性、原文逐字抽检、七格「子平在前、三命在后」的对照选取、why 文案、上限与去重、确定性与 limit、摘要/解释层/面板三处可见、知识卡。`test/classic-quotes.test.mjs` 同步改为三书、条目 ≥26、单盘取 2–5 条。统计 **79 个测试文件 / 2571 条断言**,七道闸全绿。
958
+
959
+ ## 0.36.0(已并入 0.38.2)
960
+
961
+ 把 `docs/知识扩展与待核实清单.md` 里登记的两处缺口补上:紫微的「三方四正一起飞」、六爻的「全卦逐爻旺衰」。0.35.x 的面板修复随这一版一起发。
962
+
963
+ - **紫微 · 三方四正复合飞化**(`engine/ziwei.js` 新增 `flyComposite`,挂 `chart.flyComposite`):单宫飞化只回答「这一宫自己去找谁」,这一层把本宫、对宫与两个三合宫共四宫的宫干四化一起摊开——四宫各化禄权科忌,共 16 条,按落宫归堆,落到同一宫就是会照。四类会聚单独成型:**双忌会**(同宫收到 ≥2 个忌)、**禄忌同宫**(禄随忌走)、**三化以上会宫**、**自化**(宫干化出去又落回本宫)。摘要加【三方四正飞化】行(会聚标签 + 四化去向按宫去重);解析新增「三方四正飞化」节,写清哪几股力会到哪一宫;白话加一句「N 股力最后挤在 X 这件事上」;面板并排 chip,悬停给飞入清单。
964
+ - **紫微 · 口径**:会聚判定只看「落在同一宫」这一条结构事实,不折分数、不断吉凶,也未叠大限流年四化;星未上盘时只记星、不记落宫(`to: null`)。三方四正四宫由命宫 +4/+8/+6 推得,与格局识别用的那一套同源。
965
+ - **六爻 · 全卦逐爻旺衰**(`engine/liuyao.js` 新增 `hexagramStrength`,挂 `result.hexStrength`):与用神旺衰同一套判定(月令五态、日辰五关系、月破/暗动/冲空),区别只在不挑用神——六爻每一爻都给一次,世应、动爻、旬空另标,并给出五态分布 `counts`、最旺/最弱爻与世应各自的状态。
966
+ - **六爻 · 不依赖用神**:此前旺衰只在取到用神时才算,没指定所问之事就一片空白;现在 `hexStrength` 在 `buildLiuyao` 之后独立计算,没给 `direction` 也能看整张卦的气。
967
+ - **六爻 · 口径**:只报状态、不折分数;「未纳入」删去「全卦逐爻的月建旺衰」,保留化进化退的实际力重、用神两现取舍、伏神出伏应期三项。
968
+ - **知识库**:新增 `ziwei-sanfang-fei`(复合飞化的会照取法与各家分歧)与 `liuyao-quanggu-shuai`(全卦旺衰与「用神只是一处落点」),并把 `ziwei-feixing` 的 note 从「未做完整飞星串连」更正为「串连与复合飞化已做、未叠大限流年」。全库 **44 条**。
969
+ - **自我介绍与讨论群(只在仓库页)**:README 文末新增「关于:一个人做的插件,欢迎来聊」——写明这是个人作品、能力有限,欢迎就断法口径、神煞取法、解析措辞进群讨论,报 bug 请带输入与结果;`docs/assets/dsh-metaphysics-group*.png` 放群二维码。**不进插件运行时**:面板与离线页不加这条提示,市场条目与 `locale` 描述也只说能力、不说作者(提醒只出现一次,在仓库 README)。市场条目与 `locale` 另补齐了 0.35–0.36 两项新能力。
970
+ - **测试**:新增 `test/ziwei-fly-triad.test.mjs`(44 条)与 `test/liuyao-hex-shuai.test.mjs`(53 条)——四化表与五态五关系都用另一套写法逐格复算(16 条飞化、12 卦 × 3 月 × 6 爻)、归堆与会聚独立过滤比对、60 张盘结构自洽且会聚非死规则、四种冲法构造验证、摘要/解析/白话/面板四处可见、旧结果兼容、确定性。统计 **78 个测试文件 / 2531 条断言**,七道闸全绿。
971
+
972
+ ## 0.35.1(已并入 0.38.2)
973
+
974
+ 修一个会让整个命理面板白屏的崩溃,并让它以后能自己把错误说出来。
975
+
976
+ - **崩溃根因**(`src/app.js`):为了给「问进对话」记住上一张盘,加了一个 `useEffect` 去写 `LAST`,但它落在 `const [result, setResult] = useState(null)` **之前**;React 首渲时读依赖数组撞上 TDZ,抛 `ReferenceError: Cannot access 'result' before initialization`,整个面板渲染失败——桌面端看到的就是「侧栏有『命理』、点开一片空白」。已把该 effect 移到 `result` 声明之后。
977
+ - **渲染兜底**(新增 `PanelGuard`,`React.Component` 的错误边界):面板里任何一层组件抛错时,把错误原文与前 14 行栈直接铺在面板上,并附「__PP / Engine / React / 版本」环境行——不再白屏,也不用开 devtools 才能报错。
978
+ - **版本可见**:构建时把 `package.json` 的版本注入 `window.__MP_VER`,侧栏标题显示为「命理 v0.35.1」;`__ModuleLoader__.load` 的模块描述里也带 `version`。以后一眼能确认应用加载的是哪份构建。
979
+ - 测试与闸门不变:**76 个测试文件 / 2434 条断言**,七道闸全绿。
980
+
981
+ ## 0.35.0(已并入 0.38.2)
982
+
983
+ 面板可以直接把提问送进对话窗了:排完盘点「问进对话」,这张盘的摘要和你的问题会变成一条正常的用户消息,由对话里的模型接着答。
984
+
985
+ - **提问模板**(`engine/followup.js` 新增 `askPrompt`):四段——一句说明(不用重排盘)、`体系 / 所问` 两行、`——盘面摘要——`(取 `compute` 的 `summary`,超 3000 字截断并标「摘要已截断」)、`——回答要求——`(引到具体柱/宫/爻、没依据就说「这盘里看不出来」、不给绝对化断言)。只做文本组装,不调模型、不改盘,返回 `{text, question, system, label, chars, truncated}`。
986
+ - **对话桥**(`src/app.js`):往会话作用域槽位 `conversation.input.right` 注册一个不画界面的组件,从 slot props 取 `inputActions`;点按钮时 `setDraft(text)` 写草稿再 `submit()`,走输入框正常的回车路径——有回合在跑时排队,不打断当前回答。桥没挂上(插件刚装、还没重启,或 Harness 改了槽位名)时退回复制剪贴板并提示,不报错。
987
+ - **按钮位置**:结果卡下方的追问行,「追问」(本地按盘面字段直接答)旁边多一个「问进对话」,两者共用同一个问题输入框。
988
+ - **离线页不动**:`命理排盘.html` 没有 Harness 对话窗,所以只有「追问」,不出现这个按钮。
989
+ - 测试:新增 `test/ask-prompt.test.mjs`(46 条:字段结构、体系名翻译、问题原样带入、摘要截断与占位、六套体系各跑一遍、无绝对化表述、传 null 不抛、确定性);`test/client-bundle.test.mjs` 增加对话桥注册与「提问 → setDraft → submit」源码通路的断言(现在注册三个槽)。
990
+ - 统计:**76 个测试文件 / 2431 条断言**(当时),七道闸全绿。
991
+
992
+ # 更新记录
993
+
994
+ 版本按「一组可感知的改动」发,README 与市场条目描述随能力同步。
995
+
996
+ 0.23.0–0.33.0 都只提交在本地、没有单独发到 npm;这些内容随 **0.34.0** 一并发布。npm 上的 latest 从 0.22.0 直接跳到 0.34.0,`npm i dsh-metaphysics` 装到的就是这一版。
997
+
998
+ 0.35.0–0.38.1 同样只提交在本地;这些内容随 **0.38.2** 一并发布(2026-10-29),npm 上的 latest 从 0.34.0 直接跳到 0.38.2。
999
+
1000
+ 0.39.0–0.46.4 同样只提交在本地;这些内容随 **0.46.5** 一并发布(2026-10-30),npm 上的 latest 从 0.38.2 直接跳到 0.46.5。
1001
+
1002
+ 0.47.0–0.50.0 同样只提交在本地;这些内容随 **0.50.1** 一并发布(2026-10-30),npm 上的 latest 从 0.46.5 跳到 0.50.1。
1003
+
1004
+ ## 0.34.0(已发布)
1005
+
1006
+ 六爻补上**用神旺衰**:月建给这一段时令的气,日辰给当天的扶克。此前用神只算到「落在哪一爻、与卦体怎么对」,旺不旺一律写「仍要月建日辰」,等于把最关键的一半留白。
1007
+
1008
+ - **月令五态**:爻五行与月支五行同气为旺、受月令生为相、生月令为休、克月令为囚、被月令克为死(`monthStateOf`)。
1009
+ - **日辰五关系**:站在爻这一边说——日辰生我为「日生」、克我为「日克」、同气为「比和」,反过来是我泄日辰(「泄」)或我耗日辰(「耗」)(`dayRelationOf`)。
1010
+ - **三种冲法分开命名**:月建冲爻为**月破**,日辰冲静爻为**暗动**,日辰冲旬空之爻为**冲空**,日辰冲动爻为**逢日辰冲**;不再混成一句「被冲」。
1011
+ - **月建从哪来**:给了 `datetime`(或 `asOf`)就按节气换月、与八字同源(复用奇门的 `buildSnapshot`)取月支;没给时间就不编月建,只报日辰那一半,摘要里也看不出凭空多出的月份。
1012
+ - **四处可见**:摘要加「用神旺衰:月建 午(火) 用神月建相 · 用神与日辰比和」;解析「用神落位与卦体」节加「时令对用神」段(逐爻写月建态与日辰关系、冲法);面板加一排旺衰 chip(旺/相/得日辰生用 ok 色,死/囚/月破/受日辰克/泄/耗用 warn 色);白话加一句「眼下这阵子对这件事是帮着的/不太帮忙/有帮有压」。
1013
+ - **口径**:这一层只报状态标签,不折成分数、不断成败;全卦逐爻的旺衰仍未做(现在只算到用神那几爻),化进化退叠上月建日辰后的实际力重也仍未做。
1014
+ - **知识库**:新增 `liuyao-yongshen-shuai`(variant)讲五态、五关系与三种冲法,note 写明各家对月破/暗动/冲空取法不完全一致。全库 **42 条**。
1015
+ - **发版工具**:新增 `tools/verify-publish.mjs` 与 `--verify-only` 模式——核对以「tarball 能下载、字节与 registry 记的 shasum 一致、关键文件在包里」为准,因为 npm 会先让版本条目可见、附件晚几分钟才落盘(0.34.0 发布时就撞上过这段空窗,`npm publish` 的成功字样并不作数)。
1016
+ - **测试**:新增 `test/liuyao-shuai.test.mjs`(52 条)——地支五行 12 支、月令五态与日辰关系各 144 格逐格用另一套写法复算、12 张静卦 × 3 个月建逐爻复算、月破/暗动/冲空/逢日辰冲四种冲法各自构造验证、标签次序、缺月建与缺用神的退化路径、摘要/解析/面板/白话四处可见、旧结果(无 `useGodStrength`)不炸、确定性。统计 **75 个测试文件 / 2379 条断言**(含发布核对工具的 35 条自测)。
1017
+
1018
+ ## 0.33.0
1019
+
1020
+ 奇门补上**天盘干的两层**:干对月令的旺衰,以及干与所落宫的生克。此前旺衰只算门与星,干只出现在击刑/入墓这类硬条件里,落宫关系(干与宫谁克谁)完全没说。
1021
+
1022
+ - **干宫生克**:新增 `stemPalaceRelation(stem, palace)`(`engine/qimen.js`),只吃「天干五行 + 洛书宫五行」,输出 干克宫 / 宫克干 / 干生宫 / 宫生干 / 比和 五种,附五行与一句说明;与门宫关系(门迫、宫制门)并列,**各说各的、不折成一个分数**,两者同时成立时分别列出。
1023
+ - **干旺衰**:`STEM_ELEMENT`(甲乙木、丙丁火、戊己土、庚辛金、壬癸水)并入同一套旺相休囚死判定;每宫多 `stemElement` / `stemRelation` / `stemState` 三个字段,中五宫同样有(无门但干与星照算),汇总到 `states.stem`。
1024
+ - **三处可见**:摘要【旺衰】行改为「门 … 星 … 干 …」;解读「月令旺衰」段加入天盘干一行与「干宫的落宫关系另算:宫克干 9宫辛、2宫癸;干生宫 7宫己…」;面板事实表新增**「干旺衰」「干宫生克」两行**,九宫格每格底部补干宫关系与干旺衰小字。
1025
+ - **口径**:天盘干只认三奇六仪(甲隐于六仪、盘面不出现),所以干旺衰实际覆盖 9 个符号;干宫生克是「天盘干对地盘宫」,不是天盘干对地盘干的**十干克应**——后者 100 组仍未做(各家措辞不一,需先定底本)。
1026
+ - **知识库**:`qimen-wangshuai` 扩写为「门、星与天盘干」;新增 `qimen-gan-shengke`(variant)讲干宫五态与「不折分数」,note 写明各家取象宽窄不一、十干克应未做。全库 **41 条**(诸家一致 15 / 各家有异说 25 / 待核实 1)。
1027
+ - **测试**:新增 `test/qimen-gan.test.mjs`(53 条)——用天干五行与宫五行重推 10 干 × 9 宫 = 90 组全部复算;合成盘验五侧与缺参;扫 60 个真实盘逐宫核 `stemElement` / `stemRelation` / `stemState`(含中五宫),要求 9 个天盘干、五种干宫关系、五种状态都出现(防死表);`states.stem` 与逐宫一致;三处可见 + 转义;旧结果(无 stemState/stemRelation)不炸;确定性。统计 **73 个测试文件 / 2292 条断言**。
1028
+
1029
+ ## 0.32.0
1030
+
1031
+ 八字大运补上**交运时刻(日 / 时辰级)**——此前只有「几岁几月起运」,交运年份在边界处可能差一年内;清单里的 `bazi-dayun-jiaoqi` 从「待核实」转成「各家有异说」。
1032
+
1033
+ - **口径**:三日折一年。交运时刻 = 出生时刻 + 「出生 → 起运那一侧节令」的真实天数 × 365.2422/3(≈121.7474)。这一条比例同时兑现古法三条换算——3 日折 1 年、1 日折 4 个月(≈121.75 天)、1 时辰折 10 日(≈10.15 天);顺排数到下一节、逆排数到上一节。
1034
+ - **每步大运**:在「同月同日同时刻」换,公历闰日(2 月 29 日交运)十年后退到 2 月 28 日;每步带 `fromDate` / `toDate`,八步首尾相接。
1035
+ - **结果字段**:`dayun.jiao = { at, jd, scaleDaysPerDay, yearDays, spanDays, from:{name,time}, frame, offsetMinutes, note }`,旧的 `dayun.startAge` 与 `toNextJieDays` 原样保留(向后兼容);交运时刻与四柱同口径(真太阳时盘上就是真太阳时,`frame` 写明)。
1036
+ - **三处可见**:摘要「大运:… 起运;交运 1998-08-08 02:51(平太阳时,距芒种 24.7197 天,三日折一年)」;解读「时间窗」节首行给交运时刻与换算说明,大运表新增**「交运」列**;面板运势曲线头部与页脚写交运时刻,大运 chip 的悬停标题带该步交运日期。
1037
+ - **知识库**:`bazi-dayun-jiaoqi` 由 todo 改写为 variant——讲清放大口径、同月同日同时刻换、闰日退位,并注明各家对「一年折几日」取法不一(本插件固定 365.2422 日,与按 360 日折算的流派会差一两天)。全库仍 40 条(诸家一致 15 / 各家有异说 24 / 待核实 1)。
1038
+ - **测试**:新增 `test/bazi-jiaoyun.test.mjs`(58 条)——比例与三条换算、用 `partsToJd` 独立复算偏移、顺逆取节令、八步相接与每步 10 年、闰日退位(1987-10-10 盘交运 1988-02-29 → 1998-02-28)、22 个盘的全日期合法性扫描、真太阳时口径、四处可见、旧结果兼容、确定性。`test/report.test.mjs` 的大运表断言改为按表头取列号(加列不再让它失败)。统计 **72 个测试文件 / 2239 条断言**。
1039
+
1040
+ ## 0.31.0
1041
+
1042
+ 新增第十九套体系:**十六型人格(mbti)**——一份 MBTI **风格**的 24 题问卷。这不是命理,是用户点名要的「isfp / infp 这种问答判断」;口径上单独写清它**不是官方 MBTI 量表**(题目、计分、常模都是自建的,不与任何商业量表对齐),结果只作自我参照。
1043
+
1044
+ - 新模块 `engine/mbti.js`(纯 ESM、零依赖、确定性计算):`DIMENSIONS`(EI/SN/TF/JP 四维,各带两侧白话与平手侧 I/N/F/P)、`QUESTIONS`(24 题,四维各 6 题,左右交错)、`FUNCTION_STACKS`(16 型 → 四功能码)、`FUNCTIONS`(八种认知功能各一句)、`TYPES`(16 型文案:称号、关键词、一句话、3 条优势、2 条留意、工作/关系/学习/课题)、`mbtiPaper()`(发卷)、`buildMbti({ answers })`(计分)。
1045
+ - **计分**:每题净分 =(分数 − 3)× 侧向(题目的 `side` 是该题「像我」时的加分侧),维度净分大于 0 取左字母、小于 0 取右字母、= 0 按平手侧取并标「临界」;强度按「净分 / (答数 × 2)」分四档(临界 ≤12%、轻微 ≤30%、明显 ≤60%、很强)。跳过某题传 `null`(也接受 `''`)不计入分母,**至少答 12 题**才出口径;非数组或超过 24 个报 `E_INPUT`,分值不是 1–5 整数报 `E_RANGE`。
1046
+ - **三处可见**:`compute({ system:'mbti' })` 不给 `answers` 时先返回 24 道题与量表说明;给了就返回类型 + 四维强度 + 认知功能栈 + 工作/关系/学习/课题;摘要分节写【十六型人格】【四维】【优势】【留意】【课题】【认知功能】【工作】【关系】【学习】与末行口径声明。
1047
+ - **面板与独立页**:侧栏新增「人格」tab(`src/app.js`),独立页新增 `data-tab="mbti"` 与 `#for-mbti` 输入块(`tools/build-html.mjs`),两处都是「24 个分数(1–5,空格或逗号分隔;留空先发问卷)」一个输入框;结果由 `pp.mbtiHTML` 渲染成四维强度条 + 双栏优势/留意 + 认知功能 chips + 四段白话,问卷态则列 24 题清单。tab 从 18 个变 19 个,`test/standalone.test.mjs` 的 tab 清单断言同步。
1048
+ - **工具 schema**:`system` enum 与描述加入 `mbti`,新增 `answers` 参数(24 个 1–5 整数,可含 `null`);`locale/en.json` 与 `zh.json` 的体系数从十八/十套速查改为十九/十一套,并点名十六型人格。
1049
+ - **不进知识库**:十六型人格不属命理体系、也没接解读层(`interpret()` 不处理它),所以 `engine/interpret-knowledge.js` 仍是 40 条;它的口径声明写在结果自身的 `note` 与 README「精度与口径」里。
1050
+ - 测试 `test/mbti.test.mjs` 63 条:问卷结构(24 题、四维各 6 题、左右两侧题数相同、题号唯一、平手侧齐全);试卷模式;**四组样例 × 四维独立复算**(另写「左分 − 右分」实现核净分、取值与类型);强度四档边界;全左=ESTJ、全右=INFP、全 3 分按平手取 INFP;16 型全覆盖且每型文案齐全(3 优势 / 2 留意 / 四场景)、功能栈 4 个合法码;入参校验 8 类;跳题按维度扣减答数、整维跳过标「未作答」;摘要与面板三处可见、转义、旧结果不炸;确定性与「同维同侧换题序不改分」。统计 **71 个测试文件 / 2181 条断言**。
1051
+
1052
+ ## 0.30.0(待发布)
1053
+
1054
+ 六爻的**用神落位与卦体联动**:以前解释层只有一句「问工作看官鬼」,并没有真的把用神取出来,所以「用神持世」「用神化退」「用神在六冲卦」这些话都无从对上。现在用神会真的落到某一爻上,再与卦体、动变、旬空串起来看。
1055
+
1056
+ - `engine/liuyao.js` 新增 `YONGSHEN_RULES`(七档取用)、`yongshenOf(result, { direction, gender, liuqin })`、`PURE_BY_PALACE`(宫 → 首卦,供伏神取用)、飞伏生克表 `WUXING_SAY`/`RELATION_LABEL`。
1057
+ - **取用口径**:求财与男命妻缘看妻财、工作职位考核看官鬼、文书合同学历看父母、健康以官鬼为病(子孙为医药)、出行以世爻为用、感情男看妻财女看官鬼;未指明所问之事则不取用神,只给提示,不硬凑。
1058
+ - **用神不上卦就取伏神**:回到本宫首卦(八纯卦)找同六亲的爻位,列出伏神与飞神,并按五行标出「飞生伏 / 伏生飞 / 飞克伏 / 伏克飞 / 比和」;首卦同一六亲两现时标「伏神两现」,两句都列出来、**不代选**,也不出出伏日期。
1059
+ - **与卦体联动**:六冲卦(主散)、六合卦(主成)、变六冲、变六合、内外卦伏吟、内外卦反吟(并注明来源是地支全冲还是八卦正对)、用神化进 / 化退、用神旬空、用神持世 / 临应 / 发动。标签始终挂「用神」二字,避免把全卦的动势误当成用神的处境。
1060
+ - **四处可见**:摘要新增 `用神:官鬼(工作、职位、考核)→ 2爻甲寅木(内卦)` 与 `用神联动:…`;解析在「卦体关系」之后新增「用神落位与卦体」节;面板在卦体 chips 之后加用神 chip 行;白话直答与整段白话各带一句「你问的这件事,在卦里对应第 2 爻」。
1061
+ - 知识库按实现重写 `liuyao-yongshen`(七档取用,settled)与 `liuyao-fushen`(伏神取法与两现不代选,variant+note),全库 **40 条**(15 诸家一致 / 23 异说 / 2 待核实)。
1062
+ - 测试 `test/liuyao-yongshen.test.mjs` 54 条:七档取用与感情分男女、出行用世;64 卦 × 5 档取用位置逐一核;伏神用 classics.json 里 **56 条带「缺爻」标注的卦例**对拍(伏神位必须等于本宫首卦同位,且与典籍原录的缺爻一致,100 处命中);飞伏生克方向独立按五行复算;卦体联动标签两侧都验;旬空两侧都验;摘要/解析/面板/白话四处可见;旧结果(无 `useGod`)不炸。统计 **70 个测试文件 / 2118 条断言**(当时)。
1063
+
1064
+ ## 0.29.0(待发布)
1065
+
1066
+ 紫微的**四化飞星串连**:宫干定四化、四化定落宫,再顺着这条化从落宫接着飞下去——把「命宫化忌进父母宫,父母宫又化忌进福德宫」这种逐宫传递,一路跟到它绕回来为止。
1067
+
1068
+ - `engine/ziwei.js` 新增 `FLY_TYPES`、`flyStarOf(stem, type)`、`flyStars(chart)`、`flyChain(chart, { from, type, maxSteps })`、`flyChains(chart, { from })`;`buildZiwei()` 结果新增 `fly`(12 宫 × 四化 = 48 条飞化)与 `flyChains`(命宫出发的四支链)。
1069
+ - **两条口径**:①飞化只认宫干四化表(中州派表,庚干作太阳禄、武曲权、太阴科、天同忌),星落在哪一宫就写哪一宫,落回本宫记**自化**;②串连只跟**同一支化**逐宫跳,最多 12 步,回到走过的宫即记「成环」。因为「一个宫 → 一个宫」是函数映射,完整盘上每条链必然成环——实测链长为 1、3、4、5、6 步。
1070
+ - **三处可见**:摘要新增 `【命宫飞星】禄:命宫→官禄→父母→命宫(成环)…`;解析在「四化」之后新增「四化飞星」节,逐跳写 `命宫(丙)化忌廉贞→父母`、点出成环与自化,并声明「这一层只描方向与牵引,不断吉凶」;面板在四化 chips 之后加四支飞化 chip(`飞忌 命→父母→福德→财帛→交友→父母↺`,title 给逐跳依据)。白话直答也带一句「这几件事是连着转的」。
1071
+ - 知识库新增 2 条:`ziwei-feixing`(飞星派 vs 三合派、庚干异说,标 `variant`)、`ziwei-jichuanji`(串连走几跳、借对宫飞化各派不一,本插件走满 12 宫或成环即停,标 `variant`)。
1072
+ - 测试 `test/ziwei-fly.test.mjs` 42 条:测试内**独立录入**十天干四化表核 40 条;固定盘 48 条飞化的落宫/地支/自化与盘面 `selfHua` 两处互证;四支链逐步核「宫干 → 化星 → 落宫」与首尾相接;换一张盘核 12 宫出发全成环;固定盘回归快照(禄/权/科/忌四条路径逐字);摘要/解读/白话/面板三处可见;旧结果(缺 `fly`)不炸。统计 **69 个测试文件 / 2064 条断言**。
1073
+
1074
+ ## 0.28.0(待发布)
1075
+
1076
+ 离线单文件页 `命理排盘.html` 改为**随 npm 包分发**:之前它只是本地产物(默认写到包目录之外),订阅者装完插件手里并没有这份页面;现在它就在包里。
1077
+
1078
+ - `tools/build-html.mjs` 的默认输出从 `path.resolve(root, '..', '命理排盘.html')` 改为 `path.resolve(root, '命理排盘.html')`——写进包根,`--out <路径>` 仍可另存(例如同步桌面那份手边的拷贝)。
1079
+ - `package.json` 的 `files` 增加 `命理排盘.html`,`exports` 增加 `"./命理排盘.html"`:既会被 npm 发出去,也能用 `require.resolve('dsh-metaphysics/命理排盘.html')` 拿到绝对路径。
1080
+ - 重新生成一份进包:`node tools/build-html.mjs` → 689907 字符 / 887419 字节(UTF-8),单文件零依赖,十八个 tab 齐全。外部 URL 只有三类:仓库链接、典籍出处链接(点开才联网)、可选的地理编码在线查询。
1081
+ - **介绍同步**:`README.md` 特性表加「离线单文件页(随包分发)」并新增小节,写明包内路径、`require.resolve` 用法、与面板同源同版本、以及只在这两处会联网;`SUBMIT.md` 与市场条目 `submit/xuanfu-web__dsh-metaphysics.yml` 的 en/zh 描述都补上这一句。
1082
+ - 测试 `test/standalone.test.mjs` 新增 4 条:`files` 里带离线页、`exports` 能解析、**仓库根那份与 `page()` 逐字相同**(防止改了源码忘了重建、把旧页面发给订阅者)、构建默认目标在包根而不是包外。统计 **68 个测试文件 / 2022 条断言**。
1083
+
1084
+ ## 0.27.0(待发布)
1085
+
1086
+ 六爻的「化进神 / 化退神」:动爻变出的地支与本爻同五行、且在顺次上往前一步,这一爻就有后劲;倒着退一步则渐消。
1087
+
1088
+ - `engine/liuyao.js` 新增 `jinTuiOf(from, to)`、常量 `JIN_TUI_PAIRS` 与 `JIN_OF`/`TUI_OF` 两张单向表;`bodyRelations()` 返回值新增 `jinTui: [{ position, from, to, type: '进'|'退' }]`。
1089
+ - **判定口径**:八对顺次——木 寅→卯、火 巳→午、金 申→酉、水 亥→子,土四支成环 丑→辰→未→戌→丑。同五行但不相邻(如寅→辰)不算;同支不变不算;跨五行不算。
1090
+ - `bodyLabels()` 在爻伏吟 / 爻反吟之后追加「化进神 5、6」「化退神 4」(进在前),面板 / 摘要 / 解读 / 白话读同一份标签。
1091
+ - **三处可见**:摘要「卦体:」行带化进 / 化退;「解读」的「卦体关系」节逐爻写清本支→变支并声明「同一爻化进,也得看用神旺不旺」;面板 chip 化进用 ok 色、化退用 warn 色。
1092
+ - 知识库新增 2 条:`liuyao-jintui`(settled,机制与八对表)、`liuyao-jintui-yong`(variant,讲用神化进为得力 / 忌神化进为患加剧,并注明土之进退次序各家不完全一致)。
1093
+ - 测试新增 `test/liuyao-jintui.test.mjs` 49 条:五行分组独立生成八对进神再与 12×12 全枚举重算比对、12 条语料卦例逐字对拍、静卦与跨五行不硬凑、摘要 / 面板 chip / 旧结果兼容。`test/liuyao-body.test.mjs` 的 23 条对拍改为只核卦体标签(化进 / 化退另由新测试负责)。统计 **68 个测试文件 / 2018 条断言**。
1094
+
1095
+ ## 0.26.0(当时)
1096
+
1097
+ 奇门的「月令旺衰」:八门与九星各自对月支五行分旺、相、休、囚、死,回答「这个符号当下有多少气」。
1098
+
1099
+ - `engine/qimen.js` 新增 `monthState(element, monthElement)`、`monthElementOf(branch)`、`groupByState(items, monthElement)` 与只读表 `QIMEN_STATE_TABLES`(门/星/月支三张五行表)。
1100
+ - **判定口径**:与月令同气为旺、月令所生为相、生月令为休、克月令为囚、被月令克为死。以月支五行为尺(寅卯木、巳午火、申酉金、亥子水、辰戌丑未土),八门与九星各用自己的五行去对;月令取四柱月支,与节气月同一口径。
1101
+ - 排盘结果新增 `month: { branch, element }` 与 `states: { gate: {旺,相,休,囚,死}, star: … }`;每个宫多 `gateState` / `starState`(中五宫只有星的)。
1102
+ - **三处可见**:摘要多一行「【旺衰】月令 午(火) 门 旺 景门 相 死门/生门 …」;「解读」新增「月令旺衰」节,列出五态归属、五态定义,并声明这一层只说明力量强弱、不折吉凶(门旺而宫克门仍受制);面板奇门盘下方键值表加「月令」「门旺衰」「星旺衰」三行。
1103
+ - 知识库新增 2 条(`qimen-wangshuai` 为 settled,`qimen-wangshuai-yong` 标 variant 并写明「按时令/落宫论」的流派差异)。
1104
+ - 测试新增 `test/qimen-wangshuai.test.mjs` 36 条:三张表与传世说法对拍、五行对月令的组合全部用测试内独立生克表重算、归堆不重不漏、60 个真实盘逐宫核对门/星状态与月令来源、五态在真实盘里都能出现、摘要/解读/面板三处接线、旧结果缺字段不炸。统计 **67 个测试文件 / 1969 条断言**。
1105
+
1106
+ ## 0.25.0(当时)
1107
+
1108
+ 奇门的「宫位条件」补齐两块:六仪击刑、三奇入墓——和门迫一样,都是天盘干落到某个宫就成立的硬条件,只作条件、不打分。
1109
+
1110
+ - `engine/qimen.js` 新增 `jiXingOf()` / `ruMuOf()` 与只读表 `QIMEN_CONDITION_TABLES`,排盘结果多一个 `conditions: { jiXing, ruMu }`(每项 `{palace, stem, zhi, basis}`)。
1111
+ - **判定口径**:
1112
+ - 击刑按地支相刑定宫:甲子戊震三(子刑卯)、甲戌己坤二(戌刑未)、甲申庚艮八(申刑寅)、甲午辛离九(午自刑)、甲辰壬巽四(辰自刑)、甲寅癸巽四(寅刑巳)。只判天盘六仪,地盘不计。
1113
+ - 入墓按五行墓库定宫:乙木墓未(坤二)、丙丁火墓戌(乾六)。只判天盘三奇;六仪、八门、九星的入墓说法不统一,留白。
1114
+ - **三处可见**:摘要多一行「【宫位条件】击刑 … 入墓 …」;「解读」的「宫位条件」段把门迫/宫制门/击刑/入墓并列,每条带依据(如「甲午辛,午自刑」),并声明不自动等同于用神受制;面板奇门盘下方键值表加「击刑」「入墓」两行。
1115
+ - 知识库新增 2 条(`qimen-jixing` / `qimen-rumu`,均标 variant 并写明流派差异)。
1116
+ - 测试新增 `test/qimen-rules.test.mjs` 49 条:表与「地支相刑 → 该支所在宫」的独立推导逐条对拍、合成宫位验成立/不成立两侧、60 个真实盘扫查(六仪与三奇都能触发,防表变死数据;所标之宫与盘中天盘干一致)、摘要/解读/面板三处接线、旧结果缺 `conditions` 不炸。统计 **66 个测试文件 / 1930 条断言**。
1117
+
1118
+ ## 0.24.0(当时)
1119
+
1120
+ 六爻多了「卦体」这一层:六冲卦、六合卦、卦伏吟、卦反吟、爻伏吟、爻反吟,全部由纳甲地支实配推导,并用《增删卜易》体例的 23 条带断语卦例逐条对拍。
1121
+
1122
+ - `engine/liuyao.js` 新增 `hexBody()` / `bodyRelations()` / `bodyLabels()`:结果里多一个 `body` 字段(`ben` / `bian` 的六冲六合、`fuYin`、`fanYin.by: ['chong'|'pair']`、`yaoFuYin`、`yaoFanYin`),并挂 `body.labels` 供面板与文本共用同一份措辞。
1123
+ - **判定口径(可复核)**:
1124
+ - 六冲卦 = 六爻地支正好配成子午、寅申、辰戌三组对冲。按纳甲实排共 **10 支**:八纯卦 + 天雷无妄 + 雷天大壮(传统只认八纯,故知识条目按 variant 写并注明分歧)。
1125
+ - 六合卦 = 配成子丑、寅亥、卯戌、辰酉、巳申、午未三组相合,正好 **8 支**,与传世名单完全吻合;六冲与六合无交集,重支之卦(如雷水解)不判。
1126
+ - 卦伏吟 = 变卦某宫三支与本卦对应宫逐位相同,且**卦确实变了**;纳甲上只有乾震共用子寅辰/午申戌,所以只会出在乾↔震互换。
1127
+ - 卦反吟 = 地支三爻全冲,或本卦之宫与变卦之宫在后天八卦上正对(乾巽/坎离/艮坤/震兑);爻伏吟、爻反吟按动爻本支与变支同支/相冲判。
1128
+ - **三处可见**:摘要末尾「卦体:」一行;「解析与详解」新增「卦体关系」一节(讲聚散、原地、反复,并声明「标签只说明动势,吉凶仍归用神」),整体维度「依据」加一行卦体;面板六爻卡在爻线下方加 chip 行。
1129
+ - 白话层(直答 / 说人话)各补一句卦体的话;知识库新增 4 条(`liuyao-liuchong` / `liuyao-liuhe` / `liuyao-fanyin` / `liuyao-fuyin`)。
1130
+ - 测试新增 `test/liuyao-body.test.mjs` 63 条:六合 8 支与传世表对拍、六冲 10 支(含「只认八纯」的差异说明)、伏吟「卦未变不算伏吟」回归、反吟两路分判、23 条卦例逐字对拍;统计 **65 个测试文件 / 1881 条断言**(当时)。
1131
+
1132
+ ## 0.23.0(未单独发布,并入 0.34.0)
1133
+
1134
+ 八字结果里多了「古籍原文」:格局、十神喜忌、调候三条线,各引原书一句,并附白话释义与出处。
1135
+
1136
+ - 新增 `engine/classics.js`:**19 条**原文摘句——`子平真诠` 10 章(论用神、论用神配气候得失、论正官、论财、论印绶、论食神、论偏官、论伤官、论阳刃、论建禄月劫)+ `滴天髓` 通神论 9 条(寒暖、燥湿、衰旺、中和、官杀、伤官、月令、体用、精神),照录中华典藏网通行本,逐条带章名与 url。
1137
+ - **匹配规则明确**:先按月令格局取对应十神章(如偏财格 → 论财),再按气候取《滴天髓》寒暖 / 燥湿,再补《论用神配气候得失》,最后以《论用神》兜底;去重后限 4 条,每条写明「为什么取这条」。
1138
+ - **三处可见**:八字摘要末尾【古籍】四行;「解析与详解」新增「古籍原文」一节;面板八字卡在寒暖/穷通之后新增古籍块(书名·章、原句、白话释义)。
1139
+ - 口径:原文照录通行本(各本有异文),释义为白话自撰;不把原句改写成结论,也不合并不同流派的说法。
1140
+ - 测试新增 `test/classic-quotes.test.mjs` 34 条(19 条完整性、10 处原文定值抽检、匹配规则、解释层/摘要/面板接线);统计 **64 个测试文件 / 1818 条断言**。
1141
+
1142
+ ## 0.22.0(已发布)
1143
+
1144
+ 起名不再只是「未收录」三个字:逐字给出五行、判定与可换字。
1145
+
1146
+ - 字库 190 → **391 字**(常用名用字为主,按木/火/土/金/水五行分段):丰(火)、秋(金,秋收成熟)、林(木)这类常见字不再掉「未收录」。
1147
+ - **逐字判定**:`assessName` 每个字返回五行、释义、性别倾向、来源(`lib` 自建字库 / `user` 你传入的 `charElements` / `none` 未收录)、是否合喜用;未收录的字不猜五行,但会给出**同喜用五行的可换字**(如「秋」不合喜用 → 可换坤(土)、垚(土))。
1148
+ - **不替用户下判断**:没给生辰时 `favorable` 返回 `null`(不判合不合),结论分「无生辰 / 全未收录 / 全合 / 部分合 / 全不合」五档,并把统计(几个字、几个已知、几个合喜用、字库共几字)写出来。
1149
+ - **候选去同质化**:`generateNames` 三轮选名(新字 + 新五行组合 → 新字 → 放开)× 字库顺序打散 × 两字异行优先,避免「清一色梓桐」。同一盘 8 个候选示例:李炎梓(火木)、李坤桐(土木)、李楠灿(木火)、李楷垚(木土)、李培炫(土火)、李炜城(火土)、李柏松(木木)、李煜烨(火火)。
1150
+ - **面板**新增起名卡(`pp.nameHTML`):逐字大字 + 五行 chip + 来源徽标 + 合/不合喜用 + 可换字、八字与喜用一行、结论;生成卡按「名 + 五行 chips + 释义」逐行排,不再是纯文本块。
1151
+ - 工具参数新增 `charElements`(`{字: 木|火|土|金|水}`,自定义字五行,未收录字也能参与判定);`name` 的出生信息允许省 `datetime` 用 `year/month/day`。
1152
+ - 测试新增 `test/names.test.mjs` 39 条(字库规模与去重、丰秋林逐字判定、未收录字 + 可换字、charElements 生效与非法忽略、无生辰不判、候选全合喜用、面板结构与接线);统计 **63 个测试文件 / 1784 条断言**。
1153
+
1154
+ ## 0.21.0(已发布)
1155
+
1156
+ 《穷通宝鉴》120 格逐条入库:同一「日主 + 月令」该取什么,书上怎么写的,全都摆出来。
1157
+
1158
+ - 新增 `engine/qiongtong.js`:十天干 × 十二月令共 120 格,每格含用神顺序(首取在前)、原文摘句、出处章号;
1159
+ - 用神顺序据通行整理表(knowyourbazi 整理表,首格为首选),原文摘句照录 [luckclub.cn](https://www.luckclub.cn/bazi/004/)《穷通宝鉴》每章首段(去掉「徐乐吾曰」评注);
1160
+ - 数据里的 `quoteStems` 是「原文首段依次提到的天干」,与整理表首取不同处可对照阅读(如正月庚金:表首取戊,原文先举丙);
1161
+ - 原文全章未见某用神字时(丁酉缺「丙」、癸未缺「壬」)直接写 note「按整理表录入,待以善本核对」,不替它圆场。
1162
+ - **取用**:调候优先时,寒暖判定定「这一盘缺什么」,穷通宝鉴定「这一格书上取什么」;两者不同向时以调候为先,界面与解释层把两套并列写出,不悄悄合并。
1163
+ - **评分**:流年天干正落在该格首取时 +0.3,次取 +0.15,理由写明「天干丙正是丑月乙日的首取(穷通宝鉴)」;该干属忌神时不给这笔分。
1164
+ - **解释层**新增「穷通宝鉴」一节:格(「乙日生于十二月」)+ 用神与首取 + 原文摘句 + 章号;「未纳入」一栏同步改成「已录 120 格,整理表口径、异文处已标 note」。
1165
+ - **面板**寒暖卡下新增穷通宝鉴块:用神 chips(首取高亮)、原文引句、章号;文本摘要「寒暖:」一行后追加「穷通:十二月乙取丙(首取丙)」。
1166
+ - 新增 `tools/qiongtong-scrape.mjs`(抓 113 章原文,缓存不入库)与 `tools/qiongtong-build.mjs`(生成 `engine/qiongtong.js`),数据可复现。
1167
+ - 测试 `test/qiongtong.test.mjs` 31 条:120 格齐全、用神字合法、原文摘句非空、月令月名一致、定值(乙丑取丙、庚寅首取戊/原文先举丙、丁酉与癸未的 note、未知输入返回 null)、1996 寒湿盘接入(detail/评分/解释/面板)。
1168
+ - 统计:62 个测试文件 / 1745 条断言;client.js 44 模块。
1169
+
1170
+ ## 0.20.0(已发布)
1171
+
1172
+ 调候(寒暖燥湿)不再是脚注:从「扶抑为主 + 一句提示」改成「调候优先 + 扶抑校验」的判定层。
1173
+
1174
+ - 新增 `engine/tiaohou.js`:按月令基础温度、全局火水比例、湿土燥土给出 **寒 / 寒湿 / 寒燥 / 湿滞 / 平 / 燥 / 燥热 / 温热** 八档气候,附温度与燥湿量化值和依据(如「季冬丑月、火0、水1.8、湿土2处」);由此定调候所取(寒湿取丙火、燥热取壬水)与所忌。偏寒偏燥明显时判「调候优先」,否则「扶抑为主」。
1175
+ - **用神仲裁**:调候所需与扶抑喜忌冲突时显式裁决并说明理由(「寒暖失衡时再补强弱也难受」),不冲突时写「两套取法同向,不必取舍」;`method` 字段改成「调候优先 + 扶抑校验」/「扶抑为主 + 调候校验」,读得出来用了哪套。
1176
+ - **评分接入调候**:流年/大运评分里,调候优先时天干地支合调候所需加权,合所忌扣权,寒局再逢水再扣(「地支子水加重寒湿」)。以 1996-01-19 盘为例:2020 庚子由「平 0.5」改为「忌 −0.8」并写明水助寒湿;2026 丙午「大吉 4.0」写明「寒湿之局得丙火,解冻」。
1177
+ - **解释层**新增「寒暖燥湿」一节:气候判定 + 体感白话(按日主五行各写一句)+ 调候取忌 + 仲裁;八字文本摘要加「寒暖:」一行。
1178
+ - **面板**在「用神」下新增寒暖卡:气候标签、调候优先徽标、寒—平—热标尺、调候取/忌/依据、白话叙述;独立页与面板共用。
1179
+ - 口径:调候由月令与全局寒暖燥湿判定,未逐条录入《穷通宝鉴》120 条;调候与扶抑的优先级各家有争论,界面与文档都写明采用的是「调候优先、扶抑校验」。
1180
+ - 测试新增 `test/tiaohou.test.mjs`(32 条:寒/热两盘、仲裁同向与冲突、评分方向与上下限、解释节、摘要行、面板卡);统计 61 个测试文件 / 1714 条断言。
1181
+
1182
+ ## 0.19.0(已发布)
1183
+
1184
+ 黄历、择日、公农历互转三处按「吉历」的用法补齐(只吸收合适的那部分,不搬它的小工具):
1185
+
1186
+ - **黄历增强**:值日十二神(黄道/黑道)、十二时辰吉凶(五鼠遁定干支 + 时家十二神,逐时标吉凶)、二十八宿(吉凶/七政/禽/宫)、胎神、财神/喜神/福神/阳贵/阴贵方位、日柱纳音、六合三合吉配生肖;值日神/二十八宿/胎神/吉神方位与 lunar-javascript 逐日对拍(60 天仅交节当日 1 处日界差异,已注明口径)。
1187
+ - **择日扩充**:事项从 13 类扩到 27 类(领证/提亲/收送聘金/满月酒/交易/投资/签订合同/搬家入宅/装修建造/试车买车/旅行/赴任/访亲友/入学…),面板与独立页按「常用 / 婚嫁 / 生活 / 建造 / 工商」五组下拉归类;打分与冲属相排除口径不变。
1188
+ - **公农历互转 `convert`**:新增体系。公历 → 农历(农历年月日、闰月、干支四柱、生肖)与农历 → 公历(闰月须显式指定,小月无三十报错),往返自洽;只知道农历生日时可先转公历再排盘。工具层与面板、独立页都已接入。
1189
+ - 面板与独立页 tab 由 17 个扩到 **18 个**;黄历 tab 有专属卡片(值日徽标、宜忌、四格、吉神方位、十二时辰吉凶网格)。
1190
+ - 测试新增 `test/tools3.test.mjs`(14 条:黄历新增字段定值、五鼠遁、十二时辰吉凶、公农历往返/闰月/报错、择日分组与冲属相排除、渲染与接线)。
1191
+
1192
+ ## 0.18.4(已发布)
1193
+
1194
+ 称骨补上**称骨歌原文**与白话释义(此前只有自撰的分档批语):
1195
+
1196
+ - 新增通行本《称骨歌》52 首(二两一钱 … 七两二钱),`CHENGGU_SONG` 按骨重(钱)索引,原文照录;
1197
+ 各版本有异文,断句标点统一为「,;,。」
1198
+ - `buildChenggu` 新增 `song` 字段:`{ text, plain, title, source }`;`plain` 是白话释义(自撰,明确不是原文),
1199
+ 超出 21–72 钱时给出「未见通行本歌诀」而不是编一首
1200
+ - 文本摘要把「歌诀」与「释义」分两段;口径里写明歌诀为通行本、释义为白话自撰
1201
+ - 新增 `PP.chengguHTML`:四项骨重表格 + 合计与分档徽标 + 歌诀(两行竖排大字)+ 释义 + 口径;
1202
+ 面板与独立页的称骨 tab 改用它(原先落到通用文本块)
1203
+ - 新增 `test/chenggu.test.mjs`(18 条):52 档齐全且都是四句、关键档位不串行、白话不是原文、
1204
+ summary 两段、渲染器四项与口径、两处界面接线
1205
+ - 统计:59 个测试文件 / 1668 条断言
1206
+
1207
+ ## 0.18.3(已发布)
1208
+
1209
+ K 线的第二轮打磨(0.18.2 之后的可读性修正):
1210
+
1211
+ - 大运段名从图顶挪到图下的条纹带里,不再和「最高/最低岁」标记抢位置;段名居中,条带随大运交替着色
1212
+ - 5 年 / 10 年均线在右缘标出末端数值,两条贴太近时自动上下错开
1213
+ - 纵轴补 0/25/50/75/100 刻度,横轴补「年龄(岁)」与「每岁一分 · 满分 100」;影线用 `clipPath`
1214
+ 夹在绘图区内,贴边的影线不再溢出
1215
+ - 新增统计条:全段均值、最好大运、最差大运、波动幅度。旺衰落在换档阈值附近时只给均值与波动,不给
1216
+ 「最好/最差大运」的顺位
1217
+ - 图高由 300 提到 322,给刻度与段名条留位
1218
+ - `test/kline.test.mjs` 增到 29 条(段名条、均线末端值、纵轴刻度、统计条、最好/最差大运)
1219
+ - 统计:58 个测试文件 / 1650 条断言
1220
+
1221
+ ## 0.18.2(已发布)
1222
+
1223
+ 人生 K 线从「等宽文本 + ASCII」升级成真正的蜡烛图,并嵌进八字结果:
1224
+
1225
+ - 新增 `PP.trendChart` / `PP.trendHTML`:实体=该岁相对上一岁的涨跌、影线=±4 分;叠 5 年 / 10 年均线、
1226
+ 大运交替底色与分界虚线(段名标顶部)、0–100 固定量程网格、年龄刻度、最高/最低岁标记;悬停看逐年
1227
+ 「多少岁 / 哪一年 / 什么干支 / 多少分 / 落在哪步大运」。颜色全走 CSS 变量,深浅色与打印跟随
1228
+ - 「人生K线」tab 不再输出纯文本摘要,直接给图 + 大运分段 chips + 高低年份;数据不足或空值时安全退回文本
1229
+ - **八字结果底部直接嵌同一张 K 线**(面板与独立页在排八字时顺带算一次 `trend`),与原有的
1230
+ 「人生运势曲线」(大运阶梯 + 流年折线)并存:曲线看趋势形态,K 线看逐年涨跌
1231
+ - 新增 `test/kline.test.mjs`(23 条):结构、坐标不越界、无 NaN、空/单点安全、旺衰边界不出高低结论、
1232
+ 两处嵌入点都在源码里
1233
+ - 统计:58 个测试文件 / 1644 条断言
1234
+
1235
+ ## 0.18.1(已发布)
1236
+
1237
+ 元数据与检索入口同步,**无运行时行为变化**:
1238
+
1239
+ - 把「玄学 / 算命 / 占卜 / 运势」加进 `package.json` 关键词与描述、`locale/*.json`、市场条目描述、README 与工具描述——之前只写「命理排盘」,用户搜「玄学」搜不到;现在搜「玄学」应能命中
1240
+ - 工具描述补一条触发条件:用户只搜「玄学」或问「有什么玄学工具」时也应介绍本插件
1241
+ - 排盘逻辑、输出与测试断言不变;仅 UA 随版本号更新(`dsh-metaphysics/0.18.1`)
1242
+
1243
+ ## 0.18.0(已发布)
1244
+
1245
+ 吸收同生态另一款命理插件「玄机阁」(dsh-xuanji,MIT)的能力:**按行为规格独立实现,不 vendor 源码、
1246
+ 不引入 iztro / lunar-javascript 依赖**,引擎仍为零外部依赖的纯 ESM。
1247
+
1248
+ ### 九套速查体系(新增)
1249
+
1250
+ 每套都有 `engine/*.js` + 工具分支 + 面板/独立页入口 + 测试,口径固定、同日同结果:
1251
+
1252
+ - **黄历 almanac**:农历、四柱干支(年柱按立春、月柱按节)、建除十二神、宜忌简表、冲煞与财喜神方位、
1253
+ 上一/下一节气、每日一卦。与 lunar-javascript 对拍四组日期(日柱/月柱/年柱/农历/建除全一致);
1254
+ 唯一差异是交节当日「上一节气」的日界口径(我们按正午判已交节),已记入 `meta.scope`
1255
+ - **择日 zeri**:13 类事项 × 建除适配打分,逐日分「推荐 / 可用 / 回避」,当事人属相冲煞日直接排除,
1256
+ 每条回避都带理由;明确是「排序引导」,不是吉凶断语
1257
+ - **称骨 chenggu**:年/月/日/时四项骨重求和与分档批语。年表按 `(农历年-4)%60` 查 60 甲子,
1258
+ 月日时各一张表;对拍公开黄历页修正了初版错表(1990-08-15 巳时应为**五两六钱**,不是五两五钱)
1259
+ - **小六壬 xiaoliuren**:时间起课(农历月/日/时三掐)与报数起课(三个 1–99),六宫吉凶与白话断语
1260
+ - **星座 star**:太阳星座档案 + 当日四维基调;基调由日期哈希确定性生成,同一天同一星座永远一致,
1261
+ 明写「不是随机数,也不是模型编的」
1262
+ - **生命数字 numerology**:生命路径数 / 生日数 / 态度数,11/22/33 主数保留,逐数给数义与课题;
1263
+ 与八字是两套口径,混问时会说明不可互相印证
1264
+ - **人生 K 线 trend**:复用八字的旺衰、大运、流年十神,按固定计分表给 1–100 岁逐年分与 K 线形态、
1265
+ 分大运 ASCII 走势、最佳/最差年份。旺衰恰好落在换档阈值(±0.3)时只给提示、不给顺位结论
1266
+ - **风水 fengshui**:八宅命卦(1900s/2000s 男女公式、立春界)、大游年四吉四凶、流年九宫飞星
1267
+ (2026 一白入中为锚)、24 山门主灶布局倾向、命宅配调停文案;`scope` 明写不含玄空各运盘与现场勘舆
1268
+ - **起名 name**:评估现有名字或生成候选名;按八字喜用五行(偏强喜克泄耗、偏弱喜生扶)匹配 241 字
1269
+ 自建字库,未收录的字如实标「未收录」。**不做五格剖象**(需康熙字典笔画)与音韵判断
1270
+
1271
+ ### 1986–1991 夏令时自动校正
1272
+
1273
+ `engine/dst.js`:中国 1986–1991 年夏季行夏令时,钟面时间比标准时快 1 小时。八字/紫微/合盘/验前事/
1274
+ 生时校正/人生 K 线/风水在排盘前统一校正,跨日时回退到前一天 23:xx 并给出 `dst.note`;
1275
+ `dst: false` 可显式关闭(出生证已是真实太阳口径时用)。修正了「夏令时出生按钟面时间排盘差一个时辰」的口径错误。
1276
+
1277
+ ### 合婚明细层(hepan 增强)
1278
+
1279
+ 原有总分与三维度**不动**,新增 `detail`:属相六合/三合/六冲/相害/相刑、天干五合、双向十神、
1280
+ 跨盘地支关系、年命纳音生克、吉凶象计数分档(上 / 中上 / 中 / 需磨合)。冲刑害一律中性叙述,不断「必分」。
1281
+
1282
+ ### 界面
1283
+
1284
+ - 面板与独立页 tab 由 8 个扩到 **17 个**:九套速查体系各有自己的最小输入;速查结果走通用 `pp.quickHTML`
1285
+ (等宽文本 + 标题),不套命盘模板
1286
+ - 八字面板补传 `verifyPast`,验前事区块终于会在面板里出现(此前只有独立页有)
1287
+ - 独立页「方法页」同步体系清单与已知边界
1288
+
1289
+ ### 视觉升级三项(沿用本次工作树)
1290
+
1291
+ 视觉升级三项,均不改计算口径、不新增判断:
1292
+
1293
+ - **色板拉开层级**:`--bg` 压深作「桌面」(`#fffdf8 → #f6f1e6`),`--card` 提到近白(`#fffefb → #fffdf8`),
1294
+ band / tri / soul / sel / link 一并拉开。`--hair` 随底色同步加深(`#efe9dc → #e9e2d3`),否则比背景还亮、
1295
+ 发丝线会变成高光。深色块用同一套逻辑(底更沉、卡片更亮)。
1296
+ 改动前 `--bg` 与 `--card` 只差 1/255,卡片与底色几乎同色,一切「卡片」都浮不起来。
1297
+ 前景色(ink / muted / red / lu / 十神组)一个未动,对比度、打印样式、可访问性不受影响
1298
+ - **人生运势曲线**:新增 `pp.curveHTML()`(渲染在八字盘「大运」节内)——大运作阶梯、流年作折线,
1299
+ 叠在同一坐标系;背景五条档位色带(绿=吉 / 灰=平 / 红=忌),标出全程最高运与最低运,
1300
+ 今年流年点加粗描边,悬停看逐年「年份(年龄)干支 档位 分值」。
1301
+ 纯内联 SVG、零依赖,颜色走 CSS 变量,深浅色自动跟随
1302
+ - 纵轴固定量程 −2.2 ~ 3.2(引擎实测 score ∈ [−2, 3.2]):固定而非自适应,不同盘之间才可比
1303
+ - 数据不足两步大运则不画(不画半张图);缺 `luck` 字段、传 null / 空对象均不崩
1304
+ - 新增 `test/curve.test.mjs` 36 条:几何不越界、色带无缝、阶梯形态、点与引擎数据对齐、
1305
+ 刻度不重叠、安全与无障碍、边界不崩
1306
+ - **三套内联 SVG 符号**(零依赖、零外部请求,一律 `currentColor` 跟随主题):
1307
+ - **爻线**:原先 span + 背景色拼接、靠 `flex gap:18%` 留阴爻间隙,字号一变间隙就飘;
1308
+ 改为 104×12 内联 SVG,间隙按画布坐标固定(两段各 43 + 间隙 18 = 104)。三种尺寸共用一份几何
1309
+ - **动爻标记**:沿用传统老阳 ○ / 老阴 ×,非动爻留同宽空位,六列对齐不抖;爻线列由 112px 放宽到 128px
1310
+ - **五行符号**:12×12 描边图标,形状取各元素最易辨识的意象(木=树 / 火=焰 / 土=「土」字骨 /
1311
+ 金=菱形 / 水=波纹),接入五行分类 chip 与用神喜忌行
1312
+ - **八卦小象**:14×10 三爻 SVG,接在梅花上下卦标题前;爻位由 `TRI_BITS` 自下而上翻转后渲染
1313
+ - 新增 `test/symbols.test.mjs` 79 条:三种尺寸几何、阴爻两段+间隙恰为满宽、八个卦逐爻位校验、
1314
+ 五条元素路径互不相同、整合到六爻/梅花/八字盘、既有结构回归护栏、无脏值无注入面
1315
+ - 全量 57 文件 / 1621 条 PASS(原 1362),`test:ci` 七道闸全绿
1316
+ - 新增 `test/tools.test.mjs` 65 条 + `test/tools2.test.mjs` 68 条:黄历对拍、择日排除冲属相、
1317
+ 称骨四项和、小六壬递推、星座边界、生命数字主数、DST 开关、人生 K 线边界、风水坐向、起名未收录字
1318
+
1319
+ ## 0.17.1(已发布)
1320
+
1321
+ 同步更新,**无运行时行为变化**:
1322
+
1323
+ - README 与仓库现状对齐:补齐奇门 / 合盘(八套体系)、0.16–0.17 的报告化与可核验能力、安装示例版本
1324
+ - CI 自检加固:新增 `tools/check-bundle.mjs` 产物自检闸(逐模块编译 client.js、核对与源码一致),`test:ci`
1325
+ 先构建再检查;`ask.test` 不再读取仓库外的生成物
1326
+ - 仅 UA 字符串随版本号更新(`dsh-metaphysics/0.17.1`),排盘逻辑与输出不变
1327
+
1328
+ ## 0.17.0(已发布)
1329
+
1330
+ 对应「晚子时开关 / 验前事 / 生时校正」三条用户反馈:
1331
+
1332
+ - **晚子时开关**:面板与独立页新增「晚子时换日」(八字/紫微/合盘)与奇门「归当日/归次日」;
1333
+ 之前引擎已支持 `lateZi` / `lateZiHourMode`,但 UI 没有暴露,用户无法自己调
1334
+ - **验前事**:工具参数 `verifyPast`(年数)+ 面板/独立页「验前事」区块——列出过去若干年的
1335
+ 流年信号(冲/合/刑、档位、十神),用户自评「准/不准/不确定」,用 `verifyFit` 算贴合度并给建议;
1336
+ **只读,不重排、不改盘**;贴合度低时先提示核对出生时间/时区/晚子时
1337
+ - **生时校正**:`engine/rectify.js` + 工具参数 `rectify`/`events`——对候选时辰逐一排盘,
1338
+ 按固定规则(事件类别 × 当年十神/关系/档位)打分,返回候选排序与并列说明;
1339
+ 规则显式可复核,明确「只缩小范围、不替代出生记录」
1340
+ - 测试:新增 `test/verify.test.mjs` 25 条;全量 53 个文件 / 1362 条 PASS
1341
+
1342
+ ## 0.16.0(已发布)
1343
+
1344
+ 报告化改版,对应与 Seeself 对比后的 R1–R8:
1345
+
1346
+ - **R1 报告骨架**:解析顶部新增「一页读懂」五条摘要(整体 / 事业 / 财富 / 感情 / 节奏);
1347
+ 目录锚点跳转;新增三张表——八字「大运表 / 流年表 / 触发事件表」、紫微「大限表 / 流年表 / 触发事件表」,
1348
+ 全部由已有引擎字段摊平,不新增判断;打印加 `break-inside:avoid` 与表格换行规则
1349
+ - **R2 证据卡**:每个维度的「依据」从一行灰字升级为可展开的 `<details>` 证据卡
1350
+ (盘面事实 + 技法标签),并给每个维度打「置信度 强/中/弱」(只按证据条数分档,不引新算法);
1351
+ 文本输出同步:依据行尾附 `置信度:…`
1352
+ - **R3 追问模式**:新增 `engine/followup.js` 与工具参数 `ask`——围绕已算好的盘回答
1353
+ 「某一年 / 某方面」的问题(如「2027 年事业怎么样」),只取盘面已有字段,不重排、不猜测;
1354
+ 找不到年份/未识别方面时明确说找不到并给出可问范围。面板与独立页都加了追问输入框
1355
+ - **R4 示例报告**:面板与独立页各加「看示例」,固定示例盘(1990-05-12 14:30 男 石家庄)
1356
+ 走与真实排盘完全相同的渲染路径,无示例专用分支
1357
+ - **R5 交叉验证层**:新增 `engine/crosscheck.js` 与工具参数 `cross`——八字 × 紫微对
1358
+ 事业/财富/感情/身体/节奏五项并列对照,标注「同向 / 有张力 / 互补」;只作对照,不合并数值
1359
+ - **R6 量化表达**:八字/紫微各加「量化口径」分节——明确量化只到档位(十神权重、宫位计数),
1360
+ 不换算金额、不给疾病诊断;新增 `test/report-extra.test.mjs` 断言不出现金额区间
1361
+ - **R7 方法与验证页**:独立页内置静态「方法与验证」(体系、对拍 128 条、测试与闸门、口径、已知边界),
1362
+ 离线可开
1363
+ - **R8 导出与分享**:面板与独立页加「导出 .md」(盘面 + 解析 + 交叉验证 + 追问),
1364
+ 独立页保留打印/存 PDF
1365
+ - 测试:新增 `test/report.test.mjs` 36 条、`test/report-extra.test.mjs` 31 条;
1366
+ 全量 52 个文件 / 1335 条 PASS
1367
+
1368
+ ## 0.15.0(已发布)
1369
+
1370
+ - **性能**:节气按需计算、牛顿初值用回归年、容差放宽;八字单盘 2.70ms → 1.60ms
1371
+ - **口径差异对照**:`engine/diff.js` + `tools/caliber-diff.mjs`,区分根因字段与连带变化
1372
+ - **白话四层**:直答 / 说人话 / 每维一句话 / 追问建议;术语按体系区分
1373
+ - **规则知识库**:28 条(出处 + 可信度 + 尚未实现清单)
1374
+ - **卦例对拍扩容**:《卜筮正宗》从 19 条扩到 **128 条**(93 成对 + 35 静卦),
1375
+ 新增核对动爻个数、缺爻(伏神)、旬空;排除的 5 条连同理由留在
1376
+ `tools/data-boshizhengzong.mjs` 的 `excluded`
1377
+ - **引擎入参守卫(P0)**:新增 `engine/validate.js` 的 `assertCivil()`,`buildBazi / buildZiwei /
1378
+ buildDaliuren / buildQimen / buildHepan / buildZiweiHepan / buildSnapshot` 入口统一校验;
1379
+ 坏入参从裸 `TypeError` 改为 `E_INPUT`,文案写清「该传什么」(15 类坏输入有契约测试)
1380
+ - 统一错误工厂 `engine/fail.js`;梅花的 datetime / 数字起卦错误也改为 `E_INPUT`
1381
+ - **缓存层统一(P0)**:新增 `engine/lru.js`(上限 + TTL + 命中率),节气瞬时/单年/三年窗口/
1382
+ 地址四处缓存改为同一工厂;`DSH_METRICS=1` 时 `renderText` 打印各缓存命中率
1383
+ (实测紫微盘 `termInstant` 命中 75%)
1384
+ - **规则表单一真源(P0 收尾)**:`engine/nayin.js`(六十甲子纳音,bazi/ziwei 共用)、
1385
+ `engine/sanhe.js`(三合四局 + 单支归属,bazi/hepan/daliuren 共用);纳甲本就在 `liuyao.js` 一份
1386
+ - `test/tables.test.mjs`:纳音 60 项与八字导出逐项一致、三合同局判定与五行等价、
1387
+ 乾为天纳甲起例,并用静态检查防止有人再把表复制回各模块
1388
+
1389
+ ## 0.14.3(已发布)
1390
+
1391
+ - **经典通例对拍**:新增 `test/fixtures/classics.json` 与 `test/classics.test.mjs`,把典籍里的规则表当作期望值来验实现——
1392
+ - 六爻:京房八宫卦序的宫属与世应(八纯上爻、一至五世依次、游魂四爻、归魂三爻),64 卦全表
1393
+ - 六壬:日干寄宫(甲寅乙辰丙戊巳丁己未庚申辛戌壬亥癸丑)、中气换将(雨水登明亥将起,12 个中气抽样)
1394
+ - 紫微:纳音定五行局、紫微天府以寅申为轴相照
1395
+ - 出处与录入方式写在 fixture 的 `meta.sources`,由 `tools/gen-classics-fixture.mjs` 生成,不从引擎输出反推
1396
+ - 说明:录入的是**通例表**(规则级),不是某本书的例课原文;例课需要可引用的原文,见 README「对拍」
1397
+ - **卦象/牌阵类也给出「依据」**:六爻列本卦/变卦、世应爻位与六亲六神、动爻、日辰、卦宫;梅花列本卦/互卦/变卦、体用与生克、动爻;六壬列课体、三传、月将、旬空与青龙/朱雀/六合/天后/白虎/子孙是否出现;塔罗列牌阵与牌位、主轴牌、正逆位计数与元素分布
1398
+ - 至此六个有维度的体系(八字/紫微/六爻/梅花/六壬/塔罗)都能核对依据;奇门走分节形态,事实本就写在 section 正文里
1399
+ - **《增删卜易》卦例对拍**:从 PDF 电子本(有文字层)录入 9 条原文卦例——「月建 + 日干支 + 本卦 → 变卦」,出处精确到章(元神忌神衰旺章第十、月将章第十六、日辰章第十七、独发章第三十一、星煞章第三十三、用神元神忌神仇神章第九)。引擎须按 64 卦表还原这一对(名字、翻爻、变卦生成)
1400
+ - 《卜筮正宗》(复城道长精校)此前是**扫描版 PDF、无文字层**;这次拿到同一版本的 **docx**(有文字层),从中提取 138 条带「占事」的卦例,99 条卦名可唯一解析,收 19 条进 `boshizhengzong`
1401
+ - 每条核对:本卦 → 变卦、卦宫(宫 + 五行,与八宫表互证)、有日期的样本还核旬空
1402
+ - 书中「空亡」与通用旬空不一致的例子(丙辰日作戌亥,应为子丑)只记卦名卦宫、不断言空亡;1 条卦宫与八宫表冲突(表格串行)不收,原因写在 fixture 的 `meta.sources`
1403
+ - 原文用字保留异体(遯/遁、干/乾),动爻**不录**——原书卦象图在 PDF 里被压成一行,位置不可靠,硬录等于造数据
1404
+ - **六爻补旬空**:`buildLiuyao` 现在输出 `xunShou`(旬首)与 `xunKong`(旬空两位),文本摘要多一行「旬首:甲午 旬空:辰巳」;六旬表与「丙辰日空子丑」都有断言
1405
+ - **双 UI 收口(第一步)**:新增 `src/core.js`,把「爻值解析」「问事体系」「数字输入」三条规则收成单一来源,`app.js` 与 `web-ui.js` 都改为调用 `window.__MPCore`;构建脚本把 core 一并打进 `client.js` 与独立 HTML
1406
+ - 单测 `test/core.test.mjs`(21 条)直接加载浏览器文件验证;`ask.test.mjs` 改为检查「单一来源 + 两端委托」
1407
+ - 表单编排(参数拼装)仍各留一份,下一步再收
1408
+ - **修合盘面板**:合盘的主方性别/出生地被漏在 `bazi|ziwei` 分支之外——0.14.1 起引擎把性别改为必填,面板点「合盘」会直接报 `你(主方)的gender 必须是 male 或 female`,看起来像"合盘不对"。现在三体系共用同一分支,合盘四柱与单盘一致(实测 庚午 辛巳 丁丑 丁未 对 庚午 辛巳 丁丑 丁未)
1409
+ - **奇门进面板**:新增「奇门」tab,起局时刻 + **换局规则**(fieldset + legend + `role="radiogroup"` 的原生 radio:拆补 / 超神接气 / 置闰,附 `details` 说明),`juMethod` 透传给引擎;盘面下新增 `qimenFactsHTML`,用 `dl > div > dt/dd` 列出局数、节气、四柱、值符、值使、旬首、空亡、驿马、换局规则、晚子时——事实与解读区的结论分开,全部走 `esc()`
1410
+ - 尚未做(下一步):三栏 Grid 布局、`<template>` 渲染、显式状态机(idle/missing_input/…)、960/1200 断点的布局断言
1411
+ - **独立页补齐合盘 / 奇门**:`命理排盘.html` 由六个 tab 变八个
1412
+ - 合盘:对方出生日期/时刻/性别/出生地 + 「合盘方式」八字/紫微切换;主方同样带性别与真太阳时,四柱与单盘一致
1413
+ - 奇门:换局规则用 `fieldset + legend + role="radiogroup"` 的原生 radio(拆补/超神接气/置闰,附 `details`),加「询问方向(定用神)」;结果 = 九宫盘 + `dl` 事实表 + 分节解读;换规则重起局、换方向只重出解读
1414
+ - `build-html` 导出 `page()` 且直接运行时才写盘,`test/standalone.test.mjs` 直接对生成源码做结构断言(24 条)
1415
+ - **解析深化:把"怎么推出来的"也写出来**
1416
+ - 八字 / 紫微新增四段:**看盘顺序**(月令→旺衰→用神→格局→大运→流年/命宫→三方→四化→大限,逐步引用实际值)、**时间窗**(当前与后续大运 + 近五年流年,带档位与理由)、**交叉校验**(喜忌分量对比、大运与流年同向/反向、调候与扶抑是否一致)、**未纳入**(没算什么、哪些流派差异会改变轻重)
1417
+ - 六爻 / 六壬补**看卦/看课顺序**(卦宫→世应→动爻→用神→日辰→变卦;月将→四课→三传→课体→神将)与**未纳入**
1418
+ - 这些段落全部由盘面数据推出,不新增断语;`test/deep.test.mjs` 41 条断言校验结构、关键步骤与"无占位值"
1419
+ - 测试:44 个文件 / 1147 条 PASS
1420
+
1421
+ ## 0.14.2 —— 口径、复现与性能(已发布)
1422
+
1423
+ - **1929 年前的节气改用当时的地方时**:`termInstantJd` 与农历共用同一套换算(1929-01-01 前为北京地方平时 UTC+7.7611,之后东八区),并顺手修正切点常量的半天偏移。此前农历切换、节气一律 +8,1929 年前出生者在交节前后约 14 分钟内可能月柱整柱错位
1424
+ - **晚子时口径统一**:`lateZi`(八字/六壬)与 `lateZiHourMode`(奇门)互为别名,一个概念不再有两个参数名;四套体系的摘要都会写明实际采用的口径(换日 / 不换日)。默认值保持原样(八字/六壬换日、奇门不换日),不偷偷改盘
1425
+ - **无经度必须告警**:没给出生地/经度时,八字与紫微摘要首行出现 ⚠(此前只在一行括号里提一句,海外出生很容易被忽略)
1426
+ - **可复现**:塔罗/六爻新增 `seed`(同 seed 同结果,可回放、可对拍);塔罗 `castAt` 由 `asOf` 决定;八字流年可用 `asOf` 钉死基准年(此前锚在"当前年份",隔年重算结论就变了);六爻的日辰(六神起法)也可用 `asOf` 固定,不再随本机日期漂移
1427
+ - **默认离线**:工具新增 `geocode: 'offline' | 'online'`,默认 `offline`——内置坐标表已到地级市,足够真太阳时;只有显式开启才会把出生地原文发给 Nominatim。地址解析加 6 小时缓存,UA 补上版本与仓库地址
1428
+ - **性能**:`termInstantJd` / `termWindow` 按年缓存(农历换算一次要问几百次中气,而 VSOP87 是全引擎最贵的一段)
1429
+ - 紫微盘 10.9ms → **0.5ms**,奇门 8.1ms → **0.07ms**,八字 2.4ms → **0.4ms**
1430
+ - 全量回归 15.8s → **3.3s**
1431
+ - **无障碍**:结果区补 `role="region"` + `aria-live="polite"`,错误提示 `role="alert"`,通知 `role="status"`
1432
+ - **工具层**:`geocode` / `seed` 进 schema,`asOf` 说明覆盖紫微/八字/塔罗三个体系;非法 `geocode` 值报 `E_INPUT`
1433
+ - **CI**:新增 `tools/check-html-sinks.mjs`(innerHTML 拼接必须经过白名单转义函数)与 `tools/check-patterns.mjs`(engine 纯净性、日志、`var`、`debugger`、`new Date()`/`Math.random` 白名单),正/负向都验证过
1434
+ - **稳定性扫射**:`test/fuzz.test.mjs` —— 用固定种子随机 12 组生日跑遍八个体系,覆盖参数矩阵、边界日期(1600/2400/闰年/1929 切换点)、解析层与"同参数两次结果字节一致"
1435
+ - **自刑补齐**:辰午酉亥两柱同见判「自刑」,大运/流年支与原局同支也按自刑处理。此前 `buildRelations` 遇到同支直接跳过,四柱里 3 个辰也不会报刑
1436
+ - **权重口径显式化**:五行占比(1/0.5/0.3)与日主通根(1.2/0.6/0.3)各自命名并注明用途——数值未变,只是不再像"同一件事写了两份"
1437
+ - **解析加「依据」**:八字与紫微的五个维度各附一行盘面事实(日主旺衰、月令、喜忌、大运流年、宫位主星、煞星),面板渲染 `mp-it-dev`、文本渲染「 依据:…」;卦象类的依据行在 0.14.3 补齐
1438
+ - **解析失败不再变空壳**:builder 抛错时面板显示「⚠ 解析生成失败」并把原因转义后带出,文本摘要同样标出;此前只返回一个空 dimensions 的对象,用户看到的是"没有解析"
1439
+ - **结构不变量**:`test/invariants.test.mjs` —— 不依赖外部样盘,用"盘面自身必须成立"的性质守算法:紫微 12 宫支互异/大限连续覆盖、奇门八门八神各一次、六十四卦一一对应、四柱纳音与世应合法。金标准只能覆盖少量样盘,不变量对每张盘都成立
1440
+ - 测试:39 个文件 / 1011 条 PASS(新增 historical-tz、repro、caliber、tool-geo、fuzz、relations、evidence、invariants 八组)
1441
+
1442
+ ## 0.14.1 —— 先让「通过」可信
1443
+
1444
+ 这一版不加新体系,只补三件会静默出错的地基:测试的失败信号、渲染层的转义、入参的拒绝。
1445
+
1446
+ - **测试不再假绿**:`test/_harness.mjs` 统一断言,任何一条 FAIL 都让进程非零退出。此前 bazi / calendar / liuyao / lunar / shensha / tarot / ziwei / e2e / layout 九个文件只 `console.log`,断言写错也 exit 0,`npm test` 恒报 27/27
1447
+ - `tools/check-assertions.mjs`:每个文件的 PASS 条数锁进 `test/assertion-baseline.json`,删断言即失败(`npm run test:baseline` 显式重建)
1448
+ - `tools/verify-tests-can-fail.mjs`:故意写错一条断言,必须变红——保护「测试本身」
1449
+ - **两处 XSS**:塔罗面板的「所问」与解读段落回显(`src/panel-kit.js`)、独立页错误提示(`src/web-ui.js`)此前把用户原文拼进 `innerHTML`;现改为 `esc()` 与 `textContent`,并加 `test/security.test.mjs` 回归
1450
+ - **入参校验与错误码**:`compute()` 新增 `E_INPUT / E_RANGE / E_LINES / E_COUNT / E_ASOF / E_PARTNER / E_SYSTEM`
1451
+ - 日期按月份天数与闰年校验(`1990-02-30`、`2026-04-31` 不再静默滚到下个月)
1452
+ - `bazi / ziwei / hepan` 的 gender 改为必填(缺省按男命排会让大运/大限方向整个反掉)
1453
+ - 六爻爻数 ≠ 6 时报错(不再悄悄换成随机卦);塔罗张数非 1/3/5 时报错;`asOf` 非法时报错(不再静默用「此刻」)
1454
+ - 工具层 `execute()` 统一包上 `[错误码]` 前缀,内部异常不再以堆栈式文案直出
1455
+ - **合盘口径与单盘对齐**:合盘现在把 `address / longitude / trueSolar / lateZi` 分别透传给双方(工具层也会为 `partner.address` 解析经度)。此前合盘完全忽略地址,同一次出生在单盘是 丁丑 日、在合盘里却是 戊寅 日
1456
+ - 新增 `test/hepan.test.mjs`:断言「合盘里的你 == 单盘的你」,八字与紫微两条链路都覆盖
1457
+ - **解析文案修复**:`命局身身强`(level 已含「身」)、`调候上还初夏`(硬拼连接词)、同一段两次「调候上…」、大运与流年档位并成一句导致建议前后矛盾
1458
+ - 新增 `test/interpret-copy.test.mjs`:对 8 个体系的实际输出做病句/重复/未定义值扫描
1459
+ - 测试新增 `test/args.test.mjs`(40 条)、`test/security.test.mjs`(10 条)、`test/hepan.test.mjs`(7 条)、`test/interpret-copy.test.mjs`(63 条),全量 31 个文件 893 条 PASS
1460
+ - CI 增加「断言数不低于基线」与「测试自检」两步
1461
+
1462
+ ## 0.14.0 —— 奇门、合盘与节气精度(此前只存在于工作树,本版一并落库)
1463
+
1464
+ - 新增**奇门遁甲**(时家转盘:拆补 / 超神接气 / 置闰三派取局、值符值使、九宫、空亡驿马)与对应解读
1465
+ - 新增**合盘**:八字合盘(日主关系 / 夫妻宫 / 五行互补)与紫微合盘(命宫、夫妻宫、五行局)
1466
+ - 节气计算改用 **VSOP87B 截断级数 + 岁差 + 章动 + 光行差**,与 NAOJ 历要项对拍偏差降到 1 分钟内
1467
+ - `parseDateTime` 对 ΔT 覆盖范围(1900–2100)之外的年份给出精度提示,摘要顶部标 ⚠
1468
+ - `geocodeAddress` 支持地址更细时联网(Nominatim)兜底,失败退回内置坐标表
1469
+ - 六壬补神煞与格局文案;紫微补流月/流日/流时并接入盘面与解读
1470
+ - `tools/qimen-divergence.mjs`:枚举三派取局的分裂样本,供排盘差异核对
1471
+
1472
+ ## 0.13.6
1473
+
1474
+ - 修 `npm run release` 的发布后核对:npm 的发布是异步的(PUT 返回 202,registry 生效实测要 1–4 分钟),脚本原来 30 秒就判定失败
1475
+ - 改为对 tarball 轮询 HEAD,最多等 6 分钟;超时只提示「已提交,稍后自查」而不报错
1476
+ - 顺手核对 `dist-tags`,`latest` 不指向新版本时给出 `npm dist-tag add` 的建议
1477
+
1478
+ ## 0.13.5
1479
+
1480
+ - 新增 `npm run release`(`tools/release.mjs`):一条命令走完「测试 → 构建 → 校验产物 → 发 npm」,token 只从环境变量 `NPM_TOKEN` 读,临时 `.npmrc` 用后即删
1481
+ - 发布前会拦下三种情况:git 工作区不干净、`client.js` 与源码不同步、registry 上已有同版本
1482
+ - `-- --dry-run` 只跑到校验;本机没装 npm CLI 时用 `NPM_CLI=/path/to/npm-cli.js` 指定
1483
+
1484
+ ## 0.13.4
1485
+
1486
+ - 新增 `npm run build` / `npm run build:html` / `npm test`:`tools/test-all.mjs` 顺序跑完 20 个测试文件并汇总退出码,省掉手敲一长串 `node test/*.mjs`
1487
+ - `daliuren` / `meihua` 两处旧测试统一成 `PASS/FAIL` 计数风格(此前只打印 `all pass`,CI 里数不出断言数)
1488
+ - 补 `CHANGELOG.md`;`engines.node` 声明 `>=18`;SUBMIT 文档补提交状态与阻塞说明
1489
+ - 新增 GitHub Actions(`.github/workflows/test.yml`):先构建并校验 `client.js` 与源码一致,再跑全部回归
1490
+
1491
+ ## 0.13.3
1492
+
1493
+ - **工具层打通「解析与详解」**:`compute()` 把 `question` / `direction` 透传给 `interpret()`;工具 schema 新增 `withInterpret`、`direction`(综合/财运/事业/感情/健康/学业/出行)与 `asOf`(流月流日流时的基准时刻);`renderText()` 在带解析时附上解析正文与免责声明
1494
+ - 修 `layout` 测试沿用旧类名 `.pn`(0.13.2 已改 `.ft-pn`)导致的假失败
1495
+ - 未知体系报错改为列出六种体系(原文案仍写着「紫微斗数尚未接入」)
1496
+ - `package.json` 补 `author` / `repository` / `homepage` / `bugs`;中英文案重写
1497
+ - 市场条目描述同步到当前能力(主星庙旺、流月流日流时、解析)
1498
+ - README 注明真太阳时只按经度修正、未含历史时区与夏令时
1499
+
1500
+ ## 0.13.2
1501
+
1502
+ - 叶子类名按语义补前缀(`bz-` / `dt-` / `flow-` / `ft-` / `ct-` / `hb-` / `ss-` / `ask-` 等 192 处),消除泛词类名复用隐患
1503
+
1504
+ ## 0.13.1
1505
+
1506
+ - 修三个潜伏的结构性缺陷:孤立「身」角标残骸、解析详解块调色板失效、320px 下六爻盘横向溢出
1507
+ - 打印时折叠的详解自动展开;宫格补 `aria-expanded` 同步
1508
+
1509
+ ## 0.13.0
1510
+
1511
+ - 八字四柱表按专业排盘版式重排(四列并排、无竖线、干支大字、十神分组着色、藏干逐行)
1512
+ - 末行新增五行旺相休囚死;修 `td.big` 选择器长期失效
1513
+
1514
+ ## 0.12.0
1515
+
1516
+ - 紫微补流月 / 流日 / 流时(斗君逐级下推),接入盘面与解读
1517
+
1518
+ ## 0.11.0
1519
+
1520
+ - 深色主题(盘面颜色全变量化)、存为 PDF / 打印、修 390px 下塔罗 tab 被裁
1521
+
1522
+ ## 0.10.0
1523
+
1524
+ - 紫微宫位可点击展开详情、三方四正联动;修「身宫整格消失」的类名撞车
1525
+
1526
+ ## 0.9.0
1527
+
1528
+ - 紫微十四主星加庙旺得利平不陷亮度标注;塔罗面板可选 1/3/5 张牌阵
1529
+
1530
+ ## 0.8.x
1531
+
1532
+ - 0.8.0 起卦 tab 新增「所问之事 + 询问方向」,解读按问题展开;解析区可折叠
1533
+ - 0.8.1 紫微解读补化科、流年四化不再截断
1534
+ - 0.8.2 手机竖屏紫微盘恢复 4×4 宫盘
1535
+ - 0.8.3 竖屏布局改用容器查询,修窄侧栏下盘面挤成一团
1536
+
1537
+ ## 0.7.0
1538
+
1539
+ - 新增「解析与详解」模块:五维度解析、卦象卦辞爻辞动爻、塔罗连贯解读,带免责提示
1540
+
1541
+ ## 0.6.0
1542
+
1543
+ - 六爻 / 梅花 / 六壬面板重绘(真爻线、体用标注、天地盘方盘);输入区区分出生时间与起卦时刻
1544
+
1545
+ ## 0.5.0
1546
+
1547
+ - 八字 42 神煞(七类、双查法)+ 格局 / 用神 / 大运流年评分
1548
+ - 紫微 34 格局、大限一览、流年四化
1549
+ - 塔罗模块重写:78 张牌、牌阵位义、6–8 段解读、体系声明
1550
+ - 首个进入插件市场投稿流程的版本(awesome-dsh-plugin PR)