From 18c685c428a06f4530e43218588c03ca9ce1dea3 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 4 Nov 2026 17:33:26 +0800 Subject: [PATCH] fix(engine): even-sign D30 per BPHS ch. 6 and Venus malefic for Aries / Scorpio per BPHS 34 (BUG-1560, BUG-1570) Product decision 2026-11-04: the calculation follows the sources even though rectification scores move. - scripts/varga.py: even-sign Trimsamsa 12-20 Pisces, 20-25 Capricorn, 25-30 Scorpio (was Capricorn / Scorpio / Pisces). KNOWN DEFECT comment removed; the strict xfail in tests/test_varga_bphs_starts_audit_g.py is now an ordinary test and the 0.1-degree BPHS sweep covers varga.py on all signs. - scripts/functional_benefics.py: ROLE_OVERRIDES adds Venus = malefic for Aries (BPHS 34.20) and Scorpio (34.35); profile doc lists both cells. Both feed rectification scoring; the scoring-13 identity bump, memoization golden v6 and the ERR-110 re-freeze follow in the next commits. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y --- references/functional-role-profile.md | 7 ++++--- scripts/functional_benefics.py | 6 ++++-- scripts/varga.py | 16 +++++++--------- .../test_functional_yogakaraka_kendra_trikona.py | 11 +++++++++++ tests/test_varga_bphs_starts_audit_g.py | 10 ++++------ 5 files changed, 30 insertions(+), 20 deletions(-) diff --git a/references/functional-role-profile.md b/references/functional-role-profile.md index 87cd75c0..54398513 100644 --- a/references/functional-role-profile.md +++ b/references/functional-role-profile.md @@ -17,9 +17,10 @@ not automatically malefic. Sun/Moon eighth lordship has the stated exception. Unspecified angular or second-house-only cases remain neutral/mixed. Explicit exceptions are recorded in `ROLE_OVERRIDES`: Aries Mars helpful in -association (mixed); Taurus Venus challenging, Sun supportive; Gemini Jupiter -challenging; Virgo Jupiter challenging; Libra Venus mixed, Mars challenging; -Scorpio Mars mixed and Sun yoga-supporting; Sagittarius Jupiter/Mercury mixed +association (mixed), Venus challenging (34.20); Taurus Venus challenging, Sun +supportive; Gemini Jupiter challenging; Virgo Jupiter challenging; Libra Venus +mixed, Mars challenging; Scorpio Mars mixed, Sun yoga-supporting, Venus +challenging (34.35); Sagittarius Jupiter/Mercury mixed (Mercury's association with Sun is separate); Capricorn Moon challenging; Aquarius Mars challenging, Mercury mixed; Pisces Mercury challenging. The remaining general fallbacks are identified in each planet's `role_basis`; diff --git a/scripts/functional_benefics.py b/scripts/functional_benefics.py index 1b2d0b1f..21fba515 100644 --- a/scripts/functional_benefics.py +++ b/scripts/functional_benefics.py @@ -31,12 +31,14 @@ SOURCE = "strict_functional_benefic_malefic_v2" # precedence. Neutral means mixed/association-dependent, not harmless. PROFILE = "bphs_ch34_general_with_sign_exceptions_v2" ROLE_OVERRIDES = { - "Aries": {"Mars": "neutral"}, + # BPHS 34.20 (Aries) and 34.35 (Scorpio) name Venus (sita) a malefic + # (BUG-1570, product decision 2026-11-04; scoring-13). + "Aries": {"Mars": "neutral", "Venus": "malefic"}, "Taurus": {"Venus": "malefic", "Sun": "benefic"}, "Gemini": {"Jupiter": "malefic"}, "Virgo": {"Jupiter": "malefic"}, "Libra": {"Venus": "neutral", "Mars": "malefic"}, - "Scorpio": {"Mars": "neutral", "Sun": "benefic"}, + "Scorpio": {"Mars": "neutral", "Sun": "benefic", "Venus": "malefic"}, "Sagittarius": {"Jupiter": "neutral", "Mercury": "neutral"}, "Capricorn": {"Moon": "malefic"}, "Aquarius": {"Mars": "malefic", "Mercury": "neutral"}, diff --git a/scripts/varga.py b/scripts/varga.py index 7258ad3f..93b2c5d5 100644 --- a/scripts/varga.py +++ b/scripts/varga.py @@ -57,17 +57,15 @@ def _d30_map(si, pi): if pi<25: return 2 return 6 else: - # KNOWN DEFECT, held back (BUG-1560, blocked): BPHS ch. 6 even signs are - # Venus 5, Mercury 7, Jupiter 8, Saturn 5, Mars 5 -> Taurus, Virgo, Pisces, - # Capricorn, Scorpio (PyJHora method 1; shadbala._d30_sign; trimshamsa_d30; - # divisional_charts_extended). The last three below are Capricorn / Scorpio / - # Pisces. Rectification scoring reads this D30, so the correction needs a - # scoring-13 algorithm identity and a new memoization golden; product decides. + # BPHS ch. 6 even signs: Venus 5, Mercury 7, Jupiter 8, Saturn 5, Mars 5 -> + # Taurus, Virgo, Pisces, Capricorn, Scorpio (PyJHora method 1; shadbala._d30_sign; + # trimshamsa_d30; divisional_charts_extended). Rectification scoring reads this + # D30, so the 2026-11-04 correction raised the identity to scoring-13 (BUG-1560). if pi<5: return 1 if pi<12: return 5 - if pi<20: return 9 - if pi<25: return 7 - return 11 + if pi<20: return 11 + if pi<25: return 9 + return 7 def varga_map(si, pi, div): """BPHS分盘映射:星座索引si的第pi份→目标星座索引""" diff --git a/tests/test_functional_yogakaraka_kendra_trikona.py b/tests/test_functional_yogakaraka_kendra_trikona.py index 3a898294..ff0f068b 100644 --- a/tests/test_functional_yogakaraka_kendra_trikona.py +++ b/tests/test_functional_yogakaraka_kendra_trikona.py @@ -45,3 +45,14 @@ def test_sole_twelfth_lord_is_not_automatically_malefic() -> None: # Virgo: the Sun owns only the 12th; Leo: the Moon owns only the 12th. assert "Sun" not in derive_functional_benefic_malefic("Virgo")["functional_malefics"] assert "Moon" not in derive_functional_benefic_malefic("Leo")["functional_malefics"] + + +@pytest.mark.parametrize(("sign", "houses"), [("Aries", [2, 7]), ("Scorpio", [7, 12])]) +def test_venus_is_functional_malefic_for_aries_and_scorpio(sign: str, houses: list[int]) -> None: + # BUG-1570(产品 2026-11-04 决定):BPHS 34.20「mandasaumyasitāḥ pāpāḥ」、34.35「sitajñaśanayaḥ pāpāḥ」 + # 点名金星(sita)为凶;逐上升明文优先于总则(只管角宫 / 2 宫 → 中性)。期望值独立写出,不读 ROLE_OVERRIDES。 + result = derive_functional_benefic_malefic(sign) + assert result["owned_houses"]["Venus"] == houses + assert "Venus" in result["functional_malefics"] + assert "Venus" not in result["functional_neutrals"] + result["functional_benefics"] + assert result["role_basis"]["Venus"] == "BPHS ch34 sign-specific exception" diff --git a/tests/test_varga_bphs_starts_audit_g.py b/tests/test_varga_bphs_starts_audit_g.py index a48f9cda..b81ac003 100644 --- a/tests/test_varga_bphs_starts_audit_g.py +++ b/tests/test_varga_bphs_starts_audit_g.py @@ -68,15 +68,13 @@ def test_trimsamsa_matches_bphs_in_the_extended_trimshamsa_and_shadbala_tables() assert _extended_sign(longitude, 30) == expected, ("extended", sign, degree) assert trimshamsa_d30.calc_d30_sign(longitude) == expected, ("trimshamsa_d30", sign, degree) assert shadbala._d30_sign(sign, degree) == expected, ("shadbala", sign, degree) - if sign % 2 == 0: # odd signs: varga.py already agrees - assert calc_varga(longitude, 30)["sign_idx"] == expected, ("varga", sign, degree) + assert calc_varga(longitude, 30)["sign_idx"] == expected, ("varga", sign, degree) -@pytest.mark.xfail(strict=True, reason=( - "BUG-1560 blocked: varga.py even-sign D30 (12-30 deg) still Capricorn/Scorpio/Pisces; the fix moves " - "rectification scores and needs a scoring-13 identity, pending product decision. Remove this mark with the fix." -)) def test_varga_py_even_sign_trimsamsa_matches_bphs() -> None: + # 原值: strict xfail(BUG-1560 blocked,偶数星座 12-30° 仍是摩羯 / 天蝎 / 双鱼) + # 新值: 普通测试,必须通过 + # 原因: 产品 2026-11-04 决定按 BPHS 改正 varga.py 偶数星座 D30,校正身份升到 scoring-13 for sign in range(1, 12, 2): for tenth in range(300): degree = tenth / 10 + 0.05