
    Yi6                        d Z ddlmZ ddlZddlmc 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mZ ddlZ ed      Zedz  dz  ZddZdd	Zdd
ZddZd Zd Zd Zd Zd Zd Zd Zd Zd Zy)u   tests/state_machine/test_transitions.py
명세 §3 "6개 금지 전이" + 상태 enum 검증 (task-2467)

벨레스(개발6팀 테스터) 작성. 스바로그의 구현 완료 전 선작성(TDD).
    )annotationsN)Pathz-/home/jay/workspace/.worktrees/task-2467-dev6scriptsz
taskctl.pyc                   i t         j                  }t        |       |d<   | dz  dz  j                  dd       | dz  dz  j                  dd       | dz  dz  j                  dd       | dz  d	z  j                  dd       |S )
u5   test마다 .tasks/state/ 와 .tasks/evidence/ 격리.WORKSPACE_ROOT.tasksstateT)parentsexist_okevidencememoryeventszorchestration-audit)osenvironstrmkdir)tmp_pathenvs     ;/home/jay/workspace/tests/state_machine/test_transitions.py_isolated_workspacer      s    
RZZ.CMC7"))$)F:%,,TD,I8#**4$*G0077t7TJ    c                Z    t        j                  dt        t              g| z   dd|d      S )Npython3T   )capture_outputtextr   timeout)
subprocessrunr   TASKCTL)argsr   s     r   _run_taskctlr"   $   s-    >>	CL!D($C r   c                d    | dz  dz  | dz  }t        j                  |j                               S )Nr   r	   .json)jsonloads	read_text)r   task_idps      r   _stater*   +   s2    8g%7)5(99A::akkm$$r   c                   ddl }| dz  dz  | dz  }t        j                  |j                               }||d<   |j	                  dd       |j                         D ci c]  \  }}|dk7  s|| }}}t        j                  |dd	d
      }	|j                  |	j                  d            j                         }
|
|d<   |j                  t        j                  |dd             yc c}}w )u   테스트 전용: state 파일을 직접 조작하여 체크섬 재계산 후 저장.

    구현이 _compute_checksum 로직을 노출하지 않으므로, 직접 sha256 재계산.
    r   Nr   r	   r$   current_state	_checksumFT),:)ensure_ascii	sort_keys
separatorszutf-8   )r0   indent)hashlibr%   r&   r'   popitemsdumpssha256encode	hexdigest
write_text)r   r(   target_stater5   r)   r	   kvpayloadcanonchecksums              r   _force_staterC   0   s    
 8g%7)5(99AJJq{{}%E)E/	IIk4  %B1k1Aq!tBGBJJwUdzZE~~ell734>>@H!E+LLEa@A	 Cs    C*.C*c           	        t        |       }d}d|g}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}d|g}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}d|g}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}d|g}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}t        d|g|       | dz  dz  | dz  }
|
j                  } |       }|st        j                  d      dz   dt        j                         v st        j                  |
      rt        j                  |
      ndt        j                  |      t        j                  |      dz  }t        t        j                  |            dx}}t        j                  |
