diff --git a/references/oracle/kp_precision_timing_gap_registry_2026_07_19.json b/references/oracle/kp_precision_timing_gap_registry_2026_07_19.json index 6c486d3f..533399e8 100644 --- a/references/oracle/kp_precision_timing_gap_registry_2026_07_19.json +++ b/references/oracle/kp_precision_timing_gap_registry_2026_07_19.json @@ -37,12 +37,12 @@ }, { "technique_id": "ruling_planets", - "local_code_status": "missing_runtime", - "skill_invocation_status": "not_invoked", - "api_ui_entry_status": "missing", - "external_oracle_status": "missing", + "local_code_status": "minimal_probe_present", + "skill_invocation_status": "not_invoked_runtime_probe_available", + "api_ui_entry_status": "missing_api_probe_script_available", + "external_oracle_status": "missing_ruling_planets_oracle", "commercial_sync_status": "blocked_until_oracle", - "claim_boundary": "Reference/probe only; ruling planets cannot drive rectification or timing before external oracle and negative holdout gates." + "claim_boundary": "Reference/probe only; ruling planets are exposed by scripts/kp_precision_timing_probe.py but cannot drive rectification or timing before exact question-time contract, external oracle and negative holdout gates." }, { "technique_id": "kp_significators", diff --git a/scripts/kp_precision_timing_probe.py b/scripts/kp_precision_timing_probe.py index c2c6bd0e..868d3488 100644 --- a/scripts/kp_precision_timing_probe.py +++ b/scripts/kp_precision_timing_probe.py @@ -10,10 +10,11 @@ from __future__ import annotations import hashlib import json +from datetime import datetime from pathlib import Path from typing import Any -from kp_system import calc_kp_analysis +from kp_system import calc_kp_analysis, get_kp_lords ROOT = Path(__file__).resolve().parents[1] @@ -30,6 +31,10 @@ CANONICAL_PLANETS = { "Rahu": {"sign": "Scorpio", "degree": 17.0, "house": 8}, "Ketu": {"sign": "Taurus", "degree": 17.0, "house": 2}, } +CANONICAL_MOMENT = datetime(2026, 7, 19, 12, 0, 0) +CANONICAL_ASC_LONGITUDE = 10.0 +CANONICAL_MOON_LONGITUDE = 35.0 +WEEKDAY_LORDS = ["Moon", "Mars", "Mercury", "Jupiter", "Venus", "Saturn", "Sun"] def _stable_hash(data: Any) -> str: @@ -37,8 +42,24 @@ def _stable_hash(data: Any) -> str: return hashlib.sha256(payload.encode("utf-8")).hexdigest() +def _kp_ruling_planets(moment: datetime, asc_longitude: float, moon_longitude: float) -> dict[str, Any]: + asc = get_kp_lords(asc_longitude) + moon = get_kp_lords(moon_longitude) + return { + "weekday_lord": WEEKDAY_LORDS[moment.weekday()], + "moon_sign_lord": moon.get("rasi_lord"), + "moon_star_lord": moon.get("nakshatra_lord"), + "moon_sub_lord": moon.get("sub_lord"), + "asc_sign_lord": asc.get("rasi_lord"), + "asc_star_lord": asc.get("nakshatra_lord"), + "asc_sub_lord": asc.get("sub_lord"), + "source_boundary": "Minimal KP ruling-planet probe; exact horary/timing use requires question-time location and external worked examples.", + } + + def build_probe() -> dict[str, Any]: raw = calc_kp_analysis(CANONICAL_PLANETS, asc_sign="Aries") + ruling_planets = _kp_ruling_planets(CANONICAL_MOMENT, CANONICAL_ASC_LONGITUDE, CANONICAL_MOON_LONGITUDE) planets = raw.get("planets", {}) houses = raw.get("houses", {}) kp_lords_by_planet = { @@ -72,6 +93,7 @@ def build_probe() -> dict[str, Any]: "license_boundary": "Local implementation cites diliprk/VedicAstro MIT; keep source/oracle audit before commercial precise timing.", }, "kp_lords_by_planet": kp_lords_by_planet, + "ruling_planets": ruling_planets, "planet_significators": planet_significators, "house_significators": house_significators, "raw_sha256": _stable_hash(raw), diff --git a/tests/test_high_value_gap_registries.py b/tests/test_high_value_gap_registries.py index 46c628b0..dc8f1e5e 100644 --- a/tests/test_high_value_gap_registries.py +++ b/tests/test_high_value_gap_registries.py @@ -50,6 +50,7 @@ def test_kp_registry_keeps_precision_timing_blocked_without_oracle() -> None: assert {"kp_cusps", "star_sub_lord", "ruling_planets", "kp_significators", "kp_horary"}.issubset(ids) assert ids["star_sub_lord"]["local_code_status"] == "minimal_probe_present" assert ids["star_sub_lord"]["external_oracle_status"] == "partial_sublord_csv_only" + assert ids["ruling_planets"]["local_code_status"] == "minimal_probe_present" assert ids["kp_significators"]["local_code_status"] == "minimal_probe_present" assert ids["kp_significators"]["claim_boundary"].startswith("Reference/probe only") diff --git a/tests/test_kp_precision_timing_probe.py b/tests/test_kp_precision_timing_probe.py index 237adedb..a4716ef1 100644 --- a/tests/test_kp_precision_timing_probe.py +++ b/tests/test_kp_precision_timing_probe.py @@ -33,6 +33,7 @@ def test_kp_precision_timing_probe_outputs_star_sub_lord_and_significators() -> assert {"A", "B", "C", "D"} <= set(report["planet_significators"]["Sun"]) assert "10" in report["house_significators"] assert {"A", "B", "C", "D"} <= set(report["house_significators"]["10"]) + assert {"weekday_lord", "moon_sign_lord", "moon_star_lord", "asc_sign_lord", "asc_star_lord", "asc_sub_lord"} <= set(report["ruling_planets"]) def test_kp_precision_timing_probe_preserves_oracle_and_holdout_blockers() -> None: