Files
Jyotisha/scripts/shadbala_av_component_registry.py
2026-07-19 08:59:33 +08:00

96 lines
4.1 KiB
Python

#!/usr/bin/env python3
"""Build Shadbala/Ashtakavarga component provenance registry from mismatch arbitration."""
from __future__ import annotations
import argparse
import json
from collections import Counter, defaultdict
from pathlib import Path
from typing import Any
CATEGORY_POLICY = {
"shadbala_formula_variant": {
"component_family": "shadbala_components",
"unit_contract": "Virupa/Rupa component unit must be explicit before parity claims.",
"allowed_claim": "component_method_variant",
"next_evidence_required": "worked example or source text for each six-force component formula and unit.",
},
"derived_total_from_component_variants": {
"component_family": "shadbala_total",
"unit_contract": "Total Rupa/Virupa cannot be arbitrated before component units close.",
"allowed_claim": "derived_total_blocked_until_components_close",
"next_evidence_required": "close sthana/dig/kala/chesta/naisargika/drik first, then recompute totals.",
},
"ashtakavarga_table_or_contributor_variant": {
"component_family": "ashtakavarga",
"unit_contract": "BAV/SAV tables must name contributor set, shodhana state, and Lagna inclusion.",
"allowed_claim": "table_variant",
"next_evidence_required": "public worked table with same contributor semantics and row/column schema.",
},
"endpoint_or_varga_semantics": {
"component_family": "varga_endpoint",
"unit_contract": "Sign values only; endpoint must prove requested varga/method semantics.",
"allowed_claim": "current_target_observation_only",
"next_evidence_required": "identified endpoint contract for D2/D4/D9/D10 ayanamsa/node/method.",
},
}
def build_registry(arbitration_path: str | Path) -> dict[str, Any]:
path = Path(arbitration_path)
arbitration = json.loads(path.read_text(encoding="utf-8"))
grouped: dict[str, list[dict[str, Any]]] = defaultdict(list)
for row in arbitration.get("rows") or []:
grouped[row["category"]].append(row)
registry = []
for category, rows in sorted(grouped.items()):
policy = CATEGORY_POLICY.get(category, {
"component_family": "unknown",
"unit_contract": "unknown",
"allowed_claim": "current_target_observation_only",
"next_evidence_required": "manual provenance review required.",
})
registry.append({
"category": category,
"component_family": policy["component_family"],
"row_count": len(rows),
"sections": sorted({str(row.get("section")) for row in rows}),
"sample_fields": [str(row.get("field")) for row in rows[:8]],
"unit_contract": policy["unit_contract"],
"allowed_claim": policy["allowed_claim"],
"next_evidence_required": policy["next_evidence_required"],
"truth_status": "classified_unresolved",
})
return {
"scope": "shadbala_av_component_provenance_registry",
"source_arbitration": str(path),
"status": "classified_unresolved",
"truth_policy": "method_variant_not_majority_vote",
"production_tuning_allowed": False,
"summary": {
"source_mismatch_count": arbitration.get("mismatch_count", 0),
"registry_count": len(registry),
"category_counts": dict(Counter({row["category"]: row["row_count"] for row in registry})),
},
"registry": registry,
}
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("arbitration", nargs="?", default="references/oracle/three_engine_mismatch_arbitration_2026_07_19.json")
parser.add_argument("--output", type=Path)
args = parser.parse_args()
registry = build_registry(args.arbitration)
text = json.dumps(registry, ensure_ascii=False, indent=2, sort_keys=True) + "\n"
if args.output:
args.output.parent.mkdir(parents=True, exist_ok=True)
args.output.write_text(text, encoding="utf-8")
print(text, end="")
return 0
if __name__ == "__main__":
raise SystemExit(main())