sync: import closure and audit queue utilities

This commit is contained in:
732642856
2026-07-21 19:21:02 +08:00
parent c9ef2ee093
commit 508e499bce
11 changed files with 738 additions and 1 deletions
@@ -0,0 +1,50 @@
#!/usr/bin/env python3
"""Evaluate a requested claim against every indexed evidence domain."""
from __future__ import annotations
import argparse
import json
from pathlib import Path
from typing import Any
from scripts.claim_audit_runtime_gate import evaluate_claim
ROOT = Path(__file__).resolve().parents[1]
DEFAULT_INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json"
def build(index_path: Path, requested_claim: str) -> dict[str, Any]:
index = json.loads(index_path.read_text(encoding="utf-8"))
domains = sorted({row["domain"] for row in index["packets"]})
rows = [evaluate_claim(index_path, domain, requested_claim) for domain in domains]
decisions = {name: sum(1 for row in rows if row["decision"] == name) for name in {"allow", "block", "degrade"}}
return {
"scope": "claim_audit_runtime_gate_report",
"created_at": "2026-07-19",
"requested_claim": requested_claim,
"source_index": str(index_path.relative_to(ROOT)) if index_path.is_relative_to(ROOT) else str(index_path),
"summary": {
"domain_count": len(rows),
"blocked_count": decisions["block"],
"degraded_count": decisions["degrade"],
"allowed_count": decisions["allow"],
"production_tuning_allowed_count": sum(1 for row in rows if row["production_tuning_allowed"] is True),
},
"domains": rows,
"boundary": "Batch gate report only; every high claim still resolves through per-domain evidence packets.",
}
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--index", type=Path, default=DEFAULT_INDEX)
parser.add_argument("--claim", default="production_ready")
args = parser.parse_args()
print(json.dumps(build(args.index, args.claim), ensure_ascii=False, indent=2, sort_keys=True))
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,53 @@
#!/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()
@@ -0,0 +1,39 @@
#!/usr/bin/env python3
"""Arbitrate Prashna Sphuta expected-value mismatches without truth upgrade."""
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"
OUT = ROOT / "references/oracle/prashna_sphuta_mismatch_arbitration_2026_07_20.json"
def status(row, key, tol=0.02):
exp=row['expected_degrees'][key]; got=row['computed_from_expected_degrees'][key]
return 'matches' if abs(((got-exp+180)%360)-180) <= tol else 'mismatch'
def build(date: str):
replay=json.load(open(REPLAY))
rows=[]
for row in replay['rows']:
rows.append({
'source_id': row['source_id'], 'url': row['url'],
'trisphuta_status': status(row,'trisphuta'),
'chatusphuta_status': status(row,'chatusphuta'),
'panchasphuta_status': status(row,'panchasphuta'),
'candidate_causes': ['formula_variant','source_transcription','chatusphuta_catusphuta_naming','incomplete_input_settings'],
'next_evidence_owner': 'worked_example_collection',
'next_evidence': ['raw scan/page capture','complete example input','independent translation/transcription check','legal external replay'],
'upgrade_status': 'not_oracle_ready',
'claim_boundary': 'Mismatch queue only; do not tune formulas or upgrade Prashna truth from this packet.',
})
sources=[
{'source_id':'vedastro_prasna_marga_ch5_sphuta_example','url':'https://vedastro.org/book/PrasnaMarga/Chapter5','source_role':'numeric_candidate','upgrade_status':'candidate_not_oracle'},
{'source_id':'internet_archive_prasna_marga_bv_raman_sphuta_fragment','url':'https://archive.org/details/PrasnaMarga/','source_role':'public_formula_numeric_fragment_candidate','upgrade_status':'candidate_not_oracle'},
]
return {'scope':'prashna_sphuta_mismatch_arbitration','created_at':date,'status':'arbitration_queue_ready','claim_status':'open_queue','production_tuning_allowed':False,'truth_matrix_allowed':False,'summary':{'mismatch_count':sum(r['chatusphuta_status']=='mismatch' or r['panchasphuta_status']=='mismatch' for r in rows),'source_candidate_count':len(sources),'oracle_ready_count':0},'rows':rows,'source_candidates':sources,'boundary':'Queue records candidate causes; closure requires raw source and replay evidence.'}
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,152 @@
#!/usr/bin/env python3
"""Build field-level Shadbala component closure tickets from same-unit rows."""
from __future__ import annotations
import hashlib
import json
from collections import Counter, defaultdict
from pathlib import Path
from typing import Any
ROOT = Path(__file__).resolve().parents[1]
SAME_UNIT = ROOT / "references/oracle/shadbala_same_unit_normalizer_2026_07_19.json"
SOURCE_KB = ROOT / "references/oracle/formula_source_knowledge_base_2026_07_19.json"
def stable_json(data: Any) -> str:
return json.dumps(data, ensure_ascii=False, sort_keys=True, separators=(",", ":"), default=str)
def source_by_component() -> dict[str, dict[str, Any]]:
raw = json.loads(SOURCE_KB.read_text(encoding="utf-8"))
out: dict[str, dict[str, Any]] = {}
for formula in raw.get("formulas", []):
if formula.get("family") == "Shadbala" and formula.get("component") not in {"total", None}:
out[formula["component"]] = formula
return out
def owner_for(classification: str) -> str:
if classification == "within_1_virupa_observation":
return "ready_for_tolerance_freeze"
if classification == "method_variant":
return "method_variant_decision"
if classification == "formula_or_unit_mismatch":
return "formula_source_arbitration"
return "worked_example_numeric_oracle"
def closure_for(classification: str) -> str:
if classification == "within_1_virupa_observation":
return "same_unit_observation_ready_tolerance_not_frozen"
if classification == "method_variant":
return "method_variant_unresolved"
if classification == "formula_or_unit_mismatch":
return "formula_or_unit_mismatch_unresolved"
return "insufficient_numeric_sources"
def required_evidence(classification: str) -> list[str]:
common = [
"public numeric worked example with birth data/settings",
"explicit Virupa/Rupa unit declaration",
]
if classification == "method_variant":
return common + ["variant selection note: preserve method_variant if authoritative sources diverge"]
if classification == "formula_or_unit_mismatch":
return common + ["component formula/source arbitration across local, jyotishganit, Xalen, VP Jain"]
if classification == "within_1_virupa_observation":
return common + ["freeze tolerance and add second public case before parity upgrade"]
return common + ["recover missing numeric raw/hash"]
def build() -> dict[str, Any]:
same_unit = json.loads(SAME_UNIT.read_text(encoding="utf-8"))
sources = source_by_component()
tickets: list[dict[str, Any]] = []
for row in same_unit["rows"]:
component = row["component"]
source = sources.get(component, {})
classification = row["classification"]
tickets.append(
{
"ticket_id": f"shadbala.{row['planet'].lower()}.{component}",
"planet": row["planet"],
"component": component,
"canonical_component": row["canonical_component"],
"same_unit_classification": classification,
"closure_status": closure_for(classification),
"next_evidence_owner": owner_for(classification),
"unit_contract": source.get("unit_contract", "Virupa/Rupa unit source required."),
"known_variants": source.get("known_variants", []),
"source_evidence": source.get("source_evidence", []),
"required_evidence": required_evidence(classification),
"normalized_values_virupa": {
"jyotishganit": row.get("jyotishganit_virupa"),
"xalen": row.get("xalen_virupa"),
"local": row.get("local_from_xalen_report_virupa"),
"vp_jain_published": row.get("vp_jain_published_virupa"),
"vp_jain_local": row.get("vp_jain_local_virupa"),
},
"claim_boundary": (
"Do not promote this component row to absolute parity until formula variant, "
"unit contract, and public numeric worked example all close."
),
}
)
counts = Counter(ticket["same_unit_classification"] for ticket in tickets)
by_component: dict[str, Counter[str]] = defaultdict(Counter)
for ticket in tickets:
by_component[ticket["component"]][ticket["same_unit_classification"]] += 1
component_hotspots = []
for component in sorted(by_component):
c = by_component[component]
component_hotspots.append(
{
"component": component,
"ticket_count": sum(c.values()),
"within_1_virupa_observation_count": c["within_1_virupa_observation"],
"method_variant_count": c["method_variant"],
"formula_or_unit_mismatch_count": c["formula_or_unit_mismatch"],
"insufficient_numeric_sources_count": c["insufficient_numeric_sources"],
}
)
return {
"scope": "shadbala_component_closure_queue_v2",
"created_at": "2026-07-19",
"status": "field_level_queue_ready",
"claim_status": "partial",
"production_tuning_allowed": False,
"truth_matrix_allowed": False,
"sources": {
"same_unit_matrix": str(SAME_UNIT.relative_to(ROOT)),
"formula_source_knowledge_base": str(SOURCE_KB.relative_to(ROOT)),
},
"summary": {
"ticket_count": len(tickets),
"within_1_virupa_observation_count": counts["within_1_virupa_observation"],
"method_variant_count": counts["method_variant"],
"formula_or_unit_mismatch_count": counts["formula_or_unit_mismatch"],
"insufficient_numeric_sources_count": counts["insufficient_numeric_sources"],
"absolute_parity_ready_count": 0,
},
"queue_hash": hashlib.sha256(stable_json(tickets).encode("utf-8")).hexdigest(),
"component_hotspots": component_hotspots,
"tickets": tickets,
"boundary": "Field-level Shadbala closure queue only; no majority-vote truth or production tuning upgrade.",
}
def main() -> int:
print(json.dumps(build(), ensure_ascii=False, indent=2, sort_keys=True))
return 0
if __name__ == "__main__":
raise SystemExit(main())