
    iT                   T   U d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlmZmZmZ ddlmZmZ ddlmZ ddlmZmZmZ  eej.                  j1                  dd	            Zed
z  dz  Zed
z  dz  Zedz  Z ej:                  e      Z	 ddl m!Z! ddl"m#Z#m$Z$m%Z% ddl&m'Z(m)Z)m*Z* ddl+m,Z-m.Z. ddl/m0Z0m1Z1m2Z2m3Z3 dZ4e4e!e#e$e%e(e)e*e-e.e0e1e2e3fZ8dZ9dZ:dZ;dZ<dZ=dZ>dZ?dZ@dZAdZBd ZCd!ZDd"ZEd#ZFd$ZGd%ZHd&ZIeCeDeEeFeGeHeIhZJh d'ZKd(ZLd)ZMd*ZNd+ZOd,ZPd-ZQd.ZRd/ZSd0ZTd1ZUd2ZV eWePeQeReSeTeUeVh      ZX eWeReSeTh      ZYd3ZZd4Z[d5Z\ ej                  d6       ej                  d7       ej                  d8       ej                  d9      gZ^d:e_d;<    ej                  d<      d=f ej                  d>      d?f ej                  d@      dAf ej                  dB      dCf ej                  dD      dEf ej                  dF      dGfgZ`e9ZadZbdHZcdIZddJZee G dK dL             Zfe G dM dN             ZgedOej                  f   ZidxdydPZjdzdQZk	 d{	 	 	 	 	 	 	 d|dRZld}dSZm	 	 	 	 	 	 	 	 	 	 d~dTZnddUZo	 	 	 	 	 	 ddVZp ej                  dW       ej                  dX       ej                  dY       ej                  dZ       ej                  d[      gZq	 d{	 	 	 	 	 	 	 dd\Zrd]d^e
j                  f	 	 	 	 	 	 	 	 	 	 	 dd_Zt	 	 	 	 	 	 	 	 dd`ZuddaddbZvddcZwef	 	 	 	 	 dddZx	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddeZyddfZzddgZ{ddhZ|	 	 	 	 	 	 ddiZ'	 	 	 	 	 	 ddjZ}	 d	 	 	 	 	 	 	 ddkZ~	 d{	 	 	 	 	 	 	 ddlZ ej                  dmej                         ZddnZddoZddpZe G dq dr             Z	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddsZ	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 ddtZdduZd{ddvZedwk(  r e	j                   e              yy# e5$ r9Z6ejo                  de6       dZ4dZ!dZ#dZ$dZ%dZ(dZ)dZ*dZ-i Z.dZ0dZ1dZ2dZ3Y dZ6[6\dZ6[6ww xY w)u  merge_queue_executor.py — task-2509 5 모듈 #1.

회장 명시: queue 선두 PR이 자동 머지 10조건 만족 시 회장 승인 없이 squash merge +
post-merge smoke + 후행 PR stale 재검증을 수행한다.
산출물은 정책 문서가 아니라 실행 가능한 코드 + 회귀 테스트.

자동 머지 10조건:
  1. queue head 위치 (선행 PR 모두 merged)
  2. origin/main fetch 성공 + main HEAD SHA 잠금
  3. PR base sync (BEHIND → merge sync, rebase/force 금지)
  4. effective diff = expected_files (불일치 → replacement_pr_runner 분기)
  5. forbidden path 0건
  6. CI required all SUCCESS
  7. Gemini reviewThreads unresolved 0
  8. mergeStateStatus == CLEAN
  9. HEAD SHA lock 유지 (검증 시작 == merge 직전)
 10. cherry_pick_allowed != true / serial_only conflict 0

Critical 7종 (회장 §14):
  - FORBIDDEN_PATH_INVASION
  - EFFECTIVE_DIFF_CONTAMINATION_REPLACEMENT_FAILED
  - GEMINI_REAL_BUG_SCOPE_EXPANSION
  - BLOCK_OVERRIDE_REQUIRED_OR_INSUFFICIENT_REASON
  - DEPENDENCY_CYCLE_OR_SERIAL_ONLY_CONFLICT
  - REPLACEMENT_PR_ALSO_FAILED
  - POST_MERGE_SMOKE_FAILURE

CLI:
  python3 utils/merge_queue_executor.py --pr <N> --dry-run
    → AUTO_MERGE_ALLOWED 또는 BLOCKED_WITH_REASON: <code> JSON

후속 모듈 (인터페이스만 박제):
  - replacement_pr_runner (task-2510)
  - auto_gemini_triage (task-2511)
  - post_merge_smoke_runner (task-2512)
  - critical_escalation_reporter (task-2513)
    )annotationsN)	dataclassfieldasdict)datetimetimezone)Path)AnyCallableOptionalWORKSPACE_ROOTz/home/jay/workspacememoryeventszorchestration-auditzmerge-queue.jsonl)ReplacementPRRunner)	triage_prto_legacy_gemini_stateTriageReport)run_post_merge_smokePostMergeSmokeRunSmokeStatus)process_eventLEGACY_CRITICAL_MAP)CriticalEscalationTypeEscalationPacketReviewGateStatusGeminiTriageResultTz#W1 wiring modules not available: %sFAUTO_MERGE_ALLOWEDAUTO_MERGE_SUCCESSWAITING_FOR_PREDECESSORBLOCKED_WITH_REASONHEAD_SHA_LOCK_BROKENCI_FAILURE_BLOCKCI_IN_PROGRESSGEMINI_UNRESOLVED_BLOCKMERGE_STATE_NOT_CLEANDIFF_CONTAMINATION_REPLACEMENTFORBIDDEN_PATH_INVASION/EFFECTIVE_DIFF_CONTAMINATION_REPLACEMENT_FAILEDGEMINI_REAL_BUG_SCOPE_EXPANSION.BLOCK_OVERRIDE_REQUIRED_OR_INSUFFICIENT_REASON(DEPENDENCY_CYCLE_OR_SERIAL_ONLY_CONFLICTREPLACEMENT_PR_ALSO_FAILEDPOST_MERGE_SMOKE_FAILURE>   --force--force-with-lease-f--adminreplacement_pr_runnerauto_gemini_triagepost_merge_smoke_runnercritical_escalation_reporterGEMINI_COMPLETEDGEMINI_UNRESOLVEDGEMINI_UNAVAILABLE_QUOTAGEMINI_TIMEOUTGEMINI_STALEGEMINI_REAL_BUGGEMINI_SCOPE_EXPANSIONLOWMEDIUM	HIGH_COREz ^utils/merge_queue_executor\.py$z^utils/merge_topology_gate\.py$z^dispatch\.py$z^teams/shared/verifiers/.+zlist[re.Pattern]HIGH_CORE_FILE_PATTERNSzgit\s+push\s+.*--forcez
force pushzgit\s+push\s+.*-f\bzforce push (-f)zgh\s+pr\s+merge\s+.*--adminzadmin overridezgit\s+cherry-pick\bzcherry-pickzopen\([^)]*"\.done"[^)]*"w"zmanual .done writez Path\([^)]*\)\.touch\(\).*\.donezmanual .done touchCRITICAL_ESCALATIONFALLBACK_REVIEW_FAILED"NON_DRY_RUN_REQUIRES_SMOKE_COMMANDc                  B   e Zd ZU ded<   dZded<   dZded<   dZded	<   dZded
<   dZded<   dZ	ded<   dZ
ded<    ee      Zded<    ee      Zded<    ee      Zded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<    ee      Zded<   dZded<   dZd ed!<   dZd ed"<   dZded#<   dZd ed$<   dZded%<   dZded&<    ee      Z d'ed(<    ee      Z!d)ed*<   dZ"ded+<   dZ#d ed,<   dZ$d-ed.<   dZ%d-ed/<    ee      Z&d)ed0<   d2d1Z'y)3QueueDecisionstrdecision reasonNzOptional[int]	pr_numberOptional[str]task_idmain_head_sha_startmain_head_sha_mergepr_head_sha_startpr_head_sha_mergedefault_factory	list[str]expected_fileseffective_filesforbidden_paths	ci_statusr   intgemini_unresolved_countmerge_state_statussmoke_statuscritical_code
audit_path	timestamp
list[dict]fixture_pr_replaygemini_statusFboolfallback_review_usedfallback_review_passed
risk_levelreview_gate_passedfinal_decisioncritical_escalationdictfallback_check_detailsliststatic_scan_violationspipeline_stepreplacement_usedzOptional[dict]triage_summarysmoke_envelopeescalationsc                    t        |       S N)r   )selfs    K/home/jay/workspace/.worktrees/task-2514-dev3/utils/merge_queue_executor.pyto_dictzQueueDecision.to_dict   s    d|    )returnri   )(__name__
__module____qualname____annotations__rI   rJ   rL   rM   rN   rO   rP   r   rk   rT   rU   rV   rW   rY   rZ   r[   r\   r]   r^   r`   ra   rc   rd   re   rf   rg   rh   ri   rj   rl   rm   rn   ro   rp   rq   rv    rw   ru   rE   rE      s}   MFC#I}#!G]!)--)--'+}+'+}+ %d ;NI;!&t!<OY<!&t!<OY<Is#$S$  L##'M=' $J$Is$)$$?z?#'M='!&$&#(D( $J$$$$(NM()--#(#>D>#(#>D>#'M='"d"%)NN)%)NN)d3K3rw   rE   c                  p    e Zd ZU dZded<   ded<   ded<   ded<   ded<   d	ed
<   ded<   d	ed<   dZded<   y)TaskSpecu   task spec metadata 정상화.rF   rL   rS   rT   	risk_area
dependencyparallel_policyr
   merge_queue_positionrb   stale_recheck_requiredcherry_pick_allowedNOptional[list[str]]smoke_command)ry   rz   r{   __doc__r|   r   r}   rw   ru   r   r      s>    'LN  )-M&-rw   r   .c                X    t        j                  | |xs t        t              dd|      S )NT)cwdcapture_outputtexttimeout)
