dsh-metaphysics 0.62.1 → 0.62.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/CHANGELOG.md +63 -1
  2. package/README.md +2 -2
  3. package/client.almanac.js +69 -65
  4. package/client.bazi.js +122 -118
  5. package/client.chenggu.js +69 -65
  6. package/client.convert.js +71 -67
  7. package/client.daliuren.js +119 -115
  8. package/client.fengshui.js +68 -64
  9. package/client.hepan.js +123 -119
  10. package/client.js +192 -192
  11. package/client.liuyao.js +121 -117
  12. package/client.mbti.js +69 -65
  13. package/client.name.js +69 -65
  14. package/client.numerology.js +68 -64
  15. package/client.qimen.js +124 -120
  16. package/client.star.js +69 -65
  17. package/client.tarot.js +120 -116
  18. package/client.trend.js +113 -109
  19. package/client.xiaoliuren.js +78 -74
  20. package/client.zeri.js +68 -64
  21. package/client.ziwei.js +123 -119
  22. package/docs/assets/verification-badge.svg +6 -6
  23. package/engine/almanac.js +10 -6
  24. package/engine/bazi.js +10 -6
  25. package/engine/bool.js +195 -0
  26. package/engine/calendar.js +10 -2
  27. package/engine/chenggu.js +2 -1
  28. package/engine/convert.js +2 -1
  29. package/engine/daliuren.js +2 -1
  30. package/engine/diff.js +5 -3
  31. package/engine/fengshui.js +33 -12
  32. package/engine/geju.js +16 -3
  33. package/engine/geo.js +2 -1
  34. package/engine/hepan.js +4 -3
  35. package/engine/index.js +202 -72
  36. package/engine/liuyao.js +24 -5
  37. package/engine/mbti.js +6 -1
  38. package/engine/meihua.js +21 -7
  39. package/engine/name.js +20 -12
  40. package/engine/random.js +17 -3
  41. package/engine/rectify.js +4 -3
  42. package/engine/tarot.js +22 -8
  43. package/engine/trace.js +2 -1
  44. package/engine/trend.js +7 -3
  45. package/engine/xiaoliuren.js +2 -1
  46. package/engine/ziwei.js +4 -3
  47. package/index.js +367 -42
  48. package/package.json +1 -1
  49. package//345/221/275/347/220/206/346/216/222/347/233/230.html +629 -160
