1414
1515from __future__ import annotations
1616
17- from dataclasses import dataclass
17+ from dataclasses import dataclass , replace
1818from datetime import datetime , timezone
1919
2020from . import live_review_support , reviewer_review_helpers
@@ -173,11 +173,16 @@ def apply_reminder_cadence_overlay(response: ReviewerResponseDecision, cadence)
173173 if response .response_state != "awaiting_reviewer_response" :
174174 return response
175175 reason = getattr (cadence , "exhaustion_reason" , None ) or "legacy_duplicate_reminders_exhausted"
176+ scope = (
177+ replace (response .scope , scope_basis = "reminder_cadence_exhausted" )
178+ if response .scope is not None
179+ else None
180+ )
176181 return ReviewerResponseDecision (
177182 response_state = "reviewer_reassignment_needed" ,
178183 reason = reason ,
179184 suppression_reason = reason ,
180- scope = response . scope ,
185+ scope = scope ,
181186 current_head_sha = response .current_head_sha ,
182187 anchor_timestamp = response .anchor_timestamp ,
183188 reviewer_authority_outcome = response .reviewer_authority_outcome ,
@@ -470,6 +475,13 @@ def _decorate_response(
470475 }
471476
472477
478+ def _write_approval_authority_payload (write_approval : object ) -> dict [str , object ] | None :
479+ if not isinstance (write_approval , dict ):
480+ return None
481+ authority = write_approval .get ("authority_decision" )
482+ return dict (authority ) if isinstance (authority , dict ) else None
483+
484+
473485def _record_for_current_reviewer (record : dict | None | object , current_reviewer : str ) -> dict | None :
474486 if not isinstance (record , dict ):
475487 return None
@@ -872,14 +884,19 @@ def derive_reviewer_response_state(
872884 )
873885
874886 if not isinstance (approval_result , dict ) or not approval_result .get ("ok" ):
887+ write_approval_authority = _write_approval_authority_payload (
888+ approval_result .get ("write_approval" ) if isinstance (approval_result , dict ) else None
889+ )
875890 return _decorate_response (
876891 state = "projection_failed" ,
877892 reason = "live_review_state_unknown" ,
878893 scope_fields = _current_scope_fields (review_data , current_reviewer , current_head , contributor_handoff ),
894+ write_approval_authority = write_approval_authority ,
879895 )
880896
881897 completion = approval_result ["completion" ]
882898 write_approval = approval_result ["write_approval" ]
899+ write_approval_authority = _write_approval_authority_payload (write_approval )
883900 if not completion .get ("completed" ):
884901 return _decorate_response (
885902 state = "awaiting_contributor_response" ,
@@ -906,6 +923,7 @@ def derive_reviewer_response_state(
906923 current_cycle_reviewer_handoff = reviewer_handoff ,
907924 contributor_comment = contributor_comment ,
908925 contributor_handoff = contributor_handoff ,
926+ write_approval_authority = write_approval_authority ,
909927 )
910928 if authority_response_state == "projection_failed" :
911929 authority = write_approval .get ("authority_decision" )
@@ -916,6 +934,7 @@ def derive_reviewer_response_state(
916934 state = "projection_failed" ,
917935 reason = reason ,
918936 scope_fields = _current_scope_fields (review_data , current_reviewer , current_head , contributor_handoff ),
937+ write_approval_authority = write_approval_authority ,
919938 )
920939 if not write_approval .get ("has_write_approval" ):
921940 return _decorate_response (
@@ -929,6 +948,7 @@ def derive_reviewer_response_state(
929948 current_cycle_reviewer_handoff = reviewer_handoff ,
930949 contributor_comment = contributor_comment ,
931950 contributor_handoff = contributor_handoff ,
951+ write_approval_authority = write_approval_authority ,
932952 )
933953 return _decorate_response (
934954 state = "done" ,
@@ -941,6 +961,7 @@ def derive_reviewer_response_state(
941961 current_cycle_reviewer_handoff = reviewer_handoff ,
942962 contributor_comment = contributor_comment ,
943963 contributor_handoff = contributor_handoff ,
964+ write_approval_authority = write_approval_authority ,
944965 )
945966
946967
0 commit comments