From 7bd91b3b760af2f0ec6274cc6efdada7bf68f69d Mon Sep 17 00:00:00 2001 From: 732642856 <732642856@qq.com> Date: Wed, 3 Jun 2026 19:29:15 +0800 Subject: [PATCH] Fix D10 varga benchmark precision --- CHANGELOG.md | 24 ++++++++++++++++++++++++ SKILL.md | 8 ++++---- scripts/jyotish_engine.py | 15 +++++++++------ scripts/varga.py | 14 +++++++------- 4 files changed, 44 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8be17f8..03f7776d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,29 @@ # 印度占星 Skill 更新日志 +## v6.0.6-d10-benchmark-fix(2026-06-03)— PyJHora benchmark 暴露的 D10 口径修复 + +> **触发原因**:可信度 benchmark 第三轮接入 PyJHora 后,D10 出现系统性错配;交叉查证 D10 规则为“奇数星座从本宫起算,偶数星座从第九宫起算(含本宫计数)”。 + +### 修复内容 + +- 修正 `scripts/varga.py` 中 D10 偶数星座起算偏移:第九宫含本宫计数,代码应使用 `+8` 而非 `+9`。 +- 修正非 D9 分盘 `degree_in_sign` 输出:从原先的“分段内余度 0-part_size”改为标准“分盘星座内度数 0-30°”。 +- 保持 D9 harmonic 输出口径不变,避免破坏既有 JHora-style Navamsa 结果。 + +--- + +## v6.0.5-precision-benchmark-fix(2026-06-03)— benchmark 暴露的黄经精度修复 + +> **触发原因**:可信度 benchmark 第二轮发现 Dasha 日期与 D10 边界样本存在小偏差,根因是 `full-reading` 在下游 Dasha/分盘模块复用已四舍五入到4位小数的行星黄经。 + +### 修复内容 + +- `compute_chart_data()` 为行星新增 `degree_raw` 与 `degree_in_sign_raw`,保留未四舍五入黄经。 +- `full-reading` 的 Vimshottari Dasha、Varga、Jaimini 等下游汇总优先使用 raw 度数,展示字段继续保留四舍五入格式。 +- 第二轮 benchmark 重跑后:Ascendant、D9、Dasha 100% 匹配;D10 仅保留 Rahu/Ketu 位于切分边界附近的 4 个 boundary-sensitive 字段,归因后可接受率 100%。 + +--- + ## v6.0.4-privacy-sanitized(2026-06-03)— 移除个人化资料 + 隐私隔离规则 > **触发原因**:用户明确要求“关于我个人的信息不可以暴露在印度占星skill里”。本版执行隐私清理:移除或匿名化 skill 中的真实个人星盘、出生资料、人生事件、项目背景、个案解读与回测痕迹,并新增隐私隔离规则。 diff --git a/SKILL.md b/SKILL.md index 551d61d1..19d67408 100644 --- a/SKILL.md +++ b/SKILL.md @@ -1,6 +1,6 @@ --- name: jyotish-vedic-astrology -version: 6.0.4 +version: 6.0.6 description: 印度占星(Jyotish)专业解盘与推运系统。核心能力:PDF星盘输入→严谨解盘→精确推运应期输出。触发词:印度占星、吠陀占星、Jyotish、解盘、推运、星盘分析、Dasha、Transit、Nakshatra、Yoga、出生时间矫正、PDF星盘、读取PDF、分析PDF星盘、现代解读、误判纠错、Varga分盘、综合分析、过境分析、合盘、婚姻匹配、年运盘、Prashna、Argala、Jaimini、KP系统、Shadbala、Ashtakavarga、HTML报告、深度解盘。 --- @@ -10,7 +10,7 @@ description: 印度占星(Jyotish)专业解盘与推运系统。核心能力 > **严格路由**:`references/strict-workflow-router.md`(⭐涉及事业/婚恋/财务/应期/技法验证时必须优先读取) > **覆盖矩阵**:`references/technique-capability-matrix.md`(⭐判断技法 covered/partial/missing 时必须参考) > **机器注册表**:`references/technique_registry.json` + `scripts/audit_capabilities.py`(⭐用于自动审计与CI门禁) -> **版本**:v6.0.4-privacy-sanitized | **详细变更**:`CHANGELOG.md` +> **版本**:v6.0.6-d10-benchmark-fix | **详细变更**:`CHANGELOG.md` --- @@ -255,9 +255,9 @@ $PYTHON $SCRIPT <子命令> [参数] --- -**版本**:v6.0.4-privacy-sanitized +**版本**:v6.0.6-d10-benchmark-fix **创建日期**:2026-04-20 -**最后更新**:2026-06-03(v6.0.4 移除个人化个案资料,并新增用户隐私与个案资料隔离规则) +**最后更新**:2026-06-03(v6.0.6 修正 D10 偶数星座起算与非D9分盘度数缩放口径) --- diff --git a/scripts/jyotish_engine.py b/scripts/jyotish_engine.py index b0834952..7b9c7bb4 100644 --- a/scripts/jyotish_engine.py +++ b/scripts/jyotish_engine.py @@ -311,7 +311,9 @@ def compute_chart_data(year, month, day, hour, minute, lat, lon, tz): nak_n, nak_l, _ = NAKSHATRA_LIST[ni % 27] result["planets"][pname] = { "sign": sign, "sign_cn": SIGNS_CN[sign], "degree": round(lon_p, 4), - "degree_in_sign": round(d_in_s, 4), "house": house, "status": status, + "degree_raw": lon_p, + "degree_in_sign": round(d_in_s, 4), "degree_in_sign_raw": d_in_s, + "house": house, "status": status, "retrograde": retro, "speed": round(spd, 6), "nakshatra": nak_n, "nakshatra_pada": pada, "nakshatra_lord": nak_l} if pname == 'Rahu': @@ -320,7 +322,8 @@ def compute_chart_data(year, month, day, hour, minute, lat, lon, tz): kn, kl, _ = NAKSHATRA_LIST[kni % 27] result["planets"]["Ketu"] = { "sign": SIGNS[ksi], "sign_cn": SIGNS_CN[SIGNS[ksi]], - "degree": round(klon, 4), "degree_in_sign": round(kd, 4), + "degree": round(klon, 4), "degree_raw": klon, + "degree_in_sign": round(kd, 4), "degree_in_sign_raw": kd, "house": ((ksi - asc_idx) % 12) + 1, "status": "中性", "retrograde": True, "speed": round(spd, 6), "nakshatra": kn, "nakshatra_pada": kp, "nakshatra_lord": kl} @@ -2390,7 +2393,7 @@ def cmd_varga_full(args): except ImportError as e: return {"error": f"varga模块导入失败: {e}"} planets = chart.get('planets', {}) - planet_lons = {pn: pd['degree'] for pn, pd in planets.items() if isinstance(pd, dict) and 'degree' in pd} + planet_lons = {pn: pd.get('degree_raw', pd['degree']) for pn, pd in planets.items() if isinstance(pd, dict) and 'degree' in pd} asc_deg = chart.get('ascendant', {}).get('degree', 0) divisions = [int(d.strip().replace('D','')) for d in args.divisions.split(',')] if args.divisions else None return calc_all_vargas(planet_lons, asc_deg, divisions) @@ -3071,8 +3074,8 @@ def cmd_full_reading(args): planets = chart.get('planets', {}) asc_deg = chart.get('ascendant', {}).get('degree', 0) asc_sign = chart.get('ascendant', {}).get('sign', 'Unknown') - planet_lons = {pn: pd['degree'] for pn, pd in planets.items() if isinstance(pd, dict) and 'degree' in pd} - planet_degs = {pn: pd.get('degree_in_sign', pd['degree'] % 30) for pn, pd in planets.items() if isinstance(pd, dict) and 'degree' in pd} + planet_lons = {pn: pd.get('degree_raw', pd['degree']) for pn, pd in planets.items() if isinstance(pd, dict) and 'degree' in pd} + planet_degs = {pn: pd.get('degree_in_sign_raw', pd.get('degree_in_sign', pd['degree'] % 30)) for pn, pd in planets.items() if isinstance(pd, dict) and 'degree' in pd} planet_sign_indices = {} for pn, pd in planets.items(): if isinstance(pd, dict) and 'sign' in pd: @@ -3122,7 +3125,7 @@ def cmd_full_reading(args): # ── Step 2: Vimshottari Dasha ── try: moon_data = planets.get('Moon', {}) - moon_lon = moon_data.get('degree', 0) + moon_lon = moon_data.get('degree_raw', moon_data.get('degree', 0)) nak_idx = int(moon_lon / (360 / 27)) % 27 nak_name = NAKSHATRA_LIST[nak_idx][0] nak_lord = NAKSHATRA_LIST[nak_idx][1] diff --git a/scripts/varga.py b/scripts/varga.py index 070ef99e..247fe13d 100644 --- a/scripts/varga.py +++ b/scripts/varga.py @@ -57,7 +57,7 @@ def varga_map(si, pi, div): if div==7: return (si+pi)%12 if o else (si+6+pi)%12 if div==9: el={0:0,1:9,2:6,3:3}; return (el[si%4]+pi)%12 - if div==10: return (si+pi)%12 if o else (si+9+pi)%12 # D10: even signs start from 9th (2026-05-03 fix: was +8) + if div==10: return (si+pi)%12 if o else (si+8+pi)%12 # D10: even signs count from 9th inclusively => +8 offset if div==12: return (si+pi)%12 if div==16: return ((0 if o else 4)+pi)%12 # D16: movable=+0, fixed=+4; dual needs separate (2026-05-03 fix: was +1) if div==20: return ((0 if o else 8)+pi)%12 @@ -71,19 +71,19 @@ def varga_map(si, pi, div): def calc_varga(lon, div): """计算行星在指定分盘的位置(星座+精确度数+尊贵状态)""" - # 2026-05-03修正:D9 Navamsa使用Harmonic(×9)法而非BPHS映射法 - # 原因:Harmonic法与主流Jyotish软件(Jagannatha Hora等)结果一致 - # 且在Einstein等名人案例中与人生事件吻合度更高 - # BPHS映射法(el={0:0,1:9,2:6,3:3})仍保留在varga_map中作为备选 + si=_si(lon); d=lon-si*30; ps=30.0/div; pi=int(d/ps) if div == 9: + # D9 Navamsa: retain harmonic longitude output to match existing skill/JHora-style readings. nav_lon = (lon * 9) % 360 vsi = int(nav_lon / 30) % 12 dp = nav_lon - vsi * 30 - pi = int(dp / (30.0/9)) # approximate pada from harmonic degree + pi = int(d / ps) r = {'sign': _sn(vsi), 'sign_idx': vsi, 'degree_in_sign': round(dp, 4), 'part_index': pi, 'lord': SIGN_LORDS.get(_sn(vsi), ''), 'pada': pi + 1} return r - si=_si(lon); d=lon-si*30; ps=30.0/div; pi=int(d/ps); dp=d-pi*ps + # For non-D9 vargas, degree within divisional sign is scaled to 0-30 degrees. + # Previous code returned only the within-part remainder (0-part_size), which made D10 degree output non-standard. + dp=(d-pi*ps)*div vsi=varga_map(si,pi,div) r={'sign':_sn(vsi),'sign_idx':vsi,'degree_in_sign':round(dp,4), 'part_index':pi,'lord':SIGN_LORDS.get(_sn(vsi),'')}