subprocessrunrF   	WORKSPACE)argsr   r   s      ru   _default_runnerr     s+    >>!3y> rw   c                    | D cg c]  }|t         v s|j                  d      s|  }}|rt        d|       d| v rt        d      y c c}w )Nr1   zFORBIDDEN_GIT_FLAGS detected: rebaseREBASE_FORBIDDEN)FORBIDDEN_GIT_FLAGS
startswithRuntimeError)r   abads      ru   assert_no_forbidden_git_flagsr     s]    
Ra#66!,,y:Q1
RC
R
;C5ABB4-.. 	 Ss
   A
A
c           
        g }| sd|fS | D ]  }t        |t              s|dk(  rt        j                  d|j	                               }|s|j                  |       R|j                  d      |j                  d      xs d}}|dk7  r~| ||      s|j                  |        |ddd	d
d| ddg      }|j                  j	                         r|j                  |        t        |      dk(  |fS )uR   dependency 항목 중 `.merged` 상태 task 모두 main에 반영됐는지 확인.Tnonez*^(task-\d+(?:\+\d+)?)(?:\.(merged|done))?$      mergedgitlogorigin/mainz	--onelinez--grep=z-n1r   )	
isinstancerF   rematchstripappendgroupstdoutlen)	r   runnermain_log_greppendingspecmrL   stateresults	            ru   check_predecessor_mergedr   '  s     GW} $$$6>HHBDJJLQNN4 QWWQZ%;8H$ )w'}kWWICVX\^abc}}""$NN7#'$( LA''rw   c                     | g d        | g d      }|j                   xs dj                         }|st        d      |S )u$   origin fetch + main HEAD SHA 반환.r   fetchoriginz--quiet)r   z	rev-parser   rH   MAIN_HEAD_SHA_FETCH_FAILED)r   r   r   )r   r   shas      ru   fetch_main_headr   H  sA    
0178F==B
%
%
'C788Jrw   c                    dddd}|dk7  r|S g d}t        |        |||      }d|d<   d	|d
<   |j                  dk7  r<|j                  xs d|j                  xs dz   }d|v sd|j	                         v rd|d<   |S )u3   BEHIND 시 merge sync. rebase 금지, force 금지.FN)	performedmethodconflictBEHIND)r   merger   z	--no-editr   Tr   merge_no_editr   r   rH   CONFLICTr   )r   
returncoder   stderrlower)
_pr_branch
pr_workdirr   rZ   r   r   proccombineds           ru   sync_pr_baser   S  s     F
 X%7D!$'$J'DF;&F8!KK%2$++*;<!Z8>>3C%C!%F:Mrw   c                j    | D ch c]#  }|j                         s|j                         % c}S c c}w rs   )r   )filesps     ru   _normalize_file_listr   p  s$    $2!	AGGI222s   00c                    t        |      }t        |       }t        ||z
        }t        ||z
        }t        |      dk(  xr t        |      dk(  ||fS )u   effective diff vs expected_files 대칭 비교.

    반환: (equal, extra, missing)
      - extra   = effective - expected (예상 외 파일)
      - missing = expected - effective (누락 파일)
      - equal   = extra == [] and missing == []
    r   )r   sortedr   )rU   rT   expected	effectiveextramissings         ru   compare_effective_diffr   t  sY     $N3H$_5I9x'(EX	)*GJ!O1G 1E7BBrw   z^\.github/workflows/z^teams/.*/qc/verifiers/z^utils/task_id_parser\.py$z^scripts/finish_task\.py$z^scripts/qc_verify\.py$c                    t        t              }|r|j                  |       t        |      }g }| D ]2  }||v r|D ]&  }|j	                  |      s|j                  |        2 4 |S )uP   forbidden 파일이 effective diff 안에 있는데 expected 외이면 invasion.)rk   DEFAULT_FORBIDDEN_PATTERNSextendr   searchr   )rU   allowed_expectedextra_patternspatternsr   	invasionsfr   s           ru   detect_forbidden_pathsr     sz     ./H'#$45HI = 	Axx{  #	 rw   r   g        c           	        t        t        |d            D ]<  } |dddt        |       ddg      }	 t        j                  |j
                  xs d      }|j                  d      xs g }g }	|D ]\  }
|
j                  d      xs( |
j                  d	      xs |
j                  d
      xs d}|	j                  |j                                ^ |	st        g |dc S t        d |	D              rt        |	|dc S t        d |	D              r$|dz   |k  r ||d|z  z         t        |	|dc S t        d |	D              rd|	|dc S t        |	|dc S  t        g g dS # t        j                  $ r i }Y #w xY w)uU   gh pr view --json statusCheckRollup → required all SUCCESS / FAILURE / IN_PROGRESS.r   ghprview--jsonstatusCheckRollup{}r   
conclusionstatusrH   )r   detailsrawc              3  $   K   | ]  }|d v  
 yw)>   ERRORFAILURE	CANCELLED	TIMED_OUTACTION_REQUIREDNr}   .0ss     ru   	<genexpr>z"fetch_ci_status.<locals>.<genexpr>  s     hZ[qUUh   c              3  $   K   | ]  }|d v  
 yw)>   QUEUEDPENDINGWAITINGEXPECTEDIN_PROGRESSNr}   r   s     ru   r   z"fetch_ci_status.<locals>.<genexpr>  s     bTUqOObr   r   c              3  $   K   | ]  }|d v  
 yw)>   NEUTRALSKIPPEDSUCCESS	COMPLETEDNr}   r   s     ru   r   z"fetch_ci_status.<locals>.<genexpr>  s     UqqBBUr   r  )rangemaxrF   jsonloadsr   JSONDecodeErrorgetr   upperr"   anyr#   all)rJ   r   	max_pollsbackoff_secondssleeperattemptr   payloadrollupstatusesitemr   s               ru   fetch_ci_statusr    s    Y*+ P$I)
 	jj!6$7G 017R 	+DHHW%[,)?[488HCU[Y[EOOEKKM*	+ .2fMMh_ghh.8FSSbYabb{Y&1<89,&QQUHUU'HVLL*xOO3P4 %B??' ## 	G	s   #E  E98E9c           	         |ddddd|  dg      }	 t        j                  |j                  xs d      }|j	                  d      xs g }t        |t              r<|r:d	j                  d
 |D              }d|v sd|v sd|v rdg d|dS d|v sd|v rdg d|dS |j	                  d      du s|j	                  d      du rdg ddS |j	                  d      xs i }|j	                  d      xs i }|j	                  d      xs i }	|	j	                  d      xs i }
|
j	                  d      xs g }g }|D ]y  }|j	                  d      r|j	                  d      xs i j	                  d      xs g }|r|d   ni }|j                  |j	                  dd       |j	                  d!d       d"       { |sd#g ddS t        |      }|D cg c]  }|j	                  d      |v s| }}|D cg c]  }|j	                  d      |vs| }}|rd$||t        t        d%S d&||t        d'S # t         j                  $ r i }Y w xY wc c}w c c}w )(u  gh api graphql reviewThreads → unresolved 0 필수.

    분기:
      - unresolved == 0 → ok
      - unresolved style/false-positive only & expected_files 안 → AUTO_GEMINI_TRIAGE_HOOK
      - unresolved real bug expected_files 밖 → CRITICAL_GEMINI_SCOPE_EXPANSION
    r   apigraphqlr0   z@query=query{ repository(owner:"x",name:"y"){ pullRequest(number:z_){ reviewThreads(first:50){ nodes{ isResolved comments(first:1){ nodes{ path body } } } } } } }r   errors c              3     K   | ]?  }t        |t              r|j                  d d      n
t        |      j	                          A yw)messagerH   N)r   ri   r  rF   r   )r   es     ru   r   z&fetch_gemini_status.<locals>.<genexpr>  s;      
 &04%8QUU9b!c!fKKM
s   AAquotaz
rate limitz
rate-limitunavailable_quotaN)r   
unresolvedhookr  r   deadlinestaleTpr_head_changed)r   r  r   data
repositorypullRequestreviewThreadsnodes
isResolvedcommentsr   pathrH   body)r+  r,  okcritical_scope_expansion)r   r  outsider   r\   auto_triage_candidate)r   r  insider   )r  r  r   r  r  r   rk   joinr   r   CRITICAL_ESCALATION_HOOKCRITICAL_GEMINI_SCOPE_EXPANSIONAUTO_GEMINI_TRIAGE_HOOK)rJ   r   rT   r   r  r  joinedr$  repor   threadsr(  r  nr*  firstr   ur1  r/  s                       ru   fetch_gemini_statusr<    s    eY
PQZP[  \G  	H F**V]]2d3
 [["(bF&$F 

 
 f 6,&:P-  	  *"6#  	  {{7t#w{{3D'E'M
 	
 ;;v$"D88L!'RD	-	 	&BBff_%+GKK &BEJ 55EE*%+009?R'RIIfb)IIfb)
 	 b$??#N3H#AAquuV}'@aAFA$FQfX(EqFGF0$,<
 	
 * '	 y  d BFs)   #H" H>H>&I?I"H;:H;real_bugc               >   | st         S | j                  d      xs dj                         }| j                  d      xs g }|dk(  rt        |      dk(  rt        S |dk(  rt
        S |dk(  r|rt        S t         S |dk(  rt        S |d	k(  rt        S |d
k(  rt        S t         S )uW  fetch_gemini_status() 결과 + 추가 신호 → enum 7종 중 하나.

    분류 규칙:
      - status == 'ok' AND unresolved == 0 → GEMINI_COMPLETED
      - status == 'critical_scope_expansion' → GEMINI_SCOPE_EXPANSION
      - status == 'auto_triage_candidate' AND real_bug=True → GEMINI_REAL_BUG
      - status == 'auto_triage_candidate' (real_bug=False) → GEMINI_UNRESOLVED
      - status == 'unavailable_quota' → GEMINI_UNAVAILABLE_QUOTA
      - status == 'timeout' → GEMINI_TIMEOUT
      - status == 'stale' → GEMINI_STALE
      - 그 외 → GEMINI_UNRESOLVED (보수적)
    r   rH   r  r-  r   r.  r0  r  r   r"  )
r7   r  r   r   r6   r<   r;   r8   r9   r:   )gemini_stater>  r   r  s       ru   classify_gemini_statusrA  "  s       x(.B557F!!,/52J~#j/Q.++%%(("*A0AA$$''rw   c                p    | xs g D ](  }t         D ]  }|j                  |      st        c c S  * t        S )u$   변경 파일 → risk_level 분류.)r@   r   RISK_LEVEL_HIGH_CORERISK_LEVEL_LOW)rU   r   pats      ru   assess_risk_levelrF  D  s>    " ,* 	,Czz!}++	,,
 rw   c                   g }| xs g D ]  }||z  }|j                         r|j                         s)	 |j                  dd      }t	        |j                         d      D ]U  \  }}d|v sd|v rt        D ]>  \  }}	|j                  |      s|j                  ||	||j                         dd	 d
       @ W  t        |      dk(  |dS # t        $ r Y w xY w)u   HIGH_CORE 시 변경 파일에 대해 위험 패턴 정적 검사.

    Returns:
      {"passed": bool, "violations": [{"file": str, "pattern": str, "line": int, "snippet": str}, ...]}
    utf-8replace)encodingr  r   )startRISKY_PATTERNSstatic_risky_pattern_scanN   )filepatternlinesnippetr   )passed