j                               }|d   }ddh}||v}|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d|       dz   d |iz  }t        t        j                  |            dx}}y)!uq  §3.9 (1): PR_OPEN 없이 VERIFIED 진입 차단.

    init → dispatch → ack → run → verify (PR_OPEN 미경유)
    현재 MVP 상태모델에서 RUNNING → GUARD_PASS(=VERIFIED)는
    PR_OPEN을 거치지 않으므로 허용되면 안 된다.
    신규 14+5 상태모델에서는 RUNNING → COMMITTED → PR_OPEN → ... → VERIFIED 경로만 허용.
    ztask-forbidden-01initr   ==zZ%(py7)s
{%(py7)s = %(py5)s
{%(py5)s = %(py0)s(%(py2)s, %(py3)s)
}.returncode
} == %(py10)sr"   r   py0py2py3py5py7py10assert %(py12)spy12Ndispatchackr   verifyr   r	   r$   u    state 파일이 존재해야 함zC
>assert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}
state_file)rJ   rK   py4r,   VERIFIED
GUARD_PASSnot in)z%(py0)s not in %(py3)scurrent)rJ   rL   u2   PR_OPEN 없이 VERIFIED/GUARD_PASS 진입 발생: z
>assert %(py5)srM   )r   r"   
returncode
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationexists_format_assertmsgr%   r&   r'   )r   r   r(   @py_assert1@py_assert4@py_assert6@py_assert9@py_assert8@py_format11@py_format13rU   @py_assert3@py_format5r	   r[   @py_assert2@py_format4@py_format6s                     r   6test_forbidden_transition_pr_open_to_verified_directlyrs   G   sv    h
'C!G)?<)3/?/::?a?:a????:a??????<???<???)??????3???3???/???:???a???????#W-C<-s3C3>>C!C>!CCCC>!CCCCCC<CCC<CCC-CCCCCCsCCCsCCC3CCC>CCC!CCCCCCC(><(#.>.99>Q>9Q>>>>9Q>>>>>><>>><>>>(>>>>>>#>>>#>>>.>>>9>>>Q>>>>>>>(><(#.>.99>Q>9Q>>>>9Q>>>>>><>>><>>>(>>>>>>#>>>#>>>.>>>9>>>Q>>>>>>> (G$c*H$w.G9E1BBJBBBB BBBBBBB:BBB:BBBBBBBBBBBBJJz++-.EO$G &|4 744  74              5    =WIF    r   c           	     Z   t        |       }d}d|g}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}d|g}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}d|g}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}d|g}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}d|ddg}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}t        d|ddg|      }
|
j                  }d}||k7  }|st        j                  d|fd||f      dt        j                         v st        j                  |
      rt        j                  |
      ndt        j                  |      t        j                  |      dz  }t        j                  d      dz   d|iz  }t        t        j                  |            dx}x}}t        | |      }|d   }dh}||v}|st        j                  d|fd||f      t        j                  |      t        j                  |      d z  }t        j                  d!|d          d"z   d#|iz  }t        t        j                  |            dx}x}}y)$u   §3.9 (2): VERIFIED 없이 HUMAN_APPROVED 차단.

    PR_OPEN 상태에서 approve 시도 → 차단 (VERIFIED/GUARD_PASS 필요).
    ztask-forbidden-02rE   r   rF   rH   r"   r   rI   rP   rQ   NrR   rS   r   pr-open--pr200approve--byzhuman-reviewer!=z2%(py2)s
{%(py2)s = %(py0)s.returncode
} != %(py5)sprocrJ   rK   rM   u<   VERIFIED 없이 HUMAN_APPROVED 진입이 차단되어야 함
>assert %(py7)srN   r,   HUMAN_APPROVEDrY   z%(py1)s not in %(py4)spy1rV   u.   VERIFIED 없이 HUMAN_APPROVED 진입 발생: 
>assert %(py6)spy6r   r"   r\   r]   r^   r_   r`   ra   rb   rc   rd   rf   r*   r   r   r(   rg   rh   ri   rj   rk   rl   rm   r}   rn   rr   @py_format8r	   @py_assert0rp   ro   @py_format7s                      r   =test_forbidden_transition_verified_to_human_approved_skippingr   j   s   
 h
