import json import argparse from pathlib import Path ROOT = Path(__file__).resolve().parents[1] def extract_source_paths(obj): paths = [] if isinstance(obj, dict): if "source_path" in obj: paths.append(obj["source_path"]) for k, v in obj.items(): paths.extend(extract_source_paths(v)) elif isinstance(obj, list): for item in obj: paths.extend(extract_source_paths(item)) return paths def main(): ap = argparse.ArgumentParser() ap.add_argument("--packet", default="Temp/final_decision_packet_active.json") ap.add_argument("--out", default="Temp/validate_packet_source_paths_v1.json") args = ap.parse_args() packet_path = ROOT / args.packet if not packet_path.exists(): print(f"Packet not found: {packet_path}") return 1 with open(packet_path, encoding="utf-8") as f: data = json.load(f) paths = set(extract_source_paths(data)) missing = [] for p in paths: # Resolve replacements as per P0-002 logic resolved_p = p.replace("\\", "/") if "Temp/active_artifact_manifest_v2.json" in resolved_p: resolved_p = "runtime/active_artifact_manifest.yaml" full_path = ROOT / resolved_p if not full_path.exists(): missing.append(resolved_p) out_data = { "formula_id": "VALIDATE_PACKET_SOURCE_PATHS_V1", "missing_source_path_count": len(missing), "missing_paths": missing, "gate": "PASS" if len(missing) == 0 else "FAIL" } out_file = ROOT / args.out out_file.parent.mkdir(parents=True, exist_ok=True) with open(out_file, "w", encoding="utf-8") as f: json.dump(out_data, f, indent=2) print(json.dumps(out_data, indent=2)) return 0 if len(missing) == 0 else 1 if __name__ == "__main__": import sys sys.exit(main())