violations)existsis_file	read_textOSError	enumerate
splitlinesrL  r   r   r   r   )
rU   workspace_rootrT  relr+  r   linenorQ  rE  descs
             ru   rM  rM  N  s      J$" #{{}DLLN	>>79>ED &doo&7qA 	LFD4'+F$+N+ 	T::d#%% ##' &#'::<#5	' 		* *o**EE  		s   C	CCc        	   
     \   t        |       |dk(  |xs dj                         dk(  |xs dj                         dk(  t        |      t        |      t        |      |t        k7  xs t        |      d}	|	j                         D 
cg c]
  \  }
}|r	|
 }}
}t	        |      dk(  |	|dS c c}}
w )u   8조건 검사. 모두 PASS여야 fallback_review_passed=True.

    Returns:
      {"passed": bool, "checks": {각 조건: bool}, "failed": [str, ...]}
    r   rH   r  CLEAN)effective_diff_equals_expectedforbidden_path_zeroci_all_successmerge_state_cleanhead_sha_lock_oksmoke_command_defineddry_run_decision_pass#static_risky_scan_pass_if_high_core)rS  checksfailed)rb   r	  rC  itemsr   )diff_okforbidden_countrW   rZ   re  rf  rg  re   static_scan_passedri  kvrj  s                ru   evaluate_fallback_reviewrq  p  s    $ +/w-.!3$?113y@06B==?7J !12!%&;!<!%&;!<..J$7I2JF #LLN4DAq!a4F4&kQ&&FKK 5s   
B(B(c                <    |dddt        |       ddg      }	 t        j                  |j                  xs d      }|j                  d      xs dj                         |j                  d	d      |j                  d
d      dS # t        j                  $ r i }Y ^w xY w)Nr   r   r   r   z'mergeStateStatus,headRefOid,baseRefNamer   mergeStateStatusrH   
headRefOidbaseRefName)rs  rt  ru  rF   r  r  r   r  r  r	  )rJ   r   r   r  s       ru   fetch_merge_staterw    s    dFC	N; F**V]]2d3 %[[);<BIIKkk,3{{="5   s   #B BBc                &    t        |       xr | |k(  S rs   )rb   )	start_shacurrent_shas     ru   assert_head_sha_lockr{    s    	?7yK77rw   c                    dddt        |       ddg}t        |        ||      }|j                  |j                  xs ddd  |j                  xs ddd  dS )	Nr   r   r   z--squashz--delete-branchrH   0)r   r   r   )rF   r   r   r   r   )rJ   r   r   r   s       ru   execute_squash_merger~    sc    $Y=NOD!$'D\F''==&B/==&B/ rw   c                    | sdddS  || d      }|j                   dk(  rd|j                  xs dd	d  d
S d|j                  xs dd	d  |j                  xs dd	d  t        dS )Nskippedzno smoke_command in task spec)r   r   iX  )r   r   PASSrH   r}  )r   r   FAIL)r   r   r   r\   )r   r   r   CRITICAL_POST_MERGE_SMOKE)r   r   r   s      ru   r   r     s~     #0OPPM3/FA V]]-@b%&,IJJ==&B/==&B/2	 rw   c                   g }| D ]  }|j                  d      }|t        ||      }|j                  dd      }	 t        ||      }|j                  dg       xs g }|j                  dd      xs |j                  dd      }	|j                  dg       xs g }|j                  d	g       xs g }|r)t        t        |            t        t        |            k7  nd
}| xs# t        |      j                  t        |            }t        t        ||            }t        |j                  d      xr |j                  d      |	k7        }|dk(  xs |}|j                  |||dv xs
 |xs |xs ||dk(  |dk(  |dk(  |||||t!        |      d        |S # t        j                  t
        j                  t        f$ rJ}
t        j                  d||
       |j                  dg       xs g }|j                  dd      }	Y d}
~
d}
~
ww xY w)u  queue 다음 PR들의 BEHIND/conflict/diff 오염 자동 재평가 (task-2509+1 §9 보강).

    queue 항목 = {pr_number, expected_files?, prior_effective_files?,
                  prior_main_sha?, gemini_head_sha_at_last_review?}
    반환 = 각 PR별 state. 기존 키(needs_recheck/behind/conflict/blocked) 보존 +
            신규 키(effective_diff_drift/expected_files_maintained/forbidden_path_present/
                   gemini_stale/ci_rerun_needed/current_effective_files).
    rJ   Nrs  rH   rU   rt  z!observe_pr fallback for PR %s: %sprior_effective_filesrT   Fgemini_head_sha_at_last_reviewr   >   DIRTYr   BLOCKEDr  r  )rJ   rZ   needs_recheckbehindr   blockedeffective_diff_driftexpected_files_maintainedforbidden_path_presentgemini_staleci_rerun_neededcurrent_effective_files)r  rw  
observe_prr   SubprocessErrorr  r  rX  loggerdebugr   setissubsetrb   r   r   rk   )queuer   statesentryrJ   r   msobscurrent_effectivecurrent_headexcprior_effectiverT   
diff_driftexpected_subsetforbidden_presentr  ci_reruns                     ru   recheck_following_prsr    s>    F 0IIk*	 F3XX("-	6Y/C #(92 > D"77<4Rr8RL
  ))$;R@FB#3R8>B  3()*fS5I.JJ$) 	
   D$%..s>/BC 	 !!78I>!Z[II67 L		:;|K
 (N1z""$44 CC!2C6BHngY$.)8&7(''+,='>
 	A0b MK **D,@,@'J 	6LL<iM %		*A2 F L"88L"5L	6s   AF(H>?HHc                r   |ry t         j                  dd       t        j                  dd       t        j                  t
        j                        j                  d      | _        t        j                  | j                         d      dz   }t        t        dd	      5 }|j                  |       d d d        |r\t        | d
z  }t        |dd	      5 }t        j                  | j                         |dd       d d d        t!        |      | _        |S t        S # 1 sw Y   mxY w# 1 sw Y   -xY w)NT)parentsexist_okz%Y-%m-%dT%H:%M:%S.%fZFensure_ascii
r   rH  rJ  z.merge-queue.jsonwr   r  indent)	AUDIT_DIRmkdir
EVENTS_DIRr   nowr   utcstrftimer^   r  dumpsrv   openGLOBAL_AUDIT_LOGwritedumprF   r]   )rG   rL   no_auditrQ  fhper_tasks         ru   write_auditr    s	   
 OOD4O0TD1!hll3<<=TUH::h&&(u=DD	g	6 "
7)+< ==(C'2 	LbIIh&&("5K	L!(m 	L 	Ls   #D!(D-!D*-D6c                   | t         vrt        d|        | |_        |
 || |       y t        	 |j                  xs d|j
                  xs d| d|j                  |j                  | dd}t        |t        dd	      }t        |d
      r|j                  g |_
        |j                  j                  |       y y # t        $ r }t        j                  d|       Y d }~y d }~ww xY w)NzUNKNOWN_CRITICAL_CODE: unknownr   merge_queue_executor)rG   rI   r\   )rL   rJ   
