
    \iu                   8   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 ddlmZ ddlmZmZmZ  e ee      j*                        Zee	j.                  vre	j.                  j1                  de        eej2                  j5                  dd            Zed	z  d
z  Zed	z  dz  Zedz  dz  Zedz  dz  Zedz  dz  Z edz  dz  dz  Z!dZ"dZ#de$d<   dZ%de$d<   i dh ddddhdddhddhdh dd dd!hd!d"hd"h d#d$d%d"hd%h d&d'h d(d)d*d"hd+h d,d*h d-d.h d/d0d1hd1 e&        e&        e&        e&       h d2h d3d"d4hd5Z'd6e$d7<   h d8Z(d9e$d:<   dyd;Z)dyd<Z*dzd=Z+d{d>Z,d{d?Z-d|d@Z.d}dAZ/ed|dB       Z0ed~dC       Z0dDdEd~dFZ0ddGZ1dddDdH	 	 	 	 	 ddIZ2ddJZ3dddKZ4ddLZ5ddMddN	 	 	 ddOZ6ddPZ7ddQZ8ddRZ9	 	 	 	 	 	 	 	 	 	 	 	 ddSZ:ddTZ;ddUZ<ddVZ=ddWZ>ddXZ?d|dYZ@ddZZAdd[ZBdd\ZC	 d	 	 	 dd]ZDdd^ZEdd_ZFdd`ZGddaZHddbZIddcZJdddZKddeZLddfZMddgZNddhZOddiZPddjZQddkZRddlZSddmZTddnZUddoZVddpZWddqZXddrZYddsZZddtZ[dduZ\ddvZ]dddwZ^e_dxk(  r e	j                   e^              yy)u_  
taskctl.py — main 진입 단일화 + 상태 enforcement layer (task-2467 Phase A+B 통합)

회장 절대 기준:
    "taskctl을 거치지 않고는 main을 절대 변경할 수 없다."
    "모든 PR은 bot이 생성하고, 인간은 승인만 하며, main 반영은 taskctl만 수행한다."

상태 모델 (14정상 + 5예외 = 19종):
    정상: CREATED → WORKTREE_READY → RUNNING → [HANDOFF_READY →] COMMITTED
          → PR_OPEN → CI_PENDING → GEMINI_PENDING → REVIEW_READY → VERIFIED
          → HUMAN_APPROVED → MERGING → MERGED → DONE
    예외: BLOCKED / CANCELLED / FAILED / ESCALATED / ADMIN_OVERRIDE_USED
    호환: DISPATCHED / ACKED / GUARD_PASS (기존 11상태 backwards-compat)

저장 위치:
    {WORKSPACE}/.tasks/state/<task-id>.json

Evidence:
    {WORKSPACE}/.tasks/evidence/<task-id>/<name>.json

bypass (회장 전용):
    TASKCTL_BYPASS=1 환경변수로 skip. evidence에 강제 기록.

종료 코드:
    0   PASS / 정상 전이
    1   FAIL (가드 차단, 잘못된 전이, evidence 미달, etc.)
    2   internal error (subprocess 실행 실패 등)
    )annotationsN)datetimetimezone)Path)AnyNoReturnoverloadWORKSPACE_ROOTz/home/jay/workspace.tasksstateevidencescriptszguard.shzqc_report_guard.pyzgemini_evidence_verify.pymemoryzorchestration-auditzadmin-override.jsonl)zjonghyuk.jeon@gmail.com)zcancel-kill-switchzqc-checkzhidden-path-auditzlock-in-checkzmerge-safety-checkzgemini-review-gatezci/guardguardztuple[str, ...]REQUIRED_CHECKS)CREATEDWORKTREE_READYRUNNINGHANDOFF_READY	COMMITTEDPR_OPEN
CI_PENDINGGEMINI_PENDINGREVIEW_READYVERIFIEDHUMAN_APPROVEDMERGINGMERGEDDONEBLOCKEDRECOVERABLE_BLOCKED	CANCELLEDFAILED	ESCALATEDADMIN_OVERRIDE_USED
DISPATCHEDACKED
GUARD_PASSSTATESr      r'   r&   r   r&   r'   r   r   >   r   r   r   r   r   r   >   r   r   r   r(   r   r   >   r    r   r   r   >   r    r   r   r(   r   r   r(   >   r   r   r   >   r   r   r   r   >   r#   r   r!   r   r   >   r#   r   r"   r$   >   r#   r   r   r$   r%   )r"   r#   r%   r    r!   r$   zdict[str, set[str]]ALLOWED_TRANSITIONS>   r   r#   r"   r%   zset[str]TERMINAL_STATESc                 f    t        j                  t        j                        j	                  d      S )N%Y-%m-%dT%H:%M:%SZ)r   nowr   utcstrftime     @/home/jay/workspace/.worktrees/task-2507-dev5/scripts/taskctl.py_nowr5      s!    <<%../CDDr3   c            	     H   	 t        j                         } 	 t        j                  g ddddt        t                    j                  j                         xs d}|  d| d	S # t        $ r# t        j                  j                  dd      } Y yw xY w# t        $ r d}Y Dw xY w)
NUSERunknowngitconfigz
user.emailT   capture_outputtexttimeoutcwdzunknown@localz <>)getpassgetuser	Exceptionosenvironget
subprocessrunstr	WORKSPACEstdoutstrip)useremails     r4   _actorrQ      s    1  +dA3y>
 &, , 	 V2eWA  1zz~~fi01    s#   A$ AB $)BBB! B!c                    t         |  dz  S )N.json)	STATE_DIRtask_ids    r4   _state_pathrW      s    '%(((r3   c                    | j                         D ci c]  \  }}|dk7  s|| }}}t        j                  |ddd      S c c}}w )N	_checksumFT),:)ensure_ascii	sort_keys
separators)itemsjsondumps)r   kvpayloads       r4   _canonical_jsonre      sE     %B1k1Aq!tBGB::gETjYY Cs
   AAc                x    t        j                  t        |       j                  d            j	                         S )Nutf-8)hashlibsha256re   encode	hexdigest)r   s    r4   _compute_checksumrl      s*    >>/%077@AKKMMr3   c                @    | dg d g d d d i d d d i d
ddd d ddd d d d ddS )Nr   )
git_diff_shachanged_pathsbranch	pr_numberpr_state	ci_checksguard_sh_resultqc_report_guard_resultmerge_timestamp
exit_codesFusedtsactorry   rz   r{   reasonaudit_log_offset)rV   current_statetransitionsr   human_approvedbypassadmin_overrider2   rU   s    r4   
_new_stater      s[    " #&*#
   t< $
% r3   c                $   t         j                  dd       | j                  dd        t        |       | d<   t	        | d         }|j                  d      }|j                  t        j                  | dd      d	
       |j                  |       y )NTparentsexist_okrY   rV   z	.json.tmpF   r\   indentrg   encoding)
rT   mkdirpoprl   rW   with_suffix
write_textr`   ra   replace)r   ptmps      r4   _saver      st    OOD4O0	IIk4 *51E+E)$%A
--
$CNN4::e%BWNUKKNr3   c                     y Nr2   rU   s    r4   _loadr      s    +.r3   c                    y r   r2   )rV   allow_missings     r4   r   r      s    JMr3   Fr   c          	     ~   t        |       }|j                         s|ry t        d| d|  dd       	 t        j                  |j                  d            }j                  d	d       }t        |      }||k7  rt        d
|  d| d| dd       ||d	<   |S # t        $ r}t        d| d| d       Y d }~_d }~ww xY w)Nu   state 파일 없음: u    (먼저 'taskctl init u	   ' 실행)   rg   r   u   state 파일 파싱 실패:     → rY   uJ   checksum 불일치: 외부 수정 의심 (state file tampered).
  task_id=z

  stored=z
  expected=u0   
  → taskctl만 상태 변경 가능합니다.)	rW   exists_dier`   loads	read_textrE   r   rl   )rV   r   r   r   excstoredexpecteds          r4   r   r      s    GA88:$QC'>wiyQSTU>

1;;;89 YY{D)F 'H 	 "x  " $>?
 	
  E+L  >+A3eC591==>s   %B 	B< B77B<c                r   t         | z  }|j                  dd       dj                  t        j                        t               t               t        j                         d}|j                  |       || dz  }t        j                  t        |      d      \  }}	 t        j                  |dd	
      5 }t        j                  ||dd       ddd       t        j                   |t        |             y# 1 sw Y   )xY w# t"        $ r' 	 t        j$                  |        # t&        $ r Y  w xY ww xY w)uA   9종 evidence를 .tasks/evidence/<task-id>/<name>.json에 기록.Tr    )commandr{   	timestamppidrS   .tmpdirsuffixwrg   r   Fr   r   N)EVIDENCE_DIRr   joinsysargvrQ   r5   rF   getpidupdatetempfilemkstemprK   fdopenr`   dumpr   rE   unlinkOSError)	rV   namerd   ev_dirrecordpathfdtmp_pathfs	            r4   _save_evidencer     s   G#F
LLL-88CHH%Vyy{	F MM'tfEN"D##FFCLB	YYr31 	?QIIfaeA>	?


8SY'	? 	?  	IIh 	  		sH    D 8C:'D :D?D 	D6D&%D6&	D2/D61D22D6r{   metaforcec          
        | d   }|rn{||k(  r|dv rnq|dv r|t         v ret        d| d| dd       nQt        ||       t        j	                  |t                     }||vr#t        d| d| dt        |      xs d	 d
d       || d<   | j	                  dd      }||t               |xs ddj                  t        j                        dt        t        |z        d}|rd|d<   |r||d<   | d   j                  |       y )Nr   >   r   >   r#   r    r"   r$   r!   u   비정상 전이: r   u&    (terminal 상태에서 전이 불가)r   u
    (허용: none)rV   r8   taskctlr   r   fromtorz   r{   r   	exit_codeevidence_pathTforcedr   r   )r,   r   _check_forbidden_transitionsr+   rH   setsortedr5   r   r   r   rK   r   append)	r   targetr{   r   r   srcallowedrV   entrys	            r4   _transitionr   $  s,    
 C	36[0	Y	Y/!%cU%x7]^`ab 	%S&1%))#su5 $SEvhjAZTZ@[[\] $E/ii	9-Gf#)88CHH%\G34E hf	-&r3   c                B   |dk(  r| dvrt        d|  dd       |dk(  r| dvrt        d|  dd       |d	k(  r| dk7  rt        d|  d
d       |dk(  r| dk7  rt        d|  dd       | dk(  r|t               vrt        d| dd       | dk(  r|d	k(  rt        dd       yyy)u<   6개 금지 전이를 명시적으로 차단 (회장 §3.9).r   >   r   r   r(   r   u   금지 전이: uF    → VERIFIED (반드시 REVIEW_READY 또는 GUARD_PASS 상태 필요)r   r      r   r(   u>    → HUMAN_APPROVED (VERIFIED 또는 GUARD_PASS 상태 필요)r   u+    → MERGING (HUMAN_APPROVED 상태 필요)r   r   u     → DONE (MERGED 상태 필요)r"   u   금지 전이: CANCELLED → u    (CANCELLED는 terminal 상태)r    uF   금지 전이: BLOCKED → MERGING (BLOCKED 상태에서 merge 차단)N)r   r   )r   r   s     r4   r   r   L  s     +` `cU"hi	

 !!c1K&KcU"`a	

 s&66cU"MN	

 C8OcU"BC	

 kfCE1+F83RS	

 iFi/T	
 0r3   c                j    t        d|  t        j                         t        j                  |       y )N