'C!G)?<)3/?/::?a?:a????:a??????<???<???)??????3???3???/???:???a???????#W-C<-s3C3>>C!C>!CCCC>!CCCCCC<CCC<CCC-CCCCCCsCCCsCCC3CCC>CCC!CCCCCCC(><(#.>.99>Q>9Q>>>>9Q>>>>>><>>><>>>(>>>>>>#>>>#>>>.>>>9>>>Q>>>>>>>(><(#.>.99>Q>9Q>>>>9Q>>>>>><>>><>>>(>>>>>>#>>>#>>>.>>>9>>>Q>>>>>>>"GVU;Q<;SAQALLQPQQLPQQQQQLPQQQQQQQ<QQQ<QQQ;QQQQQQSQQQSQQQAQQQLQQQPQQQQQQQQ GV5EFLD??_a_?a___?a______4___4___?___a___!________8W%E! *:); !);;  !);    "    *<    99O8PQ     r   c           	        t        |       }d}d|g}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}d|g}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}d|g}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}d|g}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}d|ddg}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}t        d|dg|      }
|
j                  }d}||k7  }|st        j                  d|fd||f      dt        j                         v st        j                  |
      rt        j                  |
      ndt        j                  |      t        j                  |      dz  }t        j                  d      dz   d|iz  }t        t        j                  |            dx}x}}t        | |      }|d   }ddh}||v}|st        j                  d|fd||f      t        j                  |      t        j                  |      d z  }t        j                  d!|d          d"z   d#|iz  }t        t        j                  |            dx}x}}g }d$}|
j                  }||v }|}|s=d%}|
j                  }||v }|}|s'd&}|
j                  }|j                  } |       }||v }|}|snt        j                  d'|fd(||f      t        j                  |      dt        j                         v st        j                  |
      rt        j                  |
      ndt        j                  |      d)z  }d*d+|iz  }|j                  |       |sjt        j                  d'fd,f      t        j                  |      dt        j                         v st        j                  |
      rt        j                  |
      ndt        j                  |      d-z  }d.d/|iz  }|j                  |       |st        j                  d'fd0f      t        j                  |      dt        j                         v st        j                  |
      rt        j                  |
      ndt        j                        t        j                        t        j                  |      d1z  }d2d3|iz  }|j                  |       t        j                   |d4      i z  } t        j                  d5|
j                         d6z   d7| iz  }!t        t        j                  |!            dx}x}x}x}x}x}x}x}x}x}x}x}}y)8u   §3.9 (3): HUMAN_APPROVED 없이 MERGING 차단.

    PR_OPEN 상태 (또는 GUARD_PASS/VERIFIED 상태)에서 merge 시도 → 거부.
    ztask-forbidden-03rE   r   rF   rH   r"   r   rI   rP   rQ   NrR   rS   r   ru   rv   300merge	--dry-runrz   r|   r}   r~   u;   HUMAN_APPROVED 없이 MERGING 진입이 차단되어야 함r   rN   r,   MERGINGMERGEDrY   r   r   u4   HUMAN_APPROVED 없이 MERGING/MERGED 진입 발생: r   r   r   u   차단blocked)in)z.%(py3)s in %(py7)s
{%(py7)s = %(py5)s.stderr
})rL   rM   rN   z%(py9)spy9)z2%(py12)s in %(py16)s
{%(py16)s = %(py14)s.stderr
})rQ   py14py16z%(py18)spy18)zh%(py21)s in %(py29)s
{%(py29)s = %(py27)s
{%(py27)s = %(py25)s
{%(py25)s = %(py23)s.stderr
}.lower
}()
})py21py23py25py27py29z%(py31)spy31   u    예상 에러 메시지 없음: z
>assert %(py34)spy34)r   r"   r\   r]   r^   r_   r`   ra   rb   rc   rd   rf   r*   stderrlowerappend_format_boolop)"r   r   r(   rg   rh   ri   rj   rk   rl   rm   r}   rn   rr   r   r	   r   rp   ro   r   @py_assert11@py_assert15@py_assert13@py_assert20@py_assert24@py_assert26@py_assert28@py_assert22@py_format10@py_format17@py_format19@py_format30@py_format32@py_format33@py_format35s"                                     r   ;test_forbidden_transition_human_approved_to_merging_skippedr      s   
 h
