diff --git a/CHANGELOG.md b/CHANGELOG.md index b55d3452..a4d703f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,26 @@ # 印度占星 Skill 更新日志 +## v6.1.10(2026-06-08)—— P0 规划继续落地:Darakaraka / RTN 接入主题化报告 + +> **目标**:继续执行覆盖度地图中的 P0 规划,把已经存在但未充分进入 full-reading / 主题报告叙事链的婚姻核心技法真正接线。 + +### 关键改进 +- `scripts/jyotish_engine.py`:将 `scripts/darakaraka_reader.py` 接入 `full-reading.modules.jaimini.darakaraka`,输出 DK 行星、星座、宫位、D9 尊严、合相影响、婚姻质量评分和叙事。 +- `scripts/orchestrator_bridge.py`:新增 Jaimini/关系层注入,把 `jaimini.darakaraka` 与 `rashi_tulya_navamsa` 转为婚姻主题证据;RTN 的凶星合相与 Gunas 平衡也分别注入健康/灵性主题。 +- `references/technique_registry.json`:补齐 Darakaraka / Rashi Tulya Navamsa 的知识引用与 v6.1.10 验证说明。 +- `docs/roadmap/jyotish_technique_coverage_map.md`:更新 P0 规划状态,标注 DK、RTN、主题报告、Yoga F1 95%+ 的当前落地状态。 + +### 验证 +```bash +python3 -m py_compile scripts/jyotish_engine.py scripts/orchestrator_bridge.py scripts/darakaraka_reader.py scripts/rashi_tulya_navamsa.py +python3 scripts/jyotish_engine.py full-reading --year 1990 --month 6 --day 15 --hour 10 --minute 30 --lat 39.9 --lon 116.4 --tz 8 +python3 scripts/orchestrator_bridge.py /tmp/jyotish_full_reading_v6110.json +python3 scripts/audit_capabilities.py --mode validate +python3 scripts/run_quality_gate.py --skip-yoga-logic +``` + +--- + ## v6.1.9(2026-06-08)—— 本地散落资料安全入仓:Benchmark、竞品研究、覆盖度地图与PDF验证方法论 > **目标**:把历史 WorkBuddy 会话中散落但有长期价值的资料,按公开仓库隐私边界整理入 `yinduzhanxing`,避免遗漏,同时不上传真实用户个案、原始 PDF 文本或 raw full-reading 输出。 diff --git a/README.md b/README.md index 9a699c00..6748afc2 100644 --- a/README.md +++ b/README.md @@ -266,24 +266,24 @@ Examples: ## Project Status -**Current version:** `v6.0.23-full-reading-regression` +**Current version:** `v6.1.10-dk-rtn-theme-bridge` ### Recently Completed -- `v6.0.11` — Shadbala internal invariant validation (1200/1200 pass); downgraded to `partial` -- `v6.0.18` — Solar Return / Varshaphala + Muntha -- `v6.0.20` — Narayana Dasha / Rishi Dasha -- `v6.0.21` — Muhurta (Panchanga-based electional astrology) -- `v6.0.22` — Nakshatra Advanced (Chandra Bala / Tara Bala) -- `v6.0.23` — Full-reading regression fix (45 modules, 0 errors) +- `v6.1.10` — Darakaraka deep reader wired into `full-reading.modules.jaimini.darakaraka`; thematic reports now consume real DK and Rashi Tulya Navamsa evidence. +- `v6.1.9` — Public/sanitized benchmark suite, competitive research, coverage roadmap and PDF validation methodology added. +- `v6.1.8` — Yoga validation reached F1=95.22% (FP=36, FN=63); thematic reports consume real `full-reading.modules` evidence. +- `v6.1.6` — Five-system Dasha convergence wired into full-reading (Vimshottari + Chara + Yogini + Ashtottari + Kalachakra). +- `v6.0.11` — Shadbala internal invariant validation (1200/1200 pass); downgraded to `partial`. ### Actively Working On (P0) 1. **Chara Dasha rewrite** — align with PyJHora KN Rao method (target: ≥95% match) 2. **Shadbala external calibration** — align with JHora / PyJHora / BV Raman -3. **KP Sub-Lord full implementation** — unequal Vimshottari subdivisions -4. **Bhava Chalit complete** — cusp-based planet reassignment -5. **Sudarshana Chakra traditional** — Sun/Moon/Lagna reference points +3. **Darakaraka / RTN external benchmark** — v6.1.10 has wired the modules; next step is traditional case validation and evidence ranking +4. **KP Sub-Lord full implementation** — unequal Vimshottari subdivisions +5. **Bhava Chalit complete** — cusp-based planet reassignment +6. **Sudarshana Chakra traditional** — Sun/Moon/Lagna reference points ### Next (P1) diff --git a/SKILL.md b/SKILL.md index 0491187f..f26688ab 100644 --- a/SKILL.md +++ b/SKILL.md @@ -313,9 +313,9 @@ $PYTHON $SCRIPT <子命令> [参数] --- -**版本**:v6.1.9-public-benchmarks-research-roadmap +**版本**:v6.1.10-dk-rtn-theme-bridge **创建日期**:2026-04-20 -**最后更新**:2026-06-08(v6.1.9 将历史散落资料安全整理入仓:新增 `benchmarks/jyotish/` 公开/虚构 smoke benchmark 套件、`docs/research/jyotish_projects_comparison.md`、`docs/roadmap/jyotish_technique_coverage_map.md` 与 `references/validation/pdf-chart-reading-validation-methodology.md`。v6.1.8 Yoga 指标保持有效:F1=95.22%,FP=36、FN=63;Yoga 当前以 `references/validation_logic_report.json` 为准。) +**最后更新**:2026-06-08(v6.1.10 继续落地 P0 规划:`full-reading.modules.jaimini.darakaraka` 已接入 Darakaraka 深度解读,主题化报告桥接层已消费 `jaimini.darakaraka` 与 `rashi_tulya_navamsa`,为婚姻/健康/灵性主题补入真实 DK/RTN 证据。v6.1.9 已将历史散落资料安全整理入仓;v6.1.8 Yoga 指标保持有效:F1=95.22%,FP=36、FN=63。) --- diff --git a/docs/roadmap/jyotish_technique_coverage_map.md b/docs/roadmap/jyotish_technique_coverage_map.md index 8a80b0d4..52792bab 100644 --- a/docs/roadmap/jyotish_technique_coverage_map.md +++ b/docs/roadmap/jyotish_technique_coverage_map.md @@ -544,10 +544,10 @@ ### P0 (最高优先级) — 影响核心解盘质量 -1. **Darakaraka深度解读** — 婚姻分析核心缺口 -2. **Rashi Tulya Navamsa** — 多维度交叉验证基础 -3. **主题化报告重构** — 从"罗列"到"叙事" -4. **Yoga F1提升至95%+** — 精度是底线 +1. **Darakaraka深度解读** — ✅ v6.1.10 已接入 `full-reading.modules.jaimini.darakaraka`,并注入主题化婚姻报告;仍需外部传统案例 benchmark 深化。 +2. **Rashi Tulya Navamsa** — ✅ v6.1.10 已从 `modules.rashi_tulya_navamsa` 注入婚姻/健康/灵性主题证据;当前仍为 partial,需继续完善变体与外部验证。 +3. **主题化报告重构** — ✅ v6.1.8 已从"罗列"升级为消费 `full-reading.modules` 的真实叙事;v6.1.10 继续补入 DK/RTN 证据。 +4. **Yoga F1提升至95%+** — ✅ v6.1.8 已达到 F1=95.22%,FP=36,FN=63。 ### P1 (高优先级) — 丰富技法覆盖 @@ -581,16 +581,16 @@ | **计算精度** | A- | 星盘/Dasha/Varga计算精确 | | **技法覆盖度** | C+ | 约37%,大量高级技法缺失 | | **解读深度** | C | 有计算但缺深度叙事 | -| **验证体系** | B | 60张标准盘,Yoga F1=93.8% | +| **验证体系** | B+ | 60张标准盘,Yoga F1=95.22%(v6.1.8),并新增公开/虚构 benchmark 套件 | | **文档完整度** | B+ | 105篇参考文档 | | **工程化程度** | B | 模块化良好,但无统一API | ### 成为全球最好需要补什么 **短期 (达到"专业级")**: -- 补齐6大缺失模块 -- Yoga F1 → 95%+ -- 主题化报告重构 +- 继续补齐/验证6大缺失模块中尚未成熟的部分(DK/RTN/主题报告/Yoga 95%+ 已进入可用层) +- 维持 Yoga F1 ≥95%,避免为召回牺牲准确率 +- 深化主题化报告的传统案例 benchmark 与 evidence ranking **中期 (达到"专家级")**: - 推运体系扩展 (Ashtottari/Yogini/Chara) diff --git a/references/technique_registry.json b/references/technique_registry.json index 8d574f02..b13e4e29 100644 --- a/references/technique_registry.json +++ b/references/technique_registry.json @@ -508,7 +508,10 @@ "karaka" ], "status": "covered", - "knowledge_refs": [], + "knowledge_refs": [ + "references/darakaraka-complete-guide.md", + "references/spouse-multi-layer-methodology.md" + ], "commands": [ "full-reading" ], @@ -516,7 +519,8 @@ "modules.jaimini.darakaraka" ], "audit_label": "Darakaraka (DK)", - "missing_impact": "Marriage/partner analysis incomplete without DK." + "missing_impact": "Marriage/partner analysis incomplete without DK.", + "validation_note": "v6.1.10 wires scripts/darakaraka_reader.py into full-reading and thematic reports; output includes DK planet/sign/house, D9 dignity, conjunctions, quality score and narrative." }, "raj_yoga": { "name": "Raj Yoga / 王者瑜伽", @@ -752,7 +756,10 @@ "marriage" ], "status": "partial", - "knowledge_refs": [], + "knowledge_refs": [ + "references/rashi-tulya-navamsa-root-impulse.md", + "references/varga-system-quick-reference.md" + ], "commands": [ "full-reading" ], @@ -761,7 +768,8 @@ ], "audit_label": "Rashi Tulya Navamsa", "missing_impact": "D1-D9 同宫对比分析不完整,婚姻/内在潜力判断受限。", - "limitation": "Rashi Tulya Navamsa 分析当前基于 D1 与 D9 同宫行星的简单对比,未完整覆盖所有变体条件(如行星在 D9 中的精确度数对比、Vargottama 与非 Vargottama 的混合情况)。婚姻和内在潜力的深度解读应结合更多分盘(D7、D12)交叉验证。" + "limitation": "Rashi Tulya Navamsa 分析当前基于 D1 与 D9 同宫行星的简单对比,未完整覆盖所有变体条件(如行星在 D9 中的精确度数对比、Vargottama 与非 Vargottama 的混合情况)。婚姻和内在潜力的深度解读应结合更多分盘(D7、D12)交叉验证。", + "validation_note": "v6.1.10 exposes RTN evidence to thematic reports: relationship mapping, curse-yoga warnings and Guna balance are injected from modules.rashi_tulya_navamsa." }, "marriage_counting": { "name": "Marriage Counting Method / 婚姻计数法", diff --git a/scripts/jyotish_engine.py b/scripts/jyotish_engine.py index 7c9175c8..51d6a17a 100644 --- a/scripts/jyotish_engine.py +++ b/scripts/jyotish_engine.py @@ -3600,6 +3600,39 @@ def cmd_full_reading(args): ak_d9 = calc_varga(ak_lon, 9) jaimini_result['karakamsha'] = calc_karakamsha( ak_d9.get('sign', 'Aries'), ak_d9.get('degree_in_sign', 0)) + + # Darakaraka 深度解读(v6.1.10) + # Registry 已将 modules.jaimini.darakaraka 标为 covered;这里把独立 DK + # reader 接入 full-reading,使婚姻主题报告可消费真实 DK 画像、D9 状态、 + # 合相影响和质量评分,而不是只停留在 chara_karaka 表格层。 + try: + from darakaraka_reader import analyze_darakaraka + d9_planets_for_dk = {} + varga_data = report['modules'].get('varga_full', {}) + d9_data = varga_data.get('D9_Navamsa', {}) if isinstance(varga_data, dict) else {} + d9_asc = d9_data.get('Ascendant', {}) if isinstance(d9_data, dict) else {} + d9_asc_idx = SIGNS.index(d9_asc.get('sign', 'Aries')) if isinstance(d9_asc, dict) and d9_asc.get('sign') in SIGNS else 0 + if isinstance(d9_data, dict): + for d9_pn, d9_pd in d9_data.items(): + if d9_pn == '_meta' or d9_pn == 'Ascendant' or not isinstance(d9_pd, dict) or 'sign' not in d9_pd: + continue + d9_sign = d9_pd.get('sign') + d9_deg = d9_pd.get('degree_in_sign', d9_pd.get('degree', 0) % 30) + d9_sign_idx = SIGNS.index(d9_sign) if d9_sign in SIGNS else 0 + d9_planets_for_dk[d9_pn] = { + 'sign': d9_sign, + 'house': ((d9_sign_idx - d9_asc_idx) % 12) + 1, + 'degree_in_sign': d9_deg, + 'dignity': _get_dignity_level(d9_pn, d9_sign, d9_deg), + } + jaimini_result['darakaraka'] = analyze_darakaraka({ + 'ascendant': chart.get('ascendant', {}), + 'planets': planets, + 'context': {'navamsa_planets': d9_planets_for_dk}, + }, use_8_karaka=True) + except Exception as dk_e: + jaimini_result['darakaraka'] = {'error': str(dk_e)} + report['modules']['jaimini'] = jaimini_result except Exception as e: report['errors'].append(f"jaimini: {e}") diff --git a/scripts/orchestrator_bridge.py b/scripts/orchestrator_bridge.py index aeb62575..dcdf1f96 100644 --- a/scripts/orchestrator_bridge.py +++ b/scripts/orchestrator_bridge.py @@ -401,6 +401,7 @@ class OrchestratorBridge: self._inject_yoga_module(modules, add) self._inject_varga_modules(modules, add) self._inject_strength_modules(modules, add) + self._inject_jaimini_relationship_modules(modules, add) self._inject_special_points(modules, add) self._inject_dasa_convergence_module(modules, add) self._inject_transit_module(modules, add) @@ -411,7 +412,8 @@ class OrchestratorBridge: "counts": counts, "source_modules": sorted(k for k in modules.keys() if k in { "yoga", "varga_full", "d9_navamsa_expanded", "ashtakavarga", "shadbala", - "special_lagnas", "vivah_saham", "dasa_convergence", "transit_multi_reference", + "jaimini", "rashi_tulya_navamsa", "special_lagnas", "vivah_saham", + "dasa_convergence", "transit_multi_reference", "dasha", "yogini_dasha", "ashtottari_dasha", "kalachakra_dasha", }), } @@ -543,6 +545,79 @@ class OrchestratorBridge: details={"source_module": "ashtakavarga", "scores": houses}, )) + def _inject_jaimini_relationship_modules(self, modules: Dict[str, Any], add) -> None: + """Inject relationship evidence from Jaimini DK and RTN modules. + + v6.1.10 connects two previously underused P0 relationship layers: + `modules.jaimini.darakaraka` and `modules.rashi_tulya_navamsa`. + Both are deterministic full-reading outputs; the bridge translates them into + marriage/health/spirituality evidence so thematic reports can narrate them. + """ + jaimini = modules.get("jaimini") or {} + darakaraka = jaimini.get("darakaraka") if isinstance(jaimini, dict) else None + if isinstance(darakaraka, dict) and darakaraka and not darakaraka.get("error"): + score = darakaraka.get("marriage_quality_score") + score_text = f",质量评分约{score:.0%}" if isinstance(score, (int, float)) else "" + conclusion = ( + f"Darakaraka:{darakaraka.get('dk_planet', '未知')}落{darakaraka.get('dk_sign', '未知')}" + f"第{darakaraka.get('dk_house', '?')}宫,伴侣原型={darakaraka.get('core_profile', '未标注')}{score_text}。" + ) + if darakaraka.get("d9_sign"): + conclusion += f" D9中落{darakaraka.get('d9_sign')},尊严={darakaraka.get('d9_dignity', '未知')}。" + add(ThemeName.MARRIAGE, ReportTechniqueResult( + technique="jaimini:darakaraka_deep_reader", + chart="D1/D9", + conclusion=conclusion, + sentiment="positive" if isinstance(score, (int, float)) and score >= 0.6 else ("negative" if isinstance(score, (int, float)) and score < 0.4 else "neutral"), + strength=StrengthLevel.STRONG, + details={"source_module": "jaimini.darakaraka", "raw": darakaraka}, + )) + + rtn_module = modules.get("rashi_tulya_navamsa") or {} + rtn = rtn_module.get("analysis") if isinstance(rtn_module, dict) and isinstance(rtn_module.get("analysis"), dict) else rtn_module + if isinstance(rtn, dict) and rtn and not rtn.get("error"): + house_mapping = rtn.get("house_mapping") or {} + curse_yogas = rtn.get("curse_yogas") or [] + strength_score = rtn.get("strength_score") + weakness_score = rtn.get("weakness_score") + marriage_planets = house_mapping.get(7) or house_mapping.get("7") or [] + summary_parts = [] + if marriage_planets: + summary_parts.append(f"RTN第7宫映射行星={marriage_planets}") + if curse_yogas: + summary_parts.append(f"检测到{len(curse_yogas)}个凶星合相命名") + if isinstance(strength_score, (int, float)) and isinstance(weakness_score, (int, float)): + summary_parts.append(f"隐藏力量={strength_score:.0%},弱点={weakness_score:.0%}") + conclusion = ";".join(summary_parts) or "Rashi Tulya Navamsa 已完成 D1/D9 映射分析。" + sentiment = "negative" if curse_yogas or (isinstance(weakness_score, (int, float)) and weakness_score > strength_score) else "positive" + add(ThemeName.MARRIAGE, ReportTechniqueResult( + technique="rashi_tulya_navamsa:relationship_mapping", + chart="D1/D9", + conclusion=conclusion, + sentiment=sentiment, + strength=StrengthLevel.MODERATE, + details={"source_module": "rashi_tulya_navamsa", "raw": rtn}, + )) + if curse_yogas: + add(ThemeName.HEALTH, ReportTechniqueResult( + technique="rashi_tulya_navamsa:curse_yogas", + chart="D1/D9", + conclusion=f"RTN凶星合相提示健康/危机压力:{[c.get('name') for c in curse_yogas[:3]]}", + sentiment="negative", + strength=StrengthLevel.MODERATE, + details={"source_module": "rashi_tulya_navamsa", "curse_yogas": curse_yogas}, + )) + guna = rtn.get("guna_narrative") + if guna: + add(ThemeName.SPIRITUALITY, ReportTechniqueResult( + technique="rashi_tulya_navamsa:guna_balance", + chart="D1/D9", + conclusion=f"RTN Gunas:{guna}", + sentiment="neutral", + strength=StrengthLevel.MODERATE, + details={"source_module": "rashi_tulya_navamsa", "guna_balance": rtn.get("guna_balance")}, + )) + def _inject_special_points(self, modules: Dict[str, Any], add) -> None: special = modules.get("special_lagnas") or {} if isinstance(special, dict): @@ -791,7 +866,8 @@ def _extract_modules(chart_data: Any) -> Dict[str, Any]: # Allow passing modules directly in tests. known = { "yoga", "varga_full", "d9_navamsa_expanded", "ashtakavarga", "shadbala", - "special_lagnas", "vivah_saham", "dasa_convergence", "transit_multi_reference", + "jaimini", "rashi_tulya_navamsa", "special_lagnas", "vivah_saham", + "dasa_convergence", "transit_multi_reference", "dasha", "yogini_dasha", "ashtottari_dasha", "kalachakra_dasha", } if any(k in chart_data for k in known):