sync: import prashna sphuta validation packets

This commit is contained in:
732642856
2026-07-20 18:40:02 +08:00
parent d757602e7c
commit c7b09fd1a9
35 changed files with 2332 additions and 503 deletions
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/env python3
"""Locate short Prasna Marga Sphuta source windows by IA text URLs."""
from __future__ import annotations
import argparse, hashlib, json
from pathlib import Path
from urllib.request import Request, urlopen
ROOT = Path(__file__).resolve().parents[1]
SRC = ROOT / "references/oracle/prashna_marga_raw_capture_packet_2026_07_20.json"
OUT = ROOT / "references/oracle/prashna_marga_excerpt_locator_2026_07_20.json"
TERMS = ["Trisphuta", "Chatusphuta", "Catusphuta", "Panchasphuta", "Gulika"]
def sha(s: str) -> str: return hashlib.sha256(s.encode('utf-8','ignore')).hexdigest()
def fetch(url: str) -> str:
req=Request(url,headers={'User-Agent':'Mozilla/5.0'})
with urlopen(req,timeout=25) as r: return r.read().decode('utf-8','ignore')
def locate(text: str, source_id: str, file_name: str, url: str):
lines=text.splitlines()
for i,line in enumerate(lines):
if any(t.lower() in line.lower() for t in TERMS):
start=max(0,i-2); end=min(len(lines),i+3)
window='\n'.join(lines[start:end])
compact=' '.join(window.split())[:240]
return {'source_id':source_id,'file_name':file_name,'download_url':url,'matched_line':i+1,'line_start':start+1,'line_end':end,'matched_terms':[t for t in TERMS if t.lower() in window.lower()],'window_hash':sha(window),'short_context':compact}
return None
def build(date: str):
src=json.load(open(SRC)); wins=[]; blocked=[]
for item in src['internet_archive_items']:
for f in item['files']:
if f['format']!='DjVuTXT': continue
try:
hit=locate(fetch(f['download_url']), item['identifier'], f['name'], f['download_url'])
if hit: wins.append(hit)
else: blocked.append({'source_id':item['identifier'],'file_name':f['name'],'status':'locator_terms_not_found'})
except Exception as e:
blocked.append({'source_id':item['identifier'],'file_name':f['name'],'status':'fetch_failed','error':type(e).__name__})
return {'scope':'prashna_marga_excerpt_locator','created_at':date,'status':'excerpt_locator_ready','claim_status':'source_intake_only','production_tuning_allowed':False,'truth_matrix_allowed':False,'summary':{'located_window_count':len(wins),'blocked_file_count':len(blocked),'oracle_ready_count':0},'located_windows':wins,'blocked_files':blocked,'missing_for_oracle':['complete_prashna_input','raw excerpt capture','line-level transcription review','legal external replay'],'upgrade_status':'candidate_not_oracle','next_steps':['raw excerpt capture with page/line coordinates and independent transcription review','compare VedAstro vs B.V. Raman wording before formula tuning'],'boundary':'Short context and hashes only; no long copyrighted text is reproduced and no truth upgrade is allowed.'}
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()
@@ -0,0 +1,33 @@
#!/usr/bin/env python3
"""Pin Internet Archive Prasna Marga source metadata for later raw excerpt capture."""
from __future__ import annotations
import argparse, hashlib, json
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
OUT = ROOT / "references/oracle/prashna_marga_raw_capture_packet_2026_07_20.json"
ITEMS = [
{
'identifier':'PrasnaMargaBVR','title':'Prasna Marga - Dr. BV Raman','metadata_url':'https://archive.org/metadata/PrasnaMargaBVR',
'files':[{'name':'Prasna Marga 1_djvu.txt','format':'DjVuTXT','sha1':'bed3491a79ca5039409dac7fd62e386f7de55a47','download_url':'https://archive.org/download/PrasnaMargaBVR/Prasna%20Marga%201_djvu.txt'}, {'name':'Prasna Marga 1.pdf','format':'Text PDF','sha1':'86839fc2d13509309ec3a14a160c861bb223d844','download_url':'https://archive.org/download/PrasnaMargaBVR/Prasna%20Marga%201.pdf'}]
},
{
'identifier':'prasna-marga-part-2-by-bv-raman','title':'Prasna Marga Part 2 By BV Raman','metadata_url':'https://archive.org/metadata/prasna-marga-part-2-by-bv-raman',
'files':[{'name':'Prasna Marga Part 2 by BV Raman_djvu.txt','format':'DjVuTXT','sha1':'17c432465520ef75bde7a2c4fa167ff119664666','download_url':'https://archive.org/download/prasna-marga-part-2-by-bv-raman/Prasna%20Marga%20Part%202%20by%20BV%20Raman_djvu.txt'}]
},
]
def digest(obj): return hashlib.sha256(json.dumps(obj,ensure_ascii=False,sort_keys=True).encode()).hexdigest()
def build(date):
items=[]
for it in ITEMS:
row={**it,'source_metadata_hash':'','upgrade_status':'candidate_not_oracle','claim_boundary':'Metadata/file hash pin only; no book text is vendored and no numeric truth is upgraded.'}
row['source_metadata_hash']=digest(row)
items.append(row)
return {'scope':'prashna_marga_raw_capture_packet','created_at':date,'status':'raw_capture_metadata_ready','claim_status':'source_intake_only','production_tuning_allowed':False,'truth_matrix_allowed':False,'summary':{'ia_item_count':len(items),'pinned_file_count':sum(len(i['files']) for i in items),'oracle_ready_count':0},'field_locator_terms':['Trisphuta','Chatusphuta','Catusphuta','Panchasphuta','Gulika'],'internet_archive_items':items,'next_steps':['raw excerpt capture around locator terms with page/line coordinates','compare B.V. Raman scan vs VedAstro transcription','only then classify formula_variant vs source_transcription'],'boundary':'Capture metadata only; long copyrighted text is not reproduced.'}
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()
@@ -0,0 +1,27 @@
#!/usr/bin/env python3
"""Summarize Prashna/Sphuta closure chain and remaining gates."""
from __future__ import annotations
import argparse, json
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
OUT = ROOT / "references/oracle/prashna_sphuta_closure_dashboard_2026_07_20.json"
CHAIN = [
'prashna_input_contract_2026_07_20.json','prashna_numeric_oracle_packet_queue_2026_07_20.json','prashna_sphuta_candidate_replay_readiness_2026_07_20.json','prashna_sphuta_mismatch_arbitration_2026_07_20.json','prashna_marga_raw_capture_packet_2026_07_20.json','prashna_marga_excerpt_locator_2026_07_20.json','prashna_sphuta_source_comparison_matrix_2026_07_20.json','prashna_sphuta_line_review_queue_2026_07_20.json','prashna_sphuta_review_result_template_2026_07_20.json','prashna_sphuta_review_result_validation_2026_07_20.json']
def build(date):
packets=[]
for f in CHAIN:
p=ROOT/'references/oracle'/f
d=json.load(open(p)); packets.append({'path':str(p.relative_to(ROOT)),'scope':d.get('scope'),'claim_status':d.get('claim_status'),'status':d.get('status')})
gates=[
{'gate_id':'human_line_review','status':'blocked','evidence':'review_result_validation valid_completed_review_count == 0'},
{'gate_id':'complete_prashna_input','status':'blocked','evidence':'candidate lacks question datetime/location/timezone/ayanamsa/node'},
{'gate_id':'legal_external_replay','status':'blocked','evidence':'no PyJHora/other legal replay packet yet'},
{'gate_id':'formula_or_transcription_arbitration','status':'open_queue','evidence':'Trisphuta matches; Chatusphuta/Panchasphuta mismatch'},
]
return {'scope':'prashna_sphuta_closure_dashboard','created_at':date,'status':'closure_dashboard_ready','claim_status':'blocked_until_human_labels','production_tuning_allowed':False,'truth_matrix_allowed':False,'commercial_sync_status':'research_observation_only','summary':{'packet_chain_count':len(packets),'blocked_gate_count':sum(g['status']=='blocked' for g in gates),'truth_upgrade_count':0},'packet_chain':packets,'gates':gates,'forbidden_uses':['do_not_use_for_deterministic_prashna_verdict','do_not_tune_formula_from_candidate_mismatch','do_not_claim_external_oracle_ready'],'next_actions':['fill review_result_template via human/second-source review','capture complete Prashna input if a worked example is found','run legal external replay only after inputs close'],'boundary':'Dashboard only; summarizes blocked gates and does not upgrade any Prashna/Sphuta claim.'}
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()
@@ -0,0 +1,19 @@
#!/usr/bin/env python3
"""Create line-level review tasks from Prasna Marga excerpt locator windows."""
from __future__ import annotations
import argparse, json
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
LOC = ROOT / "references/oracle/prashna_marga_excerpt_locator_2026_07_20.json"
OUT = ROOT / "references/oracle/prashna_sphuta_line_review_queue_2026_07_20.json"
def build(date):
loc=json.load(open(LOC)); tasks=[]
for i,w in enumerate(loc['located_windows'],1):
tasks.append({'task_id':f'PSLRQ-{i:03d}','source_id':w['source_id'],'file_name':w['file_name'],'download_url':w['download_url'],'line_start':w['line_start'],'line_end':w['line_end'],'window_hash':w['window_hash'],'short_context':w['short_context'],'fields_to_check':['trisphuta','chatusphuta','catusphuta','panchasphuta','gulika'],'review_status':'needs_human_or_second_source_review','candidate_causes':['formula_variant','source_transcription','naming_variant'],'claim_boundary':'Review task only; no formula change or truth upgrade.'})
return {'scope':'prashna_sphuta_line_review_queue','created_at':date,'status':'review_queue_ready','claim_status':'open_queue','production_tuning_allowed':False,'truth_matrix_allowed':False,'summary':{'review_task_count':len(tasks),'truth_upgrade_count':0},'acceptance_criteria':['do_not_copy_long_text','record_line_coordinates','classify_formula_variant_or_transcription','preserve_window_hash','require_second_source_or_scan_review'],'review_tasks':tasks,'boundary':'Human/second-source transcription queue only.'}
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()
+41
View File
@@ -0,0 +1,41 @@
#!/usr/bin/env python3
"""Run installed PyJHora Sphuta OSS case as isolated observation."""
from __future__ import annotations
import argparse, contextlib, hashlib, importlib.metadata as md, io, json
from pathlib import Path
ROOT=Path(__file__).resolve().parents[1]
OUT=ROOT/'references/oracle/prashna_sphuta_oss_case_probe_2026_07_20.json'
def h(o): return hashlib.sha256(json.dumps(o,ensure_ascii=False,sort_keys=True,default=str).encode()).hexdigest()
def build(date):
rows=[]; meta={}
try:
captured_stdout = io.StringIO()
captured_stderr = io.StringIO()
with contextlib.redirect_stdout(captured_stdout), contextlib.redirect_stderr(captured_stderr):
import jhora
from jhora.panchanga import drik
from jhora.horoscope.chart import sphuta
try: dist=md.metadata('jhora')
except md.PackageNotFoundError: dist=md.metadata('PyJHora')
meta={'package':dist.get('Name'),'version':dist.get('Version'),'license':dist.get('License') or 'AGPL detected from package metadata text','module_file':jhora.__file__,'captured_import_stdout_hash':h(captured_stdout.getvalue()),'captured_import_stderr_hash':h(captured_stderr.getvalue())}
dob=drik.Date(1996,12,7); tob=(10,34,0); place=drik.Place('Chennai',13.0878,80.2785,5.5)
for field,fn,expected in [('tri_sphuta',sphuta.tri_sphuta,'Pisces 20° 47 20"'),('chatur_sphuta',sphuta.chatur_sphuta,'Scorpio 12° 21 15"'),('pancha_sphuta',sphuta.pancha_sphuta,'Aries 22° 54 29"')]:
try:
with contextlib.redirect_stdout(io.StringIO()), contextlib.redirect_stderr(io.StringIO()):
got=fn(dob,tob,place,divisional_chart_factor=1)
rows.append({'field':field,'status':'observed','raw_result':got,'expected_from_oss_case':expected})
except Exception as e:
rows.append({'field':field,'status':'runtime_error','error':type(e).__name__,'expected_from_oss_case':expected})
except Exception as e:
meta={'package':'jhora','import_error':type(e).__name__}
for field in ['tri_sphuta','chatur_sphuta','pancha_sphuta']: rows.append({'field':field,'status':'runtime_error','error':'jhora_import_failed'})
data={'scope':'prashna_sphuta_oss_case_probe','created_at':date,'status':'oss_probe_ready','claim_status':'tooling_observation_only','production_tuning_allowed':False,'truth_matrix_allowed':False,'oracle_ready':False,'license_boundary':'agpl_observation_only_do_not_vendor','case':{'source':'jhora.tests.pvr_tests.sphuta_tests','dob':'1996-12-07','tob':'10:34:00','place':'Chennai 13.0878,80.2785 +05:30'},'package_metadata':meta,'rows':rows,'boundary':'Runs installed OSS package only; no AGPL implementation is copied and no oracle truth is upgraded.'}
data['raw_hash']=h({'meta':meta,'rows':rows})
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()
@@ -0,0 +1,21 @@
#!/usr/bin/env python3
"""Create blank human review result templates for Prashna Sphuta line tasks."""
from __future__ import annotations
import argparse, json
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
QUEUE = ROOT / "references/oracle/prashna_sphuta_line_review_queue_2026_07_20.json"
OUT = ROOT / "references/oracle/prashna_sphuta_review_result_template_2026_07_20.json"
ALLOWED = ["formula_variant", "source_transcription", "naming_variant", "insufficient_evidence"]
REQ = ["reviewer_id", "reviewed_at", "source_line_coordinates", "second_source_or_scan_evidence", "review_notes"]
def build(date):
q=json.load(open(QUEUE)); templates=[]
for t in q['review_tasks']:
templates.append({**t,'review_result':None,'allowed_results':ALLOWED,'required_human_fields':REQ,'completed':False,'upgrade_after_completion':'requires_replay_packet_and_gate_review'})
return {'scope':'prashna_sphuta_review_result_template','created_at':date,'status':'blank_review_template_ready','claim_status':'blocked_until_human_labels','production_tuning_allowed':False,'truth_matrix_allowed':False,'summary':{'template_count':len(templates),'completed_review_count':0,'truth_upgrade_count':0},'upgrade_policy':'no_upgrade_until_completed_review_and_replay','templates':templates,'boundary':'Blank template only; human review fields must be filled before any classification or formula change.'}
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()
@@ -0,0 +1,24 @@
#!/usr/bin/env python3
"""Validate Prashna Sphuta human review result templates."""
from __future__ import annotations
import argparse, json
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
TEMPLATE = ROOT / "references/oracle/prashna_sphuta_review_result_template_2026_07_20.json"
OUT = ROOT / "references/oracle/prashna_sphuta_review_result_validation_2026_07_20.json"
def build(date):
src=json.load(open(TEMPLATE)); rows=[]
for t in src['templates']:
missing=[]
if t.get('review_result') is None: missing.append('review_result')
for f in t['required_human_fields']:
if not t.get(f): missing.append(f)
valid=not missing and t.get('review_result') in t['allowed_results']
rows.append({'task_id':t['task_id'],'validation_status':'valid_completed_review' if valid else 'blocked_missing_human_review','missing_fields':missing,'review_result':t.get('review_result'),'replay_gate_ready':False,'claim_boundary':'Validation only; replay gate also requires complete Prashna input.'})
return {'scope':'prashna_sphuta_review_result_validation','created_at':date,'status':'validation_ready','claim_status':'blocked_until_human_labels','production_tuning_allowed':False,'truth_matrix_allowed':False,'allowed_results':src['templates'][0]['allowed_results'],'replay_gate_policy':'requires_valid_completed_review_and_complete_prashna_input','summary':{'template_count':len(rows),'valid_completed_review_count':sum(r['validation_status']=='valid_completed_review' for r in rows),'replay_gate_ready_count':0},'validation_rows':rows,'boundary':'Blank templates remain blocked; completed review alone still cannot upgrade truth without replay.'}
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()
@@ -0,0 +1,29 @@
#!/usr/bin/env python3
"""Build field-level comparison matrix for Prashna Sphuta sources."""
from __future__ import annotations
import argparse, json
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
REPLAY = ROOT / "references/oracle/prashna_sphuta_candidate_replay_readiness_2026_07_20.json"
LOCATOR = ROOT / "references/oracle/prashna_marga_excerpt_locator_2026_07_20.json"
OUT = ROOT / "references/oracle/prashna_sphuta_source_comparison_matrix_2026_07_20.json"
FIELDS=['sun','moon','lagna','gulika','rahu','trisphuta','chatusphuta','panchasphuta']
def status(row, field):
if field in ['sun','moon','lagna','gulika','rahu']: return 'input_value_only'
got=row['computed_from_expected_degrees'][field]; exp=row['expected_degrees'][field]
return 'match' if abs(((got-exp+180)%360)-180) <= .02 else 'mismatch'
def build(date):
replay=json.load(open(REPLAY)); locator=json.load(open(LOCATOR)); base=replay['rows'][0]
has_ia=locator['summary']['located_window_count']>0
rows=[]
for f in FIELDS:
rows.append({'field':f,'vedastro_expected_degree':base['expected_degrees'][f],'local_formula_degree':base['computed_from_expected_degrees'].get(f),'local_vs_vedastro_status':status(base,f),'ia_excerpt_status':'located_context' if has_ia and f in ['gulika','trisphuta','chatusphuta','panchasphuta'] else 'not_field_specific','claim_boundary':'Field comparison only; no Prashna truth upgrade without complete input/raw/replay.'})
return {'scope':'prashna_sphuta_source_comparison_matrix','created_at':date,'status':'comparison_matrix_ready','claim_status':'open_queue','production_tuning_allowed':False,'truth_matrix_allowed':False,'summary':{'field_count':len(rows),'match_count':sum(r['local_vs_vedastro_status']=='match' for r in rows),'mismatch_count':sum(r['local_vs_vedastro_status']=='mismatch' for r in rows),'truth_upgrade_count':0},'ia_excerpt_window_count':locator['summary']['located_window_count'],'field_rows':rows,'next_evidence':['line-level transcription review','complete Prashna input','legal external replay'],'boundary':'Matrix connects VedAstro expected values, local arithmetic replay, and IA locator hashes; still open queue.'}
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()