
    i                    4   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e      j*                  j*                        Zee	j.                  vre	j.                  j1                  de       	 ddlmZmZmZ  dZ! eejH                  jK                  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 d0d1d2d*hd3h d4d2h d5d6h d7d8d9hd9 e0        e0        e0        e0       h d:h d;d*d<hd=Z1d>e#d?<   h d@Z2de#dA<   ddBZ3ddCZ4ddDZ5ddEZ6ddFZ7ddGZ8ddHZ9eddI       Z:eddJ       Z:d	dKddLZ:ddMZ;ddd	dN	 	 	 	 	 ddOZ<ddPZ=dddQZ>ddRZ?ddSddT	 	 	 ddUZ@ddVZAddWZBddXZC	 	 	 	 	 	 	 	 	 	 	 	 ddYZDddZZEdd[ZFdd\ZGdd]ZHdd^ZIdd_ZJdd`ZKddaZLddbZM	 d	 	 	 ddcZNdddZOddeZPddfZQddgZRddhZSddiZTddjZUddkZVddlZWddmZXddnZYddoZZddpZ[ddqZ\ddrZ]ddsZ^ddtZ_dduZ`ddvZaddwZbddxZcddyZdddzZedd{Zfdd|Zgdd}Zhddd~Ziejdk(  r e	j                   ei              yy# e"$ r d	Z!dZh d
Zde#d<   dhZ de#d<   Y 9w xY w)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)reconcile_orphaned_mergeRECONCILE_CLASSIFICATIONSSUPPORTED_CLASSIFICATIONSTF>    state_orphaned_after_valid_merge!state_missing_after_taskctl_crash"state_corrupted_with_partial_merge#state_inconsistent_after_force_pushzset[str]_RECONCILE_CLASSIFICATIONSr   _SUPPORTED_CLASSIFICATIONS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      r0   r/   r   r/   r0   r   r   >   r    r   r   r   r   r    >   r    r$   r!   r1   r!   r"   >   r)   r    r#   r#   >   r)   r    r$   r1   r$   r%   r1   >   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.   TERMINAL_STATESc                 f    t        j                  t        j                        j	                  d      S )N%Y-%m-%dT%H:%M:%SZ)r   nowr   utcstrftime     B/home/jay/workspace/.worktrees/task-2472+1-dev2/scripts/taskctl.py_nowr>      s!    <<%../CDDr<   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     r=   _actorrZ      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    r=   _state_pathr`      s    '%(((r<   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       r=   _canonical_jsonrn      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sha256rn   encode	hexdigest)r   s    r=   _compute_checksumru      s*    >>/%077@AKKMMr<   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r   r   r   reasonaudit_log_offset)r_   current_statetransitionsr   human_approvedbypassadmin_overrider;   r^   s    r=   
_new_stater      s[    " #&*#
   t< $
% r<   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_okrb   r_   z	.json.tmpF   re   indentrp   encoding)
r]   mkdirpopru   r`   with_suffix
write_textri   rj   replace)r   ptmps      r=   _saver      st    OOD4O0	IIk4 *51E+E)$%A
--
$CNN4::e%BWNUKKNr<   c                     y Nr;   r^   s    r=   _loadr      s    +.r<   c                    y r   r;   )r_   allow_missings     r=   r   r     s    JMr<   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	   ' 실행)   rp   r   u   state 파일 파싱 실패:     → rb   uJ   checksum 불일치: 외부 수정 의심 (state file tampered).
  task_id=z

  stored=z
  expected=u0   
  → taskctl만 상태 변경 가능합니다.)	r`   exists_dieri   loads	read_textrN   r   ru   )r_   r   r   r   excstoredexpecteds          r=   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pidr\   .tmpdirsuffixwrp   r   Fr   r   N)EVIDENCE_DIRr   joinsysargvrZ   r>   rO   getpidupdatetempfilemkstemprT   fdopenri   dumpr   rN   unlinkOSError)	r_   namerm   ev_dirrecordpathfdtmp_pathfs	            r=   _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)r_   rA   taskctlr   r   fromtor   r   r   	exit_codeevidence_pathTforcedr   r   )r5   r   _check_forbidden_transitionsr4   rQ   setsortedr>   r   r   r   rT   r   append)	r   targetr   r   r   srcallowedr_   entrys	            r=   _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	-&r<   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$   r1   r#   u   금지 전이: uF    → VERIFIED (반드시 REVIEW_READY 또는 GUARD_PASS 상태 필요)r   r%      r$   r1   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     r=   r   r   h  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r<   c                j    t        d|  t        j                         t        j                  |       y )N
