#!/usr/bin/env python3 """Release Soteria #3's failed publication run after a reviewed mediator fix.""" from __future__ import annotations import hashlib import json import sqlite3 from pathlib import Path from typing import Any from gitea_api_policy import _draft_title import scm_broker_client import supervisor_state BOARD = "soteria" CHILD = "t_4095fe0d" ROOT = "t_c7c42600" SOURCE_RUN = "8" FAILED_RUN = "10" ORDINAL = 0 BRANCH = "hermes-repair/sonar-AZ9pTqVcN0JrBQvDGDs3" REMOTE_HEAD = "51133b559ad62f324e45bc61587900f08156b733" PRESERVED_HEAD = "f21833e78768e7e4045a6304e311989196846ae4" RECEIPT_DIGEST = "32f99b7ff27b2251e55cfe6fe2ff38fd3054bb781a8cc5e06b010ef855eb6c82" SOURCE_RAW_SHA = "13de550c15ecfdf6684022b07a823da1c51586f959e9d9d2b3aea67433a9085d" FAILED_RESULT_SHA = "0395eaed346eab364990de9b6d6c9a791c3d015a6b026f2473a9c80e8a1d2548" FAILED_EVENT_ID = 209 RETRY_AFTER = 1789346240 CONFIRM_RUN = "11" CONFIRM_EVENT_ID = 213 def _value(task: Any, name: str) -> Any: """Read one scalar from either native task representation.""" return task.get(name) if isinstance(task, dict) else getattr(task, name, None) def _pool_guard(database: Path, run_id: str) -> None: """Require one exact terminal mediator result and no competing assignment.""" connection = sqlite3.connect(f"file:{database}?mode=ro", uri=True) try: row = connection.execute( "SELECT payload_json,result_json,result_digest,state,worker_ordinal,attempt " "FROM assignments WHERE board=? AND task_id=? AND run_id=?", (BOARD, CHILD, run_id), ).fetchone() active = connection.execute( "SELECT 1 FROM assignments WHERE board=? AND task_id=? AND run_id<>? " "AND state IN ('assigned','running','result')", (BOARD, CHILD, run_id), ).fetchone() finally: connection.close() if row is None or active is not None or tuple(row[3:]) != ("finalized", ORDINAL, 1): raise ValueError("publication attempt is not the exact terminal run") if not isinstance(row[0], str) or not isinstance(row[1], str): raise ValueError("publication attempt evidence is malformed") try: payload, result = json.loads(row[0]), json.loads(row[1]) except json.JSONDecodeError as error: raise ValueError("publication attempt evidence is malformed") from error resume = payload.get("scm_resume") if isinstance(payload, dict) else None structured = result.get("structured") if isinstance(result, dict) else None source = resume.get("source") if isinstance(resume, dict) else None if ( hashlib.sha256(row[1].encode()).hexdigest() != FAILED_RESULT_SHA or row[2] != FAILED_RESULT_SHA or not isinstance(source, dict) or source.get("run_id") != SOURCE_RUN or source.get("worker_ordinal") != ORDINAL or resume.get("head") != PRESERVED_HEAD or not isinstance(structured, dict) or structured.get("status") != "blocked" or result.get("returncode") != 1 or result.get("capacity_failure") is not False or result.get("scm_submission") is not None ): raise ValueError("publication attempt is not the retained rejected publication") def _native_guard(run_id: str, event_id: int, status: str, event_kind: str) -> None: """Require one exact native terminal event and private root/child chain.""" from hermes_cli import kanban_db with kanban_db.scoped_current_board(BOARD): connection = kanban_db.connect(board=BOARD) try: task = kanban_db.get_task(connection, CHILD) parents = kanban_db.parent_ids(connection, CHILD) event = connection.execute( "SELECT id,run_id,kind FROM task_events WHERE task_id=? ORDER BY id DESC LIMIT 1", (CHILD,), ).fetchone() latest = connection.execute( "SELECT id,status,outcome FROM task_runs WHERE task_id=? ORDER BY id DESC LIMIT 1", (CHILD,), ).fetchone() finally: connection.close() if ( task is None or _value(task, "status") != status or _value(task, "current_run_id") is not None or _value(task, "block_kind") != "capability" or ROOT not in {str(parent) for parent in parents} or tuple(event or ()) != (event_id, int(run_id), event_kind) or tuple(latest or ()) != (int(run_id), "blocked", "blocked") ): raise ValueError("native task changed after run 10") def _receipt_guard(run_id: str) -> dict[str, Any]: """Verify the sealed source-8 receipt and its normalized title provenance.""" receipt = supervisor_state.publication_retry(BOARD, CHILD, run_id) if not isinstance(receipt, dict): raise ValueError("publication receipt is unavailable") source = receipt.get("source") if ( receipt.get("head") != PRESERVED_HEAD or receipt.get("result_digest") != RECEIPT_DIGEST or not isinstance(source, dict) or source.get("board") != BOARD or source.get("task_id") != CHILD or source.get("root_task_id") != ROOT or source.get("run_id") != SOURCE_RUN or source.get("worker_ordinal") != ORDINAL ): raise ValueError("publication receipt changed after normalization") with supervisor_state._connect(BOARD) as connection: retry = connection.execute( "SELECT source_run_id,source_ordinal,issued_run_id,resolved_run_id,reissue_count,retry_after,last_reissued_run_id " "FROM publication_retries WHERE board=? AND child_task_id=?", (BOARD, CHILD) ).fetchone() provenance = connection.execute( "SELECT raw_result_sha256,reconstruction FROM publication_retry_provenance " "WHERE board=? AND child_task_id=?", (BOARD, CHILD) ).fetchone() pending = (SOURCE_RUN, ORDINAL, run_id, "", 1, RETRY_AFTER, "9") released = (SOURCE_RUN, ORDINAL, "", "", 1, RETRY_AFTER, "9") if ( tuple(retry or ()) not in {pending, released} or provenance is None or provenance[0] != SOURCE_RAW_SHA or not isinstance(provenance[1], str) or not provenance[1].startswith("normalized-title-from-sealed-receipt-sha256:") ): raise ValueError("publication retry state changed after run 10") return receipt def _remote_guard() -> None: """Require the continuing pull request to remain open at its old broker head.""" try: pull = json.loads(scm_broker_client.read("/api/v1/repos/titan/soteria/pulls/3")) except (json.JSONDecodeError, OSError) as error: raise ValueError("pull request metadata is unavailable") from error head = pull.get("head") if isinstance(pull, dict) else None base = pull.get("base") if isinstance(pull, dict) else None if ( not isinstance(pull, dict) or pull.get("state") != "open" or pull.get("merged") is not False or not isinstance(head, dict) or head.get("ref") != BRANCH or head.get("sha") != REMOTE_HEAD or not isinstance(base, dict) or base.get("ref") != "main" ): raise ValueError("pull request changed after run 10") def _published_remote_guard(receipt: dict[str, Any]) -> None: """Require the already-published PR head and prose to equal sealed evidence.""" try: pull = json.loads(scm_broker_client.read("/api/v1/repos/titan/soteria/pulls/3")) except (json.JSONDecodeError, OSError) as error: raise ValueError("published pull request metadata is unavailable") from error head = pull.get("head") if isinstance(pull, dict) else None base = pull.get("base") if isinstance(pull, dict) else None title, body = receipt.get("title"), receipt.get("body") if ( not isinstance(title, str) or not isinstance(body, str) or not isinstance(pull, dict) or pull.get("state") != "open" or pull.get("merged") is not False or not isinstance(head, dict) or head.get("ref") != BRANCH or head.get("sha") != PRESERVED_HEAD or not isinstance(base, dict) or base.get("ref") != "main" or pull.get("title") != _draft_title(title) or pull.get("body") != body ): raise ValueError("published pull request changed after run 11") def release(pool_database: Path) -> bool: """CAS-release run 10’s issue fence without changing its retry budget/history. A retry after a crash before native unblock accepts the already-released state. Any other state is evidence that another actor changed the card. """ _pool_guard(pool_database, FAILED_RUN) _native_guard(FAILED_RUN, FAILED_EVENT_ID, "blocked", "blocked") _receipt_guard(FAILED_RUN) _remote_guard() with supervisor_state._connect(BOARD) as connection: changed = connection.execute( "UPDATE publication_retries SET issued_run_id='' WHERE board=? AND child_task_id=? " "AND source_run_id=? AND source_ordinal=? AND issued_run_id=? AND resolved_run_id='' " "AND reissue_count=1 AND retry_after=? AND last_reissued_run_id='9'", (BOARD, CHILD, SOURCE_RUN, ORDINAL, FAILED_RUN, RETRY_AFTER), ).rowcount if changed == 1: return True with supervisor_state._connect(BOARD) as connection: row = connection.execute( "SELECT source_run_id,source_ordinal,issued_run_id,resolved_run_id,reissue_count,retry_after,last_reissued_run_id " "FROM publication_retries WHERE board=? AND child_task_id=?", (BOARD, CHILD) ).fetchone() if tuple(row or ()) == (SOURCE_RUN, ORDINAL, "", "", 1, RETRY_AFTER, "9"): return False raise ValueError("publication retry state changed before CAS release") def confirm_published_release(pool_database: Path) -> bool: """Release run 11 only after its PR publish is independently visible. This intentionally does not reopen native work. The caller must separately use the native triage specification API after a fixed mediator is deployed. """ _pool_guard(pool_database, CONFIRM_RUN) _native_guard(CONFIRM_RUN, CONFIRM_EVENT_ID, "triage", "block_loop_detected") receipt = _receipt_guard(CONFIRM_RUN) _published_remote_guard(receipt) with supervisor_state._connect(BOARD) as connection: changed = connection.execute( "UPDATE publication_retries SET issued_run_id='' WHERE board=? AND child_task_id=? " "AND source_run_id=? AND source_ordinal=? AND issued_run_id=? AND resolved_run_id='' " "AND reissue_count=1 AND retry_after=? AND last_reissued_run_id='9'", (BOARD, CHILD, SOURCE_RUN, ORDINAL, CONFIRM_RUN, RETRY_AFTER), ).rowcount if changed == 1: return True with supervisor_state._connect(BOARD) as connection: row = connection.execute( "SELECT source_run_id,source_ordinal,issued_run_id,resolved_run_id,reissue_count,retry_after,last_reissued_run_id " "FROM publication_retries WHERE board=? AND child_task_id=?", (BOARD, CHILD) ).fetchone() if tuple(row or ()) == (SOURCE_RUN, ORDINAL, "", "", 1, RETRY_AFTER, "9"): return False raise ValueError("published confirmation changed before CAS release") if __name__ == "__main__": import argparse import os parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--confirm-published", action="store_true") parser.add_argument( "--pool-db", type=Path, default=Path(os.environ.get("HERMES_HOME", "/opt/data")) / "execution-pool/assignments.db", ) args = parser.parse_args() if args.confirm_published: confirm_published_release(args.pool_db) print(f"released {BOARD}/{CHILD} published_run={CONFIRM_RUN} source_run={SOURCE_RUN}") else: release(args.pool_db) print(f"released {BOARD}/{CHILD} failed_run={FAILED_RUN} source_run={SOURCE_RUN}")