#!/usr/bin/env python3 """Validate mediator-issued, one-shot SCM publication retry receipts.""" from __future__ import annotations import hashlib import json import re from typing import Any class PublicationRetryError(ValueError): """A receipt cannot safely bind a fresh continuation run to an old commit.""" SHA = re.compile(r"[0-9a-f]{40,64}\Z") RESULT_FIELDS = frozenset( {"status", "summary", "changed_files", "tests_run", "artifacts", "findings", "blockers"} ) def receipt_digest(structured: dict[str, Any], title: str, body: str) -> str: """Return the exact digest the mediator must retain with completed evidence.""" value = {"structured": structured, "title": title, "body": body} return hashlib.sha256(json.dumps( value, ensure_ascii=False, separators=(",", ":"), sort_keys=True ).encode()).hexdigest() def validate( receipt: Any, binding: dict[str, Any], *, board: str, child_task_id: str, root_task_id: str, project: str, branch: str, base_branch: str, live_head: str, ) -> tuple[dict[str, Any], int, str]: """Return a receipt only when its source and completed evidence are exact.""" source = receipt.get("source") if isinstance(receipt, dict) else None if not isinstance(source, dict) or not all( source.get(name) == binding.get(name) for name in ("board", "task_id", "run_id", "worker_ordinal", "attempt") ): raise PublicationRetryError("publication retry source binding is invalid") expected = { "board": board, "task_id": child_task_id, "root_task_id": root_task_id, "repo_url": f"https://scm.bstein.dev/titan/{project}.git", "branch": branch, "base_branch": base_branch, } if any(source.get(name) != value for name, value in expected.items()): raise PublicationRetryError("publication retry source lineage is invalid") run_id, ordinal, attempt = (source["run_id"], source["worker_ordinal"], source["attempt"]) if ( not isinstance(run_id, str) or not run_id.isdecimal() or int(run_id) < 1 or isinstance(ordinal, bool) or not isinstance(ordinal, int) or ordinal not in range(3) or isinstance(attempt, bool) or not isinstance(attempt, int) or attempt < 1 ): raise PublicationRetryError("publication retry source run is invalid") baseline, head, digest = (receipt.get(name) for name in ("baseline_sha", "head", "result_digest")) title, body, structured = receipt.get("title"), receipt.get("body"), receipt.get("structured") if ( not all(isinstance(value, str) and SHA.fullmatch(value) for value in (baseline, head)) or not isinstance(digest, str) or not re.fullmatch(r"[0-9a-f]{64}", digest) or baseline != live_head or baseline == head or not isinstance(title, str) or not title or len(title.encode()) > 512 or not isinstance(body, str) or len(body.encode()) > 32 * 1024 or not isinstance(structured, dict) or set(structured) != RESULT_FIELDS or structured.get("status") != "completed" ): raise PublicationRetryError("publication retry evidence is invalid") if digest != receipt_digest(structured, title, body): raise PublicationRetryError("publication retry result digest is invalid") for name in RESULT_FIELDS - {"status", "summary"}: if not isinstance(structured[name], list) or any(not isinstance(item, str) for item in structured[name]): raise PublicationRetryError("publication retry result is invalid") return receipt, ordinal, run_id