event_typesourceevidenceTF)r[  dry_runr  rq   z7W5 report_critical_event() failed (silent fallback): %s)CRITICAL_CODES
ValueErrorr\   report_critical_eventrL   rJ   rG   rI   r   hasattrrq   r   	Exceptionr  warning)coderG   reporter_hook_event_result_w5_excs         ru   emit_critical_escalationr    s    
 >!24&9::!H dH% !,c'//<9!)!3!3!8q"&4$,$5$5"*//)-!
 0#, "	 x78;O;O;W+-H($$++G4- -.  cXZabbcs   B	B< <	C%C  C%z```yaml\s*\n(.*?)```c                   | j                  d      }d}t        j                  |      }|r|j                  d      }t	        |d      }t	        |d      }t        |d      }t        |d      xs d	}t        |d
      }	 |r|dk7  rt        |      n|xs d}	t        |d      xs d}
t        |d      xs d}t        j                  d|t        j                        }|r|j                  d      n| j                  }t        |||xs d|||	t        |
      j                         j                         dk(  t        |      j                         j                         dk(  d	      S # t        $ r |}	Y w xY w)uG   task md에서 expected_files / dependency / parallel_policy 등 추출.rH  r  rH   r   rT   r   r   r   serial_onlyr   zn/ar   falser   z^# (task-\d+(?:\+\d+)?)trueN)	rL   rT   r   r   r   r   r   r   r   )rW  _TASK_FRONTMATTER_REr   r   _extract_yaml_list_extract_yaml_scalarrX   r  r   	MULTILINEstemr   rF   r   r   )	task_filer   
yaml_blockr   rT   r   r   r   queue_pos_raw	queue_pos	stale_raw
cherry_rawtask_id_matchrL   s                 ru   load_task_specr  J  sm   0DJ##D)AWWQZ
'
4DEN#J=J$Z=I*:7HIZ]O(5KLM"/<RWAW]+]j]sns	 %Z1IJUgI%j2GHSGJII8$MM(5m!!!$9>>G%/r'&"9~335;;=G
O11399;vE
 
  "!	"s   >E" "E0/E0c                   dt        j                  |       d}t        j                  || t         j                        }|sg S g }|j	                  d      j                         D ]  }|j                         }|j                  d      s%|dd  j                         }|j                  d      r.|j                  dd      }|dkD  r|d| n|j                  d      }	nq|j                  d      r.|j                  dd      }|dkD  r|d| n|j                  d      }	n2|j                  d	d      d   j                         j                  d      }	|	s|j                  |	        |S )
N^z:\s*\n((?:\s*-\s*.+\n?)+)r   -"r   "''#)r   escaper   r  r   rZ  r   r   findsplitr   )
r  keyrP  r   rk  rQ  r   r   endvals
             ru   r  r  k  s7   299S>"";<G
		':r||4A	E
%%' JJL||C ekkm>>#((3"C #a#a*SYYu-=C^^C ((3"C #a#a*SYYu-=C))C#A&,,.44U;CLL Lrw   c                    dt        j                  |       d}t        j                  || t         j                        }|sy|j	                  d      j                         j                  d      }|S )Nr  z:\s*([^\n#]+?)(?:\s*#.*)?$rH   r   r  )r   r  r   r  r   r   )r  r  rP  r   r  s        ru   r  r    s\    299S>""<=G
		':r||4A
''!*