'C!G)?<)3/?/::?a?:a????:a??????<???<???)??????3???3???/???:???a???????#W-C<-s3C3>>C!C>!CCCC>!CCCCCC<CCC<CCC-CCCCCCsCCCsCCC3CCC>CCC!CCCCCCC(><(#.>.99>Q>9Q>>>>9Q>>>>>><>>><>>>(>>>>>>#>>>#>>>.>>>9>>>Q>>>>>>>(><(#.>.99>Q>9Q>>>>9Q>>>>>><>>><>>>(>>>>>>#>>>#>>>.>>>9>>>Q>>>>>>>"GVU;Q<;SAQALLQPQQLPQQQQQLPQQQQQQQ<QQQ<QQQ;QQQQQQSQQQSQQQAQQQLQQQPQQQQQQQQ ';7=D??^a^?a^^^?a^^^^^^4^^^4^^^?^^^a^^^!^^^^^^^^8W%E! )X)> !)>>  !)>    "    *?    ?u_?U>VW     t{{ {* h $++ h+.E  VZVaVa VaVgVg VgVi ViIi   {           $     $     +     h+    /7      ;?    ;?    ;F     Vi    JS      W[    W[    Wb    Wh    Wj        +4;;-8       r   c           	     V   t        |       }d}d|g}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}d|g}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}d|g}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}d|g}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}d|ddg}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}t        d|g|      }
|
j                  }d}||k7  }|st        j                  d|fd||f      dt        j                         v st        j                  |
      rt        j                  |
      ndt        j                  |      t        j                  |      dz  }t        j                  d      dz   d|iz  }t        t        j                  |            dx}x}}t        | |      }|d   }dh}||v}|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  d|d          d z   d!|iz  }t        t        j                  |            dx}x}}y)"uc   §3.9 (4): MERGED 없이 DONE 차단.

    PR_OPEN 상태에서 done 명령 시도 → 거부.
    ztask-forbidden-04rE   r   rF   rH   r"   r   rI   rP   rQ   NrR   rS   r   ru   rv   400donerz   r|   r}   r~   u0   MERGED 없이 DONE 진입이 차단되어야 함r   rN   r,   DONErY   r   r   u"   MERGED 없이 DONE 진입 발생: r   r   r   r   s                      r   2test_forbidden_transition_merged_required_for_doner      s   
 h
