mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
[F044] pr_pass gate remediation points the reviewer at pr_fail, not i_am_blocked
The pr_pass gate runs the toolchain + conventions guards on the REVIEWER's workspace, but their remediation text said 'call i_am_blocked' — a verb the PR reviewer does not have. The reviewer would chase a verb they cannot call instead of rejecting the PR. Make the guards reviewer-aware: a reviewer=True flag (passed by _pr_pass_blocked) switches the remediation to pr_fail(issues=[...]) — the reviewer's reject lever, sending the PR back to needs_revision for the dev to fix the environment / validator. The dev (i_am_done) path keeps i_am_blocked, which a dev does have. _conventions_guard (the pr_pass path) now passes reviewer=True through to _conventions_rejection.
This commit is contained in:
@@ -78,6 +78,22 @@ async def test_pr_pass_guard_blocks_when_validator_cannot_run(
|
||||
assert await c._conventions_guard(uuid4(), MagicMock(), {}) is not None
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_pr_pass_guard_could_not_run_remediation_uses_pr_fail(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
# F044: _conventions_guard is the pr_pass (reviewer) path. A reviewer has no
|
||||
# i_am_blocked verb, so the could_not_run remediation must point at pr_fail
|
||||
# (the reviewer's reject lever) — not tell them to call a verb they lack.
|
||||
monkeypatch.setattr(settings, "conventions_enabled", True)
|
||||
c = _make_choreographer(check_result={"findings": [], "could_not_run": True})
|
||||
env = await c._conventions_guard(uuid4(), MagicMock(), {})
|
||||
assert env is not None
|
||||
body = env.as_dict()
|
||||
assert "i_am_blocked" not in body["remediate"]
|
||||
assert "pr_fail" in body["remediate"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_pr_pass_guard_inert_when_flag_off(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
|
||||
@@ -93,3 +93,37 @@ async def test_guard_silent_when_no_marker(monkeypatch: pytest.MonkeyPatch) -> N
|
||||
env = await c._toolchain_broken_guard(uuid4(), MagicMock())
|
||||
assert env is None
|
||||
assert not any(e.get("event") == "toolchain.unverified_gate_pass" for e in logs)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_guard_reviewer_remediation_uses_pr_fail_not_i_am_blocked(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
# F044: the pr_pass gate runs this guard on the REVIEWER's workspace. A PR
|
||||
# reviewer has no i_am_blocked verb, so the dev-path remediation ("call
|
||||
# i_am_blocked(reason='toolchain')") sends them to a verb they cannot call.
|
||||
# The reviewer's reject lever is pr_fail — the remediation must point there
|
||||
# so the PR goes back to needs_revision for the dev to fix the environment.
|
||||
monkeypatch.setattr(settings, "toolchain_match_enabled", True)
|
||||
c = _make_choreographer(status="broken")
|
||||
env = await c._toolchain_broken_guard(uuid4(), MagicMock(), reviewer=True)
|
||||
assert env is not None
|
||||
body = env.as_dict()
|
||||
assert body["error"] == "invalid_state"
|
||||
assert "i_am_blocked" not in body["remediate"]
|
||||
assert "pr_fail" in body["remediate"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_guard_dev_remediation_still_uses_i_am_blocked(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
# F044: the dev (i_am_done) path keeps i_am_blocked — a dev DOES have that
|
||||
# verb, so the original remediation is correct there. The reviewer flag must
|
||||
# not change the dev-path wording.
|
||||
monkeypatch.setattr(settings, "toolchain_match_enabled", True)
|
||||
c = _make_choreographer(status="broken")
|
||||
env = await c._toolchain_broken_guard(uuid4(), MagicMock())
|
||||
assert env is not None
|
||||
body = env.as_dict()
|
||||
assert "i_am_blocked" in body["remediate"]
|
||||
|
||||
Reference in New Issue
Block a user