[taskctl] file)printr   stderrexit)msgcodes     r=   r   r     s"    	Jse
3::.HHTNr<   c                     t        d|         y )Nr   )r   )r   s    r=   	_print_okr     s    	Jse
r<   x   )rJ   rI   envc          
         |}|2t         j                  j                  d      }|rt        |      nt        }t        j                  | dd|t        |      i t         j                  |xs i       S )NTASKCTL_CWDTrG   rH   rI   rJ   r   )rO   rP   rQ   r   rU   rR   rS   rT   )cmdrJ   rI   r   
actual_cwdenv_cwds         r=   _runr     sg     J**../&-T']9
>>
O)rzz)ciR) r<   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.keysrp   r   )zBOT_GITHUB_TOKEN=zGH_BOT_TOKEN==r   "')rO   rP   rQ   rU   r   r   
splitlines
startswithsplitrW   rN   )env_nametokenv_keyslineprefixs        r=   _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 )NrB   TrE   rF    CHAIRMAN_EMAILSrc   )rR   rS   rT   rU   rV   rW   rN   rO   rP   rQ   r   r
  r  )rY   r   es      r=   _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   rp   r   r   r	  Zz+00:00   r   Z   rE   HARD_CAP_EXCEEDED   SOFT_CAP_WARNINGr  )ADMIN_OVERRIDE_LOGr   r   r8   r   r9   r   r   rW   ri   r   rQ   fromisoformatr   daysrN   )r8   softhardr  rects_strr   deltas           r=   _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   )	r   r_   rz   r   r   head_shabypassed_checkssoft_count_this_monthhard_count_this_quarterarp   r   Fre   
)	r  parentr   r  r>   openwriteri   rj   )
r_   rz   r   r   r!  r  r  _r  r   s
             r=   _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)rO   rP   rQ   r;   r<   r=   _bypass_activer/    s    ::>>*B/366r<   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  rI   r   errorN{}json_parse_failed)	r   rT   
returncoder   rW   ri   r   rV   JSONDecodeError)rz   procs     r=   _gh_pr_viewr=    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)rC   	rev-parsez--abbrev-refHEAD)rC   diffzorigin/main..HEADz--name-only)rC   r?  r@  )rC   statusz--porcelainr   )ry   rw   rx   git_status_porcelain_lines)r   rV   rW   r   len)ry   rA  r   changeddiff_sha	porcelainlns          r=   _collect_git_evidencerI  -  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)r{   r|   	mergeablemerge_state_statuspr_view_errorr1  r2  r3  r4  z2state,mergeable,mergeStateStatus,statusCheckRollupr  r5  r   r7  gh_errorr8  zjson_parse: statusCheckRollupr   contextr	  
conclusionr   rB  UNKNOWNMISSINGrL  mergeStateStatus)r{   r|   ci_checks_allrL  rM  )r   rT   r:  r   rW   ri   r   rV   r;  rQ   r   )rz   r<  datar   rollupci_mapchkr   rR  nrequired_maps              r=   _collect_pr_evidencer]  ;  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 )NrT     zguard.sh not foundresultr   r   bash   r5  r   PASSFAILra  r   stdout_tailstderr_tail)GUARD_SHr   r   rT   r:  rV   r   )stager_   r<  s      r=   _run_guard_shrl  ^  sp    ??##AUVVXw7ED OOq0&f__{{45){{45)	 r<   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 )NrT  r_  zqc_report_guard.py not foundr`  python3	--task-idz--workspacer   r5  r   rd  re  rf  rg  )QC_REPORT_GUARDr   r   rT   rU   r:  rV   r   )r_   r<  s     r=   _run_qc_report_guardrq  j  s    !!###A_``	C(+wsS\~^D
 !OOq0&f__{{45){{45)	 r<   c                H    | syt        d | j                         D              S )NFc              3  &   K   | ]	  }|d k(    yw)SUCCESSNr;   ).0rl   s     r=   	<genexpr>z,_all_required_checks_pass.<locals>.<genexpr>|  s     :!qI~:s   )allvalues)r|   s    r=   _all_required_checks_passry  y  s"    :y'7'7'9:::r<   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   rp   r   Fr   r   N)r'  r   r   r   rT   rO   r   ri   r   r   rN   r   r   )r   rW  r   r   r   s        r=   _atomic_writer{    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   startry   rw   r	  )