'C!G)?<)3/?/::?a?:a????:a??????<???<???)??????3???3???/???:???a???????#W-C<-s3C3>>C!C>!CCCC>!CCCCCC<CCC<CCC-CCCCCCsCCCsCCC3CCC>CCC!CCCCCCC(><(#.>.99>Q>9Q>>>>9Q>>>>>><>>><>>>(>>>>>>#>>>#>>>.>>>9>>>Q>>>>>>>(><(#.>.99>Q>9Q>>>>9Q>>>>>><>>><>>>(>>>>>>#>>>#>>>.>>>9>>>Q>>>>>>>"GVU;Q<;SAQALLQPQQLPQQQQQLPQQQQQQQ<QQQ<QQQ;QQQQQQSQQQSQQQAQQQLQQQPQQQQQQQQ )3/D??SaS?aSSS?aSSSSSS4SSS4SSS?SSSaSSS!SSSSSSSS8W%E! & !1  !    "    *2    -U?-C,DE     r   c           	     	   t        |       }d}d|g}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}d|g}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}t        | |      }
|
d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}t        d|g|      }|j                  }d}||k7  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                  d      dz   d|iz  }t        t        j                  |            dx}x}}t        | |      }
|
d   }d}||k(  }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  d|
d          dz   d|iz  }t        t        j                  |            dx}x}}y)uy   §3.9 (5): CANCELLED는 terminal — 다른 상태로 복귀 불가.

    init → cancel → run 시도 → 차단.
    ztask-forbidden-05rE   r   rF   rH   r"   r   rI   rP   rQ   Ncancelr,   	CANCELLEDz%(py1)s == %(py4)sr   assert %(py6)sr   r   rz   r|   r}   r~   u1   CANCELLED에서 RUN 진입이 차단되어야 함r   rN   u&   CANCELLED에서 상태 변경 발생: r   )r   r"   r\   r]   r^   r_   r`   ra   rb   rc   rd   r*   rf   r   r   r(   rg   rh   ri   rj   rk   rl   rm   r	   r   rn   rp   ro   r   r}   rr   r   s                      r   8test_forbidden_transition_cancelled_terminal_no_recoveryr      s"   
 h
'C!G)?<)3/?/::?a?:a????:a??????<???<???)??????3???3???/???:???a???????!7+A<+S1A1<<AA<AAAA<AAAAAA<AAA<AAA+AAAAAASAAASAAA1AAA<AAAAAAAAAA8W%E!0[0![0000![000!000[0000000 (#.D??TaT?aTTT?aTTTTTT4TTT4TTT?TTTaTTT!TTTTTTTT8W%E! [ ![0  ![    "    &1    11G0HI     r   c           	     J   t        |       }d}d|g}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}d|g}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}t        d|ddg|      }
|
j                  }d}||k7  }|st        j                  d|fd||f      dt        j                         v st        j                  |
      rt        j                  |
      ndt        j                  |      t        j                  |      dz  }t        j                  d      dz   d|iz  }t        t        j                  |            dx}x}}t        | |      }|d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y)u:   §3.9 (5) 보완: CANCELLED 후 approve 시도 → 차단.ztask-forbidden-05brE   r   rF   rH   r"   r   rI   rP   rQ   Nr   rx   ry   humanrz   r|   r}   r~   u5   CANCELLED에서 approve 시도가 차단되어야 함r   rN   r,   r   r   r   r   r   r   r   s                      r   .test_forbidden_transition_cancelled_no_approver      s   
h
'C"G)?<)3/?/::?a?:a????:a??????<???<???)??????3???3???/???:???a???????!7+A<+S1A1<<AA<AAAA<AAAAAA<AAA<AAA+AAAAAASAAASAAA1AAA<AAAAAAAAAAGVW=sCD??XaX?aXXX?aXXXXXX4XXX4XXX?XXXaXXX!XXXXXXXX8W%E!0[0![0000![000!000[0000000r   c           	        t        |       }d}d|g}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}d|g}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}d|g}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}d|g}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}d|ddg}t        ||      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}t        | |d       t        | |      }
|
d   }d}||k(  }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  d      dz   d|iz  }t        t        j                  |            dx}x}}t        d|dg|      }|j                  }d}||k7  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                  d      d z   d!|iz  }t        t        j                  |            dx}x}}t        | |      }
|
d   }h d"}||v}|st        j                  d#|fd$||f      t        j                  |      t        j                  |      dz  }t        j                  d%|
d          dz   d|iz  }t        t        j                  |            dx}x}}y)&u   §3.9 (6): BLOCKED 상태에서 MERGING 진입 차단.

    state 파일을 BLOCKED로 강제 진입시킨 후 merge 시도 → 차단.
    (신규 구현에서 BLOCKED 상태 진입 명령이 추가되면 해당 명령으로 대체 가능)
    ztask-forbidden-06rE   r   rF   rH   r"   r   rI   rP   rQ   NrR   rS   r   ru   rv   600BLOCKEDr,   r   r   u   강제 BLOCKED 설정 실패r   r   r   r   rz   r|   r}   r~   u:   BLOCKED 상태에서 MERGING 진입이 차단되어야 함r   rN   >   r   r   r   rY   r   u%   BLOCKED에서 MERGING 진입 발생: )r   r"   r\   r]   r^   r_   r`   ra   rb   rc   rd   rC   r*   rf   r   s                      r   ,test_forbidden_transition_blocked_to_mergingr      s    h
