dsh-metaphysics 0.13.6 → 0.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,57 @@
2
2
 
3
3
  版本按「一组可感知的改动」发,README 与市场条目描述随能力同步。
4
4
 
5
+ ## 0.14.2 —— 口径、复现与性能
6
+
7
+ - **1929 年前的节气改用当时的地方时**:`termInstantJd` 与农历共用同一套换算(1929-01-01 前为北京地方平时 UTC+7.7611,之后东八区),并顺手修正切点常量的半天偏移。此前农历切换、节气一律 +8,1929 年前出生者在交节前后约 14 分钟内可能月柱整柱错位
8
+ - **晚子时口径统一**:`lateZi`(八字/六壬)与 `lateZiHourMode`(奇门)互为别名,一个概念不再有两个参数名;四套体系的摘要都会写明实际采用的口径(换日 / 不换日)。默认值保持原样(八字/六壬换日、奇门不换日),不偷偷改盘
9
+ - **无经度必须告警**:没给出生地/经度时,八字与紫微摘要首行出现 ⚠(此前只在一行括号里提一句,海外出生很容易被忽略)
10
+ - **可复现**:塔罗/六爻新增 `seed`(同 seed 同结果,可回放、可对拍);塔罗 `castAt` 由 `asOf` 决定;八字流年可用 `asOf` 钉死基准年(此前锚在"当前年份",隔年重算结论就变了);六爻的日辰(六神起法)也可用 `asOf` 固定,不再随本机日期漂移
11
+ - **默认离线**:工具新增 `geocode: 'offline' | 'online'`,默认 `offline`——内置坐标表已到地级市,足够真太阳时;只有显式开启才会把出生地原文发给 Nominatim。地址解析加 6 小时缓存,UA 补上版本与仓库地址
12
+ - **性能**:`termInstantJd` / `termWindow` 按年缓存(农历换算一次要问几百次中气,而 VSOP87 是全引擎最贵的一段)
13
+ - 紫微盘 10.9ms → **0.5ms**,奇门 8.1ms → **0.07ms**,八字 2.4ms → **0.4ms**
14
+ - 全量回归 15.8s → **3.3s**
15
+ - **无障碍**:结果区补 `role="region"` + `aria-live="polite"`,错误提示 `role="alert"`,通知 `role="status"`
16
+ - **工具层**:`geocode` / `seed` 进 schema,`asOf` 说明覆盖紫微/八字/塔罗三个体系;非法 `geocode` 值报 `E_INPUT`
17
+ - **CI**:新增 `tools/check-html-sinks.mjs`(innerHTML 拼接必须经过白名单转义函数)与 `tools/check-patterns.mjs`(engine 纯净性、日志、`var`、`debugger`、`new Date()`/`Math.random` 白名单),正/负向都验证过
18
+ - **稳定性扫射**:`test/fuzz.test.mjs` —— 用固定种子随机 12 组生日跑遍八个体系,覆盖参数矩阵、边界日期(1600/2400/闰年/1929 切换点)、解析层与"同参数两次结果字节一致"
19
+ - **自刑补齐**:辰午酉亥两柱同见判「自刑」,大运/流年支与原局同支也按自刑处理。此前 `buildRelations` 遇到同支直接跳过,四柱里 3 个辰也不会报刑
20
+ - **权重口径显式化**:五行占比(1/0.5/0.3)与日主通根(1.2/0.6/0.3)各自命名并注明用途——数值未变,只是不再像"同一件事写了两份"
21
+ - **解析加「依据」**:八字与紫微的五个维度各附一行盘面事实(日主旺衰、月令、喜忌、大运流年、宫位主星、煞星等),面板渲染 `mp-it-dev`、文本渲染「 依据:…」,结论出处可核对
22
+ - **解析失败不再变空壳**:builder 抛错时面板显示「⚠ 解析生成失败」并把原因转义后带出,文本摘要同样标出;此前只返回一个空 dimensions 的对象,用户看到的是"没有解析"
23
+ - **结构不变量**:`test/invariants.test.mjs` —— 不依赖外部样盘,用"盘面自身必须成立"的性质守算法:紫微 12 宫支互异/大限连续覆盖、奇门八门八神各一次、六十四卦一一对应、四柱纳音与世应合法。金标准只能覆盖少量样盘,不变量对每张盘都成立
24
+ - 测试:39 个文件 / 1011 条 PASS(新增 historical-tz、repro、caliber、tool-geo、fuzz、relations、evidence、invariants 八组)
25
+
26
+ ## 0.14.1 —— 先让「通过」可信
27
+
28
+ 这一版不加新体系,只补三件会静默出错的地基:测试的失败信号、渲染层的转义、入参的拒绝。
29
+
30
+ - **测试不再假绿**:`test/_harness.mjs` 统一断言,任何一条 FAIL 都让进程非零退出。此前 bazi / calendar / liuyao / lunar / shensha / tarot / ziwei / e2e / layout 九个文件只 `console.log`,断言写错也 exit 0,`npm test` 恒报 27/27
31
+ - `tools/check-assertions.mjs`:每个文件的 PASS 条数锁进 `test/assertion-baseline.json`,删断言即失败(`npm run test:baseline` 显式重建)
32
+ - `tools/verify-tests-can-fail.mjs`:故意写错一条断言,必须变红——保护「测试本身」
33
+ - **两处 XSS**:塔罗面板的「所问」与解读段落回显(`src/panel-kit.js`)、独立页错误提示(`src/web-ui.js`)此前把用户原文拼进 `innerHTML`;现改为 `esc()` 与 `textContent`,并加 `test/security.test.mjs` 回归
34
+ - **入参校验与错误码**:`compute()` 新增 `E_INPUT / E_RANGE / E_LINES / E_COUNT / E_ASOF / E_PARTNER / E_SYSTEM`
35
+ - 日期按月份天数与闰年校验(`1990-02-30`、`2026-04-31` 不再静默滚到下个月)
36
+ - `bazi / ziwei / hepan` 的 gender 改为必填(缺省按男命排会让大运/大限方向整个反掉)
37
+ - 六爻爻数 ≠ 6 时报错(不再悄悄换成随机卦);塔罗张数非 1/3/5 时报错;`asOf` 非法时报错(不再静默用「此刻」)
38
+ - 工具层 `execute()` 统一包上 `[错误码]` 前缀,内部异常不再以堆栈式文案直出
39
+ - **合盘口径与单盘对齐**:合盘现在把 `address / longitude / trueSolar / lateZi` 分别透传给双方(工具层也会为 `partner.address` 解析经度)。此前合盘完全忽略地址,同一次出生在单盘是 丁丑 日、在合盘里却是 戊寅 日
40
+ - 新增 `test/hepan.test.mjs`:断言「合盘里的你 == 单盘的你」,八字与紫微两条链路都覆盖
41
+ - **解析文案修复**:`命局身身强`(level 已含「身」)、`调候上还初夏`(硬拼连接词)、同一段两次「调候上…」、大运与流年档位并成一句导致建议前后矛盾
42
+ - 新增 `test/interpret-copy.test.mjs`:对 8 个体系的实际输出做病句/重复/未定义值扫描
43
+ - 测试新增 `test/args.test.mjs`(40 条)、`test/security.test.mjs`(10 条)、`test/hepan.test.mjs`(7 条)、`test/interpret-copy.test.mjs`(63 条),全量 31 个文件 893 条 PASS
44
+ - CI 增加「断言数不低于基线」与「测试自检」两步
45
+
46
+ ## 0.14.0 —— 奇门、合盘与节气精度(此前只存在于工作树,本版一并落库)
47
+
48
+ - 新增**奇门遁甲**(时家转盘:拆补 / 超神接气 / 置闰三派取局、值符值使、九宫、空亡驿马)与对应解读
49
+ - 新增**合盘**:八字合盘(日主关系 / 夫妻宫 / 五行互补)与紫微合盘(命宫、夫妻宫、五行局)
50
+ - 节气计算改用 **VSOP87B 截断级数 + 岁差 + 章动 + 光行差**,与 NAOJ 历要项对拍偏差降到 1 分钟内
51
+ - `parseDateTime` 对 ΔT 覆盖范围(1900–2100)之外的年份给出精度提示,摘要顶部标 ⚠
52
+ - `geocodeAddress` 支持地址更细时联网(Nominatim)兜底,失败退回内置坐标表
53
+ - 六壬补神煞与格局文案;紫微补流月/流日/流时并接入盘面与解读
54
+ - `tools/qimen-divergence.mjs`:枚举三派取局的分裂样本,供排盘差异核对
55
+
5
56
  ## 0.13.6
