atlas-iac/services/hermes/scripts/publication_retry.py

73 lines
3.5 KiB
Python

#!/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