#!/usr/bin/env python3 """Convert a reviewed workflow result to a local-only validation contract.""" import argparse import copy import json from wbv2_autopilot import ROOT, contained, queue_context, read_json, sha, write_json from wbv2_validation import prepare_validation_command def prepare(root, job, result_path): context = queue_context(root) source = contained(root, result_path) result = copy.deepcopy(read_json(source)) if result.get("status") != "ready": raise ValueError("only a prepared implementation can become a local contract") # Bind only the units actually declared by positive behavioral cases. units = sorted({unit for case in result["cases"] if case["kind"] == "positive" for unit in case["unitIds"]}) if not units or not set(units).issubset(result["sourceUnits"]): raise ValueError("positive cases do not bind declared source units") result["sourceUnits"] = units result["routeIds"] = units for check in result["checks"]: prepare_validation_command(root, check["argv"], check["cwd"]) return { "schemaVersion": 1, "task": context["task"], "job": job, "parentSha256": sha(contained(root, context["parentManifest"])), "origin": {"path": result_path, "sha256": sha(source)}, "acceptance": "pending independent local compilation and runtime validation", "result": result, } def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--job", required=True) parser.add_argument("--result", required=True) args = parser.parse_args() contract = prepare(ROOT, args.job, args.result) destination = contained(ROOT, f"tests/golden/WBV2/autopilot/local-plans/{args.job}.json") write_json(destination, contract) print(json.dumps({"job": args.job, "contract": str(destination.relative_to(ROOT)), "checks": len(contract["result"]["checks"]), "sourceUnits": contract["result"]["sourceUnits"], "modelRequests": 0})) if __name__ == "__main__": main()