[taskctl] file)printr   stderrexit)msgcodes     r4   r   r   y  s"    	Jse
3::.HHTNr3   c                     t        d|         y )Nr   )r   )r   s    r4   	_print_okr   ~  s    	Jse
r3   x   )rA   r@   envc          
         |}|2t         j                  j                  d      }|rt        |      nt        }t        j                  | dd|t        |      i t         j                  |xs i       S )NTASKCTL_CWDTr>   r?   r@   rA   r   )rF   rG   rH   r   rL   rI   rJ   rK   )cmdrA   r@   r   
actual_cwdenv_cwds         r4   _runr     sg     J**../&-T']9
>>
O)rzz)ciR) r3   c                    dD ]'  } t         j                  j                  |       }|s%|c S  t        dz  }|j	                         r	 |j                  d      j                         D ]_  }dD ]X  }|j                  |      s|j                  dd      d   j                         j                  d      j                  d	      c c S  a 	 y y # t        $ r Y y w xY w)
N)BOT_GITHUB_TOKENGH_BOT_TOKENz	.env.keysrg   r   )zBOT_GITHUB_TOKEN=zGH_BOT_TOKEN==r   "')rF   rG   rH   rL   r   r   
splitlines
startswithsplitrN   rE   )env_nametokenv_keyslineprefixs        r4   _load_bot_tokenr     s    8 jjnnX&J ;&H	 **G*<GGI SD SFv.#zz#q1!4::<BB3GMMcRRSS   		s   9C AC C 	CCc            	     v   	 t        j                  g ddddt        t                    j                  j                         } t        j                  j                  ddj                  t                    j                  d      }| |D cg c]  }|j                          c}v S # t        $ r d} Y ow xY wc c}w )Nr9   Tr<   r=    CHAIRMAN_EMAILSrZ   )rI   rJ   rK   rL   rM   rN   rE   rF   rG   rH   r   r  r   )rP   r   es      r4   _verify_chairmanr    s    +dA3y>
 & 	 jjnn.0IJPPQTUG01QWWY000   1s   AB% 
B6%B32B3c                     t         j                         syt        j                  t        j
                        } d\  }}t         j                  d      j                         D ]  }|j                         s	 t        j                  |      }|j                  dd      }t        j                  |j                  dd            }| |z
  j                  }|d	k  r|d
z  }|dk  r|d
z  } |dk\  r||dfS |dk\  r||dfS ||dfS # t        $ r Y w xY w)zWreturns (soft_count_30d, hard_count_90d, status: OK|SOFT_CAP_WARNING|HARD_CAP_EXCEEDED))r   r   OK)r   r   rg   r   rz   r   Zz+00:00   r   Z   r<   HARD_CAP_EXCEEDED   SOFT_CAP_WARNINGr  )ADMIN_OVERRIDE_LOGr   r   r/   r   r0   r   r   rN   r`   r   rH   fromisoformatr   daysrE   )r/   softhardr   rects_strrz   deltas           r4   _check_admin_capr    s   $$&
,,x||
$CJD$",,g,>IIK zz|
	**T"CWWT2&F''sH(EFB2XOOE{	{	 qyT...qyT---t  		s   7A/D	DDc           
     @   t         j                  j                  dd       t               \  }}}t	               | |d||||dz   |dz   d	}t         j                  dd      5 }	|	j                  t        j                  |d	
      dz          d d d        y # 1 sw Y   y xY w)NTr   chairmanr   )	rz   rV   rq   r{   r}   head_shabypassed_checkssoft_count_this_monthhard_count_this_quarterarg   r   Fr\   
)	r  parentr   r  r5   openwriter`   ra   )
rV   rq   r}   r  r  r  r  _r  r   s
             r4   _record_admin_overrider"    s     ##D4#@$&MD$f*!%#'!8
C 
	 	 w	 	7 <1	

3U3d:;< < <s   !*BBc                 H    t         j                  j                  dd      dk(  S )NTASKCTL_BYPASSr   1)rF   rG   rH   r2   r3   r4   _bypass_activer&    s    ::>>*B/366r3   c                   t        dddt        |       ddgd      }|j                  dk7  rd	|j                  d
d j	                         iS 	 t        j                  |j                  xs d      S # t
        j                  $ r d	dicY S w xY w)u   gh pr view로 PR 정보 조회.ghprview--jsonzEstate,mergeable,mergeStateStatus,statusCheckRollup,author,headRefNamer  r@   r   errorN{}json_parse_failed)	r   rK   
returncoder   rN   r`   r   rM   JSONDecodeError)rq   procs     r4   _gh_pr_viewr4    s    dFC	NY D !TU+11344.zz$++-.. .,--.s   "A/ /B	B	c            
        t        g d      j                  j                         } t        g d      }|j                  j                         D cg c]  }|j                         s| }}t        g d      j                  j                         }t        g d      j                  }| xs d |xs d |t	        |j                         D cg c]  }|j                         sd c}      dS c c}w c c}w )N)r:   	rev-parsez--abbrev-refHEAD)r:   diffzorigin/main..HEADz--name-only)r:   r6  r7  )r:   statusz--porcelainr   )rp   rn   ro   git_status_porcelain_lines)r   rM   rN   r   len)rp   r8  r   changeddiff_sha	porcelainlns          r4   _collect_git_evidencer@    s    >?FFLLNFCDD++002@Qaggiq@G@0188>>@H56==I.D (D &)y7K7K7M*\QSQYQYQ[1*\&]	  A +]s   C,%C,	C1C1c                &   | sd i d d ddS t        dddt        |       ddgd	      }|j                  d
k7  r'd i d d |j                  dd  j	                         xs ddS 	 t        j                  |j                  xs d      }|j                  d      xs g }i }|D ]m  }|j                  d      xs |j                  d      xs d}|j                  d      xs( |j                  d      xs |j                  d      xs d}|si|||<   o t        D 	ci c]  }	|	|j                  |	d       }
}	|j                  d      |
||j                  d      |j                  d      dS # t
        j                  $ r}d i d d d| dcY d }~S d }~ww xY wc c}	w )Nno_pr_number)rr   rs   	mergeablemerge_state_statuspr_view_errorr(  r)  r*  r+  z2state,mergeable,mergeStateStatus,statusCheckRollupr  r,  r   r.  gh_errorr/  zjson_parse: statusCheckRollupr   contextr   
conclusionr   r9  UNKNOWNMISSINGrC  mergeStateStatus)rr   rs   ci_checks_allrC  rD  )r   rK   r1  r   rN   r`   r   rM   r2  rH   r   )rq   r3  datar   rollupci_mapchkr   rI  nrequired_maps              r4   _collect_pr_evidencerT    s    r&*^M 	MdFC	NF D ! r&*!%TU!3!9!9!;!IzK 	KSzz$++-. XX)*0bFF &wwv:#'')"4:ggl+ 8swww/? 8*8.7 	%F4L& :IIAAvzz!Y//ILIHHW%!XXk*"hh'9:   S r&*|C5=QS 	SS Js$   #E# F#F6
F FFc                    t         j                         sddddS t        dt        t               | |gd      }|j                  dk(  rd	nd
|j                  |j
                  dd  |j                  dd  dS )NrK     zguard.sh not foundresultr   r   bash   r,  r   PASSFAILrX  r   stdout_tailstderr_tail)GUARD_SHr   r   rK   r1  rM   r   )stagerV   r3  s      r4   _run_guard_shrc  B  sp    ??##AUVVXw7ED OOq0&f__{{45){{45)	 r3   c           
        t         j                         sddddS t        dt        t               d| dt        t              gd	      }|j
                  d
k(  rdnd|j
                  |j                  dd  |j                  dd  dS )NrK  rV  zqc_report_guard.py not foundrW  python3z	--task-idz--workspacer   r,  r   r[  r\  r]  r^  )QC_REPORT_GUARDr   r   rK   rL   r1  rM   r   )rV   r3  s     r4   _run_qc_report_guardrg  N  s    !!###A_``	C(+wsS\~^D
 !OOq0&f__{{45){{45)	 r3   c                H    | syt        d | j                         D              S )NFc              3  &   K   | ]	  }|d k(    yw)SUCCESSNr2   ).0rc   s     r4   	<genexpr>z,_all_required_checks_pass.<locals>.<genexpr>`  s     :!qI~:s   )allvalues)rs   s    r4   _all_required_checks_passro  ]  s"    :y'7'7'9:::r3   c                   | j                   j                  dd       t        j                  t	        | j                         d      \  }}	 t        j                  |dd      5 }t        j                  ||dd	
       ddd       t        j                  |t	        |              y# 1 sw Y   )xY w# t        $ r' 	 t        j                  |        # t        $ r Y  w xY ww xY w)u1   tempfile + os.replace 를 이용한 atomic write.Tr   r   r   r   rg   r   Fr   r   N)r  r   r   r   rK   rF   r   r`   r   r   rE   r   r   )r   rN  r   r   r   s        r4   _atomic_writerq  h  s    KKdT2##DKK(8HLB	YYr31 	=QIIdAE!<	=


