From 38a794c2a911625b38b0dfd8b03fe3d3ebe42f1b Mon Sep 17 00:00:00 2001 From: jenkins Date: Sun, 13 Sep 2026 16:27:01 -0500 Subject: [PATCH] hermes: resolve PR follow-ups from their trusted root --- services/hermes/scripts/execution_pool_coordinator.py | 11 ++++++++--- .../test_hermes_execution_pool_coordinator_v2.py | 5 ++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/services/hermes/scripts/execution_pool_coordinator.py b/services/hermes/scripts/execution_pool_coordinator.py index 438ec103..5fb5e187 100644 --- a/services/hermes/scripts/execution_pool_coordinator.py +++ b/services/hermes/scripts/execution_pool_coordinator.py @@ -111,7 +111,6 @@ def assignment_payload( encoded = context.encode("utf-8") if len(encoded) > 32 * 1024: raise RuntimeError("Kanban worker context exceeds the 32KiB assignment limit") - repo_url, branch, base_branch = resolve_scm(task, board) # Continuation authority comes only from the coordinator-private state DB. # Board cards have no metadata column, and their text cannot select a ref. try: @@ -120,6 +119,11 @@ def assignment_payload( raise RuntimeError("supervisor continuation state is unavailable") from error lineage = child["lineage"] if child is not None else None if child is not None: + # A continuation's trusted root record establishes its repository identity. + # Do not consult a pre-existing board checkout here: it can be a + # preserved legacy workspace for another SCM owner and is never the + # private, mediated checkout that will receive this assignment. + repo_url = f"https://scm.bstein.dev/titan/{lineage.project}.git" root = supervisor_state.get_root(board, lineage.root_task_id) parent = str(child.get("parent_task_id") or "") if root != lineage or not parent: @@ -136,9 +140,10 @@ def assignment_payload( raise RuntimeError("supervisor continuation parents are invalid") if kanban_db.get_task(connection, lineage.root_task_id) is None: raise RuntimeError("supervisor continuation root is unavailable") - root_task_id = lineage.root_task_id if lineage is not None else str(_task_value(task, "id")) - if lineage is not None: branch, base_branch = lineage.branch, lineage.base_branch + else: + repo_url, branch, base_branch = resolve_scm(task, board) + root_task_id = lineage.root_task_id if lineage is not None else str(_task_value(task, "id")) runtime = int(_task_value(task, "max_runtime_seconds", 0) or 12 * 60 * 60) runtime = max(60, min(runtime, 12 * 60 * 60)) return { diff --git a/testing/tests/test_hermes_execution_pool_coordinator_v2.py b/testing/tests/test_hermes_execution_pool_coordinator_v2.py index a392fe25..d221a91c 100644 --- a/testing/tests/test_hermes_execution_pool_coordinator_v2.py +++ b/testing/tests/test_hermes_execution_pool_coordinator_v2.py @@ -171,7 +171,9 @@ def test_assignment_payload_requires_state_and_native_parents_for_continuations( monkeypatch.setattr(coordinator.supervisor_state, "get_root", lambda *_args: lineage) monkeypatch.setattr( coordinator, "resolve_assignment", - lambda *_args: ("https://scm.bstein.dev/titan/metis.git", "wrong", "wrong"), + lambda *_args: (_ for _ in ()).throw( + AssertionError("trusted continuations must not inspect a legacy checkout") + ), ) kanban = SimpleNamespace( build_worker_context=lambda *_args: "objective", @@ -179,6 +181,7 @@ def test_assignment_payload_requires_state_and_native_parents_for_continuations( ) accepted = task(id="repair", parents=("root", "review")) value = coordinator.assignment_payload(kanban, object(), accepted, "metis") + assert value["repo_url"] == "https://scm.bstein.dev/titan/metis.git" assert value["branch"] == "wt/root" assert value["continuation_kind"] == "repair" rejected = task(id="repair", parents=("root",))