#!/usr/bin/env python3 """Fail-closed one-time normalization of a mediator publication receipt.""" from __future__ import annotations import hashlib import json from typing import Any from execution_pool_protocol import truncate_utf8 from publication_retry import receipt_digest import supervisor_state def canonical_title(summary: Any) -> str: """Apply the broker's character and UTF-8-byte title limits.""" if not isinstance(summary, str) or not (text := summary.strip()): raise ValueError("publication retry summary is invalid") return truncate_utf8(text[:240], 507) def normalize( board: str, child_task_id: str, run_id: str, raw_result_sha256: str, receipt: Any, ) -> str: """Replace only a rejected title on the exact pending mediator receipt.""" if not isinstance(receipt, dict) or not isinstance(raw_result_sha256, str) or len(raw_result_sha256) != 64: raise ValueError("publication retry normalization input is invalid") with supervisor_state._connect(board) as connection: row = connection.execute( "SELECT receipt_json,issued_run_id,resolved_run_id,reissue_count,last_reissued_run_id FROM publication_retries " "WHERE board=? AND child_task_id=?", (board, child_task_id) ).fetchone() provenance = connection.execute( "SELECT raw_result_sha256,reconstruction FROM publication_retry_provenance " "WHERE board=? AND child_task_id=?", (board, child_task_id) ).fetchone() if row is None or provenance is None or provenance[0] != raw_result_sha256: raise ValueError("publication retry provenance is unavailable") pending = (run_id, "", 0, "") released = ("", "", 1, run_id) if row[1:] not in {pending, released}: raise ValueError("publication retry is not the exact pending run") try: old = json.loads(row[0]) except (TypeError, json.JSONDecodeError) as error: raise ValueError("sealed publication receipt is malformed") from error binding = old.get("source") if isinstance(old, dict) else None if not isinstance(binding, dict): raise ValueError("sealed publication receipt is malformed") old, _ordinal, _source_run = supervisor_state._retry_receipt( board, child_task_id, binding, old, path=None ) new, _ordinal, _source_run = supervisor_state._retry_receipt( board, child_task_id, binding, receipt, path=None ) unchanged = ("source", "baseline_sha", "head", "body", "structured") if any(old[name] != new[name] for name in unchanged): raise ValueError("publication retry evidence changed during normalization") expected = canonical_title(old["structured"].get("summary")) if new["title"] != expected or new["result_digest"] != receipt_digest( new["structured"], new["title"], new["body"] ): raise ValueError("publication retry title normalization is invalid") encoded = json.dumps(new, separators=(",", ":"), sort_keys=True) prefix = "normalized-title-from-sealed-receipt-sha256:" if row[0] == encoded: sealed_sha = provenance[1][len(prefix):] if isinstance(provenance[1], str) else "" if not isinstance(provenance[1], str) or not provenance[1].startswith(prefix) or len(sealed_sha) != 64: raise ValueError("publication retry normalization provenance conflicts") return sealed_sha sealed_sha = hashlib.sha256(row[0].encode()).hexdigest() marker = prefix + sealed_sha changed = connection.execute( "UPDATE publication_retries SET receipt_json=? WHERE board=? AND child_task_id=? " "AND receipt_json=? AND issued_run_id=? AND resolved_run_id='' AND reissue_count=0", (encoded, board, child_task_id, row[0], run_id), ).rowcount if changed != 1: raise ValueError("publication retry changed during normalization") connection.execute( "UPDATE publication_retry_provenance SET reconstruction=? WHERE board=? AND child_task_id=?", (marker, board, child_task_id), ) return sealed_sha