package/CHANGELOG.md CHANGED
@@ -1,4 +1,66 @@
1
- ## 0.62.1(2026-11-04,待发布)
1
+ ## 0.62.3(2026-11-06,待发布)
2
+
3
+ > 本段主题:复查 0.62.2 发布后的三处「看不见的错」——对拍报告把 127 条没有起卦日的卦例标成「旬空一致」(其实拿今天算、每换一旬页面就变),README 说「每个体系都有解析」而实际只有 7 个体系有,以及徽章只挂「0 处不符」、把「127 项未核」这个口径藏在了报告里。
4
+
5
+ > 续(同日):以 tyme4ts(寿星天文历)为外部基准做玄学口径对拍,修掉三处会算错的——月令取格按柱位而非藏干位阶、黄历拿当日正午比交节时刻、「巳」的中气/余气颠倒;并把风水命卦/月紫白的立春界统一到同一口径。
6
+
7
+ - **月令取格:按藏干位阶(本气→中气→余气),不再按柱位先遇上谁用谁**(`engine/geju.js` 的 `monthPattern`):原实现 `['year','month','hour'].find(k => cands.some(...))` 取第一个透出藏干的**柱**,于是年干透余气会把月干透本气挤掉。实测 `戊戌 甲寅 丙子 癸巳`(2018-02-13 10:00)排「食神格」、理由写「余气戊透于年干」,而月干甲是寅的本气、丙火的偏印,明明贴着月令却被跳过。抽样 1,502 盘:19.5% 有两处以上不同藏干并透,改前其中七成以上取到的不是最高位阶——即约每十盘就有一盘的格局名不同,而格局是用神、喜忌、行运评分与解读文案的输入。现按「本气透则取本气,不透再取中气、余气」遍历,同一藏干多柱并透时报「月」优先。
8
+ - **黄历:交节按「日」判,不再拿当日正午比时刻**(`engine/almanac.js` 的 `buildAlmanac`):黄历按日出版,却用 `jdNoon`(当日 12:00)去比交节时刻。交节若在午后,正午还没交节,整天仍算上个月。以 2020-02-04(立春 17:03)为例:旧输出月柱丁丑、建日、朱雀,通行黄历为戊寅月、闭日、明堂;同一页的「下一个节气」还写着「立春(今天)」,自相矛盾。每年 12 个「节」约一半落在午后 → 每年约 6 天月柱、建除、值日神全错,且 `zeri.js` 逐日调用 `buildAlmanac`,择日整块继承。现统一比「节气所在日序」(`Math.floor(jd + 0.5) <= jdn`),年柱、月柱、上一/下一节气同理;八字侧仍按精确到分的交节时刻判月柱,两者不共用这一层。对拍 2015–2035 逐日 7,670 天,建除 / 值日星神 / 二十八宿 / 年柱与基准 **0 差异**(改前交节日及次日 264 天里错 69 天)。
9
+ - **「巳」藏干改为丙庚戊**(`engine/bazi.js` 的 `HIDDEN_STEMS`、`engine/geju.js` 的 `HIDDEN`):原写「丙戊庚」,把中气给了戊土(0.5)、余气给了庚金(0.3)。按本仓库自己的 `RENYUAN_TABLE`(巳月:戊 5 日 → 庚 9 日 → 丙 16 日,与藏干互为倒序)以及「长生=中气」的同构写法(寅甲丙戊、申庚壬戊、亥壬甲),应为丙(本)庚(中)戊(余);寿星天文历亦作丙庚戊。影响:见巳的盘五行由土 +0.2 / 金 −0.2 纠正(`1990-05-12 14:30` 输出由 土3.0/金2.6 变为 土2.8/金2.8),庚辛或戊己的通根分随之 ±0.2~0.24。连带一处状态翻转:`1962-11-05` 的炎上格因财由 1.8 升到 2.0、越过「财 >1.8 耗旺气」的破格线,从「待定」转「破格」(已单钉一条断言,见下)。
10
+ - **风水:立春界与月紫白跟黄历对齐**(`engine/fengshui.js`):`guaYearOf` 的注释原来写着「按正午判,与黄历一致」,而黄历这轮已改成按日——两者会差一天。现统一按日(立春当日即算新年;命卦只按出生年取,同一天出生的人不因生在 16:27 前后换卦)。`timeFlyingOf` 原来无条件用正午比节气,给了时刻也一样:14:30 出生、当天 17:03 才立春,本应还在上月,却被算成新月的年与月。现按「给了时刻用时刻、只给日期用日」,且年紫白与月紫白共用同一个基准——否则立春当天会出现「年已甲辰、月还是丑月」的自相矛盾。另清掉黄历里算了却不用的 `nextJie`。
11
+ - **回归锁**:`test/geju.test.mjs` 新增「本气甲透月干 → 偏印格」「取格依据点名本气与月干」,并加一条结构不变量(抽样 80 盘:本气透出时月令格必须取本气,劫财按月劫论);`test/bazi.test.mjs` 新增「巳藏干为丙庚戊 / 角色序 / 金 2.8 土 2.8」三条;`test/tools.test.mjs` 把原来那条「立春当日按正午判尚未交节(已知日界口径)」改成「立春当日即换年柱甲辰、月柱丙寅」,并补 2020-02-04 三件套与「下一个节气不再是自己」;`test/bazi-special.test.mjs` 的待定样本换成 1951-07-25,另加「财过线即破格」;`test/classic-quotes.test.mjs` 的炎上格样本换成 1951-07-25(破格不配专章);`test/yongshen-neutral.test.mjs` 的中性样本换成 1983-12-06(原样本的金来自巳、已按中气计 0.5,不再属于「近零」);`test/fengshui-tigua-zibai.test.mjs` 补 5 条立春当日断言(12:00 仍癸卯/丑月、20:00 转甲辰/立春、只给日期与给 20:00 同盘)。
12
+
13
+ - **对拍报告:没有起卦日就标「旬空未核」,不再拿今天充数**(`tools/verification.mjs`、`test/verification.test.mjs`):《卜筮正宗》128 条卦例里只有 1 条记了起卦日,其余 127 条的 `dayOf(ex.date)` 返回 `undefined`,传给 `buildLiuyao` 后引擎按「今天」补日干支;而 `if (ex.kong && dayOf(ex.date))` 又把旬空比对整个跳过。结果就是页面上「期望 空辰巳 / 引擎 空午未」还标「一致」,而且每换一旬报告内容就变一次——`check-verification` 的「与源码逐字节一致」注定在某天变红(0.62.2 发布次日即复现)。现:无起卦日 → 期望写「空辰巳(未核)」、引擎写「空—(未核)」、对拍项写「旬空(未核:原表无起卦日)」、行上带 `unchecked: true`,汇总与页面卡片单列「未核 127 项」;同时给引擎传固定占位日(甲子),保证报告与系统日期完全无关。
14
+ - **徽章把「127 项未核」写在脸上,宽度随内容自适应**(`tools/verification.mjs`、`README.md`、`test/verification.test.mjs`):徽章原来只有「0 处不符|128 例 · 5 剔除 · 312 紫微 · 20 奇门 · 12 交运」,看的人会以为 128 条都核过了;现补一段「· 127 未核」(`unchecked` 为 0 时不写,不挂「0 未核」的废话)。为容纳新增文字,宽度不再写死 470,改由 `badgeTextWidth()` 按内容估算(中文/全角 1em、数字与字母 0.65em、空格 0.32em、其余符号 0.45em,两侧各留 18px),数字位数变长(如 127 → 1270)时徽章自动变宽,字不会被顶出彩色面板。README 的徽章 alt 同步改成「0 处不符(127 项未核)」。
15
+ - **回归锁**(`test/verification.test.mjs`):新增「未核行不给旬空值 / 期望与对拍项都写明未核 / 未核行仍按其余四项判一致」三条;用唯一带日期的「申月甲午日」用例锁「有起卦日照旧核旬空、改坏会被抓」;并新增「跨日期渲染逐字节一致」(把 `Date` 冻结到 2026-11-06 与 2027-03-19 各渲染一次比对),锁住「跨旬重建 → 报告与源码不一致 → CI 红」那类回归。徽章另加 6 条:含「127 未核」、未核数与 `totals` 同源、总宽=左栏 62 + 右栏、估算宽度 + 两侧留白 ≤ 右栏、数字变长时徽章跟着变宽、未核为 0 时不出现「0 未核」。
16
+ - **解析范围:README 与工具说明改成准确的 7 个体系**(`README.md`、`engine/index.js`):原文「每个体系的排盘结果下方都会跟一个『解析与详解』模块」与实际不符——实测只有 bazi / ziwei / liuyao / meihua / daliuren / qimen / tarot 产出 `interpret`;hepan 有自己的逐项对照详批、trend 有自己的阶段报告、name 有自己的五格与音韵评估,其余速查类(黄历 / 择日 / 称骨 / 小六壬 / 星座 / 生命数字 / 人格 / 公农历互转)不附解析。`withInterpret` 的 schema 说明与工具长描述同步点名范围,免得模型对速查类白传。
17
+ - **ΔT 远年外推:2100 年后改用抛物线公式**(`engine/calendar.js` 的 `deltaTSeconds`):原实现 2100 年后返回常数 110 秒,未考虑地球自转长期减慢的二次效应。Morrison & Stephenson (2004) 抛物线为 **ΔT ≈ 32 × ((year − 1820)/100)² 秒**(括号里是世纪);本实现以 2100 端点 110s 接续增长率,保证 2100→2101 连续:2101 约 112s、2200 约 321s、2400 约 936s。**发版前复查抓到的单位错误**:初版写成 `32 × (year − 1820)²`,2400 年得到 1076 万秒(约 124 天),节气与朔望会整体推后几个月(CI 里 2400 年农历、朔望全部错位);现按世纪平方修正,并加「量级 < 3600s、2100 连续、2100→2400 单调」回归锁。影响范围:`termInstantJd` 求节气时刻、`newMoonJd` 求合朔时刻均经此函数修正 TT→UT,远年农历置闰与节气定位随之纠正。
18
+
19
+ ## 0.62.2(2026-11-05)
20
+
21
+ > 已发布:npm `dsh-metaphysics@0.62.2`,shasum `13ca04fb9ad703addf3bc40ea01a7e26ff9a9bdb`,102 个文件;tag `v0.62.2` 已推,GitHub release 已建,tarball 已下载核对。
22
+
23
+ > 本段主题:复查 0.62.1 的静默错值——开关与数字的「盘面 / 句柄」口径不一致、brief 的 12KB 闸门量错了单位、以及闸门本身有早退与预留不足;随后按使用方要求把这道体积闸门整个移除,只保留表格行数限制。
24
+
25
+ - **开关口径:字符串布尔与真布尔排同一张盘**(新增 `engine/bool.js` 的 `canonicalFlags()`、`engine/index.js` 入口、各引擎读值):`trueSolar:"false"` 以前由 `!== false` 读到「开」,盘按真太阳时排,句柄却照着原文写 `false`——同一张盘两个身份,影子盘对拍、深链回放、跨版本 diff 全部错位;`lateZi` / `dst` / `isLeapMonth` / `leapAsNext` 同理,`withInterpret:"false"` 也照旧附解析。现入口一次归一成真布尔,18 个体系的开关读值统一走 `bool()`(`chenggu / daliuren / diff / fengshui / hepan / meihua / name / rectify / trend / xiaoliuren / ziwei` 一并改),合盘 `partner` / `partner2` 里的同名开关同样归一;空串 / 空白串按「没给」剔除,避免 `lateZi:""` 被折成全局缺省 true、把奇门(缺省 same-day)与紫微(缺省 current-day)排成另一张盘。
26
+ - **brief 的 12KB 改按 UTF-8 字节计**(`engine/index.js`、`test/detail-tier.test.mjs`):原闸门比的是 `String#length`,中文 1 字≈3 字节,等于把上限放宽到约 36KB。顺带修掉三处同源问题:没有能力边界/免责声明时早退、闸门被整个跳过(实测 18KB);尾注预留写死 80 字节、压完仍超两三字节;超长单行按「最后一个换行」截断后只剩标题一行。(该上限随后被整体移除,见下方「去掉解析段的 12KB 上限」。)
27
+ - **只给日期时不再静默按 00:00 排**(`engine/index.js`):`datetime:'1990-05-12'` 会被 `parseDateTime` 补齐时分 0,于是照常排出完整四柱、起好局,盘面上看不出任何异常。现对 bazi / ziwei / hepan / trend / meihua(时间起卦)/ daliuren / qimen / name 在摘要首行明确标注「按 00:00 暂算」,并按体系给出该怎么补(紫微排不出三柱、奇门要给起局时辰、八字可传 `hourUnknown`),结果里另带 `timeMissing: true` 供面板与模型判断。六爻只取日辰与月建、不看钟点,梅花数字起卦只读 upper/lower,故不提示;合盘还逐一点名 `partner` / `partner2` 里缺时刻的一方;黄历/择日/公农历只以「日」为输入,不加提示;称骨与小六壬缺时辰本就报错。
28
+ - **构建:`bool` 排到 `diff` 之前**(`tools/build-client.mjs`):分块按 `ORDER` 执行,`diff` 现在依赖 `bool`,不前置会取到 `undefined`;`check-bundle` 已按新顺序自检通过,`client.*` 与离线页重建。
29
+ - **数字口径:数字串与数字排同一张盘、同一个句柄**(`engine/bool.js` 的 `canonicalNumbers()`、`engine/index.js` 入口):句柄编码的是参数原文,`count:"3"` 与 `count:3` 抽出同一副牌却换一个句柄,影子盘对拍与深链回放会认成两张盘。入口现按 schema 的 26 个数值键 + 3 个数值数组(`lines` / `rectifyHours` / `answers`)+ 2 个笔画映射(`strokeOverrides` / `surnameStrokes`)统一转数字,只转「整串就是一个数」的写法(与宿主 `normalizeArgs` 同一把尺:指数 `1e3`、尾点 `5.` 也算),`"9运"` / `"三十"` 仍原样交给范围校验报错;空串 / 空白串按「没给」剔除(否则梅花 `upper:""` 会被 `Number("")` 读成 0、风水 `period:""` 报「收到「」」);否则 `seed:"1e3"` 与 `seed:1000` 会抽出同一副牌却拿到两个句柄。两处不只影响身份、是实打实算错的:风水 `period:"9"` 被 1–9 校验拒掉(报错里还写着「收到「9」」,看着像误报);起名 `strokeOverrides:{"秋":"9"}` 被 `overridesOf` 静默丢弃,五格退回字库笔画,用户给的笔画根本没参与计算(现另在 `engine/name.js` 兜一层,`source` 正确标成 `user`)。
30
+ - **去掉解析段的 12KB 上限**(`engine/index.js`、`index.js` 参数说明、`test/detail-tier.test.mjs`):这道闸门从「按字符数」改到「按字节」之后仍然只是把断点往前挪——一超限就从正文中部腰斩,结论、依据、「本插件不回答什么」得靠额外预留位抢救,读到的是半句话;而它省下的体积本就不大。现整段移除:删掉 `BRIEF_CAP`、`utf8Bytes`、`cutByBytes` 与「已截到 12KB」尾注,`interpretText` 一律「算多少给多少」,输出只受结构约束——**brief 只保留表格行数限制**(每表最多 8 行,超出提示「共 N 行,仅列前 8 行;全表传 detail:"lean"`),另加「长论述 ≥300 字不展开、名词解释不附」这两项同属结构层的收敛。工具说明同步改为「解析段不设体积上限,超长就长」,不再出现 12KB 字样。
31
+ - **回归锁(改向)**:`test/detail-tier.test.mjs` ②c 由「brief 必须压到 12KB 内」改为「超长解析一字不删」——构造 2000 字结论 + 1500 字人话 + 1000 字维度,断言 brief 与 full 逐字一致、无截断提示、无半截字;②e 改为源码级反查(引擎里不得再出现 `BRIEF_CAP` / `cutByBytes` / 「已截到 12KB」),防止闸门被改头换面地加回来。
32
+ - **第二轮复查:边界条件、空值与分支遗漏**(`engine/*`、`index.js`、`src/app.js`):
33
+ - **趋势时辰未知按正午算**(`engine/trend.js`):`hourUnknown` 以前只挂在结果上、没传进 `buildBazi`,摘要写着「按正午暂算」,旺衰却按日期串缺省出的 00:00 算成另一档(实测同一生日 3 分 vs 6 分)。现与八字同一口径:内部按正午占位、时柱收回。
34
+ - **合盘第三方时辰未知也拦**(`engine/index.js`):主方/对方 `hourUnknown` 会报 `HOUR_UNKNOWN`,`partner2` 却被漏掉,第三方仍按 00:00 排出三方合盘。现三方同一口径。
35
+ - **合盘十神方向文案**(`engine/hepan.js`):`tenGod(a,b)` 是「对方在我盘里」,文案却写成「你在对方盘里」,两边说反。现按 `tenGodToB / tenGodToA` 的实际含义输出。
36
+ - **梅花数字起卦拒收 null / false / []**(`engine/meihua.js`):`Number(null)` / `Number(false)` / `Number([])` 都是 0,缺参会静默起成「坤为地」。现只收真正的数字(`0` 仍是合法输入)。
37
+ - **seed 只认十进制**(`engine/random.js`):`Number("0x10")` / `Number(false)` / `Number([])` 都能过旧 `isSeed`,工具层却按 number 拒绝——同一输入两条路。现与宿主同一把尺,十六进制、布尔、数组一律 `E_INPUT`,十进制数字串仍与数字同句柄。
38
+ - **塔罗 question 非字符串不再裸 TypeError**(`engine/tarot.js`):`question:123` 以前在 `(question || '').trim()` 处抛 `E_INTERNAL`;现统一转字符串。
39
+ - **风水命卦世纪推进与日期守卫**(`engine/fengshui.js`):世纪常数只在「>=2000」切一次,2100–2400 年仍沿用 2000 年代的 99/3,整档算错;现每世纪递减(男 100→99→98,女 4→3→2),1900s/2000s 结果不变。另补 `assertCivil`(2 月 30 日不再静默滚月)、`fortuneYear` 限 1600–2400(0/负数不再出飞星)。
40
+ - **起名数理大数取模**(`engine/name.js`):`strokeOverrides` 允许任意正整数,`shuliOf(1e12)` 用 while 递减会空转一百多亿次;现改为取模,正常值结果不变。
41
+ - **schema 枚举真正生效**(`index.js`、`engine/index.js`):枚举以前只写给模型看,`direction:"romance"` 静默按 general、`gender:"女"` 在六爻静默按 male。现工具层 `normalizeArgs` 校验字符串枚举,引擎入口也校 `gender / direction`,非法值直接 `E_INPUT`。
42
+ - **面板加载态竞态**(`src/app.js`):旧一次 `ensureEngine` 晚于新一次落定时,`finally` 无条件关掉 loading,会让新一次还在加载时转圈先消失;现只有当前 token 才允许关闭。
43
+ - **回归锁**:`test/bool-flags.test.mjs`(18 体系 × 10 开关 × 4 种写法做整盘比对,含句柄与影子盘 ID;另加数字串整盘比对、笔画覆盖来源、非法写法仍报错,以及「schema 里的数值参数是否都进了归一表」的同步断言,防止以后加参数漏一刀);`test/args.test.mjs` 补引擎直调开关归一、「只给日期」两组(工具层归一过、引擎直调没有),以及本轮的趋势正午占位、第三方 hourUnknown、十神方向、梅花空值、seed 十六进制、塔罗数字所问、风水世纪命卦、数理大数、枚举校验共 26 条;`test/detail-tier.test.mjs` ②d 锁住「盘面、句柄、能力边界一个字都不裁」(②c/②e 的改向见上条)。
44
+ - **第三轮复查:把上一轮的「仅建议」项补齐**(`engine/liuyao.js`、`engine/tarot.js`、`engine/mbti.js`、`engine/index.js`、`index.js`):
45
+ - **六爻直调 seed 真正生效**:文档写着 `seed` 可复现,直接 `buildLiuyao({ seed })` 却仍走 `Math.random`;现与工具层共用 `randomOf()`,非法 seed 与非函数 `random` 当场 `E_INPUT`(显式注入的 random 仍优先)。
46
+ - **六爻辅助函数 opts=null 同口径**:`yongshenOf` 已把 null 当默认,但 `yongshenStrength / fushenAccess / hexagramStrength / jinTuiPower / yingqiWindow` 仍会在读 `opts.monthBranch` 时抛裸 TypeError;现统一走 `liuyaoOpts()`:省略或 null 按默认,显式给错类型仍 `E_INPUT`。
47
+ - **塔罗牌库外牌名不再读成空牌义**:未知牌名以前只得到「正位:。」式空句;现开场点名哪些牌不在韦特 78 张库内,逐张退回正/逆位泛义;另补「愚人 → 愚者」常见别名(只做显式别名、不做模糊匹配,避免拼错被猜成另一张)。
48
+ - **options:null 与不传等价**:MCP 客户端把「没有 options」写成 null 时,`flattenOptions` 以前报「options 必须是对象」;现与 undefined 同义。
49
+ - **MBTI 未答维度可见**:整维未答时 letter 只是平手占位,以前只在强度写「未作答」;现结果带 `unanswered: ["EI"]`,说明与摘要首行都点名,避免把占位当成测出来的结论。
50
+ - **回归锁(第三轮)**:`test/args.test.mjs` 再补 16 条(六爻 seed 复现 / 非法值、random 类型、options:null、五个辅助函数 null opts、塔罗别名与未知牌名、MBTI 未答维度)。
51
+ - **第四轮复查:把「读盘时才用」的口径在每一层都传到位**(`engine/bool.js`、`engine/index.js`、`engine/name.js`、`engine/meihua.js`):
52
+ - **合盘对方 `hourUnknown` 归一**(`engine/bool.js`):`PARTNER_FLAGS` 漏了 `hourUnknown`,`partner.hourUnknown:"false"` 会绕过归一按真值读,和 `false` 排出两套结果;现与 `lateZi / trueSolar / dst` 同一张表,缺省固定 `false`(合盘遇到 `true` 才拦 `HOUR_UNKNOWN`)。
53
+ - **紫微合盘晚子时 / 闰月口径透传**(`engine/index.js`):`chart:'ziwei'` 的 `sideOf` 只把 `lateZi` 原样带下去,紫微读的却是 `lateZishi`,于是 `lateZi:false` 与 `true` 排出的合盘一字不差;闰月 `leapMonth / leapAsNext` 也没传,闰月出生时合盘与单盘差一个月。现按 `lateZi` → `lateZishi` 映射,并把两个闰月参数一并透传。
54
+ - **八字 × 紫微交叉验证同口径**(`engine/index.js`):`cross:true` 时交叉的紫微盘没接八字的 `lateZi`,23:00 后一边按次日、一边按当日,等于拿两个生日互证。现八字显式给的 `lateZi` 映射进紫微交叉盘(显式 `lateZishi` 优先);没给时仍按紫微自己的 `current-day` 缺省,不改既有交叉结果。
55
+ - **`asOf` 年份闸与补零**(`engine/index.js`):此前只校验月日时,`1500 / 2500 / 9999` 会排进流月流日,农历表却只覆盖 1600–2400;现与 `parseDateTime / assertCivil` 同一把尺,越界报 `E_ASOF` 并点名范围。`normalizeAsOf` 把年份补到 4 位,`0000` 不再变成 `0-01-01T12:00` 报「无法解析」。
56
+ - **起名分开年月日缺时刻**(`engine/name.js`、`engine/index.js`):`year/month/day` 分开给生辰、没给 `hour` 时,`buildName` 的缺省占位是 `12:00`,与 `datetime` 只给日期走的 `00:00` 不是同一张盘;现统一按 `00:00` 占位,并打 `timeMissing`、摘要首行提示补时刻。
57
+ - **梅花数字起卦的整数闸**(`engine/meihua.js`):`upper:3.5` 会一路走到 `bitsOf` 才抛裸 TypeError;`changing:true / [3] / 2.5` 被 `Number()` 折成 1/3/2。现 `upper / lower` 只收整数,`changing` 只收 1–6 整数;十进制数字串 `"2"` 仍按第 2 爻。
58
+ - **回归锁(第四轮)**:`test/bool-flags.test.mjs` 补合盘对方 `hourUnknown` 字符串/布尔同盘、合盘紫微 `lateZi` 开/关与单盘 `lateZishi` 同命宫;`test/args.test.mjs` 补 `asOf` 六个越界值 + 两端点 + `0000` 文案、`name` 分开年月日缺时刻同盘、梅花小数/布尔/数组动爻、交叉验证 `lateZi` 与单盘夫妻宫同星;`test/ziwei-hepan.test.mjs` 补 `lateZi` 与 `leapMonth / leapAsNext` 透传;`test/meihua.test.mjs` 的缺参文案断言跟到「两个整数」。
59
+ - 基线:**155 文件 / 8184 条断言**(7894 → 8021 → 8049 → 8110 → 8136 → 8152 → 8184,全为新增)。
60
+
61
+ ## 0.62.1(2026-11-04,已发布)
62
+
63
+ > 已发布:npm `dsh-metaphysics@0.62.1`,shasum `d95c8cdae02d506c9dda58f181fb2e602f250244`,101 个文件。
2
64
 
3
65
  > 本版主题:全项目复查补漏——星座/生命数字的日期尺与全插件统一、非法 action 不再静默落默认、次级入口的 null 守卫。
4
66
 
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # dsh-metaphysics · 命理排盘
2
2
 
3
- [![公开对拍:0 处不符](docs/assets/verification-badge.svg)](docs/verification.html)
3
+ [![公开对拍:0 处不符(127 项未核)](docs/assets/verification-badge.svg)](docs/verification.html)
4
4
 
5
5
  Chinese metaphysics (玄学 / xuanxue) for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness): BaZi (Four Pillars), Zi Wei Dou Shu, LiuYao, MeiHua YiShu, Da Liu Ren, Qi Men Dun Jia, relationship compatibility, Tarot, plus quick-reference tools — almanac, date selection, bone-weight fortune, Xiao Liu Ren, horoscope, numerology, an MBTI-style 16-type questionnaire, life-curve, feng shui and name analysis.
6
6
 
@@ -141,7 +141,7 @@ Chinese metaphysics (玄学 / xuanxue) for [DeepSeek Harness](https://github.com
141
141
  - **起名 `name`**:1062 字自建字库(常用名用字,按五行分段,每字带**拼音/声调/康熙笔画**),另有**姓氏库 998 姓 + 82 复姓**(`engine/surname-data.js`,逐姓康熙笔画 + 读音;笔画由三份资料互证 + Unihan 部首结构值复算,25 个分歧字逐个裁定并把理由写在模块头);评估时**逐字**给五行、释义、来源与是否合喜用,未收录的字不猜五行但给**同喜用五行的可换字**(也可用 `charElements` 自行指定);**五格剖象**按康熙字典繁体笔画算天格/人格/地格/外格/总格,配通行本 81 数理(超 81 按 −80 回绕)与三才五行,任一字缺笔画就整体返回「算不了」并点名缺哪个字,可用 `strokeOverrides`(逐字)/`surnameStrokes`(按姓)补;多音姓(覃/查/尉…)**主读照算、又读并列显示**,只考证得出笔画的 71 个姓不猜读法、音韵直接落空;**音韵**只做机械检查——全名同调、相邻同声母/同韵母、叠字撞音,判「顺口/略拗/拗口」,**不做语义谐音**;生成候选名按「合喜用 → 两字异行 → 常用字优先 → 五格格数 → 性别倾向 → 字库序」排序,只是排序不是「吉名」判定
142
142
 
143
143
  ### 解析与详解(interpret)
144
- 每个体系的排盘结果下方都会跟一个「解析与详解」模块,帮你把盘面翻译成能看懂、能照着做的事。对话工具里加 `withInterpret: true` 即可一并返回。
144
+ 「解析与详解」把盘面翻译成能看懂、能照着做的事,覆盖**八字、紫微、六爻、梅花、大六壬、奇门、塔罗**这 7 个体系:结果下方跟一个解析模块,对话工具里加 `withInterpret: true` 即可一并返回。合盘有自己的逐项对照详批、人生 K 线有自己的阶段报告、起名有自己的五格与音韵评估,都不再套一层解析;黄历、择日、称骨、小六壬、星座、生命数字、十六型人格、公农历互转属速查类,也不附解析——对这些体系传 `withInterpret` 不会多出这一段(结果里也不会有 `interpretTier`)。
145
145
 
146
146
  - **结构化输出**:`{ moduleType, system, title, lead, dimensions[], sections[], disclaimer }`;`moduleType` 为 `natal`(命盘)/ `divination`(卦象)/ `card`(牌阵),`dimensions` 固定五个维度;`sections` 可带 `tone`(`good`/`watch`/`bad`),面板据此上色
147
147
  - **分层结构与逐宫(0.43 新增)**:紫微多出**命身底色**(命宫主星 + 亮度 + 双星组合 + 身宫落点)、**逐宫分析**(十二宫各一条:宫位取象 + 主星亮度 + 吉星/煞星 + 四化,下接一句读法)与**三层格局**(有利格局 / 结构提示 / 忌格提醒,每条写名称、人话、依据与做法);八字多出**命局框架**(日主/用神/格局 + 一句命局基调)、**正面画像**(外在取象 / 性格底色 / 事业与家庭)、**流年时间轴**(近三年逐条给档位与理由)与**专业建议**(喜用落地 / 忌神自觉 / 地支关系 / 调候)。措辞取自两份独立词库 `engine/ziwei-words.js`、`engine/bazi-words.js`——引擎只出事实,词库只出说法,词库里没有任何判断条件