'C!G)?<)3/?/::?a?:a????:a??????<???<???)??????3???3???/???:???a???????#W-C<-s3C3>>C!C>!CCCC>!CCCCCC<CCC<CCC-CCCCCCsCCCsCCC3CCC>CCC!CCCCCCC(><(#.>.99>Q>9Q>>>>9Q>>>>>><>>><>>>(>>>>>>#>>>#>>>.>>>9>>>Q>>>>>>>(><(#.>.99>Q>9Q>>>>9Q>>>>>><>>><>>>(>>>>>>#>>>#>>>.>>>9>>>Q>>>>>>>"GVU;Q<;SAQALLQPQQLPQQQQQLPQQQQQQQ<QQQ<QQQ;QQQQQQSQQQSQQQAQQQLQQQPQQQQQQQQ 7I.8W%E!NYN!Y.NNN!YNNN!NNNYNNN0NNNNNNNN ';7=D??]a]?a]]]?a]]]]]]4]]]4]]]?]]]a]]]!]]]]]]]]8W%E! )F !)FF  !)F    "    *G    0o0F/GH     r   c                    t         j                  j                  dt        t        dz               	 t        j                  d      } t        j                  |        	 t        | j                        }h d}h d}||z
  }||z
  }| }|s~t        j                  d|       dz   dd	t        j                         v st        j                  |      rt        j                  |      nd	iz  }t!        t        j"                  |            d
}|rddhdhd}t               }	|D ]3  }
|j%                  |
t                     }||z  r#|	j'                  |
       5 |	 }|s~t        j                  d|	       dz   ddt        j                         v st        j                  |	      rt        j                  |	      ndiz  }t!        t        j"                  |            d
}y
y
# w xY w)u   STATES enum이 14 정상 + 5 예외 상태를 포함하는지 검증.

    신규 구현 완료 후 통과 예상. 현재 MVP는 11종만 정의.
    r   r   taskctl>   r   r   CREATEDr   PR_OPENRUNNINGrW   	COMMITTED
CI_PENDINGREVIEW_READYHANDOFF_READYGEMINI_PENDINGr   WORKTREE_READY>   FAILEDr   r   	ESCALATEDADMIN_OVERRIDE_USEDu   누락된 예외 상태: 
>assert not %(py0)srJ   missing_exceptionN
DISPATCHEDACKEDrX   )r   rW   u(   누락된 정상 상태 (alias 없음): 
unresolved)syspathinsertr   	WORKSPACE	importlibimport_modulereloadsetSTATESr]   rf   r_   r`   ra   rb   rc   rd   getadd)taskctl_modstatesexpected_normalexpected_exceptionmissing_normalr   rg   @py_format2	alias_mapr   maliasess               r   .test_state_enum_includes_14_normal_5_exceptionr   
  s   
 HHOOAs9y012--i8%##$FO %v-N*V3 ! Q QQ$=>O=P"QQQQQQQ QQQ QQQQQQ  ,W5%
	 U
 	"AmmAsu-Gf$q!	" ~V~VV!I*VVVVVVV:VVV:VVVVVV ) 	s   *G Gc                 @   t         j                  j                  dt        t        dz               	 t        j                  d      } t        j                  |        	 | j                  }h d}dh}||z
  }| }|s~t        j                  d|       dz   dd	t        j                         v st        j                  |      rt        j                  |      nd	iz  }t        t        j                   |            d
}||z
  }|rt#        j$                  d|        y
y
# w xY w)uy   DONE/CANCELLED/FAILED/ADMIN_OVERRIDE_USED는 terminal 상태.

    TERMINAL_STATES에 반드시 포함되어야 함.
    r   r   r   >   r   r   r   r   u    누락된 core terminal 상태: r   rJ   missing_coreNu8   신규 terminal 상태 미구현 (스바로그 대기): )r   r   r   r   r   r   r   r   TERMINAL_STATESr]   rf   r_   r`   ra   rb   rc   rd   pytestxfail)r   terminalexpectedexpected_newr   rg   r   missing_news           r   'test_terminal_states_no_transitions_outr   6  s    
 HHOOAs9y012--i8%**H.H)*Lh&LNNN?~NNNNNNN|NNN|NNNNNN )KOP[}]^  	s   *D D)r   r   returndict)r!   z	list[str]r   r   r   zsubprocess.CompletedProcess)r   r   r(   r   r   r   )r   r   r(   r   r=   r   r   None) __doc__
__future__r   builtinsr_   _pytest.assertion.rewrite	assertionrewriter]   r   r%   r   r   r   pathlibr   r   r   r    r   r"   r*   rC   rs   r   r   r   r   r   r   r   r    r   r   <module>r     s   
 #      	  
  @A	
i
,
.%
B.F6>6.1$D)WX_r   