"
"5
)CJrw   c                  8   e Zd ZU  ed       Zded<   dZded<   dZded	<   d
Zded<   dZ	ded<   dZ
ded<   dZded<    ed       Zded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded <   dZded!<   dZded"<    ee      Zd#ed$<   d
Zded%<   y)&ExecutorContextc                     t         S rs   )r   r}   rw   ru   <lambda>zExecutorContext.<lambda>  s     rw   rQ   
RunnerTyper   NrK   r   r   r   Frb   r  Optional[Callable[[str], bool]]r   Optional[list[re.Pattern]]extra_forbidden_patternsfixture_main_shac                     y rs   r}   )_ss    ru   r  zExecutorContext.<lambda>  s    rw   )defaultCallable[[float], None]r  .Optional[Callable[[str, QueueDecision], None]]r  zOptional[Any]replacement_runnerzOptional[Callable]	triage_fnsmoke_envelope_fnOptional[Path]r  zOptional[list]triage_threadstriage_fix_commitstriage_pr_head_shark   following_queueapply_triage)ry   rz   r{   r   r   r|   r   r   r  r   r  r  r  r  r  r   r  r  r  r  r  rk   r  r  r}   rw   ru   r  r    s    /FGFJG $J$)-M&-Hd59M29;?8?&*m*',_'EG$EDHMAH(,,$(I!(,0)0 $I~$%)NN))--(,,!$7OT7L$rw   r  c                \   t        d| |j                  t        |j                        t        |            }t	        |      |_        t        |t              rt        |j                  d            nd}	t        ||	      |_        t        |j                  |j                  |j                        \  }
}|
s7t         |_        ddj%                  |       |_        |j"                  |_        |S h d	}|j*                  |vrft,        |_        d
|j*                  |_        t.        |_        t.        |_        t4         dt.         |_        t7        t.        ||j8                         |S |j:                  }|du xs3 t        |t<              xr! |j?                         jA                         dk(  }|rYt,        |_        d|_        t.        |_        t.        |_        t4         dt.         |_        t7        t.        ||j8                         |S |jB                  r|jB                  }ntE        |j                        }||_#        ||_$        |j                  d      xs djK                         }||_&        |dk(  r|jN                  rtQ        |j                  dd      |jN                  |j                  |      }|j                  d      r>t,        |_        d|_        tR        |_        tR        |_        t4         dtR         |_        |S tU        ||j                        \  }}}|sftW        ||j                  |jX                        }|r`t,        |_        d|_        ||_-        t\        |_        t\        |_        t4         dt\         |_        t7        t\        ||j8                         |S d|_/        ta        |dd      }|`	 |jc                  | |      }|jd                  rd|_3        |jh                  }tj        |_        g }|r|jm                  d|        |r|jm                  d|        |jm                  d| d       dd j%                  |       d!tn         |_        |j"                  |_        |S tp        }t,        |_        g }|r|jm                  d|        |r|jm                  d|        |jm                  d"|jr                          d#d j%                  |       |_        ||_        ||_        t4         d| |_        t7        |||j8                         |S tj        |_        g }|r|jm                  d|        |r|jm                  d|        dd j%                  |       d!tn         |_        |j"                  |_        |S tW        ||j                  |jX                        }|rEt,        |_        d%|_        ||_-        t\        |_        t\        |_        t4         dt\         |_        |S |j                  d&d      }||_=        |t|        k(  r7t|        |_        d'|j                  d(       |_        |j"                  |_        |S |t~        k(  r"t,        |_        d)|_        t         d*|_        |S ta        |d+d      }|	 d,dlA} ta        |d-d      xs g }!ta        |d.d      xs |}"ta        |d/d      xs g }#ta        |d0d      }$ || |!|"|#t        |j                        g |$|j                        }%t        |%      }|j                  d&      d1k(  rt        |      }d2|d&<   |%j                  | j                  |%j                        nd|_C        t        |t              rt        |j                  d            nd}&t        ||&      |_        |j                  d&d      }(t        |j                  d4g       xs g       |_F        |(d5k(  r>t,        |_        d6|_        t        |_        t        |_        t4         dt         |_        |S |(d7k(  r2t        |_        d8|j                   |_        |j"                  |_        |S |j                  t        v rHd|_J        |j
                  t        k(  rIt        |      })t        |)j                  d9      xs g       |_M        t        |)j                  d:            }*nd}*t        |d,|r|nd|dt        |j                        d|j
                  xs t        |*;	      }+|+|_Q        t        |+j                  d:            |_R        |+j                  d:      sgt,        |_        t         ddj%                  |+j                  d<      xs g        d=|j                   |_        d|_T        t         dt         |_        |S d|_T        n!|j                  t        k(  rd|_T        d|_J        |d>k7  r|d?k(  rYt,        |_        d@|_        tR        |_        tR        |_        t4         dtR         |_        t7        tR        ||j8                         |S |dk(  r"t,        |_        dA|_        t         dB|_        |S t        |_        dC| |_        |j"                  |_        |S |j                  s<t,        |_        dD|j                   dE|j                   |_        t         dF|_        |S t        |_        dG|_        |j"                  |_        |S # tt        $ r!}tv        jy                  d$|       Y d}~d}~ww xY w# tt        $ r!}'tv        jy                  d3|'       Y d}'~'d}'~'ww xY w)HuP   10조건 게이트 — 결과 decision 반환 (실제 머지 X, dry-run 가능).UNKNOWN)rG   rJ   rL   rT   rU   r>  Fr=  )r   z	pending: ,>   r  parallel_safelimited_parallelzINVALID_PARALLEL_POLICY: : Tr  z=cherry_pick_allowed=true is forbidden (DEPENDENCY_CYCLE risk)rs  rH   r   ru  main)r   r   r   rZ   r   MERGE_CONFLICT_DURING_BASE_SYNCFORBIDDEN_PATHevaluate_prr  Nzextra=zmissing=zreplacement PR #z createdzdiff contamination: z; z; hook=zreplacement_failed=z)diff contamination + replacement failed: z*W2 replacement_runner.execute() failed: %sFORBIDDEN_PATH_INSIDE_EXPECTEDr   zCI failure: r   r#   z: CI_IN_PROGRESSr   r   r  r  r  r  	completedr-  zW3 triage_fn() failed: %sr  r.  &GEMINI_REAL_BUG_OUTSIDE_EXPECTED_FILESr0  z,unresolved (auto_gemini_triage hook); count=rT  rS  )	rl  rm  rW   rZ   re  rf  rg  re   rn  rj  z; gemini_status=r`  r  MERGE_STATE_BLOCKEDMERGE_STATE_BEHIND_AFTER_SYNCz: MERGE_STATE_BEHIND_AFTER_SYNCzmergeStateStatus=z&REVIEW_GATE_NOT_PASSED: gemini_status=z; fallback_review_used=z: REVIEW_GATE_NOT_PASSEDzall 10 gates PASS)XrE   rL   rk   rT   rF  re   r   ri   rb   r  rA  ra   r   r   r   r   r   rG   r2  rI   rg   r   r    CRITICAL_DEPENDENCY_CYCLEr\   rh   FINAL_CRITICAL_PREFIXr  r  r   rF   r   r   r  r   rM   rO   r	  rZ   r   r   CRITICAL_BLOCK_OVERRIDEr   r   r  rV   CRITICAL_FORBIDDEN_PATHrm   getattrexecutesuccessrn   replacement_prr&   r   REPLACEMENT_PR_RUNNER_HOOK CRITICAL_DIFF_REPLACEMENT_FAILEDfailure_reasonr  r  r  rW   r"   r#   FINAL_BLOCKED_PREFIXdataclassesr   ro   r   r   rY   r4  r$   GEMINI_UNAVAILABLE_STATUSESrc   rC  rM  rl   rq  r   rD  rj   rd   rB   rf   r6   r%   r   ),rJ   	task_specpr_head_sharU   merge_stateci_stater@  ctxrG   _gem_real_bughead_okr   _VALID_PARALLEL_POLICIES_cherry_raw_cherry_boolmain_head_startr  syncrl  r   r   r   r   replacement_resultrepl_prreason_parts_r
_crit_codereason_parts_f_w2_excreason_partsrW   
_triage_fn_dc_triage_threads_triage_pr_head_sha_triage_fix_commits_apply_triage_triage_report_gem_real_bug2_w3_exc
gem_statusscanrn  fbs,                                               ru   r  r    s
    !!I445_-H ,O<H:D\SW:XD))*56^cM3L=YH 0

''GW
 3%chhw&7%89"*"3"3  T  (@@/5i6O6O5RS!:'@$%:$;2>W=X"Y !:HcFWFWX//Kt 	T{C(R[->->-@-F-F-HF-R  /Y!:'@$%:$;2>W=X"Y !:HcFWFWX ..)#**5#2H !,H //,
-
3	:	:	<B"$H	X~#.."}f=~~::!	
 88J 3H?HO%<H"+BH()>(?rBYAZ&[H#O 5_iF^F^_GUG*Y55s7S7S
	  3H.HO'0H$%<H"+BH()>(?rBYAZ&[H#$%<hHYHYZO "/2D9 V%+^^Iy%I"%--04H-0??G(FH%%'N&--ug.>?&--	.BC")),<WIX*NO(<TYY~=V<WW^_y^z&{HO.6.?.?H+#O "BJ(;H%%'N&--ug.>?&--	.BC")),?@R@a@a?b*cd(QRVR[R[\jRkQl&mHO-7H*3=H01F0Gr*.VH+,Z3CTCTU#O
 ;& 01(7) 450<1H0IQkPlm"*"3"3 '1133O3OI /:#, !8'>$%:$;2>U=V"W Xr*I"H$$,(i)@(AB"*"3"3N"/*%9$::J"K k40J	A%%c+;TBHbO")#/CT"J"Yk")#/CT"J"Pb#C?M'##Y--.!!	N 2.AL)[8#L1)-X&SaSpSpS|cjj1N1N&O  CGH#CMl\`CaT,"2"2:">?glN%;LSa%bH" !!(B/J'*<+;+;L"+M+SQS'TH$///B!@'F$%:$;2>]=^"_,,3HIiIiHjk"*"3"3 !<<(,%"66,_=D.2488L3I3OR.PH+!%dhhx&8!9!% &#,i"!!"&s'8'8"9"&**<n1

 +-'*.rvvh/?*@'vvh 3H)*"SXXbffX6F6L"-M,NN^_g_u_u^vw O +0H')=(>bAW@X&YH#O&*#			#3	3&*#(-% 
W}? 3H3HO%<H"+BH()>(?rBYAZ&[H#$%<hHYHYZO> 3H=HO)=(>>]&^H#O1-bT2"*"3"3 &&/4X5K5K4L M$$,$A$A#BD 	 &:$::R"S +H)HO&//HOO  VKWUUVN  	ANN6@@	As9   6B1k (B,k >Dl 	k>k99k>	l+
l&&l+c                   | j                   t        k7  r| S  ||      }|| _        t        | j                  xs d|      s5t
        | _         d| j                   d| | _        | j                   | _        | S |^ |       }|| _        | j                  rD|| j                  k7  r5t
        | _         d| j                   d| | _        | j                   | _        | S |s8|j                  s,t        | _         t        | _        t         dt         | _        | S |r| j                   | _        | S t        ||j                        }|d   dk7  r(t        | _         d	|d
    | _        t         d| _        | S |j                   N|j                  g d|j                          |j                  g d|j                         }	|	j"                  dk(  }
