from __future__ import annotations import argparse import json from pathlib import Path import yaml ROOT = Path(__file__).resolve().parents[1] REQUIRED_SECTIONS = [ "source_summary", "fail_codes", "allowed_actions", "blocked_actions", "todo_yaml", "no_order_notice", ] FORBIDDEN_WHEN_BLOCKED = [ "hts_order_table", "new_buy_recommendation", "freeform_target_price", ] def _load(path: Path): text = path.read_text(encoding="utf-8") try: return json.loads(text) except Exception: return yaml.safe_load(text) def main() -> int: ap = argparse.ArgumentParser() ap.add_argument("--report", required=True) ap.add_argument("--packet", required=True) args = ap.parse_args() report = _load(ROOT / args.report if not Path(args.report).is_absolute() else Path(args.report)) packet = _load(ROOT / args.packet if not Path(args.packet).is_absolute() else Path(args.packet)) report_text = yaml.safe_dump(report, sort_keys=False, allow_unicode=True) if isinstance(report, dict) else str(report) packet_ok = isinstance(packet, dict) and packet.get("formula_id") == "FINAL_DECISION_PACKET_V4" if isinstance(report, dict) and all(section in report for section in REQUIRED_SECTIONS): sections_ok = True elif isinstance(report, dict) and all(section in report for section in ("executive", "blockers", "action_table", "shadow_ledger", "data_missing", "education_notes")): sections_ok = True else: sections_ok = False blocked_ok = all(section not in report_text for section in FORBIDDEN_WHEN_BLOCKED) ok = packet_ok and sections_ok and blocked_ok payload = { "formula_id": "LLM_RESPONSE_CONTRACT_V4", "gate": "PASS" if ok else "FAIL", "sections_present": sections_ok, "packet_ok": packet_ok, "forbidden_section_count": sum(1 for section in FORBIDDEN_WHEN_BLOCKED if section in report_text), } out = ROOT / "Temp" / "llm_response_validation_v4.json" out.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8") print(json.dumps(payload, ensure_ascii=True, indent=2)) return 0 if ok else 1 if __name__ == "__main__": raise SystemExit(main())