8SY'	= 	=  	IIh 	  		sH   B2 $B&>'B2 &B/+B2 2	C"<CC"	CC"CC"c                   t        | j                        }|j                         rt        d| j                          yt	        | j                        }|d   j                  d dt               t               dj                  t        j                        dt        t        | j                  z        d       t        |       t               }t        | j                  ddj                  t        j                        t               t               |j!                  d      |j!                  d	      d
d
d|j!                  d	      d d
       t        d| j                   d| d       y)Nzalready initialized: r   r   r   r   r   startrp   rn   r   )
r   r{   rz   rp   r  rM   r   r   sharq   zinit u    → CREATED (r   )rW   rV   r   r   r   r   r5   rQ   r   r   r   rK   r   r   r@  r   rH   )argsr   r   git_evs       r4   cmd_initrw  }  s   DLL!Axxz)$,,89t||$E	-ITVfh88CHH%A\DLL89! 
 
%L"$F4<<88CHH%f**X&JJ~.zz.)+  dll^>!A67r3   c                    t        | j                        }t        ||t               |       t	        |       t        | j                   d|        y)Nr{   r   u   : → r   r   rV   r   rQ   r   r   )ru  r   r   r   s       r4   _simple_transition_cmdr{    sA    $,,EvVXD9	%LfVH-.r3   c                    t        | d      S )Nr&   r{  ru  s    r4   cmd_dispatchr    s    !$55r3   c                    t        | d      S )Nr'   r}  r~  s    r4   cmd_ackr    s    !$00r3   c                &   t        | j                        }|d   }|dv r:t        |dt                      t	        |       t        | j                   d       yt        |dt                      t	        |       t        | j                   d       y)Nr   r*   r   r{   u   : → RUNNINGr   rz  ru  r   r   s      r4   cmd_runr    sy    $,,E

 C
77E9FH5eT\\N-01y1	%Lm,-r3   c                    t        | d      S )u<   worktree-ready: CREATED/DISPATCHED/ACKED → WORKTREE_READY.r   r}  r~  s    r4   cmd_worktree_readyr    s    !$(899r3   c                    t        | j                        }|d   dk7  rt        d|d    dd       t        |dt	                      t        |       t        | j                   d       y	)
u#   handoff: RUNNING → HANDOFF_READY.r   r   u   handoff 불가: 현재 상태=u    (RUNNING 필요)r   r   r  u   : → HANDOFF_READYr   r   rV   r   r   rQ   r   r   ru  r   s     r4   cmd_handoffr    se    $,,E_*-eO.D-EEVWYZ[fh7	%L123r3   c                .   t        | j                        }|d   }|dvrt        d| dd       t               }|j	                  d      xs d}t        | j                  d||j	                  d	g       ||j	                  d
      ddd||d   j	                  d      d	       ||d   d<   |j	                  d
      |d   d
<   |j	                  d	g       |d   d	<   t        |dt                      t        |       t        | j                   d|dd  d       y)uC   commit: RUNNING/HANDOFF_READY → COMMITTED + commit.json evidence.r   >   r   r   u   commit 불가: 현재 상태=u&    (RUNNING 또는 HANDOFF_READY 필요)r   rn   r   commitro   rp   r   r   rq   )	rn   ro   commit_hashrp   rM   r   r   rt  rq   r   r  u   : → COMMITTED (sha=N   r   )
r   rV   r   r@  rH   r   r   rQ   r   r   )ru  r   r   rv  r  s        r4   
cmd_commitr    s#   $,,E

 C
..,SE1WXZ[\"$Fzz.)/RH4<< OR8**X&:&**;7
, 
 )1E*n%"(**X"6E*h)/OR)HE*o&{&(3	%L3HRaL>CDr3   c                   t        | j                        }|d   }|dvrt        d| dd       d}d}d}d}d}d}d	}	t               }
|
j	                  d
      xs d}|
j	                  d      xs d}t        | dd      rt               }|sOt        | j                  ddddd|ddd       t        |dt               ddi       t        |       t        dd       | j                  }d| j                   d| }d| j                   d}i }|r||d<   d}	ddd d!|d"|g}t        ||d#$      }|j                  j                         }|j                  j                         }|j                  }|j                  dk7  rt        ddd%|d&d'g|d($      }|j                  dk(  rj	 t!        j"                  |j                        }|j	                  d)      }|j	                  d*d      }|j	                  d+      xs i j	                  d,d      }d}|t        | j                  dd-| |j                  |||dd.       t        d-| d       n|}t        ddd%|d&d'g|d($      }|j                  dk(  rh	 t!        j"                  |j                        }|j	                  d)      }|j	                  d*|      }|j	                  d+      xs i j	                  d,d      }d/}|xs d}|j'                  d0      j)                  d1      }|j+                  d1      xs |j-                  d0      xs ||v }|st        | j                  dd2|d3| d4d|d5| |||d6d7       t        |dt               d8|d9       t        |       t        d:|d;d       n't        | dd      st        d<d       | j.                  }d	}	|r||d=   d><   t        |d?t               d|i       t        g d@      j                  j                         xs d}t        | j                  d| j                  ||||||xs |	|	||||dA       t        |       t1        | j                   dB| d4       y# t$        $ r Y Vw xY w# t$        $ r Y w xY w)Cuy   pr-open: COMMITTED → PR_OPEN.
    --pr <int>: 기존 PR 번호 입력
    --auto: bot token으로 직접 PR 생성
    r   >   r   r   r   r   u   pr-open 불가: 현재 상태=u"    (COMMITTED 또는 RUNNING 필요)r   Nr   r   manualrn   rp   autoFpr-openu;   BOT_GITHUB_TOKEN 미설정 — fail-fast (chairman goal #4)zBOT_GITHUB_TOKEN missingT)r-  r   rM   r   rt  rq   bot_token_missingr$   r}   r  ry  uM   pr-open --auto: BOT_GITHUB_TOKEN 미설정 — fail-fast (chairman 명시 #4)[z] zTask z% PR (auto-created by taskctl pr-open)GH_TOKENbotr(  r)  createz--titlez--body<   r   r@   r*  r+  znumber,url,authorr  numberurlauthorloginu   PR 생성 실패: )r-  r   rM   r   rt  rq   )zjeon-jonghyuk-taskctl-botzapp/z[bot]u   PR author bot 검증 실패: z (allowlist=r   znon-bot author: r\  )r-  r   rM   r   rt  rq   	pr_authorbot_author_checkpr_author_not_bot)r}   r  u   PR author 검증 실패: u    — chairman goal #2 #5u+   pr-open: --pr <번호> 또는 --auto 필요r   rq   r   r:   r6  origin/main)rV   rp   base_shar  rq   pr_urlr  
created_byrM   r   r   rt  u   : → PR_OPEN (PR #)r   rV   r   r@  rH   getattrr   r   r   rQ   r   r   rM   rN   r   r1  r`   r   rE   removeprefixremovesuffixendswithr   r)  r   )ru  r   r   rq   r  r  
stdout_str
stderr_strr   r  rv  r  rp   	bot_token
short_desctitlebodyenv_override
create_cmdr3  	find_procpr_info	view_procviBOT_AUTHOR_ALLOWLIST_authorauthor_normis_bot_authorr  s                                r4   cmd_pr_openr    s   
 $,,E

 C FF-cU2TUWXY IFIJJIJ"$Fzz.)/RHZZ!'RFtVU##%	4<<V4!%)5  {&(&(;<>%L`bcd\\
DLL>J<0t||n$IJ')'0L$J $ud


 JL"=[[&&(
[[&&(
OO	??atVVX7JK "I ##q("jj)9)9:G 'H 5I$[[3F!(X!6!<" A A'2 NI !I  t||Y1*>!%((#!%9  )*6:  FtVVX7JK "I ##q(I$4$45B "x 0IVVE62F!#!1!7R < <Wb II
  >/r**62??HW% 3!!&)322 	
 4<<8\RfQgghi$,YK8&&$*	5 	 {&((;+467 %L,YM9QRTUV tT4(>BGG	
)2j+&yi7HI 78??EEGM2H4<<<<,* -  
%L1)A>?i ! 4 ! s&   A)Q )A'Q  	QQ 	Q-,Q-c                   t        | j                        }|d   }|dk7  rt        d| dd       |d   j                  d      }t	        |      }|d   |d   d<   |d	   |d   d	<   t               }|j                  d
      xs d}t        | j                  d||d	   t        |d	         |d|j                  dd      d|d       t        |dt               d|i       t        |       t        | j                   d| d       y)uH   ci-check: PR_OPEN → CI_PENDING. 8 required CI checks 수집 + ci.json.r   r   u   ci-check 불가: 현재 상태=u    (PR_OPEN 필요)r   r   rq   rr   rs   rn   r   cirE  r   )rq   rs   all_passr  rM   r   r   rt  r   r)  ry  u   : → CI_PENDING (PR #r   )r   rV   r   rH   rT  r@  r   ro  r   rQ   r   r   )ru  r   r   pr_npr_evrv  r  s          r4   cmd_ci_checkr    s   $,,E

 C
i.se3DEqI  -D &E$)*$5E*j!%*;%7E*k""$Fzz.)/RH4<<;'-eK.@A))OR0	( 	 |684,G	%L4TF!<=r3   c                (   t        | j                        }|d   }|dk7  rt        d| dd       |d   j                  d      }t	               }|j                  d      xs d	}t
        j                  j                  d
d      }d|d}t        j                         rt        t        dz        }|t        j                  vr t        j                  j                  d|       	 ddlm}	  |	|||      }
t!        |
t"              r|j%                  |
       nt        |
      |d<   n(t)        dt         dt        j*                         d|d<   t-        | j                  d||d|j                  dd      |j                  dd      d	|j                  dd	      d|d	       t/        |dt1               d |i!       t3        |       t5        | j                   d"       y# t&        $ r0}t)        d| t        j*                         d| |d<   Y d}~d}~ww xY w)#uS   gemini-evidence: CI_PENDING → GEMINI_PENDING. evaluate_gate 호출 + gemini.json.r   r   u&   gemini-evidence 불가: 현재 상태=u    (CI_PENDING 필요)r   r   rq   rn   r   GH_REPOJeon-Jonghyuk/dev_workspaceSKIP)hold_block_passr  r   r   )evaluate_gate