nd}
|
du rbd}|| _        t        | _         d| _        t&        | _        t&        | _        t,         dt&         | _        t/        t&        | |j0                         | S |
t3        |dd      }t3        |dd      }|||	 ||nt4        } ||| j                  xs | j                  xs dd|j                  |d      }t7        |j8                  d      r|j8                  j:                  nt=        |j8                        | _        |j?                         | _         |jB                  sYt        | _         d| _        t&        | _        t&        | _        t,         dt&         | _        t/        t&        | |j0                         | S nktK        |j                  |j                        }|jM                  dd      | _        |jM                  d      dk(  rt        | _         d| _        t&        | _        t&        | _        t,         dt&         | _        t/        t&        | |j0                         | S t3        |dd      }t3        |dd      }||| 	 ||nt4        } ||| j                  xs | j                  xs dd|j                  |d      }t7        |j8                  d      r|j8                  j:                  nt=        |j8                        | _        |j?                         | _         |jB                  sYt        | _         d| _        t&        | _        t&        | _        t,         dt&         | _        t/        t&        | |j0                         | S ntK        |j                  |j                        }|jM                  dd      | _        |jM                  d      dk(  rYt        | _         d| _        t&        | _        t&        | _        t,         dt&         | _        t/        t&        | |j0                         | S t3        |dg       xs g }|rtO        ||j                        }tQ        | jR                        |z   | _)        |D ]]  }|jM                  d      r	 t/        tT        | |j0                         |jM                  d!      sB	 t/        tV        | |j0                         _ tX        | _         d#| _        | j                   | _        | S # tD        $ r}tF        jI                  d|       tK        |j                  |j                        }|jM                  dd      | _        |jM                  d      dk(  r^t        | _         d| _        t&        | _        t&        | _        t,         dt&         | _        t/        t&        | |j0                         | cY d}~S Y d}~d}~ww xY w# tD        $ r}tF        jI                  d|       tK        |j                  |j                        }|jM                  dd      | _        |jM                  d      dk(  r^t        | _         d| _        t&        | _        t&        | _        t,         dt&         | _        t/        t&        | |j0                         | cY d}~S Y d}~qd}~ww xY w# tD        $ r!}tF        jI                  d |       Y d}~&d}~ww xY w# tD        $ r!}tF        jI                  d"|       Y d}~d}~ww xY w)$uU   §9 + §10 — head SHA 재확인 후 squash merge (dry_run=False 시 실제 실행).rH   zPR head changed: start=z merge=Nzmain head changed: start=r  r   r   zsquash merge failed: r   z: SQUASH_MERGE_FAILEDr   r   )r   r   z	--ff-onlyr   FFAIL_FAST_FORWARDz:POST_MERGE_SMOKE_FAILURE: fast-forward failed before smoker  r  T)r  merge_commitr  r   rJ   skip_stale_checkvaluezDPOST_MERGE_SMOKE_FAILURE (ff-only skipped: no pr_workdir) [envelope]z4W4 smoke_envelope_fn() failed (fallback to dict): %sr   r  z9POST_MERGE_SMOKE_FAILURE (ff-only skipped: no pr_workdir)z#POST_MERGE_SMOKE_FAILURE [envelope]r-   r  r  z)W6 forbidden_path_present emit failed: %sr  zW6 blocked emit failed: %szmerged + smoke PASS)-rG   r   rP   r{  rO   r!   rI   rg   rN   rM   r   r    rC   r"  r~  r   r   r   r[   r  r\   rh   r  r  r  r  run_pm_smoke_v2r  r   rH  rF   rv   rp   allow_continuationr  r  r  r   r  r  rk   r`   r  r  r   )rG   rJ   r)  fetch_pr_head_at_mergefetch_main_head_at_merger  pr_head_nowmain_nowmerge_result	ff_resultff_oksmoke_status_str_smoke_envelope_fn_task_file_path_envelope_fnenvelope_w4_excsmoke_smoke_envelope_fn2_task_file_path2_envelope_fn2	envelope2_w4b_exc_following_queuefollowing_states_fstate_w6_exc_w6b_excs                               ru   verify_head_lock_then_mergerc    s    ..(3K!,H : : @b+N0%h&@&@%AV 	 #+"3"3++-'/$''H8T8T,T 4H+H,H,H+IQYPZ[ O '/&7&7H#O3,,/<%9$:"=_<`"a"*"3"3'	3::>LL!Q&/1,x2H1IJ%9$::O"P ~~!

