Files
Jyotisha/scripts/prashna_sphuta_candidate_replay.py
T
2026-07-21 19:21:02 +08:00

54 lines
3.0 KiB
Python

#!/usr/bin/env python3
"""Expected-value-only replay readiness for Prashna Sphuta candidates."""
from __future__ import annotations
import argparse, json, re
from pathlib import Path
from scripts.prashna_sphuta import calculate_sphuta_evidence
ROOT = Path(__file__).resolve().parents[1]
QUEUE = ROOT / "references/oracle/prashna_numeric_oracle_packet_queue_2026_07_20.json"
OUT = ROOT / "references/oracle/prashna_sphuta_candidate_replay_readiness_2026_07_20.json"
PAT = re.compile(r"(?P<sign>\d+)s\s*(?P<deg>\d+)°(?:\s*(?P<min>\d+)')?(?:\s*(?P<sec>\d+)\")?")
def parse_dms(value: str) -> float:
m = PAT.search(value)
if not m: raise ValueError(value)
sign=int(m.group('sign')); deg=int(m.group('deg')); minute=int(m.group('min') or 0); sec=int(m.group('sec') or 0)
return (sign*30 + deg + minute/60 + sec/3600) % 360
def close(a,b,tol=0.02): return abs(((a-b+180)%360)-180) <= tol
def build(date: str):
q=json.load(open(QUEUE))
rows=[]
for cand in q['rows']:
ev={k:parse_dms(v) for k,v in cand['expected_values'].items()}
calc=calculate_sphuta_evidence(ascendant_longitude=ev['lagna'], planet_longitudes={'Sun':ev['sun'],'Moon':ev['moon'],'Rahu':ev['rahu']}, gulika_longitude=ev['gulika'])
pts=calc['points']
computed={'trisphuta': pts['trisphuta'], 'chatusphuta': pts['catusphuta'], 'panchasphuta': pts['pancasphuta']}
pass_formula=all(close(computed[k], ev[k]) for k in ['trisphuta','chatusphuta','panchasphuta'])
rows.append({
'source_id': cand['source_id'],
'url': cand['url'],
'expected_degrees': ev,
'computed_from_expected_degrees': computed,
'local_formula_consistency': 'pass' if pass_formula else 'mismatch',
'replay_status': 'blocked_missing_complete_input',
'missing_for_true_replay': ['question_datetime_local','location','timezone','ayanamsa','node_mode','raw_capture_hash','legal_external_replay'],
'upgrade_status': 'not_oracle_ready',
'claim_boundary': 'Checks arithmetic consistency of published expected values only; not a true local ephemeris replay.',
})
data={
'scope':'prashna_sphuta_candidate_replay_readiness','created_at':date,'status':'replay_readiness_ready','claim_status':'tooling_observation_only',
'production_tuning_allowed':False,'truth_matrix_allowed':False,
'summary':{'candidate_count':len(rows),'local_formula_check_pass_count':sum(r['local_formula_consistency']=='pass' for r in rows),'oracle_ready_count':0},
'rows':rows,'boundary':'Expected-value arithmetic only; complete Prashna inputs are still required for oracle replay.'
}
return data
def main():
ap=argparse.ArgumentParser(); ap.add_argument('--date',default='2026-07-20'); args=ap.parse_args()
data=build(args.date); OUT.write_text(json.dumps(data,ensure_ascii=False,indent=2,sort_keys=True)+'\n'); print(json.dumps(data,ensure_ascii=False,indent=2,sort_keys=True))
if __name__=='__main__': main()