raw_resultu@   [taskctl] WARNING: evaluate_gate 호출 실패 (graceful skip): r   u   evaluate_gate 실패: warningNz[taskctl] WARNING: u%    없음 — gemini gate graceful skipu    gemini_evidence_verify.py 없음geminizgemini-code-assistseverity_countr  )	rq   r  app_slugr  r  rM   r   r   rt  r   r)  ry  u   : → GEMINI_PENDING)r   rV   r   rH   r@  rF   rG   GEMINI_EVIDENCE_VERIFYr   rK   rL   r   r   insertgemini_evidence_verifyr  
isinstancedictr   rE   r   r   r   r   rQ   r   r   )ru  r   r   r  rv  r  repogemini_resultscripts_dirr  gate_resultr   s               r4   cmd_gemini_evidencer    s   $,,E

 C
l5cU:NOQRS  -D"$Fzz.)/RH::>>)%BCD8>H$UM$$&)i/0chh&HHOOA{+		F<'h=K+t,$$[1.1+.>l+
 	!"8!99^_	
 $Fi 4<<('++,<a@(,,->G##Ir2
, 
 'vxtTlK	%L234/  	FTUXTYZadakakl)?u'EM)$	Fs   !A G 	H!&HHc                    t        | j                        }|d   }|dk7  rt        d| dd       t        |dt	                      t        |       t        | j                   d       y	)
u.   review-ready: GEMINI_PENDING → REVIEW_READY.r   r   u#   review-ready 불가: 현재 상태=u    (GEMINI_PENDING 필요)r   r   r  u   : → REVIEW_READYr   r  r  s      r4   cmd_review_readyr    se    $,,E

 C
23%7OPRST~VX6	%L012r3   c                6   t        | j                        }|d   }|t        v rt        d| dd       t	               }|d   |d   d<   |d   |d   d<   |d   |d   d<   |j                  d      xs d	}|d   j                  d
      }t        |      }|d   |d   d<   |d   |d   d<   |j                  d      |d   d<   |j                  d      |d   d<   d|v r|d   |d   d<   t        d| j                        }|d   |d   d<   ||d   d<   t        | j                        }|d   |d   d<   ||d   d<   |d   |d   d   d<   |d   |d   d   d<   t               }	|d   dk(  xr |d   dk(  }
t        | j                  d|d   |d   |	||j                  dd	      |j                  dd	      |
rdnd||d	       |
r|d v rt        |d!t               ddd"#       nt        |d!t               ddd"#       d|d   d   d<   t        |       t        | j                   d$       | j                  r!t!        t#        j$                  |d%d&'             y|d(v rt        |d)t               d*d+i#       d|d   d   d<   t        |       g }|d   dk7  r|j'                  d,|d           |d   dk7  r|j'                  d-|d           t        | j                   d.d/j)                  |       d0       | j                  r!t!        t#        j$                  |d%d&'             y)1Nr   u   verify 불가: 현재 상태=z (terminal)r   rp   r   rn   ro   r   rq   rr   rs   rC  rD  rE  pre-pushrX  rt   guard_sh_detailru   qc_report_guard_detailr   rw   verify_guard_shverify_qc_report_guardr[  verifyr_  r`  r   )	rt   ru   hidden_path_auditr  rM   r   r   rt  rq   >   r'   r   r   r   r   r&   r(   r   r   r   r   r(   )guard_shqc_report_guardry  u)   : verify PASS → GUARD_PASS (= VERIFIED)Fr   r   >   r   r(   r   r   r}   z"verify failed, demoting to PR_OPENz	guard.sh=zqc_report_guard=z: verify FAIL [, ])r   rV   r,   r   r@  rH   rT  rc  rg  _hidden_path_audit_internalr   r   rQ   r   r   machiner   r`   ra   r   r   )ru  r   r   rv  r  r  r  guard_evqc_evaudit_resultr  fail_reasonss               r4   
cmd_verifyr    s   $,,E

 C
o,SE=qA"$F"("2E*h(.~(>E*n%)/)@E*o&zz.)/RH  -D &E$)*$5E*j!%*;%7E*k"%*YY{%;E*k".3ii8L.ME**+%-2?-Cj/*Z6H+3H+=E*'(+3E*'( .E27/E*./27E*./9A+9NE*l#$56@Ek@RE*l#$<= /0L 	f$ 	&(Ov%  4<<#H-"'/),,}b1,,}b1"Q
, 
   ! ! |68*0VLN |68*0VLN45j,'1eT\\N"KLM<<$**UqAB
::E9FH"$HI	K01E*l#H-	%L LV#i(:';<=X& .uX.?@Aodii.E-FaHI||djjU1=>r3   c                r   t        | j                        }|d   }|dvrt        d| dd       t        | dd      xs
 t	               }|d   j                  d	      }d}|rWt        j                  j                  d
      }|r|}n3t        |      }|j                  d      xs i j                  d      xs d}d|v r|j                  d      d   n|}t               }	|	j                  d      xs d}
|rW|sUt        | j                  dddd|ddd|
|d	       t        |dt	               ddi       t        |       t        d| dd       |rZ||k(  rUt        | j                  ddd||ddd|
|d	       t        |dt	               ddi       t        |       t        d| dd       d }	 dd!lm}  ||      }|j                   s+d"}t#        d#|j$                   d$t&        j(                  %       d'|d(<   t        | j                  d|xs d)|d*||d"k(  t-        |d   j                  d+i             d'|
ddd|
|t/               d,       t        |d-t	               ||d.       d|d   d/   d0<   t        |       t1        | j                   d1| d       y# t*        $ r t#        d&t&        j(                  %       Y w xY w)2uL   approve: VERIFIED 또는 GUARD_PASS → HUMAN_APPROVED. self-approve 차단.r   r   u   approve 불가: 현재 상태=u$    (GUARD_PASS 또는 VERIFIED 필요)r   byNr   rq   TASKCTL_PR_AUTHOR_OVERRIDEr  r  r   r   rn   r   approvalr\  u%   pr_author lookup failed — fail-fastzgh pr view returned no author)	rX  r}   r  approverrM   r   r   rt  rq   r$   r}   pr_author_lookup_failedry  u-   approve 차단: pr_author 조회 실패 (PR #r   zself-approve detectedu   self-approve 차단zself-approveu,   self-approve 차단: PR author == approver (system)check_approver_identityr  z[WARN] P0-5: u    → manual approval로 분류r   u8   [WARN] lifecycle_guards not found — P0-5 guard skippedTr   r8   r[  rs   )r  r  rX  approval_typer  ci_passgemini_passr  rM   r   r   rt  rq   rz   r   )r  r  rw   approveu   : → HUMAN_APPROVED (by: )r   rV   r   r  rQ   rH   rF   rG   r4  r   r@  r   r   r   lifecycle_guardsr  okr   r}   r   r   ImportErrorro  r5   r   )ru  r   r   r  r  r  	_overridepr_dataapprover_loginrv  r  r  r  approver_chks                 r4   cmd_approver   C  s   $,,E

 C
,,,SE1UV	

 tT4(4FHH  -D IJJNN#?@	!I!$'G X.4"99'BJdI/2hX^^C(+HN"$Fzz.)/RHIt||Z=&5
2
 
	 	E;fh"$=>	@e<TF!DaHY.0t||Z-"&+
2
 
	 	E;fh"N3	5e;I;aH!L M[<.~>$M 3 344RSZZ #E
4<<+)"&8+,U:->-B-B;PR-STf.   'vx"0=QS12E*l#I.	%L88HJK5  [HszzZ[s   (AJ $J65J6c                    t        | j                        }t        |dt               dt	        | dd       i       t        |       t        | j                   d       y)Nr"   r}   ry  u   : → CANCELLEDr   )r   rV   r   rQ   r  r   r   r  s     r4   
cmd_cancelr    sO    $,,E{&(h =>@	%Lo./r3   c                    t        | j                        }t        |dt               d| j                  i       t        |       t        | j                   d| j                   d       y)Nr#   r}   ry  u   : → FAILED (r   r   )r   rV   r   rQ   r}   r   r   r  s     r4   cmd_failr    sS    $,,Exvx,.	%LnT[[M;<r3   c                   t        | j                  d      }|U| j                  r/t        t	        j
                  | j                  d ddd             yt        d| j                   d       y| j                  r"t        t	        j
                  |dd	
             yt        d|d           t        d|d           t        dt        |d                 |d   }t        d|j                  d              t        d|j                  d              t        d|j                  d              t        d|j                  d              t        d|d           t        d|d           y)NTr   )rV   r   missingFr  r   z: state file missingr   r   r   ztask: rV   zstate: r   ztransitions: r   r   zbranch: rp   zpr: rq   z