8cnn
MJJ8  
	 $$) ~. 0/V!:'@$%:$;2>W=X"Y !:HcFWFWX	 %S*=tD!#{D9*o.IOj$5G5S1Yh'-!)!=!=!cA]A]!cac!::'%) BIZaAb(=(=hkltl{l{h|%*2*:*:*<'22(;H%&lHO-FH*3LH01F0GrJcId.eH+,-FRURcRcd#O 3, )):):CJJGE$)IIh$;H!yy"f,$7!"])B&/H,-B,C2F_E`*a'()BHcN_N_` &c+>E"3T:+/?/KQaQm$7J7V 3\k).!)!=!=!cA]A]!cac!::'%)	 CJ)JZJZ\cBd	(8(8(>(>jmnwn~n~j%*3*;*;*=' 33(;H%&KHO-FH*3LH01F0GrJcId.eH+,-FRURcRcd#O 4, )):):CJJGE$)IIh$;H!yy"f,$7!"<)B&/H,-B,C2F_E`*a'()BHcN_N_` $+30A2#F#L"01A3::N%)(*D*D%EHX%X"' 
	KG{{34Y,-DhPSPaPab {{9%K,-DhPSPaPab
	K +H+HO&//HOA  $UW^_,S->->

K(-		(B(?%99X&&0(;H%&aHO-FH*3LH01F0GrJcId.eH+,-FRURcRcd#O 1	$b  $UW_`,S->->

K(-		(B(?%99X&&0(;H%&@HO-FH*3LH01F0GrJcId.eH+,-FRURcRcd#O 1	$H ! YNN#NPWXXY
 ! KNN#?JJKsp   C=Z	 C=] `5a"		]B9]]]	`2(B9`-!`2-`25	a>aa"	b+bbc                    |dddt        |       ddg      }	 t        j                  |j                  xs d      }|j                  d      xs g D cg c]&  }|j                  d      s|j                  dd	      ( }}|j                  d
d	      |j                  dd      |j                  d      xs d	j                         |dS # t        j                  $ r i }Y w xY wc c}w )Nr   r   r   r   z-headRefOid,baseRefName,mergeStateStatus,filesr   r   r+  rH   rt  ru  r  rs  )rt  ru  rs  rU   rv  )rJ   r   r   r  r   r   s         ru   r  r    s    dFC	NA F**V]]2d3 *1W)=)CV1fQUU62VEVkk,3{{=&9$[[);<BIIK 	   Vs   #C C#*C#C C c                &  
 t        j                  d      }|j                  dt        dd       |j                  dt        dd	
       |j                  dddd       |j                  dddd       |j                  ddd       |j                  dt        dd
       |j                  dt        t	        t
              d
       |j                  dt        dd
       |j                  dt        dd 
       |j                  |       }|j                  rt        |j                        }n(t        t        j                  t        d!d"d#$             y%|j                         s+t        t        j                  t        d&| d"d#$             y%t        |      }t         
t#        |j$                  
      }t'        |j$                  
|j(                  |j*                  '      }t-        |j$                  
|j.                        }t1        
t	        t
              |j2                  r|j2                  j5                         nd |j6                  t8        t9        
|j:                  (      nd t<        t<        nd t>        t>        nd |)      }tA        |j$                  ||jC                  d*d      |jC                  d+g       |jC                  d,d      |jC                  d-d.      d/|||0      }	tE        |	|j$                  |
fd1
fd2|j:                  3      }	tG        |	|jH                  |j6                  4       t        t        j                  |	jK                         d#d%5             |	jL                  tN        tP        hv ry6|	jL                  tR        k(  ry7y8)9Nz merge_queue_executor (task-2509))descriptionz--prTu	   PR 번호)typerequiredhelpz--task-filerH   u   queue 선두 task spec md)rg  r  ri  z	--dry-run
store_truezdry-run (default true))actionr  ri  z--no-dry-runr  store_falseu   실제 머지 수행)destrk  ri  z
--no-auditu'   audit log 기록 안 함 (테스트용))rk  ri  z--smoke-commandu   post-merge smoke 명령z--workspacezworkspace rootz--ci-max-polls   u+   CI 상태 polling 최대 횟수 (default 5)z--ci-backoff-secondsg      $@u4   CI polling 지수 백오프 기본값 (default 10.0)zmissing --task-file)rG   rI   Fr  r   ztask file not found: )r  r  )r   r  )r   r   r   r  r  r   r  r  rt  rU   rs  ru  r  )rs  ru  )rJ   r%  r&  rU   r'  r(  r@  r)  c                <    t        |       j                  dd      S )Nrt  rH   )r  r  )r9  r   s    ru   r  zmain.<locals>.<lambda>  s    Av)>)B)B<QS)T rw   c                     t               S rs   )r   )r   s   ru   r  zmain.<locals>.<lambda>  s    )@ rw   )rG   rJ   r)  rK  rL  r  )r  r  r      r   )*argparseArgumentParseradd_argumentrX   rF   r   float
parse_argsr  r	   printr  r  r    rU  r  r   r  r   r  ci_max_pollsci_backoff_secondsr<  rT   r  r   r  r  r   r  r   rI  r  r  rc  r  rL   rv   rG   r   r   r   )argvparserr   	task_pathr   pr_obscigemr)  rG   r   s             @ru   r  r    s+   $$1STF
S4kJ
CB]^
L$Mef
Y}Sij
\@ij
)RF_`
CYN^_
(sADqr
.UD  PF  GT"D ~~(	 	djj++
  	  djj+-i[9
  	  )$DF(F	&D4E4EW[WnWn	oB
dggvt/B/B
CC
y>484F4Fd((..0DWjWv.fdllS  }A(4)$-<-H/d
C ''JJ|R0

#4b9 &

+=r B!::mV<
 H +''T!@H $,,?	$**X%%'eA
FG/1CDD33rw   __main__)N<   )r   rS   r   rK   r   rX   rx   zsubprocess.CompletedProcess)r   rS   rx   Noners   )r   rS   r   r  r   r  rx   ztuple[bool, list[str]])r   r  rx   rF   )
r   rF   r   rF   r   r  rZ   rF   rx   ri   )r   rS   rx   zset[str])rU   rS   rT   rS   rx   z!tuple[bool, list[str], list[str]])rU   rS   r   rS   r   r  rx   rS   )rJ   rX   r   r  r  rX   r  ru  r  r  rx   ri   )rJ   rX   r   r  rT   rS   rx   ri   )r@  ri   r>  rb   rx   rF   )rU   rS   rx   rF   )rU   rS   r[  r	   rx   ri   )rl  rb   rm  rX   rW   rF   rZ   rF   re  rb   rf  rb   rg  rb   re   rF   rn  rb   rx   ri   )rJ   rX   r   r  rx   ri   )ry  rF   rz  rF   rx   rb   )r   r   r   r  rx   ri   )r  r_   r   r  rx   r_   )F)rG   rE   rL   rK   r  rb   rx   r  )r  rF   rG   rE   r  r  rx   r  )r  r	   rx   r   )r  rF   r  rF   rx   rS   )r  rF   r  rF   rx   rF   )rJ   rX   r%  r   r&  rF   rU   rS   r'  ri   r(  ri   r@  ri   r)  r  rx   rE   )NT)rG   rE   rJ   rX   r)  r  rK  zCallable[[int], str]rL  zOptional[Callable[[], str]]r  rb   rx   rE   )rz  r   rx   rX   )r   
__future__r   rr  r  loggingosr   r   systimer#  r   r   r   r   r   pathlibr	   typingr
   r   r   environr  r   r  r  r  	getLoggerry   r  utils.replacement_pr_runnerr   utils.auto_gemini_triager   r   r   utils.post_merge_smoke_runnerr   rI  r   r   "utils.critical_escalation_reporterr   r  r   utils.automation_contractsr   r   r   r   _WIRING_AVAILABLEImportError_wiring_import_errr  __wiring_exports__r   r   r   r    r!   r"   r#   r$   r%   r&   r  r   r4  r  r  CRITICAL_REPLACEMENT_FAILEDr  r  r   r  r5  POST_MERGE_SMOKE_HOOKr3  r6   r7   r8   r9   r:   r;   r<   	frozensetGEMINI_STATUS_VALUESr$  rD  RISK_LEVEL_MEDIUMrC  compiler@   r|   rL  FINAL_AUTO_MERGE_ALLOWEDr"  r  rB   rC   rE   r   CompletedProcessr  r   r   r   r   r   r   r   r   r   sleepr  r<  rA  rF  rM  rq  rw  r{  r~  r  r  r  DOTALLr  r  r  r  r  r  rc  r  r  exitr}   rw   ru   <module>r     s  $L #    	 	  
  0 0 '  * * 02GHI	!H,
 #88	22 			8	$"?XX 
  *  & * ) 3 + - % !3 / !A  4 #T  "C J F : 6  $# I  5 . 1 9  & ' 5 !#1  ')AL/3I"   (nl)    "  BJJ23BJJ12BJJ !BJJ,-	- )  RZZ)*L9RZZ&'):;RZZ./1ABRZZ&'7RZZ./1EFRZZ346JK . , - 1 %I " & & &R . . . c:6667
/ 6:((( 3( 	(B  	
 
:3CCC 'C( BJJ&'BJJ)*BJJ,-BJJ+,BJJ)*  26 / 	2  '+zz"@"@"@ "@ 	"@
 %"@ 
"@LSSS S 
	Sl DI D %FFF 
FDLL L 	L
 L L  L  L L L 
LD"8
& 
$>>> >J   	4 EI$c
$c$c B$c 
	$cP "rzz"9299E B0   ,rrr r 	r
 r r r 
r rt	 =AAAA 
A 1	A
 :A A AJ&IX zCHHTV Y-  
LL68JKI!LOK !s   0O) )P'..P""P'