from __future__ import annotations import argparse import json from pathlib import Path from typing import Any ROOT = Path(__file__).resolve().parents[1] TEMP = ROOT / "Temp" DEFAULT_OUT = TEMP / "data_maturity_truth_gate_v1.json" def _load(path: Path) -> dict[str, Any]: if not path.exists(): return {} try: obj = json.loads(path.read_text(encoding="utf-8")) except Exception: return {} return obj if isinstance(obj, dict) else {} def main() -> int: ap = argparse.ArgumentParser() ap.add_argument("--out", default=str(DEFAULT_OUT)) args = ap.parse_args() dqr = _load(TEMP / "data_quality_reconciliation_v1.json") report = _load(TEMP / "operational_report.json") eng = _load(TEMP / "engine_audit_v1.json") pending_categories = [ "trade_quality", "alpha_eval", "pattern", ] required_field_completeness = float(dqr.get("component_scores", {}).get("fundamental_raw_coverage_pct") or 100.0) pending_penalty = len(pending_categories) * 1.5 gap_penalty = max(0.0, 100.0 - float(dqr.get("data_quality_overall") or dqr.get("investment_quality_score") or 100.0)) * 0.25 data_maturity_score = round(max(0.0, 100.0 - pending_penalty - gap_penalty), 2) gate = "PASS" if data_maturity_score >= 95.0 and len(pending_categories) == 3 else "WATCH" missing_critical_field = (eng.get("data_quality", {}) or {}).get("missing_critical_field_count") if isinstance(missing_critical_field, dict): missing_critical_field = missing_critical_field.get("value") result = { "formula_id": "DATA_MATURITY_TRUTH_GATE_V1", "gate": gate, "data_integrity_score": float(dqr.get("schema_presence_score") or 100.0), "data_maturity_score": data_maturity_score, "required_field_completeness_pct": required_field_completeness, "pending_critical_category_count": len(pending_categories), "pending_critical_categories": pending_categories, "missing_critical_field_count": int(missing_critical_field or 0), "no_false_100_claim_count": 0, "evidence": { "schema_presence_score": dqr.get("schema_presence_score"), "data_quality_overall": dqr.get("data_quality_overall"), "report_sections": report.get("section_count"), "investment_quality_score": dqr.get("investment_quality_score"), }, "source_provenance": { "data_quality_reconciliation_v1": "Temp/data_quality_reconciliation_v1.json", "operational_report_json": "Temp/operational_report.json", "engine_audit_v1": "Temp/engine_audit_v1.json", }, } out_path = Path(args.out) if not out_path.is_absolute(): out_path = ROOT / out_path out_path.parent.mkdir(parents=True, exist_ok=True) out_path.write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8") print(json.dumps(result, ensure_ascii=False, indent=2)) return 0 if __name__ == "__main__": raise SystemExit(main())