guard_sh: rt   zqc_report_guard: ru   zhuman_approved: r   zbypass: r   )r   rV   r  r   r`   ra   r;  rH   )ru  r   evs      r4   
cmd_statusr    sl   $,,d3E}<<$**)-/=BD E  Jt||n,@AB||djjU1=>  	uY'()*o./01c%"6789::)*+,RVVK()*+
266"34567!"&&)A"B!CDE '7!8 9:;x)*+r3   c                r  & t        | j                        }	 ddlm}m}  || j                        }|d   s)t        | j                  d|       t        d|d    d        || j                        }|d   s)t        | j                  d|       t        d	|d    d       t               }t        | dd      }t        | dd      }	|rdt               t               d|d<   t        dt        j                         	 ddlm}
  |
| j                        }|j"                  s/d|d   d   d<   t%        |       t        d|j&                   d       n|r`t)               st        dd       t+               \  }}}|dk(  rt        d| d d       |d!k(  rYt        d"| d#t        j                         n8|d$   d%k7  r6d|d   d   d<   t%        |       t        d&|d$    d'| j                   d(d       |d$   d)k(  r"d|d   d   d<   t%        |       t        d*d       |d$   d+k(  r"d|d   d   d<   t%        |       t        d,d       t-        d-| j                        }|d.   |d   d/<   ||d   d0<   |d.   d1k7  r)d|d   d   d<   t%        |       t        d2|d3    d4d       t/        | j                        }|d.   |d   d5<   ||d   d6<   |d.   d1k7  r)d|d   d   d<   t%        |       t        d7|d3    d4d       |d   j1                  d8      }|rt3        |      }|d9   |d   d9<   |d:   |d   d:<   |j1                  d;      |d   d;<   |j1                  d<      |d   d<<   |j1                  d;      d=vrE|j1                  d;      4d|d   d   d<   t%        |       t        d>|j1                  d;       d       t5        |d:         s(d|d   d   d<   t%        |       t        d?|d:    d       |d   j1                  d8      }|s"d|d   d   d<   t%        |       t        d@d       t7               }|j1                  dA      xs dB}|	rt               }||d   dC<   d|d   dD<   d|d   d   d<   |d$   d%k(  s|s|rBt9        |dEt               d||dF|G       t%        |       t9        |dHt               ddi|G       nt9        |dHt               d|dI|G       t        | j                  ddJj;                  t        j<                        ddd|dBdB||ddK
       t%        |       t?        | j                   dL| d4       y|d$   d%k(  r+t9        |dEt               ||dM|xs |G       t%        |       n*|s|r&t9        |dEt               ||dMdG       t%        |       |rJt        | ddN      xs dN}tA        | j                  |||dOgP       dt               dQ|d dR|dS<   t%        |       tB        jD                  j1                  dTdU      }dVdWdtG        |      dXdYdZ|g}|r|jI                  d[       tK        |d\d]id^_      }|jL                  |jN                  d`d  |j                  d`d  da|d   db<   dB}|jL                  dk7  rr|jL                  |d   d   d<   |j                  r|j                  d`d  ndB&dc}tQ        &fdd|D              }|r\	 t9        |det               df|jL                   d4&dgd  dhdG       	 tG        tT              }|t        jV                  vr t        jV                  jY                  d|       ddll-m.}  || j                  dEdedf|jL                   dm&dgd   dn| j                   dogtT        p       t        | j                  ddJj;                  t        j<                        |jL                  dBde||jN                  d`d  |j                  d`d  ||ddq
       t%        |       t        dr|jL                   ds&dtd   du| j                   dv|jL                  xs d       t9        |dit               ddj|jL                   idG       t        | j                  ddJj;                  t        j<                        |jL                  dBdi||jN                  d`d  |j                  d`d  ||dw	       t%        |       t        dx|jL                   ds|j                  dtd   |jL                  xs d       t               }||d   dC<   d|d   d   d<   |}tK        dVdydz| d{gd|}      } | jL                  dk(  r2	 tc        jd                  | jN                        }!|!j1                  d~dB      }	 ddlm4}" d }#	 tk        |      }$|$j1                  d      xs d }# |"|||#      }%|%j"                  s{d|d   d   d<   t9        |dit               dd|%j&                   idG       t        | j                  d|%jm                                t%        |       t        d|%j&                   d       |%jn                  j1                  d|      |d   d<   t9        |dHt               ||||d|xs |G       |rt9        |dt               ddidG       t        | j                  ddJj;                  t        j<                        d|dH||jN                  d`d  |j                  d`d  |||d
       t%        |       |rt?        | j                   d| d       yt?        | j                   d| d       y# t        $ r8}t        | j                  d
dd| dd       t        d| d       Y d }~
d }~ww xY w# t        $ r0}d|d   d   d<   t%        |       t        d| d       Y d }~d }~ww xY w# tR        $ r, t9        |dit               ddj|jL                   dkidG       Y w xY w# t        t^        t`        f$ r Y pw xY w# tf        $ r dB}Y w xY w# tf        $ r d }#Y w xY w# t        $ r t        dt        j                         Y w xY w)Nr   check_state_file_present check_done_escalated_coexistencer  merge_blocked_state_missingu#   merge 차단 (state file missing): r}   r   merge_blocked_coexistenceu   merge 차단 (coexistence): "merge_blocked_guard_v2_import_failFu*   silent_corruption_guard v2 import 실패: silent_corruption_guard_v2r  r}   r   u$   merge 차단 (P-SC v2 import fail): admindry_runTrx   r   u3   ★★★ TASKCTL BYPASS USED — Chairman overrider   )check_bypass_auditr   rw   mergeu   merge 차단 (P0-8): u-   merge 차단 (lifecycle_guards import fail): u<   admin override 차단: 회장(chairman) 자격 검증 실패r	  u1   admin override 차단: HARD_CAP_EXCEEDED (분기 u   회 사용 ≥ 5회)r  u3   [taskctl] WARNING: SOFT_CAP_WARNING — 이번 달 u   회 사용 (soft limit 3회)r   r   u   merge 차단: 현재 상태=u*    (HUMAN_APPROVED 필요. 'taskctl approve u	   ' 먼저)r"   u   merge 차단: state=CANCELLEDr    u=   merge 차단: state=BLOCKED (HOLD/CONFLICT 시 머지 차단)r  rX  rt   guard_sh_detail_merger[  u+   merge 차단: guard.sh pre-push FAIL (exit=r   r   ru   qc_report_guard_detail_mergeu)   merge 차단: qc_report_guard FAIL (exit=rq   rr   rs   rC  rD  >   N	MERGEABLEu   merge 차단: PR mergeable=u1   merge 차단: 8 required CI checks 미통과 — u7   merge 차단: PR 번호 없음 (taskctl pr-open 먼저)rn   r   rv   merge_dry_runr   )r  r   r  r   r   )r  r   r   )
r   r   merge_commit_sharr   r  rM   r   rt  rq   r  u,   : dry-run merge → MERGING → MERGED (PR #)r   r  zadmin overrideself_approve_constraint)rV   rq   r}   r  r  r  r|   r   r  r  r(  r)  z--mergez--delete-branch--repo--adminTASKCTL_INVOKEDr%  r   r  r]  )r   r_  r`  merge_subprocess)zbranch protectionzRequired status checkzrequired status checkzreview requiredzapproving review
unresolvedznot in mergeable statezPull request is not mergeablezmerge state statusrL  r    DIRTYUNSTABLEBEHINDc              3  &   K   | ]  }|v  
 y wr   r2   )rk  markerr`  s     r4   rl  zcmd_merge.<locals>.<genexpr>  s     QV6[0Q   r!   ztransient merge block (exit=8)r}   r`  r#   zgh pr merge exit=z (transient detect failed)append_recovery): .tasks/evidence/z/merge.jsonrV   
from_stateto_stater}   evidence_paths	workspace)
r   r   r  rr   r  rM   r   rt  rq   	transientuC   merge 차단 (transient → RECOVERABLE_BLOCKED): gh pr merge exit=z stderr=r.  z (use 'taskctl recover z' to retry))	r   r   r  rr   r  rM   r   rt  rq   u   merge 실패: gh pr merge exit=api/repos//commits/mainr  r,  rt  )check_merge_commit_shabaseRefName)r  base_branchzP0-6 SHA mismatch: merge_sha_failu   merge 차단 (P0-6): r  u<   [WARN] lifecycle_guards not found — P0-6 SHA check skipped)r)  r   r  r  r%   zadmin override used)
r   r   r  rr   r  rM   r   rt  rq   r   z: admin-override merge PR #u/    → MERGING → MERGED → ADMIN_OVERRIDE_USEDz: merged PR #u-    → MERGING → MERGED (taskctl done 필요))8r   rV   utils.silent_corruption_guardr  r  r   r   r  r&  r  r5   rQ   r   r   r   r  r  r  r   r}   r  r  rc  rg  rH   rT  ro  r@  r   r   r   r   r"  rF   rG   rK   r   r   r1  rM   any
SystemExitrL   r   r  utils.audit_chairman_recoveryr)  AttributeErrorr   r`   r   rE   r5  r4  as_dictdetail)'ru  r   r  r  sf_chkcoex_chkr   r   r  r  r  
bypass_chkr  r  
cap_statusr  r  r  r  rv  r  merge_tsr}   r  	merge_cmdr3  r  transient_markersis_transient_ws_root_append_recovery
owner_repoapi_procapi_data_check_merge_shapr_base_ref_pr_datasha_chkr`  s'                                         @r4   	cmd_mergerQ    s   $,,E>	
 *$,,7d|4<<)FO6vh7G6HI1M3DLLA~4<<)DhO/0B/CDaH FD'5)EdIu-G&X
h
 	C#**U	K;+DLL9J==;<j!,/8e,Z->->,?@!D 
!OQRS!1!3dJ,,& 46
 ++EdVKghZZ !%5578E*l+G4%L.u_/E.F G<<@LL>T ![078E*l+G4%L0!4!Y.78E*l+G4%LPRST T\\:/7/Aj+,5=j12H'78E*l+G4%L!+./q2 %T\\26;Hoj23<Aj89?f$78E*l+G4%L{+,A/ Z $$[1(.E,1*,=E*j)-2;-?E*k*-2YY{-CE*k*6;ii@T6UE*23yy%-@@99[)5?@E*%l3G<%L5eii6L5MN -U;-?@;<j!,/8eG[)*,   -D34j,'0eFJ"$Fzz.)/RH6/7j+,-1j/*34j,'0!%555y)-%P$& %Lxvx'.$& xvx)-@$& 	t||Wxx) )! /
 	 	eT\\N"NtfTUVW _!11E9FH$*U; /E	+ 	e	5E9FH$*U;	  	e x)9:N>NLL67	
 & $#
 	e ::>>)%BCDtWc$i<MxY]^I#$D __{{45){{45)-E*()
 !37??j,'0 -1KKdkk$%(R
  Q?PQQ	(E#8.J4??J[[\,]1<TU1C"E"&(y>388+HHOOAx0 ! LL(29$//9J#kZ^Z_N`Mab*4<<.D$ (	 4<<88CHH-!__$&1$++de,++de,!!3  %L$$(OO#4H[=O<P Q))-kC $1	 	E868"&77H$IJ	  	t||Wxx) "  kk$%(kk$%(
/
 
	 	e-doo-> ?kk$%()+OO q	
 vH+3E*'(/0E*l#G, J	u
|=9:H a	"zz(//2H'||E26
_O"&	"4(H#<<6>$K #4dLzz78E*l+G4xvx&*=gnn=M(NO"$ 4<<)97??;LM%L((891=070B0BCUWg0hj,-
 xvx FU*:<o' E0"$9:	  4<<88CHH%,++de$++de$+  
%LT\\N"=dVCrst  	T\\N-v5bcd  >t||%IB3%H1L
 	
 	3C591==>6  	K78E*l+G4%L@FJJ		Kp  (E868"*.??PPj,k!l"&( ((2  9 v  	"!	"  	K	  _LSVS]S]^^_s   Bl ;Am ,n 1Bo -1o* p ( o< B4p 	m -mm	n$%nn1ooo'&o'*o98o9<pp 
pp $p65p6c                F	   t        | j                        }|d   dk7  rt        d|d    dd       	 ddlm} |d   j                  d	      }|s&t        | j                  d
ddd       t        dd       t        j                  j                  dd      } |t        |      |      }|d   s)t        | j                  d
|       t        d|d    d       	 ddlm}m}  || j                        }	|	d   s)t        | j                  d|	       t        d|	d    d        || j                        }
|
d   s)t        | j                  d|
       t        d|
