dsh-metaphysics 0.14.3 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,166 +1,213 @@
1
- # 更新记录
2
-
3
- 版本按「一组可感知的改动」发,README 与市场条目描述随能力同步。
4
-
5
- ## 0.14.3(未发布)
6
-
7
- - **经典通例对拍**:新增 `test/fixtures/classics.json` 与 `test/classics.test.mjs`,把典籍里的规则表当作期望值来验实现——
8
- - 六爻:京房八宫卦序的宫属与世应(八纯上爻、一至五世依次、游魂四爻、归魂三爻),64 卦全表
9
- - 六壬:日干寄宫(甲寅乙辰丙戊巳丁己未庚申辛戌壬亥癸丑)、中气换将(雨水登明亥将起,12 个中气抽样)
10
- - 紫微:纳音定五行局、紫微天府以寅申为轴相照
11
- - 出处与录入方式写在 fixture 的 `meta.sources`,由 `tools/gen-classics-fixture.mjs` 生成,不从引擎输出反推
12
- - 说明:录入的是**通例表**(规则级),不是某本书的例课原文;例课需要可引用的原文,见 README「对拍」
13
- - **卦象/牌阵类也给出「依据」**:六爻列本卦/变卦、世应爻位与六亲六神、动爻、日辰、卦宫;梅花列本卦/互卦/变卦、体用与生克、动爻;六壬列课体、三传、月将、旬空与青龙/朱雀/六合/天后/白虎/子孙是否出现;塔罗列牌阵与牌位、主轴牌、正逆位计数与元素分布
14
- - 至此六个有维度的体系(八字/紫微/六爻/梅花/六壬/塔罗)都能核对依据;奇门走分节形态,事实本就写在 section 正文里
15
- - **《增删卜易》卦例对拍**:从 PDF 电子本(有文字层)录入 9 条原文卦例——「月建 + 日干支 + 本卦 → 变卦」,出处精确到章(元神忌神衰旺章第十、月将章第十六、日辰章第十七、独发章第三十一、星煞章第三十三、用神元神忌神仇神章第九)。引擎须按 64 卦表还原这一对(名字、翻爻、变卦生成)
16
- - 《卜筮正宗》(复城道长精校)此前是**扫描版 PDF、无文字层**;这次拿到同一版本的 **docx**(有文字层),从中提取 138 条带「占事」的卦例,99 条卦名可唯一解析,收 19 条进 `boshizhengzong`
17
- - 每条核对:本卦 → 变卦、卦宫(宫 + 五行,与八宫表互证)、有日期的样本还核旬空
18
- - 书中「空亡」与通用旬空不一致的例子(丙辰日作戌亥,应为子丑)只记卦名卦宫、不断言空亡;1 条卦宫与八宫表冲突(表格串行)不收,原因写在 fixture 的 `meta.sources`
19
- - 原文用字保留异体(遯/遁、干/乾),动爻**不录**——原书卦象图在 PDF 里被压成一行,位置不可靠,硬录等于造数据
20
- - **六爻补旬空**:`buildLiuyao` 现在输出 `xunShou`(旬首)与 `xunKong`(旬空两位),文本摘要多一行「旬首:甲午 旬空:辰巳」;六旬表与「丙辰日空子丑」都有断言
21
- - **双 UI 收口(第一步)**:新增 `src/core.js`,把「爻值解析」「问事体系」「数字输入」三条规则收成单一来源,`app.js` 与 `web-ui.js` 都改为调用 `window.__MPCore`;构建脚本把 core 一并打进 `client.js` 与独立 HTML
22
- - 单测 `test/core.test.mjs`(21 条)直接加载浏览器文件验证;`ask.test.mjs` 改为检查「单一来源 + 两端委托」
23
- - 表单编排(参数拼装)仍各留一份,下一步再收
24
- - **修合盘面板**:合盘的主方性别/出生地被漏在 `bazi|ziwei` 分支之外——0.14.1 起引擎把性别改为必填,面板点「合盘」会直接报 `你(主方)的gender 必须是 male 或 female`,看起来像"合盘不对"。现在三体系共用同一分支,合盘四柱与单盘一致(实测 庚午 辛巳 丁丑 丁未 对 庚午 辛巳 丁丑 丁未)
25
- - **奇门进面板**:新增「奇门」tab,起局时刻 + **换局规则**(fieldset + legend + `role="radiogroup"` 的原生 radio:拆补 / 超神接气 / 置闰,附 `details` 说明),`juMethod` 透传给引擎;盘面下新增 `qimenFactsHTML`,用 `dl > div > dt/dd` 列出局数、节气、四柱、值符、值使、旬首、空亡、驿马、换局规则、晚子时——事实与解读区的结论分开,全部走 `esc()`
26
- - 尚未做(下一步):三栏 Grid 布局、`<template>` 渲染、显式状态机(idle/missing_input/…)、960/1200 断点的布局断言
27
- - **独立页补齐合盘 / 奇门**:`命理排盘.html` 由六个 tab 变八个
28
- - 合盘:对方出生日期/时刻/性别/出生地 + 「合盘方式」八字/紫微切换;主方同样带性别与真太阳时,四柱与单盘一致
29
- - 奇门:换局规则用 `fieldset + legend + role="radiogroup"` 的原生 radio(拆补/超神接气/置闰,附 `details`),加「询问方向(定用神)」;结果 = 九宫盘 + `dl` 事实表 + 分节解读;换规则重起局、换方向只重出解读
30
- - `build-html` 导出 `page()` 且直接运行时才写盘,`test/standalone.test.mjs` 直接对生成源码做结构断言(24 条)
31
- - **解析深化:把"怎么推出来的"也写出来**
32
- - 八字 / 紫微新增四段:**看盘顺序**(月令→旺衰→用神→格局→大运→流年/命宫→三方→四化→大限,逐步引用实际值)、**时间窗**(当前与后续大运 + 近五年流年,带档位与理由)、**交叉校验**(喜忌分量对比、大运与流年同向/反向、调候与扶抑是否一致)、**未纳入**(没算什么、哪些流派差异会改变轻重)
33
- - 六爻 / 六壬补**看卦/看课顺序**(卦宫→世应→动爻→用神→日辰→变卦;月将→四课→三传→课体→神将)与**未纳入**
34
- - 这些段落全部由盘面数据推出,不新增断语;`test/deep.test.mjs` 41 条断言校验结构、关键步骤与"无占位值"
35
- - 测试:44 个文件 / 1147 条 PASS
36
-
37
- ## 0.14.2 —— 口径、复现与性能(已发布)
38
-
39
- - **1929 年前的节气改用当时的地方时**:`termInstantJd` 与农历共用同一套换算(1929-01-01 前为北京地方平时 UTC+7.7611,之后东八区),并顺手修正切点常量的半天偏移。此前农历切换、节气一律 +8,1929 年前出生者在交节前后约 14 分钟内可能月柱整柱错位
40
- - **晚子时口径统一**:`lateZi`(八字/六壬)与 `lateZiHourMode`(奇门)互为别名,一个概念不再有两个参数名;四套体系的摘要都会写明实际采用的口径(换日 / 不换日)。默认值保持原样(八字/六壬换日、奇门不换日),不偷偷改盘
41
- - **无经度必须告警**:没给出生地/经度时,八字与紫微摘要首行出现 ⚠(此前只在一行括号里提一句,海外出生很容易被忽略)
42
- - **可复现**:塔罗/六爻新增 `seed`(同 seed 同结果,可回放、可对拍);塔罗 `castAt` 由 `asOf` 决定;八字流年可用 `asOf` 钉死基准年(此前锚在"当前年份",隔年重算结论就变了);六爻的日辰(六神起法)也可用 `asOf` 固定,不再随本机日期漂移
43
- - **默认离线**:工具新增 `geocode: 'offline' | 'online'`,默认 `offline`——内置坐标表已到地级市,足够真太阳时;只有显式开启才会把出生地原文发给 Nominatim。地址解析加 6 小时缓存,UA 补上版本与仓库地址
44
- - **性能**:`termInstantJd` / `termWindow` 按年缓存(农历换算一次要问几百次中气,而 VSOP87 是全引擎最贵的一段)
45
- - 紫微盘 10.9ms → **0.5ms**,奇门 8.1ms → **0.07ms**,八字 2.4ms → **0.4ms**
46
- - 全量回归 15.8s → **3.3s**
47
- - **无障碍**:结果区补 `role="region"` + `aria-live="polite"`,错误提示 `role="alert"`,通知 `role="status"`
48
- - **工具层**:`geocode` / `seed` 进 schema,`asOf` 说明覆盖紫微/八字/塔罗三个体系;非法 `geocode` 值报 `E_INPUT`
49
- - **CI**:新增 `tools/check-html-sinks.mjs`(innerHTML 拼接必须经过白名单转义函数)与 `tools/check-patterns.mjs`(engine 纯净性、日志、`var`、`debugger`、`new Date()`/`Math.random` 白名单),正/负向都验证过
50
- - **稳定性扫射**:`test/fuzz.test.mjs` —— 用固定种子随机 12 组生日跑遍八个体系,覆盖参数矩阵、边界日期(1600/2400/闰年/1929 切换点)、解析层与"同参数两次结果字节一致"
51
- - **自刑补齐**:辰午酉亥两柱同见判「自刑」,大运/流年支与原局同支也按自刑处理。此前 `buildRelations` 遇到同支直接跳过,四柱里 3 个辰也不会报刑
52
- - **权重口径显式化**:五行占比(1/0.5/0.3)与日主通根(1.2/0.6/0.3)各自命名并注明用途——数值未变,只是不再像"同一件事写了两份"
53
- - **解析加「依据」**:八字与紫微的五个维度各附一行盘面事实(日主旺衰、月令、喜忌、大运流年、宫位主星、煞星),面板渲染 `mp-it-dev`、文本渲染「 依据:…」;卦象类的依据行在 0.14.3 补齐
54
- - **解析失败不再变空壳**:builder 抛错时面板显示「⚠ 解析生成失败」并把原因转义后带出,文本摘要同样标出;此前只返回一个空 dimensions 的对象,用户看到的是"没有解析"
55
- - **结构不变量**:`test/invariants.test.mjs` —— 不依赖外部样盘,用"盘面自身必须成立"的性质守算法:紫微 12 宫支互异/大限连续覆盖、奇门八门八神各一次、六十四卦一一对应、四柱纳音与世应合法。金标准只能覆盖少量样盘,不变量对每张盘都成立
56
- - 测试:39 个文件 / 1011 条 PASS(新增 historical-tz、repro、caliber、tool-geo、fuzz、relations、evidence、invariants 八组)
57
-
58
- ## 0.14.1 —— 先让「通过」可信
59
-
60
- 这一版不加新体系,只补三件会静默出错的地基:测试的失败信号、渲染层的转义、入参的拒绝。
61
-
62
- - **测试不再假绿**:`test/_harness.mjs` 统一断言,任何一条 FAIL 都让进程非零退出。此前 bazi / calendar / liuyao / lunar / shensha / tarot / ziwei / e2e / layout 九个文件只 `console.log`,断言写错也 exit 0,`npm test` 恒报 27/27
63
- - `tools/check-assertions.mjs`:每个文件的 PASS 条数锁进 `test/assertion-baseline.json`,删断言即失败(`npm run test:baseline` 显式重建)
64
- - `tools/verify-tests-can-fail.mjs`:故意写错一条断言,必须变红——保护「测试本身」
65
- - **两处 XSS**:塔罗面板的「所问」与解读段落回显(`src/panel-kit.js`)、独立页错误提示(`src/web-ui.js`)此前把用户原文拼进 `innerHTML`;现改为 `esc()` 与 `textContent`,并加 `test/security.test.mjs` 回归
66
- - **入参校验与错误码**:`compute()` 新增 `E_INPUT / E_RANGE / E_LINES / E_COUNT / E_ASOF / E_PARTNER / E_SYSTEM`
67
- - 日期按月份天数与闰年校验(`1990-02-30`、`2026-04-31` 不再静默滚到下个月)
68
- - `bazi / ziwei / hepan` 的 gender 改为必填(缺省按男命排会让大运/大限方向整个反掉)
69
- - 六爻爻数 ≠ 6 时报错(不再悄悄换成随机卦);塔罗张数非 1/3/5 时报错;`asOf` 非法时报错(不再静默用「此刻」)
70
- - 工具层 `execute()` 统一包上 `[错误码]` 前缀,内部异常不再以堆栈式文案直出
71
- - **合盘口径与单盘对齐**:合盘现在把 `address / longitude / trueSolar / lateZi` 分别透传给双方(工具层也会为 `partner.address` 解析经度)。此前合盘完全忽略地址,同一次出生在单盘是 丁丑 日、在合盘里却是 戊寅 日
72
- - 新增 `test/hepan.test.mjs`:断言「合盘里的你 == 单盘的你」,八字与紫微两条链路都覆盖
73
- - **解析文案修复**:`命局身身强`(level 已含「身」)、`调候上还初夏`(硬拼连接词)、同一段两次「调候上…」、大运与流年档位并成一句导致建议前后矛盾
74
- - 新增 `test/interpret-copy.test.mjs`:对 8 个体系的实际输出做病句/重复/未定义值扫描
75
- - 测试新增 `test/args.test.mjs`(40 条)、`test/security.test.mjs`(10 条)、`test/hepan.test.mjs`(7 条)、`test/interpret-copy.test.mjs`(63 条),全量 31 个文件 893 条 PASS
76
- - CI 增加「断言数不低于基线」与「测试自检」两步
77
-
78
- ## 0.14.0 —— 奇门、合盘与节气精度(此前只存在于工作树,本版一并落库)
79
-
80
- - 新增**奇门遁甲**(时家转盘:拆补 / 超神接气 / 置闰三派取局、值符值使、九宫、空亡驿马)与对应解读
81
- - 新增**合盘**:八字合盘(日主关系 / 夫妻宫 / 五行互补)与紫微合盘(命宫、夫妻宫、五行局)
82
- - 节气计算改用 **VSOP87B 截断级数 + 岁差 + 章动 + 光行差**,与 NAOJ 历要项对拍偏差降到 1 分钟内
83
- - `parseDateTime` 对 ΔT 覆盖范围(1900–2100)之外的年份给出精度提示,摘要顶部标 ⚠
84
- - `geocodeAddress` 支持地址更细时联网(Nominatim)兜底,失败退回内置坐标表
85
- - 六壬补神煞与格局文案;紫微补流月/流日/流时并接入盘面与解读
86
- - `tools/qimen-divergence.mjs`:枚举三派取局的分裂样本,供排盘差异核对
87
-
88
- ## 0.13.6
89
-
90
- - 修 `npm run release` 的发布后核对:npm 的发布是异步的(PUT 返回 202,registry 生效实测要 1–4 分钟),脚本原来 30 秒就判定失败
91
- - 改为对 tarball 轮询 HEAD,最多等 6 分钟;超时只提示「已提交,稍后自查」而不报错
92
- - 顺手核对 `dist-tags`,`latest` 不指向新版本时给出 `npm dist-tag add` 的建议
93
-
94
- ## 0.13.5
95
-
96
- - 新增 `npm run release`(`tools/release.mjs`):一条命令走完「测试 → 构建 → 校验产物 → 发 npm」,token 只从环境变量 `NPM_TOKEN` 读,临时 `.npmrc` 用后即删
97
- - 发布前会拦下三种情况:git 工作区不干净、`client.js` 与源码不同步、registry 上已有同版本
98
- - `-- --dry-run` 只跑到校验;本机没装 npm CLI 时用 `NPM_CLI=/path/to/npm-cli.js` 指定
99
-
100
- ## 0.13.4
101
-
102
- - 新增 `npm run build` / `npm run build:html` / `npm test`:`tools/test-all.mjs` 顺序跑完 20 个测试文件并汇总退出码,省掉手敲一长串 `node test/*.mjs`
103
- - `daliuren` / `meihua` 两处旧测试统一成 `PASS/FAIL` 计数风格(此前只打印 `all pass`,CI 里数不出断言数)
104
- - 补 `CHANGELOG.md`;`engines.node` 声明 `>=18`;SUBMIT 文档补提交状态与阻塞说明
105
- - 新增 GitHub Actions(`.github/workflows/test.yml`):先构建并校验 `client.js` 与源码一致,再跑全部回归
106
-
107
- ## 0.13.3
108
-
109
- - **工具层打通「解析与详解」**:`compute()` 把 `question` / `direction` 透传给 `interpret()`;工具 schema 新增 `withInterpret`、`direction`(综合/财运/事业/感情/健康/学业/出行)与 `asOf`(流月流日流时的基准时刻);`renderText()` 在带解析时附上解析正文与免责声明
110
- - 修 `layout` 测试沿用旧类名 `.pn`(0.13.2 已改 `.ft-pn`)导致的假失败
111
- - 未知体系报错改为列出六种体系(原文案仍写着「紫微斗数尚未接入」)
112
- - `package.json` 补 `author` / `repository` / `homepage` / `bugs`;中英文案重写
113
- - 市场条目描述同步到当前能力(主星庙旺、流月流日流时、解析)
114
- - README 注明真太阳时只按经度修正、未含历史时区与夏令时
115
-
116
- ## 0.13.2
117
-
118
- - 叶子类名按语义补前缀(`bz-` / `dt-` / `flow-` / `ft-` / `ct-` / `hb-` / `ss-` / `ask-` 等 192 处),消除泛词类名复用隐患
119
-
120
- ## 0.13.1
121
-
122
- - 修三个潜伏的结构性缺陷:孤立「身」角标残骸、解析详解块调色板失效、320px 下六爻盘横向溢出
123
- - 打印时折叠的详解自动展开;宫格补 `aria-expanded` 同步
124
-
125
- ## 0.13.0
126
-
127
- - 八字四柱表按专业排盘版式重排(四列并排、无竖线、干支大字、十神分组着色、藏干逐行)
128
- - 末行新增五行旺相休囚死;修 `td.big` 选择器长期失效
129
-
130
- ## 0.12.0
131
-
132
- - 紫微补流月 / 流日 / 流时(斗君逐级下推),接入盘面与解读
133
-
134
- ## 0.11.0
135
-
136
- - 深色主题(盘面颜色全变量化)、存为 PDF / 打印、修 390px 下塔罗 tab 被裁
137
-
138
- ## 0.10.0
139
-
140
- - 紫微宫位可点击展开详情、三方四正联动;修「身宫整格消失」的类名撞车
141
-
142
- ## 0.9.0
143
-
144
- - 紫微十四主星加庙旺得利平不陷亮度标注;塔罗面板可选 1/3/5 张牌阵
145
-
146
- ## 0.8.x
147
-
148
- - 0.8.0 起卦 tab 新增「所问之事 + 询问方向」,解读按问题展开;解析区可折叠
149
- - 0.8.1 紫微解读补化科、流年四化不再截断
150
- - 0.8.2 手机竖屏紫微盘恢复 4×4 宫盘
151
- - 0.8.3 竖屏布局改用容器查询,修窄侧栏下盘面挤成一团
152
-
153
- ## 0.7.0
154
-
155
- - 新增「解析与详解」模块:五维度解析、卦象卦辞爻辞动爻、塔罗连贯解读,带免责提示
156
-
157
- ## 0.6.0
158
-
159
- - 六爻 / 梅花 / 六壬面板重绘(真爻线、体用标注、天地盘方盘);输入区区分出生时间与起卦时刻
160
-
161
- ## 0.5.0
162
-
163
- - 八字 42 神煞(七类、双查法)+ 格局 / 用神 / 大运流年评分
164
- - 紫微 34 格局、大限一览、流年四化
165
- - 塔罗模块重写:78 张牌、牌阵位义、6–8 段解读、体系声明
166
- - 首个进入插件市场投稿流程的版本(awesome-dsh-plugin PR)
1
+ # 更新记录
2
+
3
+ 版本按「一组可感知的改动」发,README 与市场条目描述随能力同步。
4
+
5
+ ## 0.16.0(已发布)
6
+
7
+ 报告化改版,对应与 Seeself 对比后的 R1–R8:
8
+
9
+ - **R1 报告骨架**:解析顶部新增「一页读懂」五条摘要(整体 / 事业 / 财富 / 感情 / 节奏);
10
+ 目录锚点跳转;新增三张表——八字「大运表 / 流年表 / 触发事件表」、紫微「大限表 / 流年表 / 触发事件表」,
11
+ 全部由已有引擎字段摊平,不新增判断;打印加 `break-inside:avoid` 与表格换行规则
12
+ - **R2 证据卡**:每个维度的「依据」从一行灰字升级为可展开的 `<details>` 证据卡
13
+ (盘面事实 + 技法标签),并给每个维度打「置信度 强/中/弱」(只按证据条数分档,不引新算法);
14
+ 文本输出同步:依据行尾附 `置信度:…`
15
+ - **R3 追问模式**:新增 `engine/followup.js` 与工具参数 `ask`——围绕已算好的盘回答
16
+ 「某一年 / 某方面」的问题(如「2027 年事业怎么样」),只取盘面已有字段,不重排、不猜测;
17
+ 找不到年份/未识别方面时明确说找不到并给出可问范围。面板与独立页都加了追问输入框
18
+ - **R4 示例报告**:面板与独立页各加「看示例」,固定示例盘(1990-05-12 14:30 男 石家庄)
19
+ 走与真实排盘完全相同的渲染路径,无示例专用分支
20
+ - **R5 交叉验证层**:新增 `engine/crosscheck.js` 与工具参数 `cross`——八字 × 紫微对
21
+ 事业/财富/感情/身体/节奏五项并列对照,标注「同向 / 有张力 / 互补」;只作对照,不合并数值
22
+ - **R6 量化表达**:八字/紫微各加「量化口径」分节——明确量化只到档位(十神权重、宫位计数),
23
+ 不换算金额、不给疾病诊断;新增 `test/report-extra.test.mjs` 断言不出现金额区间
24
+ - **R7 方法与验证页**:独立页内置静态「方法与验证」(体系、对拍 128 条、测试与闸门、口径、已知边界),
25
+ 离线可开
26
+ - **R8 导出与分享**:面板与独立页加「导出 .md」(盘面 + 解析 + 交叉验证 + 追问),
27
+ 独立页保留打印/存 PDF
28
+ - 测试:新增 `test/report.test.mjs` 36 条、`test/report-extra.test.mjs` 31 条;
29
+ 全量 52 个文件 / 1335 条 PASS
30
+
31
+ ## 0.15.0(已发布)
32
+
33
+ - **性能**:节气按需计算、牛顿初值用回归年、容差放宽;八字单盘 2.70ms → 1.60ms
34
+ - **口径差异对照**:`engine/diff.js` + `tools/caliber-diff.mjs`,区分根因字段与连带变化
35
+ - **白话四层**:直答 / 说人话 / 每维一句话 / 追问建议;术语按体系区分
36
+ - **规则知识库**:28 条(出处 + 可信度 + 尚未实现清单)
37
+ - **卦例对拍扩容**:《卜筮正宗》从 19 条扩到 **128 条**(93 成对 + 35 静卦),
38
+ 新增核对动爻个数、缺爻(伏神)、旬空;排除的 5 条连同理由留在
39
+ `tools/data-boshizhengzong.mjs` 的 `excluded`
40
+ - **引擎入参守卫(P0)**:新增 `engine/validate.js` 的 `assertCivil()`,`buildBazi / buildZiwei /
41
+ buildDaliuren / buildQimen / buildHepan / buildZiweiHepan / buildSnapshot` 入口统一校验;
42
+ 坏入参从裸 `TypeError` 改为 `E_INPUT`,文案写清「该传什么」(15 类坏输入有契约测试)
43
+ - 统一错误工厂 `engine/fail.js`;梅花的 datetime / 数字起卦错误也改为 `E_INPUT`
44
+ - **缓存层统一(P0)**:新增 `engine/lru.js`(上限 + TTL + 命中率),节气瞬时/单年/三年窗口/
45
+ 地址四处缓存改为同一工厂;`DSH_METRICS=1` 时 `renderText` 打印各缓存命中率
46
+ (实测紫微盘 `termInstant` 命中 75%)
47
+ - **规则表单一真源(P0 收尾)**:`engine/nayin.js`(六十甲子纳音,bazi/ziwei 共用)、
48
+ `engine/sanhe.js`(三合四局 + 单支归属,bazi/hepan/daliuren 共用);纳甲本就在 `liuyao.js` 一份
49
+ - `test/tables.test.mjs`:纳音 60 项与八字导出逐项一致、三合同局判定与五行等价、
50
+ 乾为天纳甲起例,并用静态检查防止有人再把表复制回各模块
51
+
52
+ ## 0.14.3(已发布)
53
+
54
+ - **经典通例对拍**:新增 `test/fixtures/classics.json` 与 `test/classics.test.mjs`,把典籍里的规则表当作期望值来验实现——
55
+ - 六爻:京房八宫卦序的宫属与世应(八纯上爻、一至五世依次、游魂四爻、归魂三爻),64 卦全表
56
+ - 六壬:日干寄宫(甲寅乙辰丙戊巳丁己未庚申辛戌壬亥癸丑)、中气换将(雨水登明亥将起,12 个中气抽样)
57
+ - 紫微:纳音定五行局、紫微天府以寅申为轴相照
58
+ - 出处与录入方式写在 fixture 的 `meta.sources`,由 `tools/gen-classics-fixture.mjs` 生成,不从引擎输出反推
59
+ - 说明:录入的是**通例表**(规则级),不是某本书的例课原文;例课需要可引用的原文,见 README「对拍」
60
+ - **卦象/牌阵类也给出「依据」**:六爻列本卦/变卦、世应爻位与六亲六神、动爻、日辰、卦宫;梅花列本卦/互卦/变卦、体用与生克、动爻;六壬列课体、三传、月将、旬空与青龙/朱雀/六合/天后/白虎/子孙是否出现;塔罗列牌阵与牌位、主轴牌、正逆位计数与元素分布
61
+ - 至此六个有维度的体系(八字/紫微/六爻/梅花/六壬/塔罗)都能核对依据;奇门走分节形态,事实本就写在 section 正文里
62
+ - **《增删卜易》卦例对拍**:从 PDF 电子本(有文字层)录入 9 条原文卦例——「月建 + 日干支 + 本卦 → 变卦」,出处精确到章(元神忌神衰旺章第十、月将章第十六、日辰章第十七、独发章第三十一、星煞章第三十三、用神元神忌神仇神章第九)。引擎须按 64 卦表还原这一对(名字、翻爻、变卦生成)
63
+ - 《卜筮正宗》(复城道长精校)此前是**扫描版 PDF、无文字层**;这次拿到同一版本的 **docx**(有文字层),从中提取 138 条带「占事」的卦例,99 条卦名可唯一解析,收 19 条进 `boshizhengzong`
64
+ - 每条核对:本卦 → 变卦、卦宫(宫 + 五行,与八宫表互证)、有日期的样本还核旬空
65
+ - 书中「空亡」与通用旬空不一致的例子(丙辰日作戌亥,应为子丑)只记卦名卦宫、不断言空亡;1 条卦宫与八宫表冲突(表格串行)不收,原因写在 fixture 的 `meta.sources`
66
+ - 原文用字保留异体(遯/遁、干/乾),动爻**不录**——原书卦象图在 PDF 里被压成一行,位置不可靠,硬录等于造数据
67
+ - **六爻补旬空**:`buildLiuyao` 现在输出 `xunShou`(旬首)与 `xunKong`(旬空两位),文本摘要多一行「旬首:甲午 旬空:辰巳」;六旬表与「丙辰日空子丑」都有断言
68
+ - **双 UI 收口(第一步)**:新增 `src/core.js`,把「爻值解析」「问事体系」「数字输入」三条规则收成单一来源,`app.js` 与 `web-ui.js` 都改为调用 `window.__MPCore`;构建脚本把 core 一并打进 `client.js` 与独立 HTML
69
+ - 单测 `test/core.test.mjs`(21 条)直接加载浏览器文件验证;`ask.test.mjs` 改为检查「单一来源 + 两端委托」
70
+ - 表单编排(参数拼装)仍各留一份,下一步再收
71
+ - **修合盘面板**:合盘的主方性别/出生地被漏在 `bazi|ziwei` 分支之外——0.14.1 起引擎把性别改为必填,面板点「合盘」会直接报 `你(主方)的gender 必须是 male 或 female`,看起来像"合盘不对"。现在三体系共用同一分支,合盘四柱与单盘一致(实测 庚午 辛巳 丁丑 丁未 对 庚午 辛巳 丁丑 丁未)
72
+ - **奇门进面板**:新增「奇门」tab,起局时刻 + **换局规则**(fieldset + legend + `role="radiogroup"` 的原生 radio:拆补 / 超神接气 / 置闰,附 `details` 说明),`juMethod` 透传给引擎;盘面下新增 `qimenFactsHTML`,用 `dl > div > dt/dd` 列出局数、节气、四柱、值符、值使、旬首、空亡、驿马、换局规则、晚子时——事实与解读区的结论分开,全部走 `esc()`
73
+ - 尚未做(下一步):三栏 Grid 布局、`<template>` 渲染、显式状态机(idle/missing_input/…)、960/1200 断点的布局断言
74
+ - **独立页补齐合盘 / 奇门**:`命理排盘.html` 由六个 tab 变八个
75
+ - 合盘:对方出生日期/时刻/性别/出生地 + 「合盘方式」八字/紫微切换;主方同样带性别与真太阳时,四柱与单盘一致
76
+ - 奇门:换局规则用 `fieldset + legend + role="radiogroup"` 的原生 radio(拆补/超神接气/置闰,附 `details`),加「询问方向(定用神)」;结果 = 九宫盘 + `dl` 事实表 + 分节解读;换规则重起局、换方向只重出解读
77
+ - `build-html` 导出 `page()` 且直接运行时才写盘,`test/standalone.test.mjs` 直接对生成源码做结构断言(24 条)
78
+ - **解析深化:把"怎么推出来的"也写出来**
79
+ - 八字 / 紫微新增四段:**看盘顺序**(月令→旺衰→用神→格局→大运→流年/命宫→三方→四化→大限,逐步引用实际值)、**时间窗**(当前与后续大运 + 近五年流年,带档位与理由)、**交叉校验**(喜忌分量对比、大运与流年同向/反向、调候与扶抑是否一致)、**未纳入**(没算什么、哪些流派差异会改变轻重)
80
+ - 六爻 / 六壬补**看卦/看课顺序**(卦宫→世应→动爻→用神→日辰→变卦;月将→四课→三传→课体→神将)与**未纳入**
81
+ - 这些段落全部由盘面数据推出,不新增断语;`test/deep.test.mjs` 41 条断言校验结构、关键步骤与"无占位值"
82
+ - 测试:44 个文件 / 1147 条 PASS
83
+
84
+ ## 0.14.2 —— 口径、复现与性能(已发布)
85
+
86
+ - **1929 年前的节气改用当时的地方时**:`termInstantJd` 与农历共用同一套换算(1929-01-01 前为北京地方平时 UTC+7.7611,之后东八区),并顺手修正切点常量的半天偏移。此前农历切换、节气一律 +8,1929 年前出生者在交节前后约 14 分钟内可能月柱整柱错位
87
+ - **晚子时口径统一**:`lateZi`(八字/六壬)与 `lateZiHourMode`(奇门)互为别名,一个概念不再有两个参数名;四套体系的摘要都会写明实际采用的口径(换日 / 不换日)。默认值保持原样(八字/六壬换日、奇门不换日),不偷偷改盘
88
+ - **无经度必须告警**:没给出生地/经度时,八字与紫微摘要首行出现 ⚠(此前只在一行括号里提一句,海外出生很容易被忽略)
89
+ - **可复现**:塔罗/六爻新增 `seed`(同 seed 同结果,可回放、可对拍);塔罗 `castAt` 由 `asOf` 决定;八字流年可用 `asOf` 钉死基准年(此前锚在"当前年份",隔年重算结论就变了);六爻的日辰(六神起法)也可用 `asOf` 固定,不再随本机日期漂移
90
+ - **默认离线**:工具新增 `geocode: 'offline' | 'online'`,默认 `offline`——内置坐标表已到地级市,足够真太阳时;只有显式开启才会把出生地原文发给 Nominatim。地址解析加 6 小时缓存,UA 补上版本与仓库地址
91
+ - **性能**:`termInstantJd` / `termWindow` 按年缓存(农历换算一次要问几百次中气,而 VSOP87 是全引擎最贵的一段)
92
+ - 紫微盘 10.9ms → **0.5ms**,奇门 8.1ms → **0.07ms**,八字 2.4ms → **0.4ms**
93
+ - 全量回归 15.8s → **3.3s**
94
+ - **无障碍**:结果区补 `role="region"` + `aria-live="polite"`,错误提示 `role="alert"`,通知 `role="status"`
95
+ - **工具层**:`geocode` / `seed` 进 schema,`asOf` 说明覆盖紫微/八字/塔罗三个体系;非法 `geocode` 值报 `E_INPUT`
96
+ - **CI**:新增 `tools/check-html-sinks.mjs`(innerHTML 拼接必须经过白名单转义函数)与 `tools/check-patterns.mjs`(engine 纯净性、日志、`var`、`debugger`、`new Date()`/`Math.random` 白名单),正/负向都验证过
97
+ - **稳定性扫射**:`test/fuzz.test.mjs` —— 用固定种子随机 12 组生日跑遍八个体系,覆盖参数矩阵、边界日期(1600/2400/闰年/1929 切换点)、解析层与"同参数两次结果字节一致"
98
+ - **自刑补齐**:辰午酉亥两柱同见判「自刑」,大运/流年支与原局同支也按自刑处理。此前 `buildRelations` 遇到同支直接跳过,四柱里 3 个辰也不会报刑
99
+ - **权重口径显式化**:五行占比(1/0.5/0.3)与日主通根(1.2/0.6/0.3)各自命名并注明用途——数值未变,只是不再像"同一件事写了两份"
100
+ - **解析加「依据」**:八字与紫微的五个维度各附一行盘面事实(日主旺衰、月令、喜忌、大运流年、宫位主星、煞星),面板渲染 `mp-it-dev`、文本渲染「 依据:…」;卦象类的依据行在 0.14.3 补齐
101
+ - **解析失败不再变空壳**:builder 抛错时面板显示「⚠ 解析生成失败」并把原因转义后带出,文本摘要同样标出;此前只返回一个空 dimensions 的对象,用户看到的是"没有解析"
102
+ - **结构不变量**:`test/invariants.test.mjs` —— 不依赖外部样盘,用"盘面自身必须成立"的性质守算法:紫微 12 宫支互异/大限连续覆盖、奇门八门八神各一次、六十四卦一一对应、四柱纳音与世应合法。金标准只能覆盖少量样盘,不变量对每张盘都成立
103
+ - 测试:39 个文件 / 1011 条 PASS(新增 historical-tz、repro、caliber、tool-geo、fuzz、relations、evidence、invariants 八组)
104
+
105
+ ## 0.14.1 —— 先让「通过」可信
106
+
107
+ 这一版不加新体系,只补三件会静默出错的地基:测试的失败信号、渲染层的转义、入参的拒绝。
108
+
109
+ - **测试不再假绿**:`test/_harness.mjs` 统一断言,任何一条 FAIL 都让进程非零退出。此前 bazi / calendar / liuyao / lunar / shensha / tarot / ziwei / e2e / layout 九个文件只 `console.log`,断言写错也 exit 0,`npm test` 恒报 27/27
110
+ - `tools/check-assertions.mjs`:每个文件的 PASS 条数锁进 `test/assertion-baseline.json`,删断言即失败(`npm run test:baseline` 显式重建)
111
+ - `tools/verify-tests-can-fail.mjs`:故意写错一条断言,必须变红——保护「测试本身」
112
+ - **两处 XSS**:塔罗面板的「所问」与解读段落回显(`src/panel-kit.js`)、独立页错误提示(`src/web-ui.js`)此前把用户原文拼进 `innerHTML`;现改为 `esc()` 与 `textContent`,并加 `test/security.test.mjs` 回归
113
+ - **入参校验与错误码**:`compute()` 新增 `E_INPUT / E_RANGE / E_LINES / E_COUNT / E_ASOF / E_PARTNER / E_SYSTEM`
114
+ - 日期按月份天数与闰年校验(`1990-02-30`、`2026-04-31` 不再静默滚到下个月)
115
+ - `bazi / ziwei / hepan` 的 gender 改为必填(缺省按男命排会让大运/大限方向整个反掉)
116
+ - 六爻爻数 ≠ 6 时报错(不再悄悄换成随机卦);塔罗张数非 1/3/5 时报错;`asOf` 非法时报错(不再静默用「此刻」)
117
+ - 工具层 `execute()` 统一包上 `[错误码]` 前缀,内部异常不再以堆栈式文案直出
118
+ - **合盘口径与单盘对齐**:合盘现在把 `address / longitude / trueSolar / lateZi` 分别透传给双方(工具层也会为 `partner.address` 解析经度)。此前合盘完全忽略地址,同一次出生在单盘是 丁丑 日、在合盘里却是 戊寅 日
119
+ - 新增 `test/hepan.test.mjs`:断言「合盘里的你 == 单盘的你」,八字与紫微两条链路都覆盖
120
+ - **解析文案修复**:`命局身身强`(level 已含「身」)、`调候上还初夏`(硬拼连接词)、同一段两次「调候上…」、大运与流年档位并成一句导致建议前后矛盾
121
+ - 新增 `test/interpret-copy.test.mjs`:对 8 个体系的实际输出做病句/重复/未定义值扫描
122
+ - 测试新增 `test/args.test.mjs`(40 条)、`test/security.test.mjs`(10 条)、`test/hepan.test.mjs`(7 条)、`test/interpret-copy.test.mjs`(63 条),全量 31 个文件 893 条 PASS
123
+ - CI 增加「断言数不低于基线」与「测试自检」两步
124
+
125
+ ## 0.14.0 —— 奇门、合盘与节气精度(此前只存在于工作树,本版一并落库)
126
+
127
+ - 新增**奇门遁甲**(时家转盘:拆补 / 超神接气 / 置闰三派取局、值符值使、九宫、空亡驿马)与对应解读
128
+ - 新增**合盘**:八字合盘(日主关系 / 夫妻宫 / 五行互补)与紫微合盘(命宫、夫妻宫、五行局)
129
+ - 节气计算改用 **VSOP87B 截断级数 + 岁差 + 章动 + 光行差**,与 NAOJ 历要项对拍偏差降到 1 分钟内
130
+ - `parseDateTime` 对 ΔT 覆盖范围(1900–2100)之外的年份给出精度提示,摘要顶部标 ⚠
131
+ - `geocodeAddress` 支持地址更细时联网(Nominatim)兜底,失败退回内置坐标表
132
+ - 六壬补神煞与格局文案;紫微补流月/流日/流时并接入盘面与解读
133
+ - `tools/qimen-divergence.mjs`:枚举三派取局的分裂样本,供排盘差异核对
134
+
135
+ ## 0.13.6
136
+
137
+ - 修 `npm run release` 的发布后核对:npm 的发布是异步的(PUT 返回 202,registry 生效实测要 1–4 分钟),脚本原来 30 秒就判定失败
138
+ - 改为对 tarball 轮询 HEAD,最多等 6 分钟;超时只提示「已提交,稍后自查」而不报错
139
+ - 顺手核对 `dist-tags`,`latest` 不指向新版本时给出 `npm dist-tag add` 的建议
140
+
141
+ ## 0.13.5
142
+
143
+ - 新增 `npm run release`(`tools/release.mjs`):一条命令走完「测试 → 构建 → 校验产物 → 发 npm」,token 只从环境变量 `NPM_TOKEN` 读,临时 `.npmrc` 用后即删
144
+ - 发布前会拦下三种情况:git 工作区不干净、`client.js` 与源码不同步、registry 上已有同版本
145
+ - `-- --dry-run` 只跑到校验;本机没装 npm CLI 时用 `NPM_CLI=/path/to/npm-cli.js` 指定
146
+
147
+ ## 0.13.4
148
+
149
+ - 新增 `npm run build` / `npm run build:html` / `npm test`:`tools/test-all.mjs` 顺序跑完 20 个测试文件并汇总退出码,省掉手敲一长串 `node test/*.mjs`
150
+ - `daliuren` / `meihua` 两处旧测试统一成 `PASS/FAIL` 计数风格(此前只打印 `all pass`,CI 里数不出断言数)
151
+ - 补 `CHANGELOG.md`;`engines.node` 声明 `>=18`;SUBMIT 文档补提交状态与阻塞说明
152
+ - 新增 GitHub Actions(`.github/workflows/test.yml`):先构建并校验 `client.js` 与源码一致,再跑全部回归
153
+
154
+ ## 0.13.3
155
+
156
+ - **工具层打通「解析与详解」**:`compute()` 把 `question` / `direction` 透传给 `interpret()`;工具 schema 新增 `withInterpret`、`direction`(综合/财运/事业/感情/健康/学业/出行)与 `asOf`(流月流日流时的基准时刻);`renderText()` 在带解析时附上解析正文与免责声明
157
+ - 修 `layout` 测试沿用旧类名 `.pn`(0.13.2 已改 `.ft-pn`)导致的假失败
158
+ - 未知体系报错改为列出六种体系(原文案仍写着「紫微斗数尚未接入」)
159
+ - `package.json` 补 `author` / `repository` / `homepage` / `bugs`;中英文案重写
160
+ - 市场条目描述同步到当前能力(主星庙旺、流月流日流时、解析)
161
+ - README 注明真太阳时只按经度修正、未含历史时区与夏令时
162
+
163
+ ## 0.13.2
164
+
165
+ - 叶子类名按语义补前缀(`bz-` / `dt-` / `flow-` / `ft-` / `ct-` / `hb-` / `ss-` / `ask-` 等 192 处),消除泛词类名复用隐患
166
+
167
+ ## 0.13.1
168
+
169
+ - 修三个潜伏的结构性缺陷:孤立「身」角标残骸、解析详解块调色板失效、320px 下六爻盘横向溢出
170
+ - 打印时折叠的详解自动展开;宫格补 `aria-expanded` 同步
171
+
172
+ ## 0.13.0
173
+
174
+ - 八字四柱表按专业排盘版式重排(四列并排、无竖线、干支大字、十神分组着色、藏干逐行)
175
+ - 末行新增五行旺相休囚死;修 `td.big` 选择器长期失效
176
+
177
+ ## 0.12.0
178
+
179
+ - 紫微补流月 / 流日 / 流时(斗君逐级下推),接入盘面与解读
180
+
181
+ ## 0.11.0
182
+
183
+ - 深色主题(盘面颜色全变量化)、存为 PDF / 打印、修 390px 下塔罗 tab 被裁
184
+
185
+ ## 0.10.0
186
+
187
+ - 紫微宫位可点击展开详情、三方四正联动;修「身宫整格消失」的类名撞车
188
+
189
+ ## 0.9.0
190
+
191
+ - 紫微十四主星加庙旺得利平不陷亮度标注;塔罗面板可选 1/3/5 张牌阵
192
+
193
+ ## 0.8.x
194
+
195
+ - 0.8.0 起卦 tab 新增「所问之事 + 询问方向」,解读按问题展开;解析区可折叠
196
+ - 0.8.1 紫微解读补化科、流年四化不再截断
197
+ - 0.8.2 手机竖屏紫微盘恢复 4×4 宫盘
198
+ - 0.8.3 竖屏布局改用容器查询,修窄侧栏下盘面挤成一团
199
+
200
+ ## 0.7.0
201
+
202
+ - 新增「解析与详解」模块:五维度解析、卦象卦辞爻辞动爻、塔罗连贯解读,带免责提示
203
+
204
+ ## 0.6.0
205
+
206
+ - 六爻 / 梅花 / 六壬面板重绘(真爻线、体用标注、天地盘方盘);输入区区分出生时间与起卦时刻
207
+
208
+ ## 0.5.0
209
+
210
+ - 八字 42 神煞(七类、双查法)+ 格局 / 用神 / 大运流年评分
211
+ - 紫微 34 格局、大限一览、流年四化
212
+ - 塔罗模块重写:78 张牌、牌阵位义、6–8 段解读、体系声明
213
+ - 首个进入插件市场投稿流程的版本(awesome-dsh-plugin PR)