"""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" ), }