d    d       	 dd#lm}m}  || j                        }|j                   s>t        | j                  d$|j#                                t        d%|j$                   d       |d   j                  d	      }|d   j                  d&      xs |d   j                  d'      } || j                  ||      }|j                   s>t        | j                  d(|j#                                t        d)|j$                   d       t        j                  j                  dd      }d-}t'        d.d/d0| d1gd23      }|j(                  dk(  r2	 t+        j,                  |j.                        }|j                  d4d-      }t2        d5z  d6z  }|j5                  d7d78       || j                   d9z  }|j7                  t+        j8                  | j                  t;               |d:dd;<      d=>       t        | j                  d?|t=        |      t;               d-d-d||d   j                  d	      d@       t?        |dAtA               B       tC        |       tE        | j                   dC| dD       y# t        $ r8}t        | j                  ddd| dd       t        d| d       Y d}~-d}~ww xY w# t        $ r8}t        | j                  ddd | d!d       t        d"| d       Y d}~d}~ww xY w# t        $ r8}t        | j                  ddd*| d+d       t        d,| d       Y d}~+d}~ww xY w# t0        $ r d-}Y w xY w)Eu<   done: state == MERGED 검증 + .done 생성 → DONE 전이.r   r   u   done 불가: 현재 상태=u    (MERGED 필요)r   r   )verify_done_preconditionsr   rq   done_blocked_silent_corruptionFz4pr_number missing in state.evidence (P-SC pre-check)r  r}   u7   done 차단 (P-SC): pr_number missing in state.evidencer  r  r  u&   done 차단 (P-SC silent_corruption): r}   done_blocked_guard_import_failu'   silent_corruption_guard import 실패: silent_corruption_guardr  u    done 차단 (P-SC import fail): Nr
  done_blocked_state_missingu"   done 차단 (state file missing): done_blocked_coexistenceu   done 차단 (coexistence): !done_blocked_guard_v2_import_failuf   silent_corruption_guard v2 (check_state_file_present/check_done_escalated_coexistence) import 실패: r  u#   done 차단 (P-SC v2 import fail): )check_g3_fail_blocks_donecheck_done_g3_pass_evidencedone_blocked_g3_failu   done 차단 (P0-1): r  rn   done_blocked_g3_evidenceu   done 차단 (P0-2): u    lifecycle_guards import 실패: r  u,   done 차단 (lifecycle_guards import fail): r   r(  r2  r3  r4  r  r,  rt  r   eventsTr   z.done)rV   rz   r  r   r   rg   r   done)r  	done_pathrz   rM   r   r   rt  rq   r   r  u   : → DONE (.done: r   )#r   rV   r   r9  rS  rH   r   rF   rG   intr  r  r  r  r[  r\  r  r>  r}   r   r1  r`   r   rM   rE   rL   r   r   ra   r5   rK   r   rQ   r   r   )ru  r   rS  pr_n_screpo_sc	sc_resultr   r  r  r@  rA  r[  r\  g3_fail_chkpr_n_for_g3head_sha_for_g3g3_pass_chkr  r  rK  rL  
events_dir	done_files                          r4   cmd_donerl  q  s   $,,E_))%*@)AAQR	
:K
#''44<<)IPL  JAN**..,IJ-c'lGD	4<<)I9U9)H:M9NOQRS=l)$,,7d|4<<)EvN5fX6F5GH!L 4DLLA~4<<)CXN.x/A.BCQGF[/=~~4<<)?ATATAVW'(:(:';<a@ J'++K8*!!"45 5Z $$^4 	 2$,,_]~~4<<)C[EXEXEZ['(:(:';<a@ ::>>)%BCD	uv]34H a	"zz(//2H'||E26
 X%0JTD1~U33I

t||46(8:HMVW	Y   4<<,^f:&**;7	* 	 vVX.	%L1)A>?G  :t||%E?uE.H
 	
 	/u5q99:.  = 	t||%H~  @C  D  E1K
 	
 	23%8!<<=8  Ft||%E8>'H
 	
 	;C5A1EEF(  	"!	"s\   B"O BP	 D Q $1R 	P-PP		Q
-QQ
	R-R		RR R c                    ddl m}  || j                        }t        t	        j
                  |dd             |j                  d      rdS dS )u   .tasks/state/{task_id}.json 무결성 검사.

    JSON 출력: exists, readable, json_valid, checksum_present, checksum_match, current_state, issues
    토르-A의 utils/state_repair.py::inspect_state 함수를 호출.
    r   )inspect_stateFr   r   checksum_matchr   )utils.state_repairrn  rV   r   r`   ra   rH   )ru  rn  rX  s      r4   cmd_state_inspectrq    sA     14<<(F	$**V%
:;

+,13!3r3   c                    ddl m}  || j                  | j                  | j                  t               | j                        }t        t        j                  |dd             |j                  d      rdS dS )	u   state file checksum repair.

    Chairman approval evidence 필수.
    --approved-by-chairman <name>
    --evidence <path>
    --action <recompute_checksum | rollback_to_backup>

    토르-A의 utils/state_repair.py::repair_state 함수를 호출.
    r   )repair_state)approved_by_chairmanr   r{   repair_actionFr   r   r  r   )rp  rs  rV   rt  r   rQ   actionr   r`   ra   rH   )ru  rs  rX  s      r4   cmd_state_repairrw    sa     0!66mmhkkF 
$**V%
:;

4 1'a'r3   c                    ddl m}  || j                        }t        t	        j
                  |dd             |j                  d      rdS dS )u   repair 후 후속 검증. .verify-pending 마커 제거 시 PASS.

    토르-A의 utils/state_repair.py::verify_consistency 함수를 호출.
    r   )verify_consistencyFr   r   r  r   )rp  ry  rV   r   r`   ra   rH   )ru  ry  rX  s      r4   cmd_verify_consistencyrz    s@    
 6-F	$**V%
:;

4 1'a'r3   c           
     D   t        | j                        }|d   dk7  rt        d|d    dd       |d   j                  d      }|st        dd       t        j
                  j                  d	d
      }g }||d}d\  }}}	 t        dddt        |      d|ddgd      }	|	j                  |	j                  |	j                  }}}d}|dk(  ry	 t        j                  |      }|j                  d      }|j                  d      xs g }|D cg c]  }|j                  d      r| }}|dk(  xr | }|t!        |      d|d<   nd|j%                         xs d!| i|d<   |s|j'                  d"       |d   j                  d#      xs d$}d}|r	 t        dd%d&| d'| d(gd      }|j                  dk(  rt        j                  |j                        }|j                  d)      xs g }|D cg c]:  }|j                  d*      d+k(  r$|j                  d,      d-vr|j                  d.      < }}|D cg c](  }|j                  d*      d+k7  s|j                  d.      * }}| xr | xr t)        |      }t!        |      ||d/|d0<   nd|j                  xs d$d1d i|d0<   ndd2i|d0<   |s|j'                  d3       d}	 dd4lm}  |||      }t)        t/        |d5d            }|t/        |d6d$      d7|d8<   |s|j'                  d:       d}	 t        dddt        |      d|dd;gd      }|j                  dk(  r\t        j                  |j                        }|j                  d<      xs d$}|j                  d=      xs d$} |d>v xs | d?v }|| d@|dA<   nd|j                  xs d$d1d i|dA<   |s|j'                  dB       |rTt3        | j                  dCd||dD       t        dEdFj5                  |       dGt        j6                  |dH      ddI  d       t9        |dJt;               dg dKdLM       	 t        t<              }!|!t>        j@                  vr t>        j@                  jC                  d|!       ddNl"m#}"  |"| j                  ddJdOdP| j                   dQgt<        R       t3        | j                  dSdTddJ|dU       tM        |       tO        | j                   dV       y# t        $ r%}
t        |
      j                   d|
 }Y d}
~
Nd}
~
ww xY wc c}w # t        j"                  $ r}
dd |
 i|d<   Y d}
~
d}
~
ww xY wc c}w c c}w # t        $ r*}
dt        |
      j                   d|
 i|d0<   Y d}
~
d}
~
ww xY w# t0        $ r dd9i|d8<   Y t        $ r*}
dt        |
      j                   d|
 i|d8<   Y d}
~
d}
~
ww xY w# t        $ r*}
dt        |
      j                   d|
 i|dA<   Y d}
~
Od}
~
ww xY w# t0        tH        tJ        f$ r Y vw xY w)Wu  RECOVERABLE_BLOCKED → MERGING 자동 복귀.

    4 조건 모두 충족 시에만 복귀:

    1. review threads all resolved (gh pr view --json reviewDecision,reviewThreads)
    2. required CI all PASS (gh api repos/{repo}/commits/{sha}/check-runs)
    3. Gemini High 0건 (lifecycle_guards.check_gemini_severity)
    4. mergeStateStatus CLEAN 또는 MERGEABLE

    admin override 없이 객관적 4 조건만 평가. 단일 조건 미충족 시 차단.
    r   r!   u   recover 불가: 현재 상태=u    (RECOVERABLE_BLOCKED 필요)r   r   rq   u3   recover 차단: pr_number missing in state.evidencer  r  )rq   r  )r   r   r(  r)  r*  r  r+  zreviewDecision,reviewThreadsr  r,  : NFr   reviewDecisionreviewThreads
isResolvedAPPROVED)decisionunresolved_countreviewr-  zJSON decode: zgh exit=)review_threads_unresolved_or_not_approvedrn   r   r2  r3  z	/commits/z/check-runs
check_runsr9  	completedrI  >   neutralskippedsuccessr   )totalfailedpendingr  r'  zhead_sha missingrequired_ci_not_all_pass)check_gemini_severityr  r}   rU  r  zlifecycle_guards not installedgemini_high_present_or_unknownzmergeStateStatus,mergeablerL  rC  >   CLEAN>   r  )r9  rC  merge_statemerge_state_not_cleanrecover_blocked)r  failed_conditionsr?  u$   recover 차단: 4 조건 미충족 (r  z
). detail=r  i  r   )r  r  r  r  )recovered_fromconditions_passedry  r(  z>auto-recover: 4 conditions PASS (review/ci/gemini/merge_state)r+  z/recover.jsonr,  recoverT)r  r   r   r?  u1   : RECOVERABLE_BLOCKED → MERGING (4 조건 PASS))(r   rV   r   rH   rF   rG   r   rK   r1  rM   r   rE   type__name__r`   r   r;  r2  rN   r   boolr  r  r  r  r   r   ra   r   rQ   rL   r   r   r  r<  r)  r=  r   r   r   )#ru  r   r  r  r  r?  rc1stdout1stderr1proc1r   	review_okrN  r  threadstr   r  ci_okproc2cdatarunsrbadr  	gemini_okr  gem_chkmss_okproc4mdatamssrC  rH  rI  s#                                      r4   cmd_recoverr  (  s    $,,E_!66,U?-C,D E+ ,	
   -DBAF::>>)%BCD#%+/>F )C'14THd57

 !& 0 0%,,gW I
