Files
Jyotisha/scripts/rectification/kp_cusp_observation.py
T
Jesse_Chen 8010245981
Independent Staging Quality Gate / validate (push) Failing after 6m42s
Independent Staging Quality Gate / publish (push) Has been skipped
feat(product): present consult and rectification in local skill form
Default ayanamsa to Raman with true_pushya support, attach governed Raman packets, restore Path C questionnaires and eight-method verification copy, and keep unique-minute confirmation blocked.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-20 21:42:47 +08:00

88 lines
3.4 KiB
Python

"""Display-only KP Placidus cusp observation for birth-time rectification.
This lane uses Swiss Ephemeris Placidus house cusps and Krishnamurti ayanamsa.
It must never mix into ranking, propose, or unique-minute confirmation.
Whole-sign midpoints are not a substitute.
"""
from __future__ import annotations
from typing import Any
from ayanamsa_utils import DEFAULT_AYANAMSA_NAME, apply_ayanamsa, current_ayanamsa_name
from kp_system import KP_LORDS, get_kp_lords
from scripts.domain_calculation_service import swiss_ephemeris_lock
SCAN_HOUSES = (1, 4, 7, 10)
_BLOCKED = {
"status": "blocked",
"house_system": "placidus",
"ayanamsa": "krishnamurti",
"houses": {},
"indices": {},
"note": "Swiss Ephemeris Placidus 宫头无法计算,KP 观察未执行。不计分,不挡提出门。",
}
def _cusp_row(degree: float) -> dict[str, Any]:
lords = get_kp_lords(degree)
sub_lord = str(lords.get("sub_lord") or "")
try:
sub_index = KP_LORDS.index(sub_lord)
except ValueError:
sub_index = None
return {
"cusp_degree": round(float(degree) % 360.0, 4),
"sign": lords.get("sign"),
"rasi_lord": lords.get("rasi_lord"),
"nakshatra": lords.get("nakshatra"),
"nakshatra_lord": lords.get("nakshatra_lord"),
"pada": lords.get("pada"),
"sub_lord": sub_lord,
"sub_sub_lord": lords.get("sub_sub_lord"),
"sub_index": sub_index,
}
def observe_kp_cusps(jd: float | None, lat: float | None, lon: float | None) -> dict[str, Any]:
"""Return Placidus + Krishnamurti 12-cusp snapshot, or a blocked observation."""
if not isinstance(jd, (int, float)) or not isinstance(lat, (int, float)) or not isinstance(lon, (int, float)):
return dict(_BLOCKED)
if abs(float(lat)) >= 66.0:
return dict(_BLOCKED)
previous = current_ayanamsa_name()
try:
import swisseph as swe
except ImportError:
return dict(_BLOCKED)
with swiss_ephemeris_lock():
try:
apply_ayanamsa("krishnamurti", swe)
cusps_raw, _ascmc = swe.houses(float(jd), float(lat), float(lon), b"P")
ayanamsa = float(swe.get_ayanamsa(float(jd)))
houses: dict[str, dict[str, Any]] = {}
indices: dict[str, int] = {}
for house in range(1, 13):
tropical = float(cusps_raw[house - 1])
if tropical != tropical or abs(tropical) > 720: # NaN / absurd
return dict(_BLOCKED)
sidereal = (tropical - ayanamsa) % 360.0
row = _cusp_row(sidereal)
houses[str(house)] = row
if house in SCAN_HOUSES and isinstance(row["sub_index"], int):
indices[f"kp{house}_sub_index"] = row["sub_index"]
if len(houses) != 12 or len(indices) != 4:
return dict(_BLOCKED)
return {
"status": "executed",
"house_system": "placidus",
"ayanamsa": "krishnamurti",
"houses": houses,
"indices": indices,
"note": "已按 Swiss Ephemeris Placidus + Krishnamurti 观察 12 宫头;不计分,不参与提出门或确认门。",
}
except (TypeError, ValueError, OverflowError, OSError, RuntimeError, ArithmeticError):
return dict(_BLOCKED)
finally:
apply_ayanamsa(previous or DEFAULT_AYANAMSA_NAME, swe)