Add reviewer_already_landed_classification verifier to block oldest/next eligible PR wording, review-eligible claims, and pinned reviewed head usage when a PR is already landed. Wire the check into build_final_report and tighten final_report_validator regex coverage. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
143 lines
4.7 KiB
Python
143 lines
4.7 KiB
Python
"""Already-landed PR classification verifier for reviewer reports (#295)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
from typing import Any
|
|
|
|
ALREADY_LANDED_ELIGIBILITY_CLASS = "ALREADY_LANDED_RECONCILE_REQUIRED"
|
|
|
|
_LANDED_CONTEXT_RE = re.compile(
|
|
r"already[- ]landed|ancestor proof\s*:\s*passed|"
|
|
r"eligibility class\s*:\s*already_landed",
|
|
re.IGNORECASE,
|
|
)
|
|
_ELIGIBILITY_CLASS_LINE_RE = re.compile(
|
|
r"eligibility class\s*:\s*(.+)$",
|
|
re.IGNORECASE | re.MULTILINE,
|
|
)
|
|
_INELIGIBLE_SELECTION_RE = re.compile(
|
|
r"\b(?:next|oldest)\s+eligible\s+pr\b",
|
|
re.IGNORECASE,
|
|
)
|
|
_REVIEW_ELIGIBLE_RE = re.compile(
|
|
r"\beligible for (?:review|merge)\b|\bready for (?:review|merge)\b",
|
|
re.IGNORECASE,
|
|
)
|
|
_PINNED_REVIEWED_HEAD_RE = re.compile(
|
|
r"\bpinned reviewed head\s*:",
|
|
re.IGNORECASE,
|
|
)
|
|
_CANDIDATE_HEAD_RE = re.compile(
|
|
r"\bcandidate head sha\s*:",
|
|
re.IGNORECASE,
|
|
)
|
|
_REVIEWED_HEAD_NONE_RE = re.compile(
|
|
r"\breviewed head sha\s*:\s*none\b",
|
|
re.IGNORECASE,
|
|
)
|
|
_VALIDATION_PROOF_RE = re.compile(
|
|
r"(?:validation passed|pytest.*passed|diff review passed|"
|
|
r"validated on pinned head)",
|
|
re.IGNORECASE,
|
|
)
|
|
_QUEUE_BLOCKED_RE = re.compile(
|
|
r"queue blocked by already[- ]landed|"
|
|
r"reconciliation(?:-only)?\s+(?:next step|required)",
|
|
re.IGNORECASE,
|
|
)
|
|
|
|
|
|
def _landed_context(report_text: str, eligibility_class: str | None) -> bool:
|
|
if (eligibility_class or "").strip().upper() == ALREADY_LANDED_ELIGIBILITY_CLASS:
|
|
return True
|
|
return bool(_LANDED_CONTEXT_RE.search(report_text or ""))
|
|
|
|
|
|
def assess_already_landed_classification_report(
|
|
report_text: str,
|
|
*,
|
|
eligibility_class: str | None = None,
|
|
selected_pr_already_landed: bool | None = None,
|
|
) -> dict[str, Any]:
|
|
"""#295: already-landed PRs are reconciliation-only, not review eligible."""
|
|
text = report_text or ""
|
|
reasons: list[str] = []
|
|
|
|
landed = _landed_context(text, eligibility_class)
|
|
if selected_pr_already_landed is True:
|
|
landed = True
|
|
if not landed:
|
|
return {
|
|
"proven": True,
|
|
"block": False,
|
|
"landed_context": False,
|
|
"reasons": [],
|
|
"safe_next_action": "proceed",
|
|
}
|
|
|
|
if _INELIGIBLE_SELECTION_RE.search(text):
|
|
reasons.append(
|
|
"already-landed PR must not be described as oldest/next eligible PR; "
|
|
"use 'Oldest open PR requiring action' and "
|
|
f"'Eligibility class: {ALREADY_LANDED_ELIGIBILITY_CLASS}'"
|
|
)
|
|
|
|
if _REVIEW_ELIGIBLE_RE.search(text):
|
|
reasons.append(
|
|
"already-landed PR must not be described as eligible for review or merge"
|
|
)
|
|
|
|
class_match = _ELIGIBILITY_CLASS_LINE_RE.search(text)
|
|
if class_match:
|
|
declared = class_match.group(1).strip().upper()
|
|
if declared != ALREADY_LANDED_ELIGIBILITY_CLASS:
|
|
reasons.append(
|
|
"already-landed PR eligibility class must be "
|
|
f"{ALREADY_LANDED_ELIGIBILITY_CLASS}"
|
|
)
|
|
elif selected_pr_already_landed is True:
|
|
reasons.append(
|
|
f"already-landed selected PR must declare Eligibility class: "
|
|
f"{ALREADY_LANDED_ELIGIBILITY_CLASS}"
|
|
)
|
|
|
|
if _PINNED_REVIEWED_HEAD_RE.search(text):
|
|
if not _VALIDATION_PROOF_RE.search(text):
|
|
reasons.append(
|
|
"already-landed pre-review report must use Candidate head SHA, "
|
|
"not Pinned reviewed head, unless validation and diff review passed"
|
|
)
|
|
|
|
if selected_pr_already_landed is True and not _CANDIDATE_HEAD_RE.search(text):
|
|
if _PINNED_REVIEWED_HEAD_RE.search(text) or "head sha" in text.lower():
|
|
reasons.append(
|
|
"already-landed ancestry check must report Candidate head SHA"
|
|
)
|
|
|
|
if selected_pr_already_landed is True and not _REVIEWED_HEAD_NONE_RE.search(text):
|
|
if _PINNED_REVIEWED_HEAD_RE.search(text) and not _VALIDATION_PROOF_RE.search(text):
|
|
reasons.append(
|
|
"already-landed report must state 'Reviewed head SHA: none' "
|
|
"when validation did not run"
|
|
)
|
|
|
|
if selected_pr_already_landed is True and not _QUEUE_BLOCKED_RE.search(text):
|
|
reasons.append(
|
|
"already-landed queue blocker must state reconciliation requirement "
|
|
"or queue blocked wording"
|
|
)
|
|
|
|
proven = not reasons
|
|
return {
|
|
"proven": proven,
|
|
"block": not proven,
|
|
"landed_context": True,
|
|
"reasons": reasons,
|
|
"safe_next_action": (
|
|
"classify as ALREADY_LANDED_RECONCILE_REQUIRED, use Candidate head SHA, "
|
|
"and stop normal review"
|
|
if not proven
|
|
else "proceed"
|
|
),
|
|
} |