ax	@::g&Dxx 01Hhh/52G%,HAEE,4G!HJH!Z/C^I$$'
O F8 $W]]_%H(3%8HIx  !LM Z $$^4:HE	EuvYxjLME 1$

5<<0yy.4" ,0&'uuX+5l+3TT EE&M 
 37YQ!%%/[:X155=YY B7{BT
 Y!& t !(%,,*<"de)DEt  !34t  !;< IE:'$TB$67	gx4
x   !AB FJ4THd35

 q JJu||,E))./52C		+.4"II%Cm)CF/2$KF=!%,u||/Ar45.I$JF=!   !89 t||%6!29
 	
 	2499=N3O2P Qjje<TcBCE	
 y(=+TVW
y>388#HHOOAx(	
 	LL,S"4<<.>  		
 4<<%	-  
%L<<.IJ i  1#Y''(3%01 I ## 	@ '=)>?F8	@*
 Z  	E#S	(:(:';2cU%CDF4L	E&  G#%EFx E#S	(:(:';2cU%CDxE,  J!(T#Y-?-?,@3%*H I}JT 1 s   AS( ?T 
T!T%T AU .?U	-U 3UU AU  9V	 B!W 6A2X (	T1TTT U1
UU	
U 	VVV	WW$W		W	XW??XXXc                 d   g d} g d}d}g }g }| D ]d  }	 t        j                  ddd|gt        t              ddd	      }|j                  d
k(  r%|j
                  j                         D ]  }|j                  dd      }|r|d
   n|t        |      dk\  r|d   nddv r9t        fd|D              rNj                  d      r`j                         }	|	j                  d      xsJ |	j                  d      xs7 |	j                  d      xs$ |	j                  d      xs |	j                  d      }
t        fd|D              }|
s|s|j                  |       |j                  |       
 g |sdnd}|||dS # t        $ r}|j                  d|        Y d}~d}~ww xY w)u%  repo 전체 grep으로 금지 패턴 검색. PASS/FAIL 반환.

    회장 §3.8: 주석/docstring/문자열 단순 언급은 violation 아님. 실제 subprocess 호출만 차단.
    code_call_markers: subprocess.run / _run([ / 리스트 형태로 인자 전달 — 실제 호출 패턴.
    )zgh pr createzgh pr mergezgit push origin mainzgit push --force origin mainz&worktree_manager finish --action merge)z.gittestsfixtures
.worktreesnode_modules__pycache__)
zsubprocess.z_run(z_run([z"gh", "pr", "create"z'gh', 'pr', 'create'z"gh", "pr", "merge"z'gh', 'pr', 'merge'
check_callcheck_outputzPopen(r:   grepz-nTr  )rA   r>   r?   r@   r   r[   r   r
  r   zscripts/taskctl.pyc              3  &   K   | ]  }|v  
 y wr   r2   )rk  r   r   s     r4   rl  z._hidden_path_audit_internal.<locals>.<genexpr>  s     ;33$;;r&  )z.mdz.txtrS   z.logz.jsonlz.ymlz.yaml#z- z* z"""z'''c              3  &   K   | ]  }|v  
 y wr   r2   )rk  mcontents     r4   rl  z._hidden_path_audit_internal.<locals>.<genexpr>  s     )R1!w,)Rr&  zaudit_error: Nr[  r\  )rX  
violationswarnings)rI   rJ   rK   rL   r1  rM   r   r   r;  r:  r  rN   r   r   rE   )forbidden_patternsexcludescode_call_markersr  r  patternr3  r   partsstripped
is_commenthas_call_markerr   rX  r  r   s                 @@r4   r  r    s    ZH JH% %5$	5>>g.	N#$D
 !# KK224 ,D JJsA.E',58$D*-e*/eAhrG+t3 ;(;; }}%`a &}}H !++C0 6#..t46#..t46 $..u56 $..u5  '*)R@Q)R&RO! - %%d+7,%5L &V6FJHMM  	5cU344	5s   E F	F/F**F/c                    ~ t               }|d   dk(  rt        d       yt        dt        |d          dt        j
                         |d   D ]   }t        d	| t        j
                         " y
)u@   audit-hidden-paths: repo 전체 grep으로 우회 경로 감지.rX  r[  u*   hidden-path-audit PASS: 우회 경로 0건r   z"[taskctl] hidden-path-audit FAIL: r  u
   건 발견r   z  VIOLATION: r   )r  r   r   r;  r   r   )ru  rX  rc   s      r4   cmd_audit_hidden_pathsr  *  sx    (*Fh6!>?23vl7K3L2MZX::	% 	8AM!%CJJ7	8r3   c                
   | j                   | j                  | j                  t        t        dz        }|t
        j                  vr t
        j                  j                  d|       	 ddlm} t        d	z  d
z  z  t        j                  t        j                        }|j                  d      |j                  d      	 dM	 	 	 dNfd}t        dz  dz   dz  j!                         s |d d       t        d d        dt              \  }}|s<dj#                  |      } |ddj#                  |       d       t        d| d       t%        dddg      }	|	j&                  dk7  rR |d d|	j(                  j+                          d       t        d d|	j(                  j+                          d       j-                  d d!      t        d"z   d# z  j!                         r |d$ d%       t        d& d       d' d# t%        dddg      }
|
j&                  dk(  r |d( d)       t        d* d+d       t%        g d,      }|j&                  dk7  r't        d-|j(                  j+                          d       |j.                  j+                         t        d	z  d
z  z  }|d. dz  dOfd/}t%        dd0d1t              d2d3g      }|j&                  dk7  r1d4|j(                  j+                          } ||       t        |d       dz  d5z  }|j!                         st        dz  d5z  }|j!                         sAt%        dd0d6d7t              g       t%        dd8d9g       d:| } ||       t        |d       t1        j2                  t
        j4                  t        |      d;d<gddd=t              i t6        j8                  d>t        t              i?      }|j&                  dk7  rit%        dd0d6d7t              g       t%        dd8d9g       d@|j&                   dA|j(                  dBd j+                          } ||       t        |d       j-                  dC      t              t              dD|j.                  dEd dF}t;        |       t=        dG dHj-                  dC       dI dJ dK dL        y# t        $ r}t        d| d| dd       Y d}~d}~ww xY w)Puo   takeover: handoff 검증 → 새 worktree+branch 생성 → start_task_guard 자동 호출 → evidence 저장.r   r   )validate_handoffu'   validate_handoff 모듈 import 실패: z
  u9   /validate_handoff.py 파일이 있는지 확인하세요.r   Nr   r   z%Y%m%dT%H%M%SZr.   c                    	 j                  dd       |xs i j                  d      d d 	d| |d
}t        d d	z  |       y # t        $ r Y y w xY w)
NTr   previous_bottask/-r  )
rV   r  new_botfrom_branch
new_branch
started_atts_filenametakeover_statusfailure_reasonfailure_check	takeover-rS   )r   rH   rq  rE   )
r}   r  handoff_data_partialr  evidence_dir_earlyr  r  rV   r  ts_isos
       r4   _save_early_failurez)cmd_takeover.<locals>._save_early_failureV  s    	$$TD$A"!5!; @ @ P"* %gYay9$*#+"(!.B ,;-u/MMrR 		s   AA 	AAr   handoffsrS   u   handoff 파일 없음: 1_handoff_existsr   T)rV   rp   check_head_shaworkspace_rootu   handoff 검증 실패: z; 2_validate_handoffu   handoff 검증 실패:
  r:   r6  z--verifyzfrom-branch 'u   ' 존재하지 않음: 3_from_branch_existsr  r   r  r  u#   새 worktree 경로 이미 존재: 5_worktree_path_collisionu/   새 worktree 경로가 이미 존재합니다: r  u   새 branch 이미 존재: 6_branch_collisionu   새 branch 'u_   '가 이미 존재합니다. 다른 bot ID를 사용하거나 기존 branch를 삭제하세요.r  u    origin/main HEAD 조회 실패: r  c                    	 j                  d      
t              t        	      d| d}t        |       y # t        $ r Y y w xY w)Nr  r  )rV   r  r  r  r  handoff_pathr  r  new_worktree_pathr  r  r  r  )rH   rK   rq  rE   )r}   r  r  evidence_filer  handoff_datar  r  r  r  recorded_headrV   r  r  s     r4   _save_failed_evidencez+cmd_takeover.<locals>._save_failed_evidence  sj    	" , 0 0 @"$) #L 1*(%():%;$*#+"(B -, 		s   =A 	AAworktreeaddz-br  u   git worktree add 실패: zstart_task_guard.pyremovez--forcerp   z-Du   start_task_guard.py 없음: z--task--botr   r
   r   u   start_task_guard 실패 (exit=r*  r.  r  r  r]  )rV   r  r  r  r  r  r  r  r  r  r  r  start_guard_stdoutu   takeover 성공: z
  previous_bot=u    → new_bot=z
  new branch:   z
  new worktree: z
  evidence:     r   )r}   rK   r  rK   r  zdict | NonereturnNone)r}   rK   r  r  )rV   r  r  rK   rL   r   r   r  r  r  r   r   r/   r   r0   r1   r   r   r   r1  r   rN   rH   rM   rI   rJ   
