#!/usr/bin/env python3 """Seed verified, native roots for the reviewed legacy pull requests.""" from __future__ import annotations from dataclasses import dataclass import json import re from typing import Any, Callable import scm_broker_client import supervisor_state from supervisor_lineage import Lineage SHA = re.compile(r"[0-9a-f]{40}\Z") @dataclass(frozen=True) class Root: """One reviewed PR whose existing branch may be continued in place.""" board: str root_task_id: str project: str ref: str pr_number: int base: str head: str @property def pull_request(self) -> str: return f"https://scm.bstein.dev/titan/{self.project}/pulls/{self.pr_number}" @property def lineage(self) -> Lineage: return Lineage(self.root_task_id, self.ref, self.pull_request, self.project, self.base) def adoption(self) -> dict[str, Any]: """Return the exact schema consumed by the broker's Flux registry.""" return {"repo": self.project, "ref": self.ref, "board": self.board, "root_task_id": self.root_task_id, "latest_head": self.head, "pr_number": self.pr_number} # This reviewed registry mirrors task-branch-adoptions-configmap.yaml. The # regression test keeps the board-side lineage seed and broker ownership ledger # on the same exact PR/ref/head set. ROOTS = ( Root("soteria", "t_f1593f8c", "soteria", "wt/t_f1593f8c", 11, "main", "0143d472469c8dfe44f23f1440123e27d415baae"), Root("soteria", "t_c7c42600", "soteria", "hermes-repair/sonar-AZ9pTqVcN0JrBQvDGDs3", 3, "main", "51133b559ad62f324e45bc61587900f08156b733"), Root("soteria", "t_f4f726e1", "soteria", "hermes-repair/sonar-AZ9pTqWRN0JrBQvDGDs4", 4, "main", "45170df566c2aa387f8b706c3a704abce5aa2557"), Root("titan-iac", "t_26da4c88", "atlas-iac", "feature/t_26da4c88-titan-capacity-guardrails-v4", 53, "main", "3c6301d581bef0a1fce5284f9a28c1cf4c4a99ad"), Root("titan-iac", "t_39cf1905", "atlas-iac", "feature/t_39cf1905-webui-build-token", 54, "main", "f94f96a7042ba863768938e0c1afa79406397b77"), Root("titan-iac", "t_e9597d89", "atlas-iac", "feature/hermes-three-lane-placement", 17, "main", "48cbe13ee50ce3fcb07cea3fe8d088cfed349e0c"), Root("titan-iac", "t_a6a22d7c", "atlas-iac", "feature/hermes-cli-process-reaping", 20, "main", "a242dcc786576ae1a18000cb4941836ff610dff2"), Root("titan-iac", "t_c425c446", "atlas-iac", "fix/t_39cf1905-jenkins-controller-priority", 49, "main", "f997171b5526f104d2474022c2a56683ec2960c3"), Root("titan-iac", "t_cf89a2ec", "atlas-iac", "feature/hermes-next-hux", 55, "main", "98c7c6184f6edfe3cdac228529c2287584db3006"), Root("cassandra", "t_b89e3903", "cassandra", "handoff/generated-strategy-audit-20260813", 1, "main", "14c07111b6ed8d7fc529362eb34fa0afa0694325"), ) def _live_head(root: Root, read: Callable[[str], bytes]) -> str: """Return a live canonical PR head, or an empty string on any mismatch.""" try: pull = json.loads(read(f"/api/v1/repos/titan/{root.project}/pulls/{root.pr_number}")) except (OSError, TypeError, ValueError): return "" if not isinstance(pull, dict): return "" head, base = pull.get("head"), pull.get("base") canonical = f"titan/{root.project}" valid = ( pull.get("state") == "open" and isinstance(head, dict) and isinstance(base, dict) and head.get("ref") == root.ref and isinstance(head.get("repo"), dict) and head["repo"].get("full_name") == canonical and base.get("ref") == root.base and isinstance(base.get("repo"), dict) and base["repo"].get("full_name") == canonical ) value = head.get("sha") if isinstance(head, dict) else "" return value if valid and isinstance(value, str) and SHA.fullmatch(value) else "" def seed_root(kanban_db: Any, root: Root, read: Callable[[str], bytes]) -> str: """Seed one absent state row after proving both native task and live PR.""" with kanban_db.scoped_current_board(root.board): connection = kanban_db.connect(board=root.board) try: if kanban_db.get_task(connection, root.root_task_id) is None: return "missing-task" finally: connection.close() existing = supervisor_state.get_root(root.board, root.root_task_id) if existing is not None: return "already-seeded" if existing == root.lineage else "lineage-conflict" if _live_head(root, read) != root.head: return "live-pr-mismatch" supervisor_state.record_submission(root.board, root.root_task_id, root.lineage, root.head) return "seeded" def run(kanban_db: Any, read: Callable[[str], bytes]) -> dict[str, int]: """Seed each independent root and return compact operator-visible counts.""" counts: dict[str, int] = {} for root in ROOTS: outcome = seed_root(kanban_db, root, read) counts[outcome] = counts.get(outcome, 0) + 1 return counts def main() -> int: """Run the explicit operator migration without changing nonmatching state.""" from hermes_cli import kanban_db counts = run(kanban_db, scm_broker_client.read) print(json.dumps(counts, sort_keys=True)) failures = {"missing-task", "lineage-conflict", "live-pr-mismatch"} return 0 if not failures & counts.keys() else 1 if __name__ == "__main__": raise SystemExit(main())