From 42e0c163dfe0dde7b75b3116cc6b18066c6e5087 Mon Sep 17 00:00:00 2001 From: Armand Date: Tue, 16 Jun 2026 15:47:13 -0500 Subject: [PATCH 1/5] fix(tier4): prove self-quorum settlement blocker --- scripts/settle_tier4_pr.py | 215 ++++++++++++++++++++++++-- tests/scripts/test_settle_tier4_pr.py | 180 +++++++++++++++++++++ 2 files changed, 383 insertions(+), 12 deletions(-) diff --git a/scripts/settle_tier4_pr.py b/scripts/settle_tier4_pr.py index a2b94de7c2..b7b2394278 100644 --- a/scripts/settle_tier4_pr.py +++ b/scripts/settle_tier4_pr.py @@ -57,6 +57,8 @@ def github_cli_env( HUMAN_SETTLEMENT_CONTEXT = "aragora/human-settlement" HUMAN_SETTLEMENT_STATUS_BLOCKER = f"missing or unsuccessful {HUMAN_SETTLEMENT_CONTEXT} status" MERGE_QUORUM_CONTEXT = "aragora-merge-quorum" +DIAGNOSTIC_MERGE_PACKET_KEY = "_diagnostic_ignore_own_quorum_check" +DIAGNOSTIC_MERGE_PACKET_ERROR_KEY = "_diagnostic_ignore_own_quorum_check_error" OPERATOR_COMMENT_BLOCKER = "missing repo-visible Tier 4 operator settlement comment" REQUIRED_CHECKS_BLOCKER = "required checks are missing" REQUIRED_CHECK_VISIBILITY_SKEW_BLOCKER = "required_check_visibility_skew" @@ -72,6 +74,7 @@ def github_cli_env( SUCCESS_STATES = {"SUCCESS", "PASS", "PASSED", "SKIPPED", "NEUTRAL"} BLOCKING_MERGE_STATES = {"DIRTY", "CONFLICTING"} MIN_TIER4_COUNTED_REVIEWER_IDS = 2 +REQUIRED_SELF_QUORUM_MODEL_FAMILIES = {"grok", "openai"} ALLOWED_TIER4_NOT_READY = { "human_risk_settlement", "tier4_human_risk_settlement", @@ -653,6 +656,112 @@ def _required_quorum_only_failure(required_checks: list[dict[str, Any]] | None) return saw_quorum_failure +def _merge_packet_self_quorum_blocker(merge_packet: dict[str, Any], *, pr: int) -> bool: + not_ready = merge_packet.get("not_ready") + return isinstance(not_ready, list) and str(pr) in {str(item) for item in not_ready} + + +def _diagnostic_merge_packet_from(merge_packet: dict[str, Any]) -> dict[str, Any] | None: + diagnostic = merge_packet.get(DIAGNOSTIC_MERGE_PACKET_KEY) + return diagnostic if isinstance(diagnostic, dict) else None + + +def _entry_head_sha(entry: dict[str, Any]) -> str: + for key in ("head_sha", "headRefOid", "head"): + value = str(entry.get(key) or "").strip() + if value: + return value + return "" + + +def _entry_tier(entry: dict[str, Any]) -> int | None: + try: + return int(entry.get("tier")) + except (TypeError, ValueError): + return None + + +def _entry_has_owner_mailbox_blocker(entry: dict[str, Any]) -> bool: + for key in ( + "owner_blocker", + "mailbox_blocker", + "active_owner", + "active_mailbox", + "owner_active", + "mailbox_active", + ): + if bool(entry.get(key)): + return True + return False + + +def _packet_has_required_self_quorum_model_families( + merge_packet: dict[str, Any], *, pr: int +) -> bool: + entry = _entry_for_pr(merge_packet, pr=pr) + if not entry: + return False + families = entry.get("counted_model_families") + counted = ( + {str(item).strip().lower() for item in families if str(item).strip()} + if isinstance(families, list) + else set() + ) + return REQUIRED_SELF_QUORUM_MODEL_FAMILIES.issubset(counted) + + +def _diagnostic_packet_proves_self_quorum_missing_settlement( + diagnostic_merge_packet: dict[str, Any] | None, + *, + pr: int, + expected_head: str, + required_checks: list[dict[str, Any]] | None, +) -> bool: + if not isinstance(diagnostic_merge_packet, dict): + return False + if not _required_quorum_only_failure(required_checks): + return False + entry = _entry_for_pr(diagnostic_merge_packet, pr=pr) + if not entry: + return False + if _entry_head_sha(entry) != expected_head: + return False + if _entry_tier(entry) != 4: + return False + if str(entry.get("status") or "") != "human_preapproval_required": + return False + if bool(entry.get("unresolved_dissent")): + return False + if _entry_has_owner_mailbox_blocker(entry): + return False + if not _packet_has_required_self_quorum_model_families(diagnostic_merge_packet, pr=pr): + return False + if not _packet_has_counted_tier4_evidence(diagnostic_merge_packet, pr=pr): + return False + return _packet_marks_tier4_human_settlement(diagnostic_merge_packet, pr=pr) + + +def _effective_required_checks( + required_checks: list[dict[str, Any]] | None, + *, + self_quorum_missing_settlement_proven: bool, +) -> list[dict[str, Any]] | None: + if not self_quorum_missing_settlement_proven or not required_checks: + return required_checks + effective: list[dict[str, Any]] = [] + for check in required_checks: + if not isinstance(check, dict): + continue + if _required_check_is_merge_quorum(check): + patched = dict(check) + patched["state"] = "SUCCESS" + patched["self_quorum_failure_ignored"] = True + effective.append(patched) + else: + effective.append(check) + return effective + + def _packet_proves_quorum_missing_settlement(merge_packet: dict[str, Any], *, pr: int) -> bool: entry = _entry_for_pr(merge_packet, pr=pr) if not entry: @@ -829,6 +938,7 @@ def evaluate_tier4_gate( expected_head: str, pr_view: dict[str, Any], merge_packet: dict[str, Any], + diagnostic_merge_packet: dict[str, Any] | None = None, required_checks: list[dict[str, Any]] | None = None, require_branch_protection_token: bool = False, repo: str = DEFAULT_REPO, @@ -845,6 +955,22 @@ def evaluate_tier4_gate( if bool(pr_view.get("isDraft")): blockers.append(f"PR #{pr} is draft") merge_state = str(pr_view.get("mergeStateStatus") or "") + diagnostic_merge_packet = diagnostic_merge_packet or _diagnostic_merge_packet_from(merge_packet) + self_quorum_missing_settlement_proven = ( + _diagnostic_packet_proves_self_quorum_missing_settlement( + diagnostic_merge_packet, + pr=pr, + expected_head=expected_head, + required_checks=required_checks, + ) + ) + effective_merge_packet = ( + diagnostic_merge_packet if self_quorum_missing_settlement_proven else merge_packet + ) + effective_required_checks = _effective_required_checks( + required_checks, + self_quorum_missing_settlement_proven=self_quorum_missing_settlement_proven, + ) required_failing: list[str] = [] blockers.extend(_mergeability_blockers(pr=pr, pr_view=pr_view)) for check in required_checks or []: @@ -852,12 +978,14 @@ def evaluate_tier4_gate( state = _required_check_state(check) if not _state_is_success(state): required_failing.append(f"{name}={state}") + if self_quorum_missing_settlement_proven and _required_check_is_merge_quorum(check): + continue blockers.append(f"required check {name} is {state}") merge_packet_blockers: list[str] = [] not_ready = merge_packet.get("not_ready") if isinstance(not_ready, list): allowed_not_ready = set(ALLOWED_TIER4_NOT_READY) - if _packet_marks_tier4_human_settlement(merge_packet, pr=pr): + if _packet_marks_tier4_human_settlement(effective_merge_packet, pr=pr): allowed_not_ready.add(str(pr)) merge_packet_blockers = sorted({str(item) for item in not_ready} - allowed_not_ready) if merge_packet_blockers: @@ -865,7 +993,7 @@ def evaluate_tier4_gate( f"merge-packet has unexpected blockers: {', '.join(merge_packet_blockers)}" ) - required_checks_green = _required_checks_are_green(required_checks) + required_checks_green = _required_checks_are_green(effective_required_checks) authorization_precondition_blockers: list[str] = [] if actual_head == expected_head: if not required_checks: @@ -874,7 +1002,7 @@ def evaluate_tier4_gate( pass elif not _human_settlement_status_is_success(pr_view): authorization_precondition_blockers.append(HUMAN_SETTLEMENT_STATUS_BLOCKER) - elif not _packet_has_counted_tier4_evidence(merge_packet, pr=pr): + elif not _packet_has_counted_tier4_evidence(effective_merge_packet, pr=pr): authorization_precondition_blockers.append(TIER4_EVIDENCE_BLOCKER) blockers.extend(authorization_precondition_blockers) @@ -900,8 +1028,8 @@ def evaluate_tier4_gate( pr_view, pr=pr, head=expected_head, - merge_packet=merge_packet, - required_checks=required_checks, + merge_packet=effective_merge_packet, + required_checks=effective_required_checks, require_branch_protection_token=require_branch_protection_token, repo=repo, cwd=cwd, @@ -913,6 +1041,11 @@ def evaluate_tier4_gate( blockers.append(OPERATOR_COMMENT_BLOCKER) packet_diagnostics = _merge_packet_entry_diagnostics(merge_packet, pr=pr) + diagnostic_packet_diagnostics = ( + _merge_packet_entry_diagnostics(diagnostic_merge_packet, pr=pr) + if diagnostic_merge_packet is not None + else None + ) return { "ok": not blockers, "pr": pr, @@ -924,6 +1057,8 @@ def evaluate_tier4_gate( "required_failing": required_failing, "merge_packet_blockers": merge_packet_blockers, "merge_packet": packet_diagnostics, + "diagnostic_merge_packet": diagnostic_packet_diagnostics, + "self_quorum_missing_settlement_proven": self_quorum_missing_settlement_proven, "reasons": packet_diagnostics["reasons"], "settle_eligible": not blockers, "authorized_actions": sorted(authorized_actions), @@ -937,6 +1072,7 @@ def evaluate_tier4_settlement_preconditions( expected_head: str, pr_view: dict[str, Any], merge_packet: dict[str, Any], + diagnostic_merge_packet: dict[str, Any] | None = None, required_checks: list[dict[str, Any]] | None = None, quorum_missing_settlement_proof: bool = False, trusted_operator_logins: Sequence[str] | None = None, @@ -955,6 +1091,18 @@ def evaluate_tier4_settlement_preconditions( blockers.append(f"PR #{pr} is draft") merge_state = str(pr_view.get("mergeStateStatus") or "") blockers.extend(_mergeability_blockers(pr=pr, pr_view=pr_view)) + diagnostic_merge_packet = diagnostic_merge_packet or _diagnostic_merge_packet_from(merge_packet) + self_quorum_missing_settlement_proven = ( + _diagnostic_packet_proves_self_quorum_missing_settlement( + diagnostic_merge_packet, + pr=pr, + expected_head=expected_head, + required_checks=required_checks, + ) + ) + effective_merge_packet = ( + diagnostic_merge_packet if diagnostic_merge_packet is not None else merge_packet + ) if not required_checks: blockers.append(REQUIRED_CHECKS_BLOCKER) @@ -963,7 +1111,9 @@ def evaluate_tier4_settlement_preconditions( merge_packet, pr=pr ) has_quorum_missing_settlement_proof = ( - packet_missing_settlement_proof or quorum_missing_settlement_proof + packet_missing_settlement_proof + or quorum_missing_settlement_proof + or self_quorum_missing_settlement_proven ) quorum_only_failure = _required_quorum_only_failure(required_checks) for check in required_checks: @@ -981,7 +1131,7 @@ def evaluate_tier4_settlement_preconditions( if quorum_only_failure and not has_quorum_missing_settlement_proof: blockers.append(MERGE_QUORUM_SETTLEMENT_PROOF_BLOCKER) - not_ready = merge_packet.get("not_ready") + not_ready = effective_merge_packet.get("not_ready") if isinstance(not_ready, list): allowed_not_ready = set(ALLOWED_TIER4_NOT_READY) allowed_not_ready.add(str(pr)) @@ -989,9 +1139,14 @@ def evaluate_tier4_settlement_preconditions( if unexpected: blockers.append(f"merge-packet has unexpected blockers: {', '.join(unexpected)}") - if not _packet_marks_tier4_settlement_surface(merge_packet, pr=pr): + if not _packet_marks_tier4_settlement_surface(effective_merge_packet, pr=pr): blockers.append("merge-packet does not mark Tier 4 human-risk settlement") - if not _packet_has_counted_tier4_evidence(merge_packet, pr=pr): + if not _packet_has_counted_tier4_evidence(effective_merge_packet, pr=pr): + blockers.append(TIER4_EVIDENCE_BLOCKER) + elif ( + diagnostic_merge_packet is not None + and not _packet_has_required_self_quorum_model_families(diagnostic_merge_packet, pr=pr) + ): blockers.append(TIER4_EVIDENCE_BLOCKER) allowed_logins = _trusted_operator_logins(trusted_operator_logins) @@ -1023,6 +1178,7 @@ def evaluate_tier4_settlement_preconditions( "invoker_login": normalized_invoker, "invoker_has_admin_permission": invoker_has_admin_permission, "blockers": blockers, + "self_quorum_missing_settlement_proven": self_quorum_missing_settlement_proven, } @@ -1553,6 +1709,29 @@ def _load_live_inputs( cwd=cwd, ) required_checks = _load_required_checks(pr, cwd=cwd, repo=repo, pr_view=pr_view) + if _required_quorum_only_failure(required_checks) and _merge_packet_self_quorum_blocker( + merge_packet, pr=pr + ): + merge_packet = dict(merge_packet) + try: + merge_packet[DIAGNOSTIC_MERGE_PACKET_KEY] = _run_json( + [ + sys.executable, + "-m", + "aragora.cli.main", + "review-queue", + "merge-packet", + "--pr", + str(pr), + "--repo", + repo, + "--ignore-own-quorum-check", + "--json", + ], + cwd=cwd, + ) + except RuntimeError as exc: + merge_packet[DIAGNOSTIC_MERGE_PACKET_ERROR_KEY] = str(exc) return pr_view, merge_packet, required_checks @@ -1956,10 +2135,20 @@ def main(argv: Sequence[str] | None = None) -> int: ) applied_commands: list[list[str]] = [] if args.settle_only: + diagnostic_merge_packet = _diagnostic_merge_packet_from(merge_packet) + diagnostic_missing_settlement_proof = ( + _diagnostic_packet_proves_self_quorum_missing_settlement( + diagnostic_merge_packet, + pr=args.pr, + expected_head=args.head, + required_checks=required_checks, + ) + ) quorum_missing_settlement_proof = False - if _required_quorum_only_failure( - required_checks - ) and not _packet_proves_quorum_missing_settlement(merge_packet, pr=args.pr): + if _required_quorum_only_failure(required_checks) and not ( + _packet_proves_quorum_missing_settlement(merge_packet, pr=args.pr) + or diagnostic_missing_settlement_proof + ): quorum_missing_settlement_proof = _quorum_failure_log_proves_missing_settlement( required_checks, repo=args.repo, @@ -1971,6 +2160,7 @@ def main(argv: Sequence[str] | None = None) -> int: expected_head=args.head, pr_view=pr_view, merge_packet=merge_packet, + diagnostic_merge_packet=diagnostic_merge_packet, required_checks=required_checks, quorum_missing_settlement_proof=quorum_missing_settlement_proof, trusted_operator_logins=args.trusted_operator_login, @@ -1991,6 +2181,7 @@ def main(argv: Sequence[str] | None = None) -> int: expected_head=args.head, pr_view=pr_view, merge_packet=merge_packet, + diagnostic_merge_packet=diagnostic_merge_packet, required_checks=required_checks, quorum_missing_settlement_proof=quorum_missing_settlement_proof, trusted_operator_logins=args.trusted_operator_login, diff --git a/tests/scripts/test_settle_tier4_pr.py b/tests/scripts/test_settle_tier4_pr.py index e712c820ff..21e0b9fd81 100644 --- a/tests/scripts/test_settle_tier4_pr.py +++ b/tests/scripts/test_settle_tier4_pr.py @@ -121,6 +121,36 @@ def _tier4_repair_packet_missing_settlement(pr: int = 7423) -> dict[str, Any]: return packet +def _tier4_diagnostic_human_preapproval_packet( + head: str, + pr: int = 7423, + *, + counted_model_families: list[str] | None = None, + unresolved_dissent: bool = False, +) -> dict[str, Any]: + packet = _tier4_packet( + pr=pr, + counted_reviewer_ids=["grok", "openai"], + dogfood_evidence=[{"reviewer_id": "grok"}, {"reviewer_id": "openai"}], + unresolved_dissent=unresolved_dissent, + ) + entry = packet["entries"][0] + entry.update( + { + "head_sha": head, + "tier": 4, + "tier_name": "tier_4_preapproval_required", + "status": "human_preapproval_required", + "verdict": "tier_4_human_preapproval_required", + "counted_model_families": ( + ["grok", "openai"] if counted_model_families is None else counted_model_families + ), + "requires_human_preapproval": True, + } + ) + return packet + + def test_json_read_gh_probe_prefers_app_auth_and_preserves_cwd( monkeypatch: Any, tmp_path: Path ) -> None: @@ -480,6 +510,48 @@ def fake_run_json_any(command: list[str], *, cwd: Path | None = None) -> Any: assert gate["ok"] is True +def test_load_live_inputs_fetches_diagnostic_packet_for_self_quorum_failure( + monkeypatch: Any, tmp_path: Path +) -> None: + head = "57c740022e3c432718462efa12ca79f1df4f674d" + normal_packet = _tier4_repair_packet_missing_settlement() + diagnostic_packet = _tier4_diagnostic_human_preapproval_packet(head) + merge_packet_calls: list[list[str]] = [] + + def fake_run_json(command: list[str], *, cwd: Path | None = None) -> dict[str, Any]: + if command[:3] == ["gh", "pr", "view"]: + return _pr_view(head, comments=[], human_settlement_state=None) + if command[:4] == [sys.executable, "-m", "aragora.cli.main", "review-queue"]: + merge_packet_calls.append(command) + return diagnostic_packet if "--ignore-own-quorum-check" in command else normal_packet + raise AssertionError(f"unexpected _run_json command: {command}") + + def fake_run_json_any(command: list[str], *, cwd: Path | None = None) -> Any: + if command[:4] == ["gh", "pr", "checks", "7423"]: + return [ + {"name": "lint", "state": "SUCCESS"}, + {"name": "aragora-merge-quorum", "state": "FAILURE"}, + ] + raise AssertionError(f"unexpected _run_json_any command: {command}") + + monkeypatch.setattr(settler, "_run_json", fake_run_json) + monkeypatch.setattr(settler, "_run_json_any", fake_run_json_any) + + _, merge_packet, required_checks = settler._load_live_inputs( + 7423, + cwd=tmp_path, + repo="synaptent/aragora", + ) + + assert required_checks == [ + {"name": "lint", "state": "SUCCESS"}, + {"name": "aragora-merge-quorum", "state": "FAILURE"}, + ] + assert len(merge_packet_calls) == 2 + assert "--ignore-own-quorum-check" in merge_packet_calls[1] + assert merge_packet[settler.DIAGNOSTIC_MERGE_PACKET_KEY] is diagnostic_packet + + def test_load_live_inputs_fills_missing_required_check_rows_from_direct_runs( monkeypatch: pytest.MonkeyPatch, tmp_path: Path ) -> None: @@ -1987,6 +2059,114 @@ def fake_quorum_proof(checks: list[dict[str, str]], *, repo: str, cwd: Path, hea assert commands[0][0][:3] == ["gh", "api", "--method"] +def test_settle_only_allows_self_quorum_failure_with_diagnostic_packet() -> None: + head = "57c740022e3c432718462efa12ca79f1df4f674d" + + result = settler.evaluate_tier4_settlement_preconditions( + pr=7423, + expected_head=head, + pr_view=_pr_view(head, comments=[], human_settlement_state=None), + merge_packet=_tier4_repair_packet_missing_settlement(), + diagnostic_merge_packet=_tier4_diagnostic_human_preapproval_packet(head), + required_checks=[ + {"name": "lint", "state": "SUCCESS"}, + {"name": "aragora-merge-quorum", "state": "FAILURE"}, + ], + ) + + assert result["ok"] is True + assert result["blockers"] == [] + assert result["self_quorum_missing_settlement_proven"] is True + + +def test_settle_only_diagnostic_packet_does_not_hide_non_quorum_required_failure() -> None: + head = "57c740022e3c432718462efa12ca79f1df4f674d" + + result = settler.evaluate_tier4_settlement_preconditions( + pr=7423, + expected_head=head, + pr_view=_pr_view(head, comments=[], human_settlement_state=None), + merge_packet=_tier4_repair_packet_missing_settlement(), + diagnostic_merge_packet=_tier4_diagnostic_human_preapproval_packet(head), + required_checks=[ + {"name": "lint", "state": "FAILURE"}, + {"name": "aragora-merge-quorum", "state": "FAILURE"}, + ], + ) + + assert result["ok"] is False + assert "required check lint is FAILURE" in result["blockers"] + assert result["self_quorum_missing_settlement_proven"] is False + + +def test_settle_only_diagnostic_packet_does_not_hide_missing_model_quorum() -> None: + head = "57c740022e3c432718462efa12ca79f1df4f674d" + + result = settler.evaluate_tier4_settlement_preconditions( + pr=7423, + expected_head=head, + pr_view=_pr_view(head, comments=[], human_settlement_state=None), + merge_packet=_tier4_repair_packet_missing_settlement(), + diagnostic_merge_packet=_tier4_diagnostic_human_preapproval_packet( + head, + counted_model_families=["grok"], + ), + required_checks=[ + {"name": "lint", "state": "SUCCESS"}, + {"name": "aragora-merge-quorum", "state": "FAILURE"}, + ], + ) + + assert result["ok"] is False + assert settler.TIER4_EVIDENCE_BLOCKER in result["blockers"] + assert result["self_quorum_missing_settlement_proven"] is False + + +def test_settle_only_diagnostic_packet_does_not_hide_unresolved_dissent() -> None: + head = "57c740022e3c432718462efa12ca79f1df4f674d" + + result = settler.evaluate_tier4_settlement_preconditions( + pr=7423, + expected_head=head, + pr_view=_pr_view(head, comments=[], human_settlement_state=None), + merge_packet=_tier4_repair_packet_missing_settlement(), + diagnostic_merge_packet=_tier4_diagnostic_human_preapproval_packet( + head, + unresolved_dissent=True, + ), + required_checks=[ + {"name": "lint", "state": "SUCCESS"}, + {"name": "aragora-merge-quorum", "state": "FAILURE"}, + ], + ) + + assert result["ok"] is False + assert settler.TIER4_EVIDENCE_BLOCKER in result["blockers"] + assert result["self_quorum_missing_settlement_proven"] is False + + +def test_settle_only_diagnostic_packet_does_not_hide_owner_blocker() -> None: + head = "57c740022e3c432718462efa12ca79f1df4f674d" + diagnostic_packet = _tier4_diagnostic_human_preapproval_packet(head) + diagnostic_packet["entries"][0]["active_owner"] = True + + result = settler.evaluate_tier4_settlement_preconditions( + pr=7423, + expected_head=head, + pr_view=_pr_view(head, comments=[], human_settlement_state=None), + merge_packet=_tier4_repair_packet_missing_settlement(), + diagnostic_merge_packet=diagnostic_packet, + required_checks=[ + {"name": "lint", "state": "SUCCESS"}, + {"name": "aragora-merge-quorum", "state": "FAILURE"}, + ], + ) + + assert result["ok"] is False + assert settler.MERGE_QUORUM_SETTLEMENT_PROOF_BLOCKER in result["blockers"] + assert result["self_quorum_missing_settlement_proven"] is False + + def test_quorum_failure_log_proves_missing_human_settlement( monkeypatch: Any, tmp_path: Path ) -> None: From f1f62a7fe6fecb00576099229fc34ad9d6d1eaab Mon Sep 17 00:00:00 2001 From: Armand Date: Tue, 16 Jun 2026 18:07:20 -0500 Subject: [PATCH 2/5] fix(tier4): reject unproven diagnostic packets --- scripts/settle_tier4_pr.py | 12 ++++++- tests/scripts/test_settle_tier4_pr.py | 51 +++++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/scripts/settle_tier4_pr.py b/scripts/settle_tier4_pr.py index b7b2394278..616af7ee4a 100644 --- a/scripts/settle_tier4_pr.py +++ b/scripts/settle_tier4_pr.py @@ -59,6 +59,7 @@ def github_cli_env( MERGE_QUORUM_CONTEXT = "aragora-merge-quorum" DIAGNOSTIC_MERGE_PACKET_KEY = "_diagnostic_ignore_own_quorum_check" DIAGNOSTIC_MERGE_PACKET_ERROR_KEY = "_diagnostic_ignore_own_quorum_check_error" +DIAGNOSTIC_OWNER_MAILBOX_BLOCKER = "diagnostic merge-packet reports owner/mailbox blocker" OPERATOR_COMMENT_BLOCKER = "missing repo-visible Tier 4 operator settlement comment" REQUIRED_CHECKS_BLOCKER = "required checks are missing" REQUIRED_CHECK_VISIBILITY_SKEW_BLOCKER = "required_check_visibility_skew" @@ -1058,6 +1059,7 @@ def evaluate_tier4_gate( "merge_packet_blockers": merge_packet_blockers, "merge_packet": packet_diagnostics, "diagnostic_merge_packet": diagnostic_packet_diagnostics, + "diagnostic_merge_packet_error": merge_packet.get(DIAGNOSTIC_MERGE_PACKET_ERROR_KEY), "self_quorum_missing_settlement_proven": self_quorum_missing_settlement_proven, "reasons": packet_diagnostics["reasons"], "settle_eligible": not blockers, @@ -1101,7 +1103,12 @@ def evaluate_tier4_settlement_preconditions( ) ) effective_merge_packet = ( - diagnostic_merge_packet if diagnostic_merge_packet is not None else merge_packet + diagnostic_merge_packet if self_quorum_missing_settlement_proven else merge_packet + ) + diagnostic_entry = ( + _entry_for_pr(diagnostic_merge_packet, pr=pr) + if isinstance(diagnostic_merge_packet, dict) + else None ) if not required_checks: @@ -1148,6 +1155,8 @@ def evaluate_tier4_settlement_preconditions( and not _packet_has_required_self_quorum_model_families(diagnostic_merge_packet, pr=pr) ): blockers.append(TIER4_EVIDENCE_BLOCKER) + if isinstance(diagnostic_entry, dict) and _entry_has_owner_mailbox_blocker(diagnostic_entry): + blockers.append(DIAGNOSTIC_OWNER_MAILBOX_BLOCKER) allowed_logins = _trusted_operator_logins(trusted_operator_logins) normalized_invoker = str(invoker_login or "").strip().lower() @@ -1178,6 +1187,7 @@ def evaluate_tier4_settlement_preconditions( "invoker_login": normalized_invoker, "invoker_has_admin_permission": invoker_has_admin_permission, "blockers": blockers, + "diagnostic_merge_packet_error": merge_packet.get(DIAGNOSTIC_MERGE_PACKET_ERROR_KEY), "self_quorum_missing_settlement_proven": self_quorum_missing_settlement_proven, } diff --git a/tests/scripts/test_settle_tier4_pr.py b/tests/scripts/test_settle_tier4_pr.py index 21e0b9fd81..ce9d3a0454 100644 --- a/tests/scripts/test_settle_tier4_pr.py +++ b/tests/scripts/test_settle_tier4_pr.py @@ -2118,7 +2118,7 @@ def test_settle_only_diagnostic_packet_does_not_hide_missing_model_quorum() -> N ) assert result["ok"] is False - assert settler.TIER4_EVIDENCE_BLOCKER in result["blockers"] + assert settler.MERGE_QUORUM_SETTLEMENT_PROOF_BLOCKER in result["blockers"] assert result["self_quorum_missing_settlement_proven"] is False @@ -2141,7 +2141,7 @@ def test_settle_only_diagnostic_packet_does_not_hide_unresolved_dissent() -> Non ) assert result["ok"] is False - assert settler.TIER4_EVIDENCE_BLOCKER in result["blockers"] + assert settler.MERGE_QUORUM_SETTLEMENT_PROOF_BLOCKER in result["blockers"] assert result["self_quorum_missing_settlement_proven"] is False @@ -2167,6 +2167,53 @@ def test_settle_only_diagnostic_packet_does_not_hide_owner_blocker() -> None: assert result["self_quorum_missing_settlement_proven"] is False +def test_settle_only_log_proof_does_not_allow_diagnostic_owner_blocker() -> None: + head = "57c740022e3c432718462efa12ca79f1df4f674d" + diagnostic_packet = _tier4_diagnostic_human_preapproval_packet(head) + diagnostic_packet["entries"][0]["active_owner"] = True + + result = settler.evaluate_tier4_settlement_preconditions( + pr=7423, + expected_head=head, + pr_view=_pr_view(head, comments=[], human_settlement_state=None), + merge_packet=_tier4_repair_packet_missing_settlement(), + diagnostic_merge_packet=diagnostic_packet, + required_checks=[ + {"name": "lint", "state": "SUCCESS"}, + {"name": "aragora-merge-quorum", "state": "FAILURE"}, + ], + quorum_missing_settlement_proof=True, + ) + + assert result["ok"] is False + assert "diagnostic merge-packet reports owner/mailbox blocker" in result["blockers"] + assert result["self_quorum_missing_settlement_proven"] is False + + +def test_settle_only_log_proof_does_not_allow_missing_diagnostic_model_quorum() -> None: + head = "57c740022e3c432718462efa12ca79f1df4f674d" + + result = settler.evaluate_tier4_settlement_preconditions( + pr=7423, + expected_head=head, + pr_view=_pr_view(head, comments=[], human_settlement_state=None), + merge_packet=_tier4_repair_packet_missing_settlement(), + diagnostic_merge_packet=_tier4_diagnostic_human_preapproval_packet( + head, + counted_model_families=["grok"], + ), + required_checks=[ + {"name": "lint", "state": "SUCCESS"}, + {"name": "aragora-merge-quorum", "state": "FAILURE"}, + ], + quorum_missing_settlement_proof=True, + ) + + assert result["ok"] is False + assert settler.TIER4_EVIDENCE_BLOCKER in result["blockers"] + assert result["self_quorum_missing_settlement_proven"] is False + + def test_quorum_failure_log_proves_missing_human_settlement( monkeypatch: Any, tmp_path: Path ) -> None: From 0921b350efd706e5ceb4b354ef1245cb6b731a2c Mon Sep 17 00:00:00 2001 From: Armand Date: Tue, 16 Jun 2026 19:25:23 -0500 Subject: [PATCH 3/5] fix(tier4): align diagnostic packet blockers --- scripts/settle_tier4_pr.py | 4 ++-- tests/scripts/test_settle_tier4_pr.py | 30 ++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/scripts/settle_tier4_pr.py b/scripts/settle_tier4_pr.py index 616af7ee4a..d54664d396 100644 --- a/scripts/settle_tier4_pr.py +++ b/scripts/settle_tier4_pr.py @@ -983,7 +983,7 @@ def evaluate_tier4_gate( continue blockers.append(f"required check {name} is {state}") merge_packet_blockers: list[str] = [] - not_ready = merge_packet.get("not_ready") + not_ready = effective_merge_packet.get("not_ready") if isinstance(not_ready, list): allowed_not_ready = set(ALLOWED_TIER4_NOT_READY) if _packet_marks_tier4_human_settlement(effective_merge_packet, pr=pr): @@ -1151,7 +1151,7 @@ def evaluate_tier4_settlement_preconditions( if not _packet_has_counted_tier4_evidence(effective_merge_packet, pr=pr): blockers.append(TIER4_EVIDENCE_BLOCKER) elif ( - diagnostic_merge_packet is not None + self_quorum_missing_settlement_proven and not _packet_has_required_self_quorum_model_families(diagnostic_merge_packet, pr=pr) ): blockers.append(TIER4_EVIDENCE_BLOCKER) diff --git a/tests/scripts/test_settle_tier4_pr.py b/tests/scripts/test_settle_tier4_pr.py index ce9d3a0454..ce759949dc 100644 --- a/tests/scripts/test_settle_tier4_pr.py +++ b/tests/scripts/test_settle_tier4_pr.py @@ -2190,7 +2190,7 @@ def test_settle_only_log_proof_does_not_allow_diagnostic_owner_blocker() -> None assert result["self_quorum_missing_settlement_proven"] is False -def test_settle_only_log_proof_does_not_allow_missing_diagnostic_model_quorum() -> None: +def test_settle_only_log_proof_ignores_unproven_diagnostic_model_quorum() -> None: head = "57c740022e3c432718462efa12ca79f1df4f674d" result = settler.evaluate_tier4_settlement_preconditions( @@ -2209,11 +2209,35 @@ def test_settle_only_log_proof_does_not_allow_missing_diagnostic_model_quorum() quorum_missing_settlement_proof=True, ) - assert result["ok"] is False - assert settler.TIER4_EVIDENCE_BLOCKER in result["blockers"] + assert result["ok"] is True + assert settler.TIER4_EVIDENCE_BLOCKER not in result["blockers"] assert result["self_quorum_missing_settlement_proven"] is False +def test_gate_blocks_unexpected_diagnostic_not_ready_when_self_quorum_proven() -> None: + head = "57c740022e3c432718462efa12ca79f1df4f674d" + diagnostic_packet = _tier4_diagnostic_human_preapproval_packet(head) + diagnostic_packet["not_ready"] = [7423, "unexpected_diagnostic_blocker"] + + result = settler.evaluate_tier4_gate( + pr=7423, + expected_head=head, + pr_view=_pr_view(head, comments=[], human_settlement_state=None), + merge_packet=_tier4_repair_packet_missing_settlement(), + diagnostic_merge_packet=diagnostic_packet, + required_checks=[ + {"name": "lint", "state": "SUCCESS"}, + {"name": "aragora-merge-quorum", "state": "FAILURE"}, + ], + ) + + assert result["ok"] is False + assert ( + "merge-packet has unexpected blockers: unexpected_diagnostic_blocker" in result["blockers"] + ) + assert result["self_quorum_missing_settlement_proven"] is True + + def test_quorum_failure_log_proves_missing_human_settlement( monkeypatch: Any, tmp_path: Path ) -> None: From fa5094742dc5d2e074742a2e3a618f0fe089ff01 Mon Sep 17 00:00:00 2001 From: Armand Date: Tue, 16 Jun 2026 22:00:53 -0500 Subject: [PATCH 4/5] fix(tier4): keep self-quorum proof settlement-only --- scripts/settle_tier4_pr.py | 15 ++++++-------- tests/scripts/test_settle_tier4_pr.py | 28 +++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/scripts/settle_tier4_pr.py b/scripts/settle_tier4_pr.py index d54664d396..36bb778610 100644 --- a/scripts/settle_tier4_pr.py +++ b/scripts/settle_tier4_pr.py @@ -965,13 +965,12 @@ def evaluate_tier4_gate( required_checks=required_checks, ) ) - effective_merge_packet = ( - diagnostic_merge_packet if self_quorum_missing_settlement_proven else merge_packet - ) - effective_required_checks = _effective_required_checks( - required_checks, - self_quorum_missing_settlement_proven=self_quorum_missing_settlement_proven, - ) + # The self-quorum diagnostic packet is only a settlement-prep escape hatch: + # it lets --settle-only prove that aragora-merge-quorum is failing because + # the human settlement artifact is missing. Final --check/--merge-apply must + # still require the real branch-protection checks and normal merge-packet. + effective_merge_packet = merge_packet + effective_required_checks = required_checks required_failing: list[str] = [] blockers.extend(_mergeability_blockers(pr=pr, pr_view=pr_view)) for check in required_checks or []: @@ -979,8 +978,6 @@ def evaluate_tier4_gate( state = _required_check_state(check) if not _state_is_success(state): required_failing.append(f"{name}={state}") - if self_quorum_missing_settlement_proven and _required_check_is_merge_quorum(check): - continue blockers.append(f"required check {name} is {state}") merge_packet_blockers: list[str] = [] not_ready = effective_merge_packet.get("not_ready") diff --git a/tests/scripts/test_settle_tier4_pr.py b/tests/scripts/test_settle_tier4_pr.py index ce759949dc..feca639c87 100644 --- a/tests/scripts/test_settle_tier4_pr.py +++ b/tests/scripts/test_settle_tier4_pr.py @@ -2079,6 +2079,26 @@ def test_settle_only_allows_self_quorum_failure_with_diagnostic_packet() -> None assert result["self_quorum_missing_settlement_proven"] is True +def test_gate_requires_real_quorum_check_when_diagnostic_proves_settlement_only() -> None: + head = "57c740022e3c432718462efa12ca79f1df4f674d" + + result = settler.evaluate_tier4_gate( + pr=7423, + expected_head=head, + pr_view=_pr_view(head, comments=[_authorized_comment(head)]), + merge_packet=_tier4_repair_packet_missing_settlement(), + diagnostic_merge_packet=_tier4_diagnostic_human_preapproval_packet(head), + required_checks=[ + {"name": "lint", "state": "SUCCESS"}, + {"name": "aragora-merge-quorum", "state": "FAILURE"}, + ], + ) + + assert result["ok"] is False + assert "required check aragora-merge-quorum is FAILURE" in result["blockers"] + assert result["self_quorum_missing_settlement_proven"] is True + + def test_settle_only_diagnostic_packet_does_not_hide_non_quorum_required_failure() -> None: head = "57c740022e3c432718462efa12ca79f1df4f674d" @@ -2214,7 +2234,7 @@ def test_settle_only_log_proof_ignores_unproven_diagnostic_model_quorum() -> Non assert result["self_quorum_missing_settlement_proven"] is False -def test_gate_blocks_unexpected_diagnostic_not_ready_when_self_quorum_proven() -> None: +def test_gate_uses_normal_packet_when_self_quorum_diagnostic_is_settlement_only() -> None: head = "57c740022e3c432718462efa12ca79f1df4f674d" diagnostic_packet = _tier4_diagnostic_human_preapproval_packet(head) diagnostic_packet["not_ready"] = [7423, "unexpected_diagnostic_blocker"] @@ -2232,9 +2252,9 @@ def test_gate_blocks_unexpected_diagnostic_not_ready_when_self_quorum_proven() - ) assert result["ok"] is False - assert ( - "merge-packet has unexpected blockers: unexpected_diagnostic_blocker" in result["blockers"] - ) + assert "required check aragora-merge-quorum is FAILURE" in result["blockers"] + assert "merge-packet has unexpected blockers: 7423" in result["blockers"] + assert not any("unexpected_diagnostic_blocker" in item for item in result["blockers"]) assert result["self_quorum_missing_settlement_proven"] is True From 724f0ab536dc52dfe56673ca11f82135299830ea Mon Sep 17 00:00:00 2001 From: Armand Date: Tue, 16 Jun 2026 22:04:13 -0500 Subject: [PATCH 5/5] fix(tier4): block diagnostic dissent during settlement proof --- scripts/settle_tier4_pr.py | 2 ++ tests/scripts/test_settle_tier4_pr.py | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/scripts/settle_tier4_pr.py b/scripts/settle_tier4_pr.py index 36bb778610..98193743c9 100644 --- a/scripts/settle_tier4_pr.py +++ b/scripts/settle_tier4_pr.py @@ -1154,6 +1154,8 @@ def evaluate_tier4_settlement_preconditions( blockers.append(TIER4_EVIDENCE_BLOCKER) if isinstance(diagnostic_entry, dict) and _entry_has_owner_mailbox_blocker(diagnostic_entry): blockers.append(DIAGNOSTIC_OWNER_MAILBOX_BLOCKER) + if isinstance(diagnostic_entry, dict) and bool(diagnostic_entry.get("unresolved_dissent")): + blockers.append("diagnostic merge-packet reports unresolved dissent") allowed_logins = _trusted_operator_logins(trusted_operator_logins) normalized_invoker = str(invoker_login or "").strip().lower() diff --git a/tests/scripts/test_settle_tier4_pr.py b/tests/scripts/test_settle_tier4_pr.py index feca639c87..45e1bf7582 100644 --- a/tests/scripts/test_settle_tier4_pr.py +++ b/tests/scripts/test_settle_tier4_pr.py @@ -2210,6 +2210,30 @@ def test_settle_only_log_proof_does_not_allow_diagnostic_owner_blocker() -> None assert result["self_quorum_missing_settlement_proven"] is False +def test_settle_only_log_proof_does_not_allow_diagnostic_unresolved_dissent() -> None: + head = "57c740022e3c432718462efa12ca79f1df4f674d" + + result = settler.evaluate_tier4_settlement_preconditions( + pr=7423, + expected_head=head, + pr_view=_pr_view(head, comments=[], human_settlement_state=None), + merge_packet=_tier4_repair_packet_missing_settlement(), + diagnostic_merge_packet=_tier4_diagnostic_human_preapproval_packet( + head, + unresolved_dissent=True, + ), + required_checks=[ + {"name": "lint", "state": "SUCCESS"}, + {"name": "aragora-merge-quorum", "state": "FAILURE"}, + ], + quorum_missing_settlement_proof=True, + ) + + assert result["ok"] is False + assert "diagnostic merge-packet reports unresolved dissent" in result["blockers"] + assert result["self_quorum_missing_settlement_proven"] is False + + def test_settle_only_log_proof_ignores_unproven_diagnostic_model_quorum() -> None: head = "57c740022e3c432718462efa12ca79f1df4f674d"