from __future__ import annotations import argparse import json from pathlib import Path from typing import Any def read_json(path: Path) -> dict[str, Any]: return json.loads(path.read_text(encoding="utf-8")) def check_next_action(plan: dict[str, Any], action_payload: dict[str, Any]) -> dict[str, Any]: failures: list[str] = [] if action_payload.get("schema") != "codex_1c_moxel_next_action.v1": failures.append("unexpected next action schema") action = action_payload.get("action") if isinstance(action_payload.get("action"), dict) else None experiments = [item for item in plan.get("experiments") or [] if isinstance(item, dict)] if not action: if experiments: failures.append("next action is empty but experiments are available") else: action_id = action.get("id") matching = [item for item in experiments if item.get("id") == action_id] if not matching: failures.append(f"next action id is not present in plan: {action_id}") command = str(action.get("capture_command_with_pipeline") or "") if "--run-pipeline-after" not in command: failures.append("capture_command_with_pipeline must include --run-pipeline-after") for field in ("manual_action", "expected_signal", "target"): if not action.get(field): failures.append(f"next action must include {field}") return { "schema": "codex_1c_moxel_next_action_check.v1", "status": "ok" if not failures else "failed", "failures": failures, "counts": {"experiments": len(experiments), "has_action": action is not None}, } def main() -> int: parser = argparse.ArgumentParser(description="Validate the machine-readable 1C MOXCEL next action artifact.") parser.add_argument("--plan", default="reports/1c-template-baselines/moxel-next-experiments.json") parser.add_argument("--action", default="reports/1c-template-baselines/moxel-next-action.json") parser.add_argument("--output", default="reports/1c-template-baselines/moxel-next-action-check.json") args = parser.parse_args() report = check_next_action(read_json(Path(args.plan)), read_json(Path(args.action))) output_path = Path(args.output) output_path.parent.mkdir(parents=True, exist_ok=True) output_path.write_text(json.dumps(report, ensure_ascii=False, indent=2), encoding="utf-8") print(json.dumps(report, ensure_ascii=False, indent=2)) return 0 if report["status"] == "ok" else 1 if __name__ == "__main__": raise SystemExit(main())