fix(yoga): Neecha Bhanga lists the conditions that hold, never Raja Yoga (T8, BUG-1205)

Astrologer ruling 乙14. One condition source, yogas_doshas.calc_nicha_bhanga_raj_yoga
(conditions A-F, now also structured). New scripts/main_yoga_detectors.py turns it
into yoga_engine-shaped rows (zh + en twins) that YogaEngine.detect appends; the
four neechabhanga_* rules are reference_only (kept, renamed, not evaluated).
Card: traditional_yogas canonical 落陷取消(Neecha Bhanga) with 成立条件; compact
yoga entries keep conditions/reductions. Report: category 落陷取消, mixed group,
not raja; personal-report alias neecha_bhanga -> special.

Changed assertion (test_consultation_yoga_detection_merge): canonical name
'Neecha Bhanga Raja Yoga' -> '落陷取消(Neecha Bhanga)' (ruling 乙14).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
This commit is contained in:
Jesse_Chen
2026-10-03 11:38:52 +08:00
co-authored by Claude Opus 5.5
parent 0cf2249e6b
commit df21e591e8
10 changed files with 342 additions and 26 deletions
+3 -1
View File
@@ -223,6 +223,7 @@ def _strip_pl9_user_engineering_markers(markdown: str) -> str:
"common": "常见",
"occasional": "偶见",
"raja": "王权/事业",
"neecha_bhanga": "落陷取消",
"dhana": "财富",
"putra": "子女/创造",
"ayur": "寿命/健康",
@@ -2500,7 +2501,8 @@ def render_pl9_parity_markdown(packet: dict) -> str:
name = str(row.get('name') or row.get('name_cn') or row.get('type') or '').lower()
if category in {'durbhaga', 'ari'} or 'daridra' in name or 'arishta' in name:
return 'Applicable Malefic Yogas'
if category in {'conjunction', 'special', 'kalatra', 'solar_yoga', 'lunar_yoga'} or 'dosha' in name:
# A Neecha Bhanga only lists the conditions that hold (BUG-1205).
if category in {'conjunction', 'special', 'kalatra', 'solar_yoga', 'lunar_yoga', 'neecha_bhanga'} or 'dosha' in name:
return 'Applicable Mixed Yogas'
return 'Applicable Benefic Yogas'