diff --git a/role_session_router.py b/role_session_router.py index b9a0406..23eb945 100644 --- a/role_session_router.py +++ b/role_session_router.py @@ -5,12 +5,14 @@ returns a route result before any downstream mutation tools run. """ from __future__ import annotations +import os ROUTE_ALLOWED = "allowed_current_session" ROUTE_WRONG_ROLE = "wrong_role_stop" ROUTE_TO_AUTHOR = "route_to_author_session" ROUTE_TO_REVIEWER = "route_to_reviewer_session" ROUTE_AMBIGUOUS = "ambiguous_task_stop" +ROUTE_INFRA_STOP = "infra_stop" REVIEWER_TASKS = frozenset({ "review_pr", @@ -93,6 +95,23 @@ def route_task_session( _record_route(result) return result + if required_role == "reviewer" and check_mid_merge(): + result = { + "task_type": task_type, + "required_role": required_role, + "active_role": active_role_kind, + "active_profile": active_profile, + "route_result": ROUTE_INFRA_STOP, + "downstream_allowed": False, + "reasons": [ + "infra_stop: Unresolved merge conflict or mid-merge state detected in MCP runtime source.", + "Please resolve all conflicts manually, finish/abort the merge, restart the MCP server, and retry." + ], + "message": "infra_stop: Unresolved merge conflict or mid-merge state detected in MCP runtime source.", + } + _record_route(result) + return result + if allowed_in_current_session: result = { "task_type": task_type, @@ -192,4 +211,37 @@ def check_author_mutation_after_reviewer_stop(mutation_task: str) -> tuple[bool, "task and relaunches an author MCP session.", f"Attempted fallback mutation: {mutation_task}", ] - return True, [] \ No newline at end of file + return True, [] + + +def check_mid_merge() -> bool: + """Return True if the repository is mid-merge, mid-rebase, or has conflict markers.""" + project_root = os.path.dirname(os.path.abspath(__file__)) + git_dir = os.path.join(project_root, ".git") + if os.path.exists(git_dir): + if (os.path.exists(os.path.join(git_dir, "MERGE_HEAD")) + or os.path.exists(os.path.join(git_dir, "rebase-merge")) + or os.path.exists(os.path.join(git_dir, "rebase-apply"))): + return True + + # Scan python files for conflict markers + conflict_patterns = [ + b"<" * 7 + b" ", + b"=" * 7 + b"\n", + b"=" * 7 + b"\r\n", + b">" * 7 + b" " + ] + for root, dirs, files in os.walk(project_root): + if any(p in root for p in ("venv", ".git", ".pytest_cache", "branches")): + continue + for file in files: + if file.endswith(".py"): + file_path = os.path.join(root, file) + try: + with open(file_path, "rb") as f: + content = f.read() + if any(pattern in content for pattern in conflict_patterns): + return True + except Exception: + pass + return False \ No newline at end of file