Files
Jyotisha/scripts/jyotishganit_field_probe.py
T
2026-07-21 16:52:58 +08:00

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())