fix(dignity): record Neecha Bhanga kendras and clip the first dasha from its full parent (BUG-1268, upstream 4a807e7d)

This commit is contained in:
jesse-ux
2026-10-07 17:40:58 +08:00
parent f02d27a73f
commit edeec41309
4 changed files with 202 additions and 36 deletions
@@ -0,0 +1,73 @@
"""Dignity-path Neecha Bhanga records the two kendra conditions (BUG-1268)."""
from __future__ import annotations
from datetime import datetime
from scripts.jyotish_engine import (
_build_dignity_context,
_get_dignity_level,
_neecha_bhanga_evidence,
cmd_dasha,
)
def _capricorn_jupiter(**extra_planets):
planets = {
"Jupiter": {"sign": "Capricorn", "degree": 10.0, "house": 10},
"Moon": {"sign": "Gemini", "degree": 5.0, "house": 3},
"Mars": {"sign": "Leo", "degree": 5.0, "house": 5},
}
planets.update(extra_planets)
return planets
def test_dispositor_kendra_from_lagna_is_checked_and_is_not_a_raja_yoga() -> None:
planets = _capricorn_jupiter(Saturn={"sign": "Aries", "degree": 4.0, "house": 1})
context = _build_dignity_context(planets)
assert context["Saturn"]["house"] == 1
evidence = _neecha_bhanga_evidence("Jupiter", "Capricorn", context)
assert evidence["conditions_checked"] == [
"dispositor_exalted",
"exaltation_lord_conjunct_debilitation_sign",
"dispositor_kendra_from_moon",
"dispositor_kendra_from_lagna",
]
assert evidence["royal_yoga_label_allowed"] is False
assert "Raja Yoga" in evidence["claim_boundary"]
assert {row["condition"] for row in evidence["reasons"]} == {"dispositor_kendra_from_lagna"}
assert _get_dignity_level("Jupiter", "Capricorn", 10.0, context) == "NEECHA_BHANGA"
def test_dispositor_kendra_from_moon_is_checked() -> None:
planets = _capricorn_jupiter(
Saturn={"sign": "Cancer", "degree": 4.0, "house": 5},
Moon={"sign": "Cancer", "degree": 8.0, "house": 5},
)
context = _build_dignity_context(planets)
evidence = _neecha_bhanga_evidence("Jupiter", "Capricorn", context)
assert {row["condition"] for row in evidence["reasons"]} == {"dispositor_kendra_from_moon"}
assert evidence["reasons"][0]["house_from_moon"] == 1
def test_first_mahadasha_antardasha_keeps_the_unclipped_parent_start() -> None:
# 原值 / 新值 / 原因: 旧小运从截断后的可见段重排;新值保留未截断起点并裁掉出生前已结束的小运。
args = type("Args", (), {
"moon_lon": 79.0,
"nakshatra": None,
"pada": None,
"birthdate": "1990-01-15",
"today": "2026-05-04",
})()
first = cmd_dasha(args)["timeline"][0]
birth = datetime(1990, 1, 15)
assert first["is_balance"] is True
ads = first["antardasha_timeline"]
assert ads
for row in ads:
assert datetime.fromisoformat(row["start_datetime"]) >= birth
assert datetime.fromisoformat(row["end_datetime"]) > birth
assert "unclipped_start_datetime" in row
straddling = [row for row in ads if row["unclipped_start_datetime"] != row["start_datetime"]]
assert straddling
assert datetime.fromisoformat(straddling[0]["unclipped_start_datetime"]) < birth