From f908aa894bebabd58567720ed5f14617a3f959d4 Mon Sep 17 00:00:00 2001 From: Molecule AI Core-BE Date: Wed, 13 May 2026 22:19:54 +0000 Subject: [PATCH] fix(gate-check): map infra-sre Gitea login to core-devops agent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit infra-sre IS the engineers/core-devops agent (same team, same work). Without this alias, infra-sre reviews and comments never satisfy the engineers gate in signal_1_comment_scan, causing PRs to remain blocked even when infra-sre explicitly posts [devops-agent] APPROVED. Changes: - Add LOGIN_ALIASES dict: infra-sre → core-devops - Resolve aliases in signal_1_comment_scan comment-matching loop - Resolve aliases in signal_1_comment_scan reviews collection - Add test covering infra-sre APPROVED review → engineers CLEAR Fixes #896. [core-be-agent] Co-Authored-By: Claude Opus 4.7 --- tools/gate-check-v3/gate_check.py | 18 ++++++++--- tools/gate-check-v3/test_gate_check.py | 42 ++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/tools/gate-check-v3/gate_check.py b/tools/gate-check-v3/gate_check.py index 963a8ab4..729cf277 100644 --- a/tools/gate-check-v3/gate_check.py +++ b/tools/gate-check-v3/gate_check.py @@ -110,6 +110,13 @@ AGENT_LOGIN_MAP = { "offsec": "core-offsec", } +# Map alternate Gitea logins → canonical logins for gate matching. +# infra-sre is the engineers/core-devops agent (same team, same work). +# Without this alias, infra-sre comments/reviews never satisfy the engineers gate. +LOGIN_ALIASES = { + "infra-sre": "core-devops", +} + # SOP-6 tier → required agent groups # tier:low → engineers,managers,ceo (OR: any one suffices) # tier:medium → managers AND engineers AND qa,security (AND) @@ -168,17 +175,18 @@ def signal_1_comment_scan(pr_number: int, repo: str) -> dict: except GiteaError: pass - # Collect APPROVED reviews from agent logins + # Collect APPROVED reviews from agent logins (resolving LOGIN_ALIASES) try: reviews = api_list(f"/repos/{owner}/{name}/pulls/{pr_number}/reviews") for r in reviews: login = r.get("user", {}).get("login", "") - if login in login_to_group and r.get("state") == "APPROVED": + canonical = LOGIN_ALIASES.get(login, login) + if canonical in login_to_group and r.get("state") == "APPROVED": comments.append( { "id": f"review-{r['id']}", - "user": {"login": login}, - "body": f"[{login}-agent] APPROVED", + "user": {"login": canonical}, + "body": f"[{canonical}-agent] APPROVED", "created_at": r.get("submitted_at") or r.get("created_at", ""), "source": "review", } @@ -193,6 +201,8 @@ def signal_1_comment_scan(pr_number: int, repo: str) -> dict: for c in comments: body = c.get("body", "") or "" user_login = c.get("user", {}).get("login", "") + # Resolve LOGIN_ALIASES so alternate logins satisfy the canonical gate + user_login = LOGIN_ALIASES.get(user_login, user_login) if user_login != login: continue for m in AGENT_TAG_RE.finditer(body): diff --git a/tools/gate-check-v3/test_gate_check.py b/tools/gate-check-v3/test_gate_check.py index f27e2be8..190cfa92 100644 --- a/tools/gate-check-v3/test_gate_check.py +++ b/tools/gate-check-v3/test_gate_check.py @@ -32,3 +32,45 @@ def test_run_skips_pr_not_targeting_default_branch(monkeypatch): assert result["verdict"] == "CLEAR" assert result["skipped"] is True assert "staging" in result["reason"] + + +def test_signal_1_infra_sre_login_alias_resolved_to_core_devops(monkeypatch): + """infra-sre posts [devops-agent] APPROVED → engineers gate satisfied via LOGIN_ALIASES.""" + mod = load_gate_check() + + def fake_api_get(path): + # PR 900 has tier:low label + if path == "/repos/molecule-ai/molecule-core/pulls/900": + return { + "number": 900, + "labels": [{"name": "tier:low"}], + } + raise AssertionError(f"unexpected api_get: {path}") + + def fake_api_list(path): + if path == "/repos/molecule-ai/molecule-core/issues/900/comments": + return [] + if path == "/repos/molecule-ai/molecule-core/pulls/900/comments": + return [] + if path == "/repos/molecule-ai/molecule-core/pulls/900/reviews": + return [ + { + "id": 1, + "user": {"login": "infra-sre"}, + "state": "APPROVED", + "submitted_at": "2026-05-13T10:00:00Z", + } + ] + raise AssertionError(f"unexpected api_list: {path}") + + monkeypatch.setattr(mod, "api_get", fake_api_get) + monkeypatch.setattr(mod, "api_list", fake_api_list) + + result = mod.signal_1_comment_scan(900, "molecule-ai/molecule-core") + + assert result["verdict"] == "CLEAR" + assert result["signal"] == "agent_tag_comments" + # infra-sre (aliased to core-devops) should satisfy engineers gate + engineers = result["results"]["core-devops"] + assert engineers["verdict"] == "APPROVED" + assert engineers["group"] == "engineers" -- 2.45.2