v6.0.12: add Dispositor Chain + Inter-chart Linkage techniques

- New functions: calc_dispositor_chain, calc_inter_chart_linkage, calc_all_dispositor_chains, calc_all_inter_chart_linkages
- cmd_full_reading Step 4.7: compute and attach dispositor_chains, inter_chart_linkage, final_dispositors to modules
- technique_registry.json: add dispositor_chain and inter_chart_linkage as covered techniques; update 3 routes
- strict-workflow-router.md: sync routes and audit table with new techniques
- CHANGELOG.md: add v6.0.12 entry
- SKILL.md: bump version to 6.0.12
This commit is contained in:
732642856
2026-06-04 04:19:50 +08:00
parent 3d2faf3380
commit f6deae7a25
5 changed files with 548 additions and 76 deletions
+24
View File
@@ -1,5 +1,29 @@
# 印度占星 Skill 更新日志
## v6.0.12-dispositor-chain-inter-chart-linkage2026-06-04)—— 新增 Dispositor Chain + Inter-chart Linkage 技法
> **触发原因**:用户指出当前 skill 缺少"定位星链"和"分盘间飞星落宫"两个高级技法,导致事业/婚恋/财务等解盘无法完整分析行星能量流向和分盘间验证。
### 新增功能
- `scripts/jyotish_engine.py` 新增 4 个函数:
- `calc_dispositor_chain(planet_name, planets_data)`:计算单个行星的定位星链
- `calc_inter_chart_linkage(...)`:计算单行星在 D1/D9/D10/D12 的分盘间飞星落宫
- `calc_all_dispositor_chains(planets_data)`:批量计算所有行星定位星链
- `calc_all_inter_chart_linkages(...)`:批量计算所有行星分盘间飞星
- `cmd_full_reading` 新增 Step 4.7:调用上述函数,输出 `modules.dispositor_chains``modules.inter_chart_linkage``modules.final_dispositors`
- `references/technique_registry.json` 新增 2 个技法注册:`dispositor_chain``inter_chart_linkage`,状态均为 `covered`
- `references/strict-workflow-router.md` 同步更新:3 个路由(`career-timing-strict``event-verification-strict``full-reading-strict`)的 `required_techniques` 新增 `dispositor_chain``inter_chart_linkage`Technique Audit Table 模板新增对应行
### 验证结果
- Python 语法检查通过
- `full-reading` 测试运行:`errors: []`,新增 3 个模块均输出正确
- Venus 定位星链:Venus→Jupiter→Mercury(循环),最终定位星 Mercury ✓
- Venus 分盘间飞星:D1 Pisces/8H、D9 Libra/4H、D10 Aquarius/3H ✓
---
## v6.0.11-shadbala-capability-downgrade2026-06-04)— Shadbala 能力标注降级
> **触发原因**:第九轮 Shadbala benchmark 证明当前实现内部一致,但源码仍包含多处简化公式,尚未完成 JHora/公开书例级别的外部绝对值校准,不应继续标记为完整 `covered`。
+1 -1
View File
@@ -1,6 +1,6 @@
---
name: jyotish-vedic-astrology
version: 6.0.11
version: 6.0.12
description: 印度占星(Jyotish)专业解盘与推运系统。核心能力:PDF星盘输入→严谨解盘→精确推运应期输出。触发词:印度占星、吠陀占星、Jyotish、解盘、推运、星盘分析、Dasha、Transit、Nakshatra、Yoga、出生时间矫正、PDF星盘、读取PDF、分析PDF星盘、现代解读、误判纠错、Varga分盘、综合分析、过境分析、合盘、婚姻匹配、年运盘、Prashna、Argala、Jaimini、KP系统、Shadbala、Ashtakavarga、HTML报告、深度解盘。
---
+5
View File
@@ -62,6 +62,8 @@ Use when the user asks about career, profession, job, project, public recognitio
| Arudha | AL and A10/Karma Pada if available | special lagna / manual if needed |
| Strength | Shadbala for Dasha lord, 10L, AmK, Saturn, Jupiter | `shadbala` |
| Transit strength | SAV/BAV for key transit signs and houses | `ashtakavarga` |
| Dispositor Chain | Final dispositor / energy flow for 10L, AmK, Saturn | `full-reading` |
| Inter-chart Linkage | D1->D9->D10 planet linkage for 10L, 2L, 11L | `full-reading` |
| Argala | Argala/Virodha on 10H, 10L, D10 10H, AmK | `argala` |
| KP / sub-lord | Use for yes/no or project landing questions | `nakshatra-adv`, KP references |
| Historical reliability | If user gives events, back-test same technique | `predict --past-verify` if applicable |
@@ -138,6 +140,7 @@ Use when the user provides past events and asks whether the technique is reliabl
1. Extract the exact event date or window.
2. Identify which prediction rule would have implied it.
3. Apply the same rule to the past event without changing interpretation after seeing the result.
3.5. Check Dispositor Chain and Inter-chart Linkage for consistency across D1/D9/D10.
4. Score match quality:
- A: same theme + same timing + multiple systems support.
- B: same theme + approximate timing or delayed manifestation.
@@ -168,6 +171,8 @@ Every Level 2+ output must include this table near the end.
| AL / A10 | Used / partial / unavailable | ... | ... |
| Shadbala | Used / partial / not used | Internally consistent relative strength; external absolute calibration pending | Cap precise strength claims |
| Ashtakavarga | Used / not used | ... | ... |
| Dispositor Chain | Used / not used | ... | ... |
| Inter-chart Linkage | Used / not used | ... | ... |
| Argala | Used / not used | ... | ... |
| KP / Sub-lord | Used / not required / unavailable | ... | ... |
| Historical verification | Used / not provided | ... | ... |
+361 -75
View File
@@ -17,188 +17,474 @@
"lesson": "Validate registry-like configuration against a schema before using it. This project keeps a stdlib validator to avoid new dependencies."
}
],
"status_vocabulary": ["covered", "partial", "knowledge-only", "workflow-only", "not-integrated", "missing"],
"status_vocabulary": [
"covered",
"partial",
"knowledge-only",
"workflow-only",
"not-integrated",
"missing"
],
"techniques": {
"d1_rashi": {
"name": "D1 / Rashi",
"domains": ["core", "static"],
"domains": [
"core",
"static"
],
"status": "covered",
"knowledge_refs": ["references/signs-and-houses.md"],
"commands": ["chart", "full-reading"],
"output_paths": ["modules.chart"],
"knowledge_refs": [
"references/signs-and-houses.md"
],
"commands": [
"chart",
"full-reading"
],
"output_paths": [
"modules.chart"
],
"audit_label": "D1/Rashi",
"missing_impact": "No reliable static chart basis."
},
"d9_navamsa": {
"name": "D9 / Navamsa",
"domains": ["varga", "strength", "relationship", "dharma"],
"domains": [
"varga",
"strength",
"relationship",
"dharma"
],
"status": "covered",
"knowledge_refs": ["references/navamsa-d9-interpretation-template.md", "references/varga-system-quick-reference.md"],
"commands": ["varga-full", "full-reading"],
"output_paths": ["modules.varga_full.D9_Navamsa", "modules.d9_navamsa_expanded"],
"knowledge_refs": [
"references/navamsa-d9-interpretation-template.md",
"references/varga-system-quick-reference.md"
],
"commands": [
"varga-full",
"full-reading"
],
"output_paths": [
"modules.varga_full.D9_Navamsa",
"modules.d9_navamsa_expanded"
],
"audit_label": "D9/Navamsa",
"missing_impact": "Inner strength and marriage/dharma layer incomplete."
},
"d10_dasamsa": {
"name": "D10 / Dasamsa",
"domains": ["career", "varga"],
"domains": [
"career",
"varga"
],
"status": "covered",
"knowledge_refs": ["references/varga-system-quick-reference.md", "references/divisional-chart-deep-reading.md"],
"commands": ["varga-full", "full-reading"],
"output_paths": ["modules.varga_full.D10_Dasamsa"],
"knowledge_refs": [
"references/varga-system-quick-reference.md",
"references/divisional-chart-deep-reading.md"
],
"commands": [
"varga-full",
"full-reading"
],
"output_paths": [
"modules.varga_full.D10_Dasamsa"
],
"audit_label": "D10/Dasamsa",
"missing_impact": "Career-specific varga layer missing; career timing confidence must be capped."
},
"vimshottari_dasha": {
"name": "Vimshottari Dasha",
"domains": ["timing", "event"],
"domains": [
"timing",
"event"
],
"status": "covered",
"knowledge_refs": ["references/dasha-calculation-tool.md"],
"commands": ["dasha", "full-reading"],
"output_paths": ["modules.dasha"],
"knowledge_refs": [
"references/dasha-calculation-tool.md"
],
"commands": [
"dasha",
"full-reading"
],
"output_paths": [
"modules.dasha"
],
"audit_label": "Vimshottari",
"missing_impact": "Primary timing layer unavailable."
},
"dasha_sandhi": {
"name": "Dasha Sandhi",
"domains": ["timing", "transition"],
"domains": [
"timing",
"transition"
],
"status": "covered",
"knowledge_refs": ["references/strict-workflow-router.md"],
"commands": ["full-reading"],
"output_paths": ["modules.dasha_sandhi"],
"knowledge_refs": [
"references/strict-workflow-router.md"
],
"commands": [
"full-reading"
],
"output_paths": [
"modules.dasha_sandhi"
],
"audit_label": "Dasha Sandhi",
"missing_impact": "Transition windows may be overstated or understated."
},
"jaimini_chara_dasha": {
"name": "Jaimini / Chara Dasha",
"domains": ["timing", "career", "relationship"],
"domains": [
"timing",
"career",
"relationship"
],
"status": "partial",
"knowledge_refs": ["references/jaimini-complete-system.md"],
"commands": ["jaimini", "full-reading"],
"output_paths": ["modules.jaimini"],
"knowledge_refs": [
"references/jaimini-complete-system.md"
],
"commands": [
"jaimini",
"full-reading"
],
"output_paths": [
"modules.jaimini"
],
"audit_label": "Jaimini/Chara",
"missing_impact": "Rashi-based timing confirmation is partial; timing confidence must be capped unless corroborated by Vimshottari, Dasha Sandhi, transit, D10/A10 and Ashtakavarga.",
"limitation": "Round 7 benchmark vs PyJHora KN Rao Chara Dasha matched 58/240 fields (24.17%). Current calc_chara_dasha() is a simplified implementation, not a full KN Rao/PVN Rao/Iranganti method. Karaka/Karakamsha remain usable; Chara Dasha timing is partial."
},
"karakamsha_ak_amk": {
"name": "Karakamsha / AK / AmK",
"domains": ["career", "soul", "dharma"],
"domains": [
"career",
"soul",
"dharma"
],
"status": "covered",
"knowledge_refs": ["references/jaimini-complete-system.md"],
"commands": ["jaimini", "full-reading"],
"output_paths": ["modules.jaimini.karakas", "modules.jaimini.karakamsha"],
"knowledge_refs": [
"references/jaimini-complete-system.md"
],
"commands": [
"jaimini",
"full-reading"
],
"output_paths": [
"modules.jaimini.karakas",
"modules.jaimini.karakamsha"
],
"audit_label": "AK/AmK/Karakamsha",
"missing_impact": "Jaimini career/soul indicator layer incomplete."
},
"a10_karma_pada": {
"name": "A10 / Karma Pada / Rajya Pada",
"domains": ["career", "public_image"],
"domains": [
"career",
"public_image"
],
"status": "covered",
"knowledge_refs": ["references/technique-capability-matrix.md"],
"commands": ["full-reading", "scripts/special_lagnas.py --tenth-lord"],
"output_paths": ["modules.special_lagnas.A10_Karma_Pada"],
"knowledge_refs": [
"references/technique-capability-matrix.md"
],
"commands": [
"full-reading",
"scripts/special_lagnas.py --tenth-lord"
],
"output_paths": [
"modules.special_lagnas.A10_Karma_Pada"
],
"audit_label": "A10/Karma Pada",
"missing_impact": "Career public-image layer incomplete."
},
"argala": {
"name": "Argala",
"domains": ["static", "intervention", "event"],
"domains": [
"static",
"intervention",
"event"
],
"status": "covered",
"knowledge_refs": ["references/argala-complete-guide.md"],
"commands": ["argala", "full-reading"],
"output_paths": ["modules.argala"],
"knowledge_refs": [
"references/argala-complete-guide.md"
],
"commands": [
"argala",
"full-reading"
],
"output_paths": [
"modules.argala"
],
"audit_label": "Argala",
"missing_impact": "Intervention/blocking layer missing."
},
"shadbala": {
"name": "Shadbala",
"domains": ["strength", "static"],
"domains": [
"strength",
"static"
],
"status": "partial",
"knowledge_refs": ["references/shadbala-complete-methodology.md"],
"commands": ["shadbala", "full-reading"],
"output_paths": ["modules.shadbala"],
"knowledge_refs": [
"references/shadbala-complete-methodology.md"
],
"commands": [
"shadbala",
"full-reading"
],
"output_paths": [
"modules.shadbala"
],
"audit_label": "Shadbala",
"missing_impact": "Planetary strength claims are quantitatively anchored only as an internally consistent reference, not as externally calibrated absolute Parashara Shadbala.",
"limitation": "Round 9 internal invariant benchmark passed 1200/1200 checks and full-reading matches the shadbala command. However scripts/shadbala.py still uses simplified Nathonnata Bala, approximate Saptavargaja sub-vargas, Chesta speed buckets and simplified Drik aspect weights. Use for relative strength ranking with confidence cap until an external full Shadbala table benchmark is frozen."
},
"ashtakavarga": {
"name": "Ashtakavarga",
"domains": ["transit", "strength", "timing"],
"domains": [
"transit",
"strength",
"timing"
],
"status": "covered",
"knowledge_refs": ["references/ashtakavarga-complete-system.md"],
"commands": ["ashtakavarga", "full-reading"],
"output_paths": ["modules.ashtakavarga"],
"knowledge_refs": [
"references/ashtakavarga-complete-system.md"
],
"commands": [
"ashtakavarga",
"full-reading"
],
"output_paths": [
"modules.ashtakavarga"
],
"audit_label": "Ashtakavarga",
"missing_impact": "Transit strength filter missing."
},
"avastha": {
"name": "Avastha",
"domains": ["strength", "state"],
"domains": [
"strength",
"state"
],
"status": "covered",
"knowledge_refs": ["references/technique-capability-matrix.md"],
"commands": ["full-reading"],
"output_paths": ["modules.avasthas"],
"knowledge_refs": [
"references/technique-capability-matrix.md"
],
"commands": [
"full-reading"
],
"output_paths": [
"modules.avasthas"
],
"audit_label": "Avastha",
"missing_impact": "Planet condition/state layer missing."
},
"vargottama": {
"name": "Vargottama",
"domains": ["varga", "strength"],
"domains": [
"varga",
"strength"
],
"status": "covered",
"knowledge_refs": ["references/varga-system-quick-reference.md"],
"commands": ["full-reading"],
"output_paths": ["modules.vargottama"],
"knowledge_refs": [
"references/varga-system-quick-reference.md"
],
"commands": [
"full-reading"
],
"output_paths": [
"modules.vargottama"
],
"audit_label": "Vargottama",
"missing_impact": "D1-D9 consistency strength may be undercounted."
},
"pushkara": {
"name": "Pushkara Navamsa / Pushkara Bhaga",
"domains": ["varga", "dignity", "grace"],
"domains": [
"varga",
"dignity",
"grace"
],
"status": "covered",
"knowledge_refs": ["references/planetary-dignity-complete-reference.md", "references/navamsa-marriage-deep-analysis.md"],
"commands": ["full-reading"],
"output_paths": ["modules.pushkara"],
"knowledge_refs": [
"references/planetary-dignity-complete-reference.md",
"references/navamsa-marriage-deep-analysis.md"
],
"commands": [
"full-reading"
],
"output_paths": [
"modules.pushkara"
],
"audit_label": "Pushkara",
"missing_impact": "D9 grace/support layer may be undercounted."
},
"bhava_chalit": {
"name": "Bhava Chalit",
"domains": ["house_cusp", "event"],
"domains": [
"house_cusp",
"event"
],
"status": "partial",
"knowledge_refs": ["references/kp-astrology-complete-system.md"],
"commands": ["chart", "full-reading"],
"output_paths": ["modules.chart.houses"],
"knowledge_refs": [
"references/kp-astrology-complete-system.md"
],
"commands": [
"chart",
"full-reading"
],
"output_paths": [
"modules.chart.houses"
],
"audit_label": "Bhava Chalit",
"missing_impact": "Planet reassignment near cusps is not fully recalibrated.",
"limitation": "House cusps exist, but full Chalit Chart planet reassignment is not implemented."
},
"sudarshana_chakra": {
"name": "Sudarshana Chakra",
"domains": ["multi_chart", "confirmation"],
"domains": [
"multi_chart",
"confirmation"
],
"status": "partial",
"knowledge_refs": ["references/varga-system-quick-reference.md"],
"commands": ["full-reading"],
"output_paths": ["modules.varga_full", "modules.d9_navamsa_expanded"],
"knowledge_refs": [
"references/varga-system-quick-reference.md"
],
"commands": [
"full-reading"
],
"output_paths": [
"modules.varga_full",
"modules.d9_navamsa_expanded"
],
"audit_label": "Sudarshana Chakra",
"missing_impact": "Traditional triple-lagna confirmation is partial only.",
"limitation": "D1-D9-D10 triangle verification exists as a substitute; traditional Sudarshana module is absent."
},
"dispositor_chain": {
"name": "Dispositor Chain / 定位星链",
"domains": [
"strength",
"flow",
"dignity"
],
"status": "covered",
"knowledge_refs": [
"references/technique-capability-matrix.md"
],
"commands": [
"full-reading"
],
"output_paths": [
"modules.dispositor_chains",
"modules.final_dispositors"
],
"audit_label": "Dispositor Chain",
"missing_impact": "Planet energy flow / final dispositor analysis incomplete."
},
"inter_chart_linkage": {
"name": "Inter-chart Linkage / 分盘间飞星",
"domains": [
"varga",
"confirmation",
"multi_chart"
],
"status": "covered",
"knowledge_refs": [
"references/varga-system-quick-reference.md"
],
"commands": [
"full-reading"
],
"output_paths": [
"modules.inter_chart_linkage"
],
"audit_label": "Inter-chart Linkage",
"missing_impact": "Cross-chart planet linkage (D1->D9->D10) analysis incomplete."
}
},
"routes": {
"career_timing_strict": {
"trigger_keywords": ["事业", "职业", "工作机会", "项目落地", "名声", "社会身份"],
"required_techniques": ["d1_rashi", "d9_navamsa", "d10_dasamsa", "vimshottari_dasha", "dasha_sandhi", "jaimini_chara_dasha", "karakamsha_ak_amk", "a10_karma_pada", "argala", "shadbala", "ashtakavarga", "vargottama", "pushkara"],
"optional_techniques": ["bhava_chalit", "sudarshana_chakra"]
"trigger_keywords": [
"事业",
"职业",
"工作机会",
"项目落地",
"名声",
"社会身份"
],
"required_techniques": [
"d1_rashi",
"d9_navamsa",
"d10_dasamsa",
"vimshottari_dasha",
"dasha_sandhi",
"jaimini_chara_dasha",
"karakamsha_ak_amk",
"a10_karma_pada",
"argala",
"shadbala",
"ashtakavarga",
"vargottama",
"pushkara",
"dispositor_chain",
"inter_chart_linkage"
],
"optional_techniques": [
"bhava_chalit",
"sudarshana_chakra"
]
},
"event_verification_strict": {
"trigger_keywords": ["验证", "回测", "历史事件", "可靠性", "是不是遗漏"],
"required_techniques": ["d1_rashi", "vimshottari_dasha", "dasha_sandhi", "jaimini_chara_dasha", "argala", "shadbala", "ashtakavarga"],
"optional_techniques": ["d9_navamsa", "d10_dasamsa", "a10_karma_pada", "bhava_chalit", "sudarshana_chakra"]
"trigger_keywords": [
"验证",
"回测",
"历史事件",
"可靠性",
"是不是遗漏"
],
"required_techniques": [
"d1_rashi",
"vimshottari_dasha",
"dasha_sandhi",
"jaimini_chara_dasha",
"argala",
"shadbala",
"ashtakavarga",
"dispositor_chain",
"inter_chart_linkage"
],
"optional_techniques": [
"d9_navamsa",
"d10_dasamsa",
"a10_karma_pada",
"bhava_chalit",
"sudarshana_chakra"
]
},
"full_reading_strict": {
"trigger_keywords": ["综合解盘", "完整解盘", "full-reading"],
"required_techniques": ["d1_rashi", "d9_navamsa", "d10_dasamsa", "vimshottari_dasha", "dasha_sandhi", "jaimini_chara_dasha", "argala", "shadbala", "ashtakavarga", "avastha", "vargottama", "pushkara"],
"optional_techniques": ["bhava_chalit", "sudarshana_chakra"]
"trigger_keywords": [
"综合解盘",
"完整解盘",
"full-reading"
],
"required_techniques": [
"d1_rashi",
"d9_navamsa",
"d10_dasamsa",
"vimshottari_dasha",
"dasha_sandhi",
"jaimini_chara_dasha",
"argala",
"shadbala",
"ashtakavarga",
"avastha",
"vargottama",
"pushkara",
"dispositor_chain",
"inter_chart_linkage"
],
"optional_techniques": [
"bhava_chalit",
"sudarshana_chakra"
]
}
}
}
}
+157
View File
@@ -221,6 +221,102 @@ def _calc_dasha_sandhi(dasha_result, reference_date=None, orb_days=90):
return {'reference_date': ref.strftime('%Y-%m-%d'), 'orb_days': orb_days, 'sandhi_windows': sandhi}
# ============================================================================
# 新增:Dispositor Chain + Inter-chart Linkage (v6.0.12)
# ============================================================================
def calc_dispositor_chain(planet_name, planets_data, max_depth=12):
"""
计算行星的定位星链(dispositor chain)。
返回列表:[{planet, sign, dispositor, dispositor_sign}, ...]
直到循环或达到 max_depth。
"""
chain = []
current_planet = planet_name
visited = set()
for _ in range(max_depth):
if current_planet in visited:
break
visited.add(current_planet)
pdata = planets_data.get(current_planet, {})
if not isinstance(pdata, dict) or 'sign' not in pdata:
break
sign = pdata['sign']
dispositor = SIGN_LORDS.get(sign, '')
chain.append({
'planet': current_planet,
'sign': sign,
'sign_cn': SIGNS_CN.get(sign, ''),
'dispositor': dispositor,
'dispositor_sign': sign, # 定位星所在的星座(即当前行星所在星座)
})
if not dispositor:
break
current_planet = dispositor
return chain
def calc_inter_chart_linkage(planet_name, d1_data, d9_data, d10_data, d12_data=None, d1_asc_idx=None, d9_asc_idx=None, d10_asc_idx=None):
"""
计算行星在 D1/D9/D10 分盘之间的飞星落宫。
返回 {chart_type: {sign, house_in_chart, lord_of_sign_in_chart}}
"""
result = {}
charts = [
('D1', d1_data, d1_asc_idx),
('D9', d9_data, d9_asc_idx),
('D10', d10_data, d10_asc_idx),
]
if d12_data:
charts.append(('D12', d12_data, None))
for chart_name, chart_data, asc_idx in charts:
if not isinstance(chart_data, dict):
continue
pdata = chart_data.get(planet_name, {})
if not isinstance(pdata, dict) or 'sign' not in pdata:
continue
sign = pdata['sign']
sign_idx = SIGNS.index(sign) if sign in SIGNS else 0
house = None
if asc_idx is not None:
house = ((sign_idx - asc_idx) % 12) + 1
lord = SIGN_LORDS.get(sign, '')
result[chart_name] = {
'planet': planet_name,
'sign': sign,
'sign_cn': SIGNS_CN.get(sign, ''),
'house': house,
'lord': lord,
}
return result
def calc_all_dispositor_chains(planets_data):
"""为所有行星计算定位星链"""
result = {}
for pname in ['Sun', 'Moon', 'Mars', 'Mercury', 'Jupiter', 'Venus', 'Saturn', 'Rahu', 'Ketu']:
if pname in planets_data:
result[pname] = calc_dispositor_chain(pname, planets_data)
return result
def calc_all_inter_chart_linkages(d1_data, d9_data, d10_data, d12_data=None, d1_asc_idx=None, d9_asc_idx=None, d10_asc_idx=None):
"""
为所有行星计算 D1/D9/D10 分盘间飞星。
需要各分盘的 asc_idx 来正确计算落宫。
"""
result = {}
for pname in ['Sun', 'Moon', 'Mars', 'Mercury', 'Jupiter', 'Venus', 'Saturn', 'Rahu', 'Ketu']:
result[pname] = calc_inter_chart_linkage(
pname, d1_data, d9_data, d10_data, d12_data,
d1_asc_idx, d9_asc_idx, d10_asc_idx
)
return result
def _get_dignity_level(planet, sign, deg_in_sign=None):
"""判断行星在某星座的尊严等级 (用于 Vimsopaka 映射)"""
if EXALTATION.get(planet) == sign:
@@ -3297,6 +3393,67 @@ def cmd_full_reading(args):
except Exception as e:
report['errors'].append(f"varga-extended: {e}")
# ── Step 4.7: Dispositor Chains + Inter-chart Linkage (v6.0.12) ──
try:
# 准备分盘数据:从 varga_full 提取 D1/D9/D10/D12
vf = report['modules'].get('varga_full', {})
d1_for_dc = vf.get('D1_Rashi', {})
d9_for_ic = vf.get('D9_Navamsa', {}) if isinstance(vf.get('D9_Navamsa'), dict) else {}
d10_for_ic = vf.get('D10_Dasamsa', {}) if isinstance(vf.get('D10_Dasamsa'), dict) else {}
d12_for_ic = vf.get('D12_Dwadashamsa', {}) if isinstance(vf.get('D12_Dwadashamsa'), dict) else None
# Dispositor Chains:基于 D1 行星数据
dc_result = calc_all_dispositor_chains(planets)
report['modules']['dispositor_chains'] = dc_result
# Inter-chart Linkage:需要各分盘的 asc_idx
# D1 asc_idx 已知;D9/D10/D12 的 asc_idx 需要从各自分盘数据提取
d9_asc_idx = None
d10_asc_idx = None
d12_asc_idx = None
if isinstance(d9_for_ic, dict):
d9_asc = d9_for_ic.get('Ascendant', {})
if isinstance(d9_asc, dict) and 'sign' in d9_asc:
d9_asc_idx = SIGNS.index(d9_asc['sign']) if d9_asc['sign'] in SIGNS else None
if isinstance(d10_for_ic, dict):
d10_asc = d10_for_ic.get('Ascendant', {})
if isinstance(d10_asc, dict) and 'sign' in d10_asc:
d10_asc_idx = SIGNS.index(d10_asc['sign']) if d10_asc['sign'] in SIGNS else None
if d12_for_ic and isinstance(d12_for_ic, dict):
d12_asc = d12_for_ic.get('Ascendant', {})
if isinstance(d12_asc, dict) and 'sign' in d12_asc:
d12_asc_idx = SIGNS.index(d12_asc['sign']) if d12_asc['sign'] in SIGNS else None
ic_result = calc_all_inter_chart_linkages(
d1_for_dc, d9_for_ic, d10_for_ic, d12_for_ic,
asc_idx, d9_asc_idx, d10_asc_idx
)
report['modules']['inter_chart_linkage'] = ic_result
# 补充:每个行星的"最终定位星"Dispositor Chain 的最后一个非循环元素)
final_dispositors = {}
for pname, chain in dc_result.items():
if chain:
# 找到最后一个不重复的元素
seen = set()
last_valid = None
for item in chain:
if item['dispositor'] in seen:
break
seen.add(item['dispositor'])
last_valid = item
if last_valid:
final_dispositors[pname] = last_valid['dispositor']
else:
final_dispositors[pname] = chain[-1]['dispositor'] if chain else None
else:
final_dispositors[pname] = None
report['modules']['final_dispositors'] = final_dispositors
except Exception as e:
report['errors'].append(f"dispositor-chain+inter-chart: {e}")
# ── Step 5: 精确相位 ──
try:
from aspects import calc_all_aspects