"""validate_execution_precedence_lock_v2.py — P0-004 수용 검증기 AUDIT_ONLY 상태에서 HTS 주문 행수가 0이고, child_engine_internal_allowed와 global_execution_gate가 명시적으로 분리됨을 검증한다. """ from __future__ import annotations import json from pathlib import Path from v7_hardening_common import ROOT, TEMP, load_json, save_json DEFAULT_OUT = TEMP / "execution_precedence_lock_v2.json" import sys if sys.stdout.encoding and sys.stdout.encoding.lower() not in ("utf-8", "utf8"): sys.stdout = open(sys.stdout.fileno(), mode="w", encoding="utf-8", buffering=1) def main() -> int: v4 = load_json(TEMP / "final_execution_decision_v4.json") scr = ( load_json(TEMP / "smart_cash_recovery_v7.json") or load_json(TEMP / "smart_cash_recovery_v6.json") or load_json(TEMP / "smart_cash_recovery_v5.json") ) errors: list[str] = [] if not v4: errors.append("final_execution_decision_v4.json not found — run build_final_execution_decision_v4.py") else: global_gate = str(v4.get("global_execution_gate") or "") hts_count = int(v4.get("hts_order_count") or 0) child_internal = v4.get("child_engine_internal_allowed") # AUDIT_ONLY에서 HTS 주문 수는 반드시 0 if global_gate == "AUDIT_ONLY" and hts_count > 0: errors.append(f"AUDIT_ONLY 상태에서 hts_order_count={hts_count} > 0 — P0-004 위반") # child_engine_internal_allowed 필드가 존재해야 함 if "child_engine_internal_allowed" not in v4: errors.append("child_engine_internal_allowed 필드 누락 — P0-004 명시적 분리 미완") # child=true이더라도 global=AUDIT_ONLY이면 HTS 0임을 확인 if child_internal is True and global_gate == "AUDIT_ONLY" and hts_count == 0: pass # 정상 상태 # smart_cash의 execution_allowed가 있더라도 v4에서 명시적으로 분리됐는지 scr_exec = scr.get("execution_allowed") if scr_exec is True and global_gate == "AUDIT_ONLY": # child가 허용이어도 global이 AUDIT_ONLY면 HTS 0이어야 함 → 이미 체크됨 pass # precedence_note 또는 child_execution_state 존재 if "child_execution_state" not in v4: errors.append("child_execution_state 필드 누락") status = "PASS" if not errors else "FAIL" result = { "formula_id": "EXECUTION_PRECEDENCE_LOCK_V2", "status": status, "errors": errors, "global_execution_gate": v4.get("global_execution_gate") if v4 else "MISSING", "hts_order_count": v4.get("hts_order_count") if v4 else None, "child_engine_internal_allowed": v4.get("child_engine_internal_allowed") if v4 else None, "child_execution_state": v4.get("child_execution_state") if v4 else None, } save_json(str(DEFAULT_OUT), result) print(json.dumps(result, ensure_ascii=False, indent=2)) if status == "PASS": print("EXECUTION_PRECEDENCE_LOCK_V2_OK") else: print("EXECUTION_PRECEDENCE_LOCK_V2_FAIL") for e in errors: print(f" ERROR: {e}") return 0 if status == "PASS" else 1 if __name__ == "__main__": raise SystemExit(main())