Bind mutation/credential paths to a process-local native MCP runtime so env spoofing, direct imports, and offline helpers cannot reconstruct session gates after native transport failure. Quarantine contaminated formal reviews under controller authority and honor quarantine in review feedback, merge eligibility, merge mutation, and canonical handoff validation. Add regression coverage for the second (PR #694 / review 427) incident class.
95 lines
3.6 KiB
Python
95 lines
3.6 KiB
Python
"""Merge approval must pin the current PR head SHA (#471 / #695).
|
|
|
|
Formal APPROVED reviews that predate the live PR head must not satisfy
|
|
``gitea_merge_pr`` eligibility. Contaminated / quarantined approvals (#695)
|
|
must not authorize merge either. Pure assessment helpers are isolated here
|
|
for hermetic unit tests apart from MCP HTTP calls.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
def assess_merge_approval_head(
|
|
*,
|
|
current_head_sha: str | None,
|
|
latest_by_reviewer: dict,
|
|
quarantined_review_ids: set | None = None,
|
|
) -> dict:
|
|
"""Return whether a visible approval applies to the live PR head.
|
|
|
|
Args:
|
|
current_head_sha: Current PR head commit SHA.
|
|
latest_by_reviewer: Map of reviewer login → review entry dicts with
|
|
``verdict``, ``dismissed``, and ``reviewed_head_sha`` keys.
|
|
Optional ``review_id`` / ``id`` used for quarantine checks (#695).
|
|
quarantined_review_ids: Optional set of review IDs that must not count
|
|
toward merge authorization (#695).
|
|
|
|
Returns:
|
|
dict with ``approval_at_current_head``, ``latest_approved_head_sha``,
|
|
and ``stale_approval_block_reason`` (set when merge must fail closed).
|
|
"""
|
|
current = (current_head_sha or "").strip()
|
|
blocked_ids = {int(x) for x in (quarantined_review_ids or set()) if x is not None}
|
|
|
|
def _rid(entry: dict):
|
|
raw = entry.get("review_id", entry.get("id"))
|
|
try:
|
|
return int(raw) if raw is not None else None
|
|
except (TypeError, ValueError):
|
|
return None
|
|
|
|
approved_entries = []
|
|
quarantined_at_head = []
|
|
for entry in (latest_by_reviewer or {}).values():
|
|
if (entry.get("verdict") or "").upper() != "APPROVED":
|
|
continue
|
|
if entry.get("dismissed"):
|
|
continue
|
|
rid = _rid(entry)
|
|
head = (entry.get("reviewed_head_sha") or "").strip()
|
|
if rid is not None and rid in blocked_ids:
|
|
if current and head == current:
|
|
quarantined_at_head.append(entry)
|
|
continue
|
|
if entry.get("quarantined"):
|
|
if current and head == current:
|
|
quarantined_at_head.append(entry)
|
|
continue
|
|
approved_entries.append(entry)
|
|
|
|
at_current = any(
|
|
(entry.get("reviewed_head_sha") or "").strip() == current
|
|
for entry in approved_entries
|
|
if current
|
|
)
|
|
latest_approved = None
|
|
if approved_entries:
|
|
latest_entry = sorted(
|
|
approved_entries,
|
|
key=lambda entry: (
|
|
entry.get("submitted_at") or "",
|
|
entry.get("reviewed_head_sha") or "",
|
|
),
|
|
)[-1]
|
|
latest_approved = (latest_entry.get("reviewed_head_sha") or "").strip() or None
|
|
reason = None
|
|
if quarantined_at_head and not at_current:
|
|
reason = (
|
|
"contaminated/quarantined approval at current head is void for "
|
|
"merge authorization (#695); required next action: fresh native "
|
|
"MCP re-review after controller quarantine evidence is recorded"
|
|
)
|
|
elif approved_entries and not at_current:
|
|
reason = (
|
|
f"stale approval: approved SHA '{latest_approved}' does not match "
|
|
f"current live PR head SHA '{current or '(unknown)'}' (fail closed); "
|
|
"required next action: re-review PR at current head before merge"
|
|
)
|
|
|
|
return {
|
|
"approval_at_current_head": at_current,
|
|
"latest_approved_head_sha": latest_approved,
|
|
"stale_approval_block_reason": reason,
|
|
"quarantined_approvals_at_current_head": len(quarantined_at_head),
|
|
} |