executablerF   rG   rq  r   ) ru  r  r  r   now_utcr  r  errors	err_linesr3  proc_branch	proc_mainevidence_dirr  proc_wtr}   start_guard_script
proc_guardr   r  r  r  r  r  r  r  r  r  r  rV   r  r  s                       @@@@@@@@@@@@@r4   cmd_takeoverr  >  s   <<G''K88G i)+,K#((";'
5 #X-
:WDll8<<(G""#34K23F AE2=IM ( x'*4'%7HHL 5l^DFXY&|n5q9/ 	 B KK'	5dii6G5HI0(	* 	))5q9Z=>D!K=(?@Q@Q@S?TU"	

 	K=(?@Q@Q@S?TU	

 !$$Z4M!L0gYay3II!12C1DE'	

 	=>O=PQ	

 	7),J{J
CDK"(5 	

 	:, 'Q R	
 89Iq /	0@0@0F0F0H/IJAN%%'Hx'*4w>L Y{m5#AAM  * z5j	 G Q,W^^-A-A-C,DEf%VQ*Y69NN$$&&25JJ$$&eZ9c:K6LMNeXtZ01/0B/CDf%VQ	/0(GWgV!"<rzz<+S^<J !eZ9c:K6LMNeXtZ01,Z-B-B,C3  '--/02 	 	f%VQ $((8!L)"  !23"$(//6H -*
G9 %&**>:;=	 R%, ',- .(/		+ k  
5cU ;VX	
 	

s   7T 	U "T;;U c                    t        j                  dd      } | j                  dd      }d }|j                  dd	
      } ||       |j	                  t
               |j                  dd
      } ||       |j	                  t               |j                  dd
      } ||       |j	                  t               |j                  dd
      } ||       |j	                  t               |j                  dd
      } ||       |j                  dt        d d       |j                  ddd       |j	                  t               |j                  dd
      } ||       |j                  ddd       |j	                  t               |j                  dd 
      } ||       |j                  d!d d"#       |j	                  t               |j                  d$d%
      } ||       |j                  d&dd'       |j                  d(dd)       |j                  d*d d+#       |j	                  t               |j                  d,d-
      } ||       |j                  d*d .       |j	                  t               |j                  d/d0
      } ||       |j                  d*d1       |j	                  t                |j                  d2d3
      } ||       |j                  ddd4       |j	                  t"               |j                  d5d6
      } ||       |j                  d7d8dd9d:;       |j                  d<dd=>       |j	                  t$               |j                  d?d@
      } ||       |j	                  t&               |j                  dAdB
      } ||       |j	                  t(               |j                  dCdD
      } ||       |j	                  t*               |j                  dEdF
      } ||       |j	                  t,               |j                  dGdH
      } ||       |j	                  t.               |j                  dIdJ
      } ||       |j	                  t0               |j                  dKdL
      } ||       |j	                  t2               |j                  dMdN
      } ||       |j	                  t4               |j                  dOdP
      }|j	                  t6               |j                  dQdR
      } ||       |j	                  t8               |j                  dSdT
      } ||       |j                  dUddV>       |j                  dWddX>       |j                  dYdZd[gdd\]       |j	                  t:               |j                  d^d_
      } ||       |j	                  t<               | S )`Nr   uh   task 상태 enforcement layer + main 진입 단일 경로 (task-2467: 14+5 state machine + PR lifecycle))progdescriptionr   T)destrequiredc                *    | j                  dd       y )NrV   u   task ID (예: task-2467)help)add_argument)sps    r4   _add_taskidz!build_parser.<locals>._add_taskid	  s    
	(BCr3   initu   CREATED 상태 생성r  )funcdispatchu    DISPATCHED 전환 (compat alias)acku   ACKED 전환 (compat alias)rJ   u   RUNNING 전환r  u<   PR_OPEN 전환 (bot token PR 생성 또는 PR 번호 입력)z--pru   PR 번호 (수동 입력))r  defaultr  z--auto
store_trueu    bot token으로 직접 PR 생성)rv  r  r  uS   evidence 자동 수집 + guard.sh + qc_report_guard, PASS 시 GUARD_PASS(=VERIFIED)z	--machineu   state JSON 출력r  u+   HUMAN_APPROVED 전환 (self-approve 차단)z--byu6   승인자 (human login). 미지정 시 _actor() 사용)r  r  r  u.   main 진입 단일 경로 (MERGING → MERGED)z	--dry-runu,   actual gh pr merge skip — 상태만 전이r  u1   chairman admin override (audit log 자동 기록)z--reasonu   admin override 사유cancelu   CANCELLED 전환)r  failu   FAILED 전환)r  r9  u   현재 상태 + evidence 출력u   JSON 출력takeoveruQ   handoff evidence 기반 봇 인계 — 새 worktree + branch + start_guard 자동z--fromr  BRANCHu/   이전 봇의 branch (예: task/task-2458-dev4))r  r  metavarr  r  u   새 봇 ID (예: dev5))r  r  zworktree-readyu*   WORKTREE_READY 전환 (dispatch/ack alias)handoffu0   HANDOFF_READY 전환 (RUNNING → HANDOFF_READY)r  u6   COMMITTED 전환 (RUNNING/HANDOFF_READY → COMMITTED)zci-checku/   CI_PENDING 전환 + 8 required CI checks 수집zgemini-evidenceu,   GEMINI_PENDING 전환 + evaluate_gate 호출zreview-readyu5   REVIEW_READY 전환 (GEMINI_PENDING → REVIEW_READY)r`  u3   DONE 전환 (MERGED → DONE + .done 파일 생성)r  uW   RECOVERABLE_BLOCKED → MERGING 복귀 (review/CI/gemini/merge_state 4 조건 PASS 시)zaudit-hidden-pathsuV   repo 전체 grep으로 우회 경로 감지 (gh pr create/merge, git push origin main)zstate-inspectu6   state file 무결성 검사 (checksum, json 유효성)zstate-repairu*   checksum repair (chairman evidence 필수)z--approved-by-chairmanu   승인자 이름z
--evidenceu!   chairman approval evidence 경로z--actionrecompute_checksumrollback_to_backupu   repair 동작 선택)choicesr  r  zverify-consistencyu?   repair 후 후속 검증 (.verify-pending 마커 제거 확인))argparseArgumentParseradd_subparsers
add_parserset_defaultsrw  r  r  r  r  rb  r  r  r   rQ  r  r  r  r  r  r  r  r  r  r  rl  r  r  rq  rw  rz  )r   subr  r  s       r4   build_parserr  	  sX   =	A 

	D

9CD 
%<	=BOR__(_3	
)K	LBOR__,_7	$A	BBOR__'_2	$4	5BOR__'_2		(f	gBOOOFd9TOUOOH\8ZO[OOO%	b 
 
dBOOOK;NOOOOO$		(U	VBOOOFD/gOhOOO%	&V	WBOOOKG  IOOIlL  NOOJ3JOKOOO#	'9	:BOOOJO-OOO$	_	5BOOOJO.OOO"	'H	IBOOOK=OIOOO$	` 
 
B OOO}tX>   OOGd1IOJOOO& 
(/[	\BOR__*<_=		(Z	[BOR__+_6	'_	`BOR__*_5	
)Z	[BOR__,_7	)0^	_BOR__*=_>	-d	eBOR__*:_;	%Z	[BOR__(_3 
f 
 
B OR__+_6	,e 
 
gBOO/O0 
.f	gBOR__*;_<	-Y	ZBOOO,tBTOUOOL46YOZOO%';<#	   OO)O*	,3t	uBOR__*@_AHr3   c                D   t               }|j                  |       }	 |j                  |      }xs dS # t        $ r  t        j
                  $ r}t        d| d       Y d }~6d }~wt        $ r/}t        dt        |      j                   d| d       Y d }~ld }~ww xY w)Nzsubprocess timeout: r   zinternal error: r}  r   )
r  
parse_argsr
  r;  rI   TimeoutExpiredr   rE   r  r  )r   parserru  rcr   s        r4   mainr$  	  s    ^FT"D@YYt_ 7N  $$ .#C5)1-- @S	 2 232cU;Q??@s!   4 BA$$B0%BB__main__)r  rK   )rV   rK   r  r   )r   dict[str, Any]r  rK   )rV   rK   r  r&  )r   r&  r  r  )rV   rK   r   r  r  dict[str, Any] | None)rV   rK   r   rK   rd   r&  r  r  )r   r&  r   rK   r{   
str | Noner   r'  r   r  r  r  )r   rK   r   rK   r  r  )r   )r   rK   r   rb  r  r   )r   rK   r  r  )
r   	list[str]rA   zPath | Noner@   rb  r   zdict[str, str] | Noner  zsubprocess.CompletedProcess)r  r(  )r  r  )r  ztuple[int, int, str])rV   rK   rq   
int | Noner}   rK   r  rK   r  r)  r  r  )rq   rb  r  r&  )r  r&  )rq   r*  r  r&  )rb  rK   rV   rK   r  r&  )rs   zdict[str, str]r  r  )r   r   rN  r&  r  r  )ru  argparse.Namespacer  rb  r   )ru  r+  r   rK   r   r'  r  rb  )r  zargparse.ArgumentParser)r   zlist[str] | Noner  rb  )a__doc__
__future__r   r  rC   rh   r`   rF   rI   r   r   r   r   pathlibr   typingr   r   r	   rK   __file__r  _SCRIPTS_DIRr   r  rG   rH   rL   rT   r   ra  rf  r  r  r  r   __annotations__r)   r   r+   r,   r5   rQ   rW   re   rl   r   r   r   r   r   r   r   r   r   r   r  r  r"  r&  r4  r@  rT  rc  rg  ro  rq  rw  r{  r  r  r  r  r  r  r  r  r  r  r  r   r  r  r  rQ  rl  rq  rw  rz  r  r  r  r  r  r$  r  r   r2   r3   r4   <module>r3     s4  8 #     	  
  '  * *
 4>(()sxxHHOOA|$  02GHI	 7*	8#j0y :-i'*>>"Y.1LL ),AADZZ .	$ 	 <,8, 7,-, i)*	,
 yk, 8, i-, ), B, #Y/, <, D, !9-, ;, 7,$ :%,& vh',( CE),, e5> I23=, ( D S RE()Z
N: 
 . 
 .	 M 
 M16 <> LP.2#%'+%'%'(,%'P%
Z
 04C&*#/J,.	16<<'<14<<$-< 
<47.& F	;*> ;?"7CF61 :
:\~8.b	"UzbJ<Qr}J	4(,( yB>NB(ARCL zCHHTV r3   