Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions scripts/reviewer_bot_core/reviewer_response_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,9 @@ def derive_reviewer_response_state(
reason="pull_request_head_unavailable",
scope_fields={"current_scope_key": None, "current_scope_basis": None},
)
# Plain PR issue/review comments are diagnostic-only in v65. Explicit
# command handoff is represented separately by current_cycle_reviewer_handoff.
reviewer_comment = None

reviewer_handoff = _current_cycle_reviewer_handoff_record(
review_data,
Expand Down Expand Up @@ -824,7 +827,7 @@ def derive_reviewer_response_state(
if reviewer_handoff is not None and latest_reviewer_response is reviewer_handoff:
return _decorate_response(
state="awaiting_contributor_response",
reason="accepted_same_scope_reviewer_activity",
reason="reviewer_feedback_handoff",
scope_fields=_current_scope_fields(review_data, current_reviewer, current_head, contributor_handoff),
anchor_timestamp=reviewer_handoff.get("timestamp"),
current_head_sha=current_head,
Expand Down Expand Up @@ -860,7 +863,7 @@ def derive_reviewer_response_state(
response_anchor = reviewer_comment if isinstance(reviewer_comment, dict) else reviewer_handoff
return _decorate_response(
state="awaiting_contributor_response",
reason="accepted_same_scope_reviewer_activity",
reason="reviewer_feedback_handoff",
scope_fields=_current_scope_fields(review_data, current_reviewer, current_head, contributor_handoff),
anchor_timestamp=response_anchor.get("timestamp") if isinstance(response_anchor.get("timestamp"), str) else None,
current_head_sha=current_head,
Expand Down Expand Up @@ -989,6 +992,10 @@ def compute_reviewer_response_state(
stored_reviewer_review = reviewer_review
contributor_comment = review_data.get("contributor_comment", {}).get("accepted")
had_reviewer_review = isinstance(reviewer_review, dict)
if is_pr:
# Plain PR issue/review comments are diagnostic-only in v65. Explicit
# command handoff is represented separately by current_cycle_reviewer_handoff.
reviewer_comment = None

if not is_pr:
return derive_reviewer_response_state(
Expand Down
15 changes: 11 additions & 4 deletions scripts/reviewer_bot_lib/issue314_state_health.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,10 +486,17 @@ def _row_from_input(input: Issue314StateHealthClassificationInput, row: dict[str
reason = "row_can_still_trigger_reviewer_reminder"
blockers.append(reason)
elif has_drift and issue_number == 264:
health = "operator_action_required"
repair = "not_attempted"
status_risk = "operator_visible_stale"
reason = "pr264_status_label_repair_deferred_to_issue_scoped_live_repair"
if projection.response_state != "reviewer_reassignment_needed":
health = "blocked"
repair = "blocked"
status_risk = "blocked_unknown"
reason = "pr264_projection_handoff_response_state_mismatch"
blockers.append(reason)
else:
health = "operator_action_required"
repair = "not_attempted"
status_risk = "operator_visible_stale"
reason = "pr264_status_label_repair_deferred_to_issue_scoped_live_repair"
elif has_drift:
health = "repairable"
repair = "not_attempted"
Expand Down
6 changes: 5 additions & 1 deletion scripts/reviewer_bot_lib/reminder_comments.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,11 @@ def _matched_shape(first_line: str, body: str) -> str | None:
if first_line.startswith(f"<!-- {TRANSITION_NOTICE_MARKER_PREFIX} "):
return "markerized_transition_notice"
normalized = body.lower()
if "**review reminder**" in normalized and "transition period" in normalized:
if "**review reminder**" in normalized and (
"transition period" in normalized
or "transitioned from producer to observer" in normalized
or "if no action is taken" in normalized
):
return "legacy_unmarked_warning"
if "**transition period ended**" in normalized:
return "legacy_unmarked_transition_notice"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
pull_request_payload,
review_payload,
)
from tests.fixtures.reviewer_bot_builders import accept_reviewer_review
from tests.fixtures.reviewer_bot_builders import (
accept_contributor_revision,
accept_reviewer_comment,
accept_reviewer_review,
)
from tests.fixtures.reviewer_bot_fakes import RouteGitHubApi

pytestmark = pytest.mark.integration
Expand Down Expand Up @@ -38,8 +42,8 @@ def test_execute_run_preview_issue314_state_health_is_read_only_and_inspects_act
state,
264,
reviewer="iglesias",
assigned_at="2026-02-10T17:20:07Z",
active_cycle_started_at="2026-02-10T17:20:07Z",
assigned_at="2026-02-26T04:58:03.401345+00:00",
active_cycle_started_at="2026-02-26T04:58:03.401345+00:00",
)
accept_reviewer_review(
review,
Expand All @@ -48,6 +52,19 @@ def test_execute_run_preview_issue314_state_health_is_read_only_and_inspects_act
actor="iglesias",
reviewed_head_sha="head-old",
)
accept_contributor_revision(
review,
semantic_key="pull_request_sync:264:head-live",
timestamp="2026-03-18T12:09:36.450502+00:00",
actor="manhatsu",
head_sha="head-live",
)
accept_reviewer_comment(
review,
semantic_key="issue_comment:4240237244",
timestamp="2026-04-13T23:23:25Z",
actor="iglesias",
)
routes = RouteGitHubApi().add_request(
"GET",
"issues/264",
Expand Down Expand Up @@ -83,16 +100,26 @@ def test_execute_run_preview_issue314_state_health_is_read_only_and_inspects_act
status_code=200,
payload=[
{
"id": 9001,
"user": {"login": "github-actions[bot]"},
"created_at": "2026-04-13T00:44:23Z",
"body": "⚠️ **Review Reminder**\n\ntransition period",
"id": 4240237244,
"user": {"login": "iglesias"},
"created_at": "2026-04-13T23:23:25Z",
"body": "LGTM",
},
{
"id": 9002,
"id": 4240517367,
"user": {"login": "github-actions[bot]"},
"created_at": "2026-04-14T00:44:23Z",
"body": "⚠️ **Review Reminder**\n\ntransition period",
"body": "⚠️ **Review Reminder**\n\n"
"Hey @iglesias, it's been more than 14 days since you were assigned to review this.\n\n"
"If no action is taken within 14 days, you may be transitioned from Producer to Observer status.",
},
{
"id": 4240520000,
"user": {"login": "github-actions[bot]"},
"created_at": "2026-04-14T00:52:09Z",
"body": "⚠️ **Review Reminder**\n\n"
"Hey @iglesias, this review has already received its final transition notice.\n\n"
"If no action is taken, the reviewer may be transitioned from Producer to Observer status.",
},
],
)
Expand Down
47 changes: 37 additions & 10 deletions tests/integration/reviewer_bot/test_app_preview_overdue.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@
pull_request_payload,
review_payload,
)
from tests.fixtures.reviewer_bot_builders import accept_reviewer_review
from tests.fixtures.reviewer_bot_builders import (
accept_contributor_revision,
accept_reviewer_comment,
accept_reviewer_review,
)
from tests.fixtures.reviewer_bot_fakes import RouteGitHubApi

pytestmark = pytest.mark.integration
Expand All @@ -37,8 +41,8 @@ def test_execute_run_preview_check_overdue_uses_frozen_pr264_operational_project
state,
264,
reviewer="iglesias",
assigned_at="2026-02-10T17:20:07Z",
active_cycle_started_at="2026-02-10T17:20:07Z",
assigned_at="2026-02-26T04:58:03.401345+00:00",
active_cycle_started_at="2026-02-26T04:58:03.401345+00:00",
)
accept_reviewer_review(
review,
Expand All @@ -47,6 +51,19 @@ def test_execute_run_preview_check_overdue_uses_frozen_pr264_operational_project
actor="iglesias",
reviewed_head_sha="head-old",
)
accept_contributor_revision(
review,
semantic_key="pull_request_sync:264:head-live",
timestamp="2026-03-18T12:09:36.450502+00:00",
actor="manhatsu",
head_sha="head-live",
)
accept_reviewer_comment(
review,
semantic_key="issue_comment:4240237244",
timestamp="2026-04-13T23:23:25Z",
actor="iglesias",
)

routes = RouteGitHubApi().add_request(
"GET",
Expand All @@ -71,16 +88,26 @@ def test_execute_run_preview_check_overdue_uses_frozen_pr264_operational_project
status_code=200,
payload=[
{
"id": 9001,
"user": {"login": "github-actions[bot]"},
"created_at": "2026-04-13T00:44:23Z",
"body": "⚠️ **Review Reminder**\n\ntransition period",
"id": 4240237244,
"user": {"login": "iglesias"},
"created_at": "2026-04-13T23:23:25Z",
"body": "LGTM",
},
{
"id": 9002,
"id": 4240517367,
"user": {"login": "github-actions[bot]"},
"created_at": "2026-04-14T00:44:23Z",
"body": "⚠️ **Review Reminder**\n\ntransition period",
"body": "⚠️ **Review Reminder**\n\n"
"Hey @iglesias, it's been more than 14 days since you were assigned to review this.\n\n"
"If no action is taken within 14 days, you may be transitioned from Producer to Observer status.",
},
{
"id": 4240520000,
"user": {"login": "github-actions[bot]"},
"created_at": "2026-04-14T00:52:09Z",
"body": "⚠️ **Review Reminder**\n\n"
"Hey @iglesias, this review has already received its final transition notice.\n\n"
"If no action is taken, the reviewer may be transitioned from Producer to Observer status.",
},
],
)
Expand Down Expand Up @@ -113,7 +140,7 @@ def test_execute_run_preview_check_overdue_uses_frozen_pr264_operational_project
assert payload["response_state"] == "reviewer_reassignment_needed"
assert payload["reviewer_authority_outcome"] == "tracked_reviewer_confirmed"
assert payload["suppression_reason"] == "legacy_duplicate_reminders_exhausted"
assert payload["current_scope_key"] == "reviewer=iglesias|head=head-live|cycle=2026-02-10T17:20:07Z|anchor=2026-02-10T17:20:07Z"
assert payload["current_scope_key"] == "reviewer=iglesias|head=head-live|cycle=2026-02-26T04:58:03.401345+00:00|anchor=2026-03-18T12:09:36.450502+00:00"
assert payload["current_scope_basis"] == "reminder_cadence_exhausted"
assert payload["would_post_warning"] is False
assert payload["would_post_transition"] is False
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
pull_request_payload,
review_payload,
)
from tests.fixtures.reviewer_bot_builders import accept_reviewer_review
from tests.fixtures.reviewer_bot_builders import (
accept_contributor_revision,
accept_reviewer_comment,
accept_reviewer_review,
)
from tests.fixtures.reviewer_bot_fakes import RouteGitHubApi

pytestmark = pytest.mark.integration
Expand All @@ -34,8 +38,8 @@ def test_execute_run_preview_status_label_projection_is_read_only_pr264_contract
state,
264,
reviewer="iglesias",
assigned_at="2026-02-10T17:20:07Z",
active_cycle_started_at="2026-02-10T17:20:07Z",
assigned_at="2026-02-26T04:58:03.401345+00:00",
active_cycle_started_at="2026-02-26T04:58:03.401345+00:00",
)
accept_reviewer_review(
review,
Expand All @@ -44,6 +48,19 @@ def test_execute_run_preview_status_label_projection_is_read_only_pr264_contract
actor="iglesias",
reviewed_head_sha="head-old",
)
accept_contributor_revision(
review,
semantic_key="pull_request_sync:264:head-live",
timestamp="2026-03-18T12:09:36.450502+00:00",
actor="manhatsu",
head_sha="head-live",
)
accept_reviewer_comment(
review,
semantic_key="issue_comment:4240237244",
timestamp="2026-04-13T23:23:25Z",
actor="iglesias",
)
routes = RouteGitHubApi().add_request(
"GET",
"issues/264",
Expand Down Expand Up @@ -79,16 +96,26 @@ def test_execute_run_preview_status_label_projection_is_read_only_pr264_contract
status_code=200,
payload=[
{
"id": 9001,
"user": {"login": "github-actions[bot]"},
"created_at": "2026-04-13T00:44:23Z",
"body": "⚠️ **Review Reminder**\n\ntransition period",
"id": 4240237244,
"user": {"login": "iglesias"},
"created_at": "2026-04-13T23:23:25Z",
"body": "LGTM",
},
{
"id": 9002,
"id": 4240517367,
"user": {"login": "github-actions[bot]"},
"created_at": "2026-04-14T00:44:23Z",
"body": "⚠️ **Review Reminder**\n\ntransition period",
"body": "⚠️ **Review Reminder**\n\n"
"Hey @iglesias, it's been more than 14 days since you were assigned to review this.\n\n"
"If no action is taken within 14 days, you may be transitioned from Producer to Observer status.",
},
{
"id": 4240520000,
"user": {"login": "github-actions[bot]"},
"created_at": "2026-04-14T00:52:09Z",
"body": "⚠️ **Review Reminder**\n\n"
"Hey @iglesias, this review has already received its final transition notice.\n\n"
"If no action is taken, the reviewer may be transitioned from Producer to Observer status.",
},
],
)
Expand Down
Loading
Loading