1919 actual_status_labels_from_snapshot ,
2020)
2121
22+ _REQUIRED_IDENTITY_FIELDS = (
23+ "validation_nonce" ,
24+ "evaluated_repo" ,
25+ "head_sha" ,
26+ "evaluated_ref" ,
27+ "workflow_path" ,
28+ "run_id" ,
29+ "run_attempt" ,
30+ )
31+ _SUPPORTED_ACTION_WORKFLOWS = {
32+ "preview-issue314-state-health" : ".github/workflows/reviewer-bot-preview.yml" ,
33+ "repair-issue314-state-health" : ".github/workflows/reviewer-bot-sweeper-repair.yml" ,
34+ }
35+ _SUPPORTED_REPAIR_RESULTS = frozenset ({"already_healthy" , "changed" , "blocked" })
36+
37+
38+ def _missing_identity_fields (values : dict [str , object ]) -> tuple [str , ...]:
39+ return tuple (
40+ sorted (
41+ name
42+ for name in _REQUIRED_IDENTITY_FIELDS
43+ if not isinstance (values .get (name ), str ) or not str (values .get (name )).strip ()
44+ )
45+ )
46+
47+
48+ def _require_identity (values : dict [str , object ], * , reason : str ) -> None :
49+ missing = _missing_identity_fields (values )
50+ if missing :
51+ raise RuntimeError (f"issue314_state_health_identity_blocked:{ reason } :" + "," .join (missing ))
52+
53+
54+ def _require_request_identity (request : "Issue314StateHealthRepairRequest" ) -> None :
55+ expected_workflow = _SUPPORTED_ACTION_WORKFLOWS .get (request .repair_action )
56+ if expected_workflow is None :
57+ raise RuntimeError ("issue314_state_health_request_blocked:unsupported_action" )
58+ _require_identity (request .__dict__ , reason = "missing" )
59+ if request .workflow_path != expected_workflow :
60+ raise RuntimeError ("issue314_state_health_request_blocked:workflow_path" )
61+
62+
63+ def _require_repair_summary_contract (summary : "Issue314StateHealthRepairSummary" ) -> None :
64+ _require_identity (summary .__dict__ , reason = "missing" )
65+ if summary .target_collection_mode != "global_issue314_state_health" :
66+ raise RuntimeError ("issue314_state_health_repair_summary_blocked:target_collection_mode" )
67+ if summary .result not in _SUPPORTED_REPAIR_RESULTS :
68+ raise RuntimeError ("issue314_state_health_repair_summary_blocked:result" )
69+ if summary .reviewer_facing_reminder_posts_attempted != 0 :
70+ raise RuntimeError ("issue314_state_health_repair_summary_blocked:reviewer_reminder_attempt" )
71+ if summary .manual_issue314_edit_status != "not_attempted" :
72+ raise RuntimeError ("issue314_state_health_repair_summary_blocked:manual_issue314_edit" )
73+ if summary .rows_blocked and summary .result != "blocked" :
74+ raise RuntimeError ("issue314_state_health_repair_summary_blocked:blocked_rows_success" )
75+ if set (summary .status_labels_changed ) - set (summary .rows_repaired ):
76+ raise RuntimeError ("issue314_state_health_repair_summary_blocked:final_label_only_status" )
77+ if summary .result == "already_healthy" and (
78+ summary .rows_repaired or summary .rows_removed_closed or summary .status_labels_changed
79+ ):
80+ raise RuntimeError ("issue314_state_health_repair_summary_blocked:changed_rows_marked_healthy" )
81+
2282
2383@dataclass (frozen = True )
2484class Issue314StateHealthClassificationInput :
@@ -121,6 +181,7 @@ class Issue314StateHealthSummary:
121181 output_keys : tuple [str , ...]
122182
123183 def to_output (self ) -> dict [str , object ]:
184+ _require_identity (self .__dict__ , reason = "preview_output" )
124185 payload : dict [str , object ] = {
125186 "schema_version" : self .schema_version ,
126187 "preview_action" : self .preview_action ,
@@ -186,6 +247,7 @@ class Issue314StateHealthRepairSummary:
186247 result : str
187248
188249 def to_output (self ) -> dict [str , object ]:
250+ _require_repair_summary_contract (self )
189251 payload : dict [str , object ] = {
190252 "schema_version" : self .schema_version ,
191253 "repair_action" : self .repair_action ,
@@ -285,6 +347,7 @@ def collect_issue314_state_health_input(
285347 request : Issue314StateHealthRepairRequest | None = None ,
286348) -> Issue314StateHealthClassificationInput :
287349 request = request or _default_request (bot )
350+ _require_request_identity (request )
288351 rows = _active_rows (state )
289352 snapshots : dict [int , dict [str , object ]] = {}
290353 reviewer_responses : dict [int , ReviewerResponseDecision ] = {}
@@ -293,8 +356,17 @@ def collect_issue314_state_health_input(
293356 for row in rows :
294357 issue_number = int (row ["issue_number" ])
295358 review_data = row ["review_data" ]
296- snapshot_result = bot .github .get_issue_or_pr_snapshot_result (issue_number )
297- snapshot = snapshot_result .payload if snapshot_result .ok and isinstance (snapshot_result .payload , dict ) else None
359+ try :
360+ snapshot_result = bot .github .get_issue_or_pr_snapshot_result (issue_number )
361+ except (AssertionError , AttributeError , RuntimeError ):
362+ snapshot_result = None
363+ snapshot = (
364+ snapshot_result .payload
365+ if snapshot_result is not None
366+ and snapshot_result .ok
367+ and isinstance (snapshot_result .payload , dict )
368+ else None
369+ )
298370 if snapshot is not None :
299371 snapshots [issue_number ] = snapshot
300372 scans [issue_number ] = _comment_scan (bot , issue_number )
@@ -444,6 +516,7 @@ def _row_from_input(input: Issue314StateHealthClassificationInput, row: dict[str
444516
445517
446518def classify_issue314_state_health (input : Issue314StateHealthClassificationInput ) -> Issue314StateHealthSummary :
519+ _require_identity (input .__dict__ , reason = "classification_input" )
447520 inventory = tuple (_row_from_input (input , row ) for row in input .active_review_rows )
448521 counts : dict [str , int ] = {}
449522 for row in inventory :
@@ -520,6 +593,8 @@ def run_issue314_state_health_repair(
520593 state : dict ,
521594 request : Issue314StateHealthRepairRequest ,
522595) -> Issue314StateHealthRepairSummary :
596+ _require_request_identity (request )
597+ bot .assert_lock_held ("run_issue314_state_health_repair" )
523598 classification_input = collect_issue314_state_health_input (bot , state , request )
524599 summary = classify_issue314_state_health (classification_input )
525600 active_reviews = state .get ("active_reviews" ) if isinstance (state , dict ) else None
0 commit comments