r   r   r   ry   r   rV   r   r   sharz   zinit u    → CREATED (r   )r`   r_   r   r   r   r   r>   rZ   r   r   r   rT   r   r   rI  r   rQ   )argsr   r   git_evs       r=   cmd_initr    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r<   c                    t        | j                        }t        ||t               |       t	        |       t        | j                   d|        y)Nr   r   u   : → r   r   r_   r   rZ   r   r   )r  r   r   r   s       r=   _simple_transition_cmdr    sA    $,,EvVXD9	%LfVH-.r<   c                    t        | d      S )Nr/   r  r  s    r=   cmd_dispatchr    s    !$55r<   c                    t        | d      S )Nr0   r  r  s    r=   cmd_ackr    s    !$00r<   c                &   t        | j                        }|d   }|dv r:t        |dt                      t	        |       t        | j                   d       yt        |dt                      t	        |       t        | j                   d       y)Nr   r3   r   r   u   : → RUNNINGr   r  r  r   r   s      r=   cmd_runr    sy    $,,E

 C
77E9FH5eT\\N-01y1	%Lm,-r<   c                    t        | d      S )u<   worktree-ready: CREATED/DISPATCHED/ACKED → WORKTREE_READY.r   r  r  s    r=   cmd_worktree_readyr    s    !$(899r<   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   r_   r   r   rZ   r   r   r  r   s     r=   cmd_handoffr    se    $,,E_*-eO.D-EEVWYZ[fh7	%L123r<   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   rw   r	  commitrx   ry   r   r   rz   )	rw   rx   commit_hashry   rV   r   r   r~  rz   r   r  u   : → COMMITTED (sha=N   r   )
r   r_   r   rI  rQ   r   r   rZ   r   r   )r  r   r   r  r   s        r=   
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r<   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   manualrw   ry   autoFpr-openu;   BOT_GITHUB_TOKEN 미설정 — fail-fast (chairman goal #4)zBOT_GITHUB_TOKEN missingT)r6  r   rV   r   r~  rz   bot_token_missingr-   r   r  r  uM   pr-open --auto: BOT_GITHUB_TOKEN 미설정 — fail-fast (chairman 명시 #4)[z] zTask z% PR (auto-created by taskctl pr-open)GH_TOKENbotr1  r2  createz--titlez--body<   r   rI   r3  r4  znumber,url,authorr  numberurlauthorloginu   PR 생성 실패: )r6  r   rV   r   r~  rz   )zjeon-jonghyuk-taskctl-botzapp/z[bot]u   PR author bot 검증 실패: z (allowlist=r   znon-bot author: re  )r6  r   rV   r   r~  rz   	pr_authorbot_author_checkpr_author_not_bot)r   r  u   PR author 검증 실패: u    — chairman goal #2 #5u+   pr-open: --pr <번호> 또는 --auto 필요r   rz   r    rC   r?  origin/main)r_   ry   base_shar   rz   pr_urlr  
created_byrV   r   r   r~  u   : → PR_OPEN (PR #)r   r_   r   rI  rQ   getattrr  r   r   rZ   r   r   rV   rW   r   r:  ri   r   rN   removeprefixremovesuffixendswithr   r2  r   )r  r   r   rz   r  r  
stdout_str
stderr_strr   r  r  r   ry   	bot_token
short_desctitlebodyenv_override
create_cmdr<  	find_procpr_info	view_procviBOT_AUTHOR_ALLOWLIST_authorauthor_normis_bot_authorr  s                                r=   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   rz   r{   r|   rw   r	  cirN  r   )rz   r|   all_passr   rV   r   r   r~  r!   r2  r  u   : → CI_PENDING (PR #r   )r   r_   r   rQ   r]  rI  r   ry  r   rZ   r   r   )r  r   r   pr_npr_evr  r   s          r=   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!<=r<   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   rz   rw   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  )	rz   r   app_slugr  r  rV   r   r   r~  r"   r2  r  u   : → GEMINI_PENDING)r   r_   r   rQ   rI  rO   rP   GEMINI_EVIDENCE_VERIFYr   rT   rU   r   r   insertgemini_evidence_verifyr  
isinstancedictr   rN   r   r   r   r   rZ   r   r   )r  r   r   r  r  r   repogemini_resultscripts_dirr  gate_resultr   s               r=   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      r=   cmd_review_readyr    se    $,,E

 C
23%7OPRST~VX6	%L012r<   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   ry   r   rw   rx   r	  rz   r{   r|   rL  rM  rN  pre-pushra  r}   guard_sh_detailr~   qc_report_guard_detailr   r   verify_guard_shverify_qc_report_guardrd  verifyrh  ri  r   )	r}   r~   hidden_path_auditr   rV   r   r   r~  rz   >   r0   r    r   r   r!   r/   r1   r#   r   r"   r   r1   )guard_shqc_report_guardr  u)   : verify PASS → GUARD_PASS (= VERIFIED)Fr   r   >   r$   r1   r%   r    r   z"verify failed, demoting to PR_OPENz	guard.sh=zqc_report_guard=z: verify FAIL [, ])r   r_   r5   r   rI  rQ   r]  rl  rq  _hidden_path_audit_internalr   r   rZ   r   r   machiner   ri   rj   r   r   )r  r   r   r  r   r  r  guard_evqc_evaudit_resultr  fail_reasonss               r=   
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=>r<   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   rz   TASKCTL_PR_AUTHOR_OVERRIDEr  r  r   r   rw   r	  approvalre  u%   pr_author lookup failed — fail-fastzgh pr view returned no author)	ra  r   r  approverrV   r   r   r~  rz   r-   r   pr_author_lookup_failedr  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   rA   rd  r|   )r  r  ra  approval_typer  ci_passgemini_passr   rV   r   r   r~  rz   r   r%   )r  r  r   approveu   : → HUMAN_APPROVED (by: )r   r_   r   r  rZ   rQ   rO   rP   r=  r  rI  r   r   r   lifecycle_guardsr  okr   r   r   r   ImportErrorry  r>   r   )r  r   r   r  r  r  	_overridepr_dataapprover_loginr  r   r  r  approver_chks                 r=   cmd_approver
  _  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   r  u   : → CANCELLEDr   )r   r_   r   rZ   r  r   r   r  s     r=   
cmd_cancelr    sO    $,,E{&(h =>@	%Lo./r<   c                    t        | j                        }t        |dt               d| j                  i       t        |       t        | j                   d| j                   d       y)Nr,   r   r  u   : → FAILED (r   r   )r   r_   r   rZ   r   r   r   r  s     r=   cmd_failr    sS    $,,Exvx,.	%LnT[[M;<r<   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   )r_   r   missingFr%  r   z: state file missingr   r   r   ztask: r_   zstate: r   ztransitions: r   r   zbranch: ry   zpr: rz   z
guard_sh: r}   zqc_report_guard: r~   zhuman_approved: r   zbypass: r   )r   r_   r  r   ri   rj   rD  rQ   )r  r   evs      r=   
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)*+r<   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_runTr   r   u3   ★★★ TASKCTL BYPASS USED — Chairman overrider   )check_bypass_auditr   r   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  ra  r}   guard_sh_detail_mergerd  u+   merge 차단: guard.sh pre-push FAIL (exit=r   r   r~   qc_report_guard_detail_mergeu)   merge 차단: qc_report_guard FAIL (exit=rz   r{   r|   rL  rM  >   N	MERGEABLEu   merge 차단: PR mergeable=u1   merge 차단: 8 required CI checks 미통과 — u7   merge 차단: PR 번호 없음 (taskctl pr-open 먼저)rw   r	  r   merge_dry_runr&   )r  r   r  r   r'   )r  r   r   )
r   r   merge_commit_shar{   r   rV   r   r~  rz   r  u,   : dry-run merge → MERGING → MERGED (PR #)r   r  zadmin overrideself_approve_constraint)r_   rz   r   r   r!  r  r   r   r  r  r1  r2  z--mergez--delete-branch--repo--adminTASKCTL_INVOKEDr.  r   r  rf  )r   rh  ri  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 statusrU  r)   DIRTYUNSTABLEBEHINDc              3  &   K   | ]  }|v  
 y wr   r;   )ru  markerri  s     r=   rv  zcmd_merge.<locals>.<genexpr>  s     QV6[0Q   r*   ztransient merge block (exit=8)r   ri  r,   zgh pr merge exit=z (transient detect failed)append_recovery): .tasks/evidence/z/merge.jsonr_   
from_stateto_stater   evidence_paths	workspace)
r   r   r$  r{   r   rV   r   r~  rz   	transientuC   merge 차단 (transient → RECOVERABLE_BLOCKED): gh pr merge exit=z stderr=r7  z (use 'taskctl recover z' to retry))	r   r   r$  r{   r   rV   r   r~  rz   u   merge 실패: gh pr merge exit=api/repos//commits/mainr  r5  r~  )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)r2  r   r  r$  r.   zadmin override used)
r   r   r$  r{   r   rV   r   r~  rz   r   z: admin-override merge PR #u/    → MERGING → MERGED → ADMIN_OVERRIDE_USEDz: merged PR #u-    → MERGING → MERGED (taskctl done 필요))8r   r_   utils.silent_corruption_guardr  r  r   r   r  r/  r  r>   rZ   r   r   r   r  r  r  r   r   r  r  rl  rq  rQ   r]  ry  rI  r   r   r   r   r+  rO   rP   rT   r   r   r:  rV   any
SystemExitrU   r   r  utils.audit_chairman_recoveryr3  AttributeErrorr   ri   r   rN   r?  r=  as_dictdetail)'r  r   r  r  sf_chkcoex_chkr   r   r  r  r  
bypass_chkr  r  
cap_statusr  r  r  r  r  r   merge_tsr   r  	merge_cmdr<  r$  transient_markersis_transient_ws_root_append_recovery
owner_repoapi_procapi_data_check_merge_shapr_base_ref_pr_datasha_chkri  s'                                         @r=   	cmd_merger[    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   rz   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$  rw   done_blocked_g3_evidenceu   done 차단 (P0-2): u    lifecycle_guards import 실패: r  u,   done 차단 (lifecycle_guards import fail): r	  r1  r<  r=  r>  r  r5  r~  r   eventsTr   z.done)r_   r   r$  r   r   rp   r   done)r$  	done_pathr   rV   r   r   r~  rz   r(   r  u   : → DONE (.done: r   )#r   r_   r   rC  r]  rQ   r   rO   rP   intr  r  r  r  re  rf  r  rH  r   r   r:  ri   r   rV   rN   rU   r   r   rj   r>   rT   r   rZ   r   r   )r  r   r]  pr_n_screpo_sc	sc_resultr   r  r  rJ  rK  re  rf  g3_fail_chkpr_n_for_g3head_sha_for_g3g3_pass_chkr  r$  rU  rV  
events_dir	done_files                          r=   cmd_donerv    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_repairrx  r_   r   ri   rj   rQ   )r  rx  ra  s      r=   cmd_state_inspectr{    sA     14<<(F	$**V%
:;

+,13!3r<   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   )rz  r}  r_   r~  r   rZ   actionr   ri   rj   rQ   )r  r}  ra  s      r=   cmd_state_repairr    sa     0!66mmhkkF 
$**V%
:;

4 1'a'r<   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   )rz  r  r_   r   ri   rj   rQ   )r  r  ra  s      r=   cmd_verify_consistencyr  4  s@    
 6-F	$**V%
:;

4 1'a'r<   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   rz   u3   recover 차단: pr_number missing in state.evidencer  r  )rz   r  )r	  r	  r1  r2  r3  r&  r4  zreviewDecision,reviewThreadsr  r5  : NFr   reviewDecisionreviewThreads
isResolvedAPPROVED)decisionunresolved_countreviewr6  zJSON decode: zgh exit=)review_threads_unresolved_or_not_approvedrw   r	  r<  r=  z	/commits/z/check-runs
check_runsrB  	completedrR  >   neutralskippedsuccessr   )totalfailedpendingr  r1  zhead_sha missingrequired_ci_not_all_pass)check_gemini_severityr  r   r_  r  zlifecycle_guards not installedgemini_high_present_or_unknownzmergeStateStatus,mergeablerU  rL  >   CLEAN>   r"  )rB  rL  merge_statemerge_state_not_cleanrecover_blocked)r  failed_conditionsrI  u$   recover 차단: 4 조건 미충족 (r  z
). detail=r%  i  r&   )r  r  r  r  )recovered_fromconditions_passedr  r2  z>auto-recover: 4 conditions PASS (review/ci/gemini/merge_state)r5  z/recover.jsonr6  recoverT)r  r   r   rI  u1   : RECOVERABLE_BLOCKED → MERGING (4 조건 PASS))(r   r_   r   rQ   rO   rP   r   rT   r:  rV   r   rN   type__name__ri   r   rD  r;  rW   r   boolr  r  r  r  r   r   rj   r   rZ   rU   r   r   r  rF  r3  rG  r   r   r   )#r  r   r  r  r  rI  rc1stdout1stderr1proc1r   	review_okrW  r  threadstr*  r   ci_okproc2cdatarunsrbadr  	gemini_okr  gem_chkmss_okproc4mdatamssrL  rR  rS  s#                                      r=   cmd_recoverr  D  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                    t         st        dd       | j                  }| j                  }t	        | j
                        }| j                  }|st        dd       |t        vrt        d|dt        t               d       |t        vr t        d|dt        t               dd       i }| j                  xs g D ]L  }d|vrt        d	|d
d       |j                  dd      \  }}|j                         ||j                         <   N dD cg c]	  }||vs| }	}|	rt        d|	 dd       |d   }
|d   }t        |      }|j                         s	t        |z  }t!        |      }t"        j$                  j'                  dd      }t)        d| d| d|
 d|dd  d	       t*        t        dd       t+        ||
|||t        |      }t-        |d||
||||d   |j'                  d      |j'                  d      |j'                  d      |j'                  d       d!
       |d   s0t        d"|j'                  d       d#|j'                  d       d       t)        d$| d%|j'                  d        d&|j'                  d              y'c c}w )(u  reconcile: state file missing + PR merge + .done valid 케이스 정합화.

    classification enum 4종 중 ``state_orphaned_after_valid_merge``만 1차 지원.
    기타 enum은 reject (인식만).

    검증 단계:
    1. PR state=MERGED
    2. mergeCommit ancestor of origin/main
    3. .done payload schema (task-timer or taskctl_done 포맷)
    4. .done sha256 audit jsonl 일치
    5. .g3-fail 자동 분류 (false_alert_resolved_by_late_report만 허용)
    6. state 재구성 (CREATED→...→DONE 합성)
    7. checksum 생성 (taskctl 호환)
    8. audit 14필드 jsonl append
    9. verify-consistency
    10. marker read-only 유지
    ug   reconcile 불가: utils.state_repair import 실패. WORKSPACE_ROOT 환경변수 또는 sys.path 확인.r   uW   reconcile 차단: --approved-by-chairman 플래그 필수 (회장 승인 확인 필요)u!   reconcile 차단: classification=u)    은 정의되지 않은 enum.
  허용: u6    는 enum 인식만 지원.
  1차 실 동작 지원: u7   
  이 케이스는 향후 spec 갱신 + 구현 필요.r   u   --evidence 형식 오류: u    (key=value 필요))r2  merge-commitu0   reconcile 차단: --evidence 필수 키 없음: u6   
  예: --evidence pr=40 --evidence merge-commit=<sha>r2  r  r  r  u   reconcile 시작: task_id=z, classification=z, pr=z, merge_commit=N   z...uD   reconcile 불가: state_repair 모듈 핸들 None (재import 실패))r_   rz   r$  r   r  r:  r~  	reconciler  step_failedr   
audit_path
state_path)
classificationrz   r$  r   r~  	result_okr  r   r  r  u   reconcile 실패: step_failed=z	, reason=u   reconcile 성공: task_id=u    → DONE
  state_path=z
  audit_path=r   )_STATE_REPAIR_AVAILABLEr   r_   r  r  r~  r   r   r   r   r   r  rW   r   is_absoluterU   rT   rO   rP   rQ   r   _reconcile_orphaned_merger   )r  r_   r  approvedevidence_path_strevidence_dictitemrk   rl   missing_keysrz   r$  ev_pathevidence_path_absr  ra  s                   r=   cmd_reconciler    s   $ #B	
 <<G--N$334H!//fhij77//A B :;<>	
 77//A B))/0J)K(L MEF 		
 %'M$" -d?-dX5HI1Mzz#q!1#$779aggi 	-  6P!-9OAPLP>|n MD E	
 d#I$^4$%G g%G::>>)%BCD
$WI->~>N O[(8"(='>c	C !(SUVW&)'%F 7K(,* (D\zz-0**X&jj.jj.*  $<,VZZ-F,G Hjj*+-	
 
$WI .

<01 2

<01	3
 } Qs   	JJ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(rC   grepz-nTr  )rJ   rG   rH   rI   r   rd   r   r  r	  zscripts/taskctl.pyc              3  &   K   | ]  }|v  
 y wr   r;   )ru  r   r   s     r=   rv  z._hidden_path_audit_internal.<locals>.<genexpr>  s     ;33$;;r0  )z.mdz.txtr\   z.logz.jsonlz.ymlz.yaml#z- z* z"""z'''c              3  &   K   | ]  }|v  
 y wr   r;   )ru  mcontents     r=   rv  z._hidden_path_audit_internal.<locals>.<genexpr>  s     )R1!w,)Rr0  zaudit_error: Nrd  re  )ra  
violationswarnings)rR   rS   rT   rU   r:  rV   r   r  rD  rD  r  rW   r   r   rN   )forbidden_patternsexcludescode_call_markersr  r  patternr<  r  partsstripped
is_commenthas_call_markerr   ra  r  r   s                 @@r=   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으로 우회 경로 감지.ra  rd  u*   hidden-path-audit PASS: 우회 경로 0건r   z"[taskctl] hidden-path-audit FAIL: r  u
   건 발견r   z  VIOLATION: r   )r  r   r   rD  r   r   )r  ra  rl   s      r=   cmd_audit_hidden_pathsr    sx    (*Fh6!>?23vl7K3L2MZX::	% 	8AM!%CJJ7	8r<   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%SZr7   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  )
r_   r  new_botfrom_branch
new_branch
started_atts_filenametakeover_statusfailure_reasonfailure_check	takeover-r\   )r   rQ   r{  rN   )
r   r  handoff_data_partialr  evidence_dir_earlyr  r  r_   r  ts_isos
       r=   _save_early_failurez)cmd_takeover.<locals>._save_early_failure  s    	$$TD$A"!5!; @ @ P"* %gYay9$*#+"(!.B ,;-u/MMrR 		s   AA 	AAr   handoffsr\   u   handoff 파일 없음: 1_handoff_existsr   T)r_   ry   check_head_shaworkspace_rootu   handoff 검증 실패: z; 2_validate_handoffu   handoff 검증 실패:
  rC   r?  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  )r_   r  r  r  r   handoff_pathr  r  new_worktree_pathr  r  r  r  )rQ   rT   r{  rN   )r   r  r  evidence_filer  handoff_datar  r  r  r  recorded_headr_   r  r  s     r=   _save_failed_evidencez+cmd_takeover.<locals>._save_failed_evidenceD	  sj    	" , 0 0 @"$) #L 1*(%():%;$*#+"(B -, 		s   =A 	AAworktreeaddz-br  u   git worktree add 실패: zstart_task_guard.pyremovez--forcery   z-Du   start_task_guard.py 없음: z--task--botr   r   r   u   start_task_guard 실패 (exit=r4  r7  r  r  rf  )r_   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   rT   r  rT   r  zdict | NonereturnNone)r   rT   r  r  )r_   r  r  rT   rU   r   r   r  r  r  r   r   r8   r   r9   r:   r   r   r   r:  r   rW   rQ   rV   rR   rS   
executablerO   rP   r{  r   ) r  r  r  r   now_utcr  r  errors	err_linesr<  proc_branch	proc_mainevidence_dirr	  proc_wtr   start_guard_script
proc_guardr   r  r  r  r  r  r  r  r  r  r  r_   r  r  s                       @@@@@@@@@@@@@r=   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                  dQddR>       |j                  dSdt7        g dT      dUV       |j                  dWdXg dYZ       |j                  d[dd\       |j                  d]dd^>       |j	                  t8               |j                  d_d`
      }|j	                  t:               |j                  dadb
      } ||       |j	                  t<               |j                  dcdd
      } ||       |j                  d[dde>       |j                  dWddf>       |j                  dgdhdigddjk       |j	                  t>               |j                  dldm
      } ||       |j	                  t@               | S )nNr   uh   task 상태 enforcement layer + main 진입 단일 경로 (task-2467: 14+5 state machine + PR lifecycle))progdescriptionr   T)destrequiredc                *    | j                  dd       y )Nr_   u   task ID (예: task-2467)help)add_argument)sps    r=   _add_taskidz!build_parser.<locals>._add_taskid	  s    
	(BCr<   initu   CREATED 상태 생성r"  )funcdispatchu    DISPATCHED 전환 (compat alias)acku   ACKED 전환 (compat alias)rS   u   RUNNING 전환r  u<   PR_OPEN 전환 (bot token PR 생성 또는 PR 번호 입력)z--pru   PR 번호 (수동 입력))r  defaultr#  z--auto
store_trueu    bot token으로 직접 PR 생성)r  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   rB  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)rj  u3   DONE 전환 (MERGED → DONE + .done 파일 생성)r  uW   RECOVERABLE_BLOCKED → MERGING 복귀 (review/CI/gemini/merge_state 4 조건 PASS 시)r  ui   state file missing + PR merge + .done valid 케이스를 정합화 (state_orphaned_after_valid_merge 등)ro  u   대상 task IDz--classification)r   r   r   r   u   reconcile 케이스 분류)r   choicesr#  z
--evidencer   uW   key=value 형식 evidence (반복 가능: --evidence pr=40 --evidence merge-commit=abc))r  r+  r#  z--approved-by-chairmanu9   회장 승인 (필수 — 이 플래그 없이는 차단)z--evidence-pathu   회장 audit jsonl 경로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 필수)u   승인자 이름u!   chairman approval evidence 경로z--actionrecompute_checksumrollback_to_backupu   repair 동작 선택)r3  r   r#  zverify-consistencyu?   repair 후 후속 검증 (.verify-pending 마커 제거 확인))!argparseArgumentParseradd_subparsers
add_parserset_defaultsr  r  r  r  r$  rl  r  r  r
  r[  r  r  r  r  r  r  r  r  r  r  rv  r  r   r  r  r{  r  r  )r   subr&  r%  s       r=   build_parserr<  	  s   =	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 
6 
 
B
 OOK$5EOFOO 
  *  
 OOf	   OO H  
 OO%;VOWOOO'	,e 
 
gBOO/O0 
.f	gBOR__*;_<	-Y	ZBOOO,tBTOUOOL46YOZOO%';<#	   OO)O*	,3t	uBOR__*@_AHr<   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(  rE  rR   TimeoutExpiredr   rN   r  r  )r   parserr  rcr   s        r=   mainrB  F
  s    ^FT"D@YYt_ 7N  $$ .#C5)1-- @S	 2 232cU;Q??@s!   4 BA$$B0%BB__main__)r  rT   )r_   rT   r  r   )r   dict[str, Any]r  rT   )r_   rT   r  rD  )r   rD  r  r  )r_   rT   r   r  r  dict[str, Any] | None)r_   rT   r   rT   rm   rD  r  r  )r   rD  r   rT   r   
str | Noner   rE  r   r  r  r  )r   rT   r   rT   r  r  )r   )r   rT   r   rl  r  r   )r   rT   r  r  )
r   	list[str]rJ   zPath | NonerI   rl  r   zdict[str, str] | Noner  zsubprocess.CompletedProcess)r  rF  )r  r  )r  ztuple[int, int, str])r_   rT   rz   
int | Noner   rT   r   rT   r!  rG  r  r  )rz   rl  r  rD  )r  rD  )rz   rH  r  rD  )rk  rT   r_   rT   r  rD  )r|   zdict[str, str]r  r  )r   r   rW  rD  r  r  )r  argparse.Namespacer  rl  r   )r  rI  r   rT   r   rE  r  rl  )r  zargparse.ArgumentParser)r   zlist[str] | Noner  rl  )l__doc__
__future__r   r6  rL   rq   ri   rO   rR   r   r   r   r   pathlibr   typingr   r   r	   rT   __file__r'  _SCRIPTS_DIRr   r  _WORKSPACE_ROOT_STRrz  r
   r  r   r   r   r   r  r  __annotations__rP   rQ   rU   r]   r   rj  rp  r  r  r
  r   r2   r   r4   r5   r>   rZ   r`   rn   ru   r   r   r   r   r   r   r   r   r   r  r  r  r+  r/  r=  rI  r]  rl  rq  ry  r{  r  r  r  r  r  r  r  r  r  r  r  r  r  r
  r  r  r  r[  rv  r{  r  r  r  r  r  r  r  r<  rB  r  r   r;   r<   r=   <module>rR     s  8 #     	  
  '  * *
 4>(()sxxHHOOA|$
 $x.//667 chh&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uz>NB(ARcL zCHHTV eP  # $,  	+, s   K9 9LL