feat(functional): adopt upstream BPHS ch.34 profile v2; fix Pancha Mahapurusha self-conjunction; yoga engine reads the same functional roles
Ported verbatim from the upstream skill repo (yinduzhanxing e9beae6b) with product authorization 2026-10-02: scripts/functional_benefics.py, scripts/pancha_mahapurusha.py, references/functional-role-profile.md; only the two functional-role methods of scripts/yoga_engine.py (our file diverged). v5 77-case rectification eval: 5 cells up (to +7.8pp), one cell -1.3pp (one case); product accepted. Rectification memoization golden still to be regenerated (scores change with the grouping). 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:
co-authored by
Claude Opus 5.5
parent
f85794661b
commit
57782aea8a
@@ -26,16 +26,22 @@ SIGN_LORDS = {
|
||||
"Pisces": "Jupiter",
|
||||
}
|
||||
PLANETS = ("Sun", "Moon", "Mars", "Mercury", "Jupiter", "Venus", "Saturn")
|
||||
# v2 (2026-10-02, BUG-1158 partial, product decision on
|
||||
# TASK-consult-career-yoga-functional-20261002 T1): a yogakaraka must own one
|
||||
# kendra among 4 / 7 / 10 AND one trikona among 5 / 9 (BPHS ch.34 v13); the
|
||||
# 1st house no longer counts for this test, so a lagna lord is not a
|
||||
# yogakaraka by owning the 1st. The benefic / malefic / neutral grouping is
|
||||
# unchanged from v1. The full per-lagna BPHS ch.34 table waits for an
|
||||
# astrology consultant on branch codex/consult-career-yoga-functional-t1-20261002.
|
||||
SOURCE = "strict_functional_benefic_malefic_v2"
|
||||
YOGAKARAKA_KENDRAS = frozenset({4, 7, 10})
|
||||
YOGAKARAKA_TRIKONAS = frozenset({5, 9})
|
||||
# General ownership rules, with explicit sign-specific statements taking
|
||||
# precedence. Neutral means mixed/association-dependent, not harmless.
|
||||
PROFILE = "bphs_ch34_general_with_sign_exceptions_v2"
|
||||
ROLE_OVERRIDES = {
|
||||
"Aries": {"Mars": "neutral"},
|
||||
"Taurus": {"Venus": "malefic", "Sun": "benefic"},
|
||||
"Gemini": {"Jupiter": "malefic"},
|
||||
"Virgo": {"Jupiter": "malefic"},
|
||||
"Libra": {"Venus": "neutral", "Mars": "malefic"},
|
||||
"Scorpio": {"Mars": "neutral", "Sun": "benefic"},
|
||||
"Sagittarius": {"Jupiter": "neutral", "Mercury": "neutral"},
|
||||
"Capricorn": {"Moon": "malefic"},
|
||||
"Aquarius": {"Mars": "malefic", "Mercury": "neutral"},
|
||||
"Pisces": {"Mercury": "malefic"},
|
||||
}
|
||||
|
||||
|
||||
def normalize_sign(value: Any) -> str | None:
|
||||
@@ -74,7 +80,7 @@ def derive_functional_benefic_malefic(ascendant: Any) -> dict[str, Any]:
|
||||
|
||||
trines = {1, 5, 9}
|
||||
kendras = {1, 4, 7, 10}
|
||||
challenging = {3, 6, 8, 11, 12}
|
||||
challenging = {3, 6, 8, 11}
|
||||
benefics: set[str] = set()
|
||||
malefics: set[str] = set()
|
||||
yogakarakas: set[str] = set()
|
||||
@@ -88,9 +94,10 @@ def derive_functional_benefic_malefic(ascendant: Any) -> dict[str, Any]:
|
||||
owns_kendra = any(house in kendras for house in houses)
|
||||
owns_challenge = any(house in challenging for house in houses)
|
||||
|
||||
if owns_trine and owns_kendra and planet not in {"Sun", "Moon"}:
|
||||
if YOGAKARAKA_KENDRAS & set(houses) and YOGAKARAKA_TRIKONAS & set(houses):
|
||||
yogakarakas.add(planet)
|
||||
# House 1 remains both angular and trinal, but cannot be reused as
|
||||
# two distinct lordships for this strict Yoga-karaka field.
|
||||
if set(houses) & {4, 7, 10} and set(houses) & {5, 9}:
|
||||
yogakarakas.add(planet)
|
||||
benefics.add(planet)
|
||||
elif owns_trine:
|
||||
benefics.add(planet)
|
||||
@@ -106,6 +113,12 @@ def derive_functional_benefic_malefic(ascendant: Any) -> dict[str, Any]:
|
||||
malefics.remove(eighth_lord)
|
||||
neutrals.add(eighth_lord)
|
||||
|
||||
for planet, role in ROLE_OVERRIDES.get(asc_sign, {}).items():
|
||||
benefics.discard(planet)
|
||||
malefics.discard(planet)
|
||||
neutrals.discard(planet)
|
||||
{"benefic": benefics, "malefic": malefics, "neutral": neutrals}[role].add(planet)
|
||||
|
||||
return {
|
||||
"status": "used",
|
||||
"ascendant": asc_sign,
|
||||
@@ -119,4 +132,19 @@ def derive_functional_benefic_malefic(ascendant: Any) -> dict[str, Any]:
|
||||
"若功能属性与自然属性冲突,应降低置信度或显式标记冲突。"
|
||||
),
|
||||
"source": SOURCE,
|
||||
"profile": PROFILE,
|
||||
"lagna_lord": SIGN_LORDS[asc_sign],
|
||||
"yogakaraka_definition": "distinct lordships: one of 4/7/10 and one of 5/9",
|
||||
"rule_reference": "references/functional-role-profile.md",
|
||||
"assertion_label": "parameter_sensitive",
|
||||
"role_basis": {
|
||||
planet: "BPHS ch34 sign-specific exception" if planet in ROLE_OVERRIDES.get(asc_sign, {})
|
||||
else "BPHS ch34 general ownership; associations not evaluated"
|
||||
for planet in PLANETS
|
||||
},
|
||||
"conditions": [
|
||||
"Neutral/mixed is association-dependent, not an absence of risk.",
|
||||
"Natural nature, strength, maraka roles and dasha activation remain separate.",
|
||||
"Strict yogakarakas do not exhaust the text's broader yoga-producing associations.",
|
||||
],
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user