134 lines
4.9 KiB
Python
134 lines
4.9 KiB
Python
#!/usr/bin/env python3
|
|
"""Run a local jyotishganit same-case raw field probe.
|
|
|
|
Observation-only: records raw/hash/schema for D2/D4/D9/D10, Panchanga,
|
|
BAV/SAV and Shadbala availability without promoting truth.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import hashlib
|
|
import json
|
|
import sys
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
JYOTISHGANIT_ROOT = ROOT / "references/open_source_sources/jyotishganit"
|
|
TARGET_VARGAS = ["d2", "d4", "d9", "d10"]
|
|
|
|
|
|
def stable_json(data: Any) -> str:
|
|
return json.dumps(data, ensure_ascii=False, sort_keys=True, separators=(",", ":"), default=str)
|
|
|
|
|
|
def schema_fingerprint(data: Any) -> Any:
|
|
if isinstance(data, dict):
|
|
return {k: schema_fingerprint(v) for k, v in sorted(data.items())}
|
|
if isinstance(data, list):
|
|
if not data:
|
|
return []
|
|
return [schema_fingerprint(data[0])]
|
|
return type(data).__name__
|
|
|
|
|
|
def sign_table(chart: dict[str, Any]) -> dict[str, Any]:
|
|
out: dict[str, Any] = {}
|
|
for code in TARGET_VARGAS:
|
|
section = chart.get("divisionalCharts", {}).get(code)
|
|
if not isinstance(section, dict):
|
|
out[code.upper()] = {"status": "missing"}
|
|
continue
|
|
rows = []
|
|
for house in section.get("houses", []):
|
|
for occ in house.get("occupants", []):
|
|
rows.append(
|
|
{
|
|
"planet": occ.get("celestialBody"),
|
|
"sign": occ.get("sign"),
|
|
"d1HousePlacement": occ.get("d1HousePlacement"),
|
|
}
|
|
)
|
|
out[code.upper()] = {
|
|
"status": "present",
|
|
"ascendant_sign": section.get("ascendant", {}).get("sign"),
|
|
"planet_signs": sorted(rows, key=lambda r: str(r.get("planet"))),
|
|
}
|
|
return out
|
|
|
|
|
|
def build_probe(args: argparse.Namespace) -> dict[str, Any]:
|
|
sys.path.insert(0, str(JYOTISHGANIT_ROOT))
|
|
from jyotishganit.main import calculate_birth_chart # type: ignore
|
|
|
|
dt = datetime.fromisoformat(args.datetime)
|
|
chart = calculate_birth_chart(dt, args.latitude, args.longitude, args.timezone, args.location, args.name)
|
|
raw = chart.to_dict()
|
|
selected = {
|
|
"panchanga": raw.get("panchanga"),
|
|
"varga_sign_table": sign_table(raw),
|
|
"ashtakavarga": raw.get("ashtakavarga"),
|
|
"shadbala": raw.get("shadbala"),
|
|
"strengths": raw.get("strengths"),
|
|
}
|
|
payload = {
|
|
"scope": "jyotishganit_field_probe",
|
|
"created_at": "2026-07-19",
|
|
"status": "complete",
|
|
"claim_status": "observation_only",
|
|
"production_tuning_allowed": False,
|
|
"truth_matrix_allowed": False,
|
|
"engine": {
|
|
"name": "jyotishganit",
|
|
"local_path": str(JYOTISHGANIT_ROOT.relative_to(ROOT)),
|
|
},
|
|
"request": {
|
|
"name": args.name,
|
|
"datetime": args.datetime,
|
|
"latitude": args.latitude,
|
|
"longitude": args.longitude,
|
|
"timezone": args.timezone,
|
|
"location": args.location,
|
|
},
|
|
"coverage": {
|
|
"panchanga": raw.get("panchanga") is not None,
|
|
"D2": selected["varga_sign_table"]["D2"]["status"] == "present",
|
|
"D4": selected["varga_sign_table"]["D4"]["status"] == "present",
|
|
"D9": selected["varga_sign_table"]["D9"]["status"] == "present",
|
|
"D10": selected["varga_sign_table"]["D10"]["status"] == "present",
|
|
"BAV_SAV": isinstance(raw.get("ashtakavarga"), dict)
|
|
and "sav" in raw.get("ashtakavarga", {}),
|
|
"Shadbala": raw.get("shadbala") is not None or raw.get("strengths") is not None,
|
|
},
|
|
"raw_hash": hashlib.sha256(stable_json(raw).encode("utf-8")).hexdigest(),
|
|
"selected_hash": hashlib.sha256(stable_json(selected).encode("utf-8")).hexdigest(),
|
|
"schema_fingerprint": schema_fingerprint(selected),
|
|
"selected_raw": selected,
|
|
"boundary": "Raw/hash observation only. Missing Shadbala field or matching signs do not prove formula truth or production timing readiness.",
|
|
}
|
|
return payload
|
|
|
|
|
|
def main() -> int:
|
|
ap = argparse.ArgumentParser()
|
|
ap.add_argument("--datetime", default="1955-02-24T19:15:00")
|
|
ap.add_argument("--latitude", type=float, default=37.3382)
|
|
ap.add_argument("--longitude", type=float, default=-122.0383)
|
|
ap.add_argument("--timezone", type=float, default=-8.0)
|
|
ap.add_argument("--location", default="San Francisco, CA")
|
|
ap.add_argument("--name", default="Steve Jobs public")
|
|
ap.add_argument("--output")
|
|
args = ap.parse_args()
|
|
payload = build_probe(args)
|
|
text = json.dumps(payload, ensure_ascii=False, indent=2, sort_keys=True)
|
|
if args.output:
|
|
Path(args.output).write_text(text + "\n", encoding="utf-8")
|
|
print(text)
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|