6
57
 
7
58
  - 修 `npm run release` 的发布后核对:npm 的发布是异步的(PUT 返回 202,registry 生效实测要 1–4 分钟),脚本原来 30 秒就判定失败
package/README.md CHANGED
@@ -68,6 +68,7 @@ Chinese metaphysics for [DeepSeek Harness](https://github.com/deepseek-ai/deepse
68
68
 
69
69
  - **结构化输出**:`{ moduleType, system, title, lead, dimensions[], sections[], disclaimer }`;`moduleType` 为 `natal`(命盘)/ `divination`(卦象)/ `card`(牌阵),`dimensions` 固定五个维度
70
70
  - **五个维度**:整体运势、工作与职业选择、事业发展、爱情与感情、健康状况——每项给「解读 + 行动建议」
71
+ - **依据可核对**:命盘类(八字 / 紫微)每个维度都附一行「依据」,列出这条结论引用的盘面事实(日主与旺衰、月令、喜忌、大运流年、宫位主星、煞星等),面板与文本两条路径都会显示;卦象类的"依据"就是上方的卦面本身
71
72
  - **卦象**(六爻/梅花/大六壬)额外给:卦名与卦辞大意、爻辞与动爻、体用关系、互卦与变卦、落到生活里
72
73
  - **塔罗**额外给:整盘连贯解读(把几张牌串成一条线,避免各张互相矛盾)与牌面结构(大阿卡纳占比、元素分布、正逆位)
73
74
  - **文案口径**:第二人称、温和、只给倾向与建议,不作绝对判断;底部保留理性参考的免责提示
@@ -133,17 +134,20 @@ dsh plugin install ./dsh-metaphysics-0.6.0.tgz
133
134
 
134
135
  ## 精度与口径
135
136
 
136
- - **节气**:Meeus 低精度太阳黄经,与公开历书相差 −3 ~ −8 分钟;出生时刻距「节」不足 15 分钟时会提示复核
137
+ - **节气**:VSOP87B 截断级数(105 项)+ 岁差 + 章动 + 光行差;与日本国立天文台《暦要項》对拍,2024/2025 共 48 个节气最大偏差 **0.6 分钟**;出生时刻距「节」不足 20 分钟时会提示复核。**1929-01-01 之前按北京地方平时(UTC+7.7611)**推算,之后按东八区——与农历共用同一套换算,避免 14 分钟错位
137
138
  - **农历**:定朔(Meeus 第 49 章,误差约 1 分钟)+ 冬至所在月为十一月 + 无中气置闰
138
- - **真太阳时**:经度差 + 均时差;内置 34 个省会 + 200 个地级市坐标(±0.2°),地址更细时可开「联网精确到区县」(Nominatim)。只按经度修正,**未含历史时区与夏令时**:海外出生请先把当地钟表时间换算成东八区标准时再输入
139
+ - **真太阳时**:经度差 + 均时差;内置 34 个省会 + 200 个地级市坐标(±0.2°),地址更细时可开「联网精确到区县」(Nominatim)。**单盘与合盘用的是同一套修正**(合盘双方各按自己出生地算)。只按经度修正,**未含历史时区与夏令时**:海外出生请先把当地钟表时间换算成东八区标准时再输入;没给经度时摘要首行会出 ⚠
140
+ - **晚子时**:八字/大六壬默认 23:00 后换日,奇门默认归当日;`lateZi` 与 `lateZiHourMode` 是同一个开关的两个名字。各体系摘要都会写明本次采用的口径,不改默认值、不偷偷改盘
141
+ - **可复现**:塔罗/六爻给 `seed` 即得同一次抽牌/摇卦;紫微流月流日流时、塔罗的抽牌时刻、八字的流年基准年都可传 `asOf` 钉死
139
142
  - **紫微四化**:中州派常用表(庚干作太阳禄、武曲权、太阴科、天同忌)
140
143
  - **日主旺衰**:量化算法,非唯一流派
144
+ - **入参**:日期按月份天数与闰年校验(`1990-02-30` 直接报错,不滚到下个月);八字/紫微/合盘的性别必填(性别决定大运大限顺逆,不做默认);六爻爻值必须正好 6 个,留空才随机摇卦。非法入参带错误码返回(`E_INPUT` / `E_LINES` / `E_COUNT` / `E_ASOF` / `E_PARTNER`),不静默改成另一个盘
141
145
 
142
146
  ## 数据与隐私
143
147
 
144
148
  - 全部计算在本地完成
145
- - 唯一可能的网络请求:开启「联网精确到区县」时的 OpenStreetMap Nominatim 查询;失败即回退内置坐标表
146
- - 不收集、不上传任何数据
149
+ - **默认不联网**:地址只查内置坐标表(最细到地级市,足够真太阳时)。只有把 `geocode` 设为 `online`(面板上勾「联网精确到区县」)才会把出生地原文发给 OpenStreetMap Nominatim,用于精确到区县/路名;失败即回退内置表,同一地址 6 小时内不重复请求
150
+ - 不收集、不上传任何其他数据
147
151
 
148
152
  ## 开发
149
153
 
@@ -151,10 +155,24 @@ dsh plugin install ./dsh-metaphysics-0.6.0.tgz
151
155
  npm run build # 生成 client.js(浏览器端产物)
152
156
  npm run build:html # 生成独立的 命理排盘.html(可离线双击使用)
153
157
  npm test # 顺序跑完 test/ 下全部 *.test.mjs 并汇总
158
+ npm run test:ci # 回归 + 断言基线 + 测试自检 + HTML 注入面 + 工程约定(CI 跑的就是这条)
159
+ npm run test:baseline # 断言数确实要减少时,显式重建基线
160
+ npm run check:html # 单独跑 HTML 注入面扫描
161
+ npm run check:patterns # 单独跑工程约定检查
154
162
  npm run release # 测试 → 构建 → 校验产物 → 发 npm(token 从 NPM_TOKEN 读)
155
163
  ```
156
164
 
157
- 也可以直接调脚本:`node tools/build-client.mjs`、`node tools/build-html.mjs`、`node tools/test-all.mjs`、`node tools/release.mjs`。
165
+ 也可以直接调脚本:`node tools/build-client.mjs`、`node tools/build-html.mjs`、`node tools/test-all.mjs`、`node tools/check-assertions.mjs`、`node tools/verify-tests-can-fail.mjs`、`node tools/check-html-sinks.mjs`、`node tools/check-patterns.mjs`、`node tools/release.mjs`。
166
+
167
+ **测试的四道闸 + 一道稳定性扫射**:
168
+
169
+ 1. `test/_harness.mjs`——任何一条 `ok()` 失败都让进程非零退出(此前 9 个文件只打印不失败,全量"全绿"没有意义)
170
+ 2. `test/assertion-baseline.json`——每个文件的 PASS 条数低于基线即失败,防止"删断言让测试变绿"
171
+ 3. `tools/verify-tests-can-fail.mjs`——故意写错一条断言,必须真的变红,防止第 1 条被改回去
172
+ 4. `tools/check-html-sinks.mjs`——`innerHTML` 里拼接的量必须经过白名单转义函数,否则 CI 直接红
173
+ 5. `tools/check-patterns.mjs`——engine 不得引用浏览器/Node API 与 `console`,不得用 `var`/`debugger`,`new Date()` 与 `Math.random` 只允许出现在白名单文件
174
+ 6. `test/fuzz.test.mjs`——固定种子的随机生日扫射八个体系,覆盖边界日期、参数矩阵与"同参数必得同结果"
175
+
158
176
  `client.js` 是构建产物,不要手改;改动记录见 [CHANGELOG.md](CHANGELOG.md)。
159
177
 
160
178
  ### 发版
@@ -195,3 +213,4 @@ NPM_CLI=/path/to/npm-cli.js NPM_TOKEN=... npm run release # 本机没有 npm C
195
213
  ## License
196
214
 
197
215
  MIT
216
+