
    i                    h   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	m
Z
 ddlmZ ddlZ e
e      j                         j                   d   ZddZ ej&                         dd       Zdd	Zdd
Zej.                  j1                  dg d      	 	 	 	 	 	 dd       ZddZddZddZddZddZy)u  tests/regression/test_finish_task_routing.py — task-2471+1 자동화 회귀.

회장 명령 (A): ``finish-task`` 자동화 경로 — state machine 라우팅 검증.

dry-run 모드에서 현재 state별 다음 액션 라우팅을 검증한다 (실제 gh / git 호출
불필요). 잘못된 routing / no_route 상태에서 fail-closed (exit 1) 검증.

검증 routing:
- COMMITTED → pr-open
- PR_OPEN → ci-check
- CI_PENDING → gemini-evidence
- GEMINI_PENDING → review-ready
- REVIEW_READY → verify
- VERIFIED → approve
- HUMAN_APPROVED → merge
- MERGED → done
- DONE → halt (steps_taken=0, no action)
- terminal non-DONE (FAILED/CANCELLED) → halt fail
    )annotationsN)Path)Any   c                p   | j                  dt        |             t        j                  j	                  dt        t
        dz  dz              }|r|j                  sJ t        j                  j                  |      }|t        j                  |j                  <   |j                  j                  |       |S )NWORKSPACE_ROOTtaskctl_isolated_finishscriptsz
taskctl.py)setenvstr	importlibutilspec_from_file_location	WORKSPACEloadermodule_from_specsysmodulesnameexec_module)monkeypatchrootspecmods       \/home/jay/workspace/.worktrees/task-2471+1-dev2/tests/regression/test_finish_task_routing.py_load_taskctlr   #   s    'T3>>11!I	!L01D DKK
..
)
)$
/C CKK		KKC J    c                    | dz  dz  }| dz  dz  }| dz  dz  }| dz  dz  }||||fD ]  }|j                  dd        t        ||       }| |||d	S )
Nz.tasksstateevidencememoryeventszorchestration-auditT)parentsexist_ok)tmp_pathr   	state_dir
events_dir)mkdirr   )r%   r   r&   evidence_dirr'   	audit_dirdr   s           r   isolatedr,   0   s    8#g-Ih&3LH$x/J8#&;;Iz9= -	t,-
X
.C 	 r   c                <   ||g d g ddd i d d d i d
ddd d ddd d d d dd}t        j                  |ddd	
      }t        j                  |j	                  d            j                         |d<   | | dz  j                  t        j                  |dd      d       y )Nztask/x-dev0   )
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)r9   r:   r;   reasonaudit_log_offset)task_idcurrent_statetransitionsr    human_approvedbypassadmin_overrideT),:)ensure_ascii	sort_keys
separatorszutf-8	_checksumz.jsonr   )rF   indent)encoding)jsondumpshashlibsha256encode	hexdigest
write_text)r&   r>   r?   payload	canonicals        r   _write_staterU   A   s    & ##&*#
   t< $
%G4 

et
I #>>)*:*:7*CDNNPGKG9E""..

7q9G / r   c                r    t        j                  | |j                  dd      |j                  dd            S )Ndry_runT	max_steps   )r>   rW   rX   )argparse	Namespaceget)r>   kws     r   _nsr^   e   s4    y$'&&b) r   zsrc_state,expected_action))	COMMITTEDzpr-open)PR_OPENzci-check)
CI_PENDINGzgemini-evidence)GEMINI_PENDINGzreview-ready)REVIEW_READYverify)VERIFIEDapprove)HUMAN_APPROVEDmerge)MERGEDdonec                   d|j                          }t        | d   ||       | d   j                  t        |d             |j	                         j
                  }t        j                         }d}g }|t        |      k  ro||d  j                         }	|	snY|t        ||d        t        |	      z
  z  }|j                  ||d        \  }
}|j                  |
       ||z  }|t        |      k  ro|sJ d       |d   }|j                  d	      sJ d
| d|        |d	   d   }|j                  d      du sJ |d   |k(  sJ |d   |k(  sJ y )Nztask-finish-r&   r   TrW   r   z#no JSON output from cmd_finish_tasklogzempty log for state=z: rW   r   action)lowerrU   cmd_finish_taskr^   
readouterroutrL   JSONDecoderlenlstrip
raw_decodeappendr\   )r,   capsys	src_stateexpected_actionr>   rs   decoderidxobjss_stripobjendrecfirsts                 r   5test_finish_task_dryrun_routes_to_correct_next_actionr   m   sr     Y__./0G+&;UO##C$>?




!
!C  G
CD
C.cd)""$s3st9~G,,%%c#$i0SCs
 C. 6664
r(C775>D1)BseDD>JqME99Y4'''>Y&&&?o---r   c                >   d}t        | d   |d       | d   | dz  j                  d       | d   j                  t        |d	             |j	                         j
                  }t        j                         }d
}g }|t        |      k  rK||   dk7  r|dz  }	 |j                  ||d       \  }}|j                  |       ||z  }|t        |      k  rKt        |      dk\  sJ |d   }	|	d   |k(  sJ |	d   dk(  sJ y# t        j                  $ r |dz  }Y w xY w)uE   이미 DONE이면 추가 액션 없이 verify-consistency 후 종료.ztask-finish-already-doner&   DONEr'   z.donez{}r   Frl   r   {r.   Nrm   r>   final_state)rU   rR   rq   r^   rr   rs   rL   rt   ru   rw   JSONDecodeErrorrx   )
r,   ry   r>   rs   r|   r}   r~   r   r   finals
             r   ,test_finish_task_done_already_short_circuitsr      sE   (G+&8l	//;;DAUO##C$?@




!
!C G
CD
C.s8s?1HC	))#cd)4HC 	Cs
 C. t9>>HEw&&&6))) ## 	1HC	s   D DDc                    d}t        | d   |d       | d   j                  t        |d            }|dk(  sJ |j                         j                  }t        j                  |      }|d   du sJ |d	   dk(  sJ y
)u    FAILED 상태 → halt + exit 1.ztask-finish-failedr&   FAILEDr   Frl   r.   okr   NrU   rq   r^   rr   rs   rL   loadsr,   ry   r>   rcrs   r   s         r   'test_finish_task_terminal_failed_blocksr      s    "G+&:	%	(	(We)D	EB7N7




!
!C
**S/Ct9})))r   c                    d}t        | d   |d       | d   j                  t        |d            }|dk(  sJ |j                         j                  }t        j                  |      }|d   du sJ d	|d
   v sJ y)u>   라우팅 불가능한 state (예: BLOCKED) → halt + exit 1.ztask-finish-blockedr&   BLOCKEDr   Frl   r.   r   zno automation router<   Nr   r   s         r    test_finish_task_no_route_blocksr      s    #G+&;	%	(	(We)D	EB7N7




!
!C
**S/Ct9 CM111r   c                t    d}t        | d   |d       | d   j                  t        |dd            }|dv sJ y	)
uF   max_steps=0 가드는 정수로 강제되며 1 이상 (안전 가드).ztask-finish-guardr&   r_   r   Tr   )rW   rX   )r   r.   N)rU   rq   r^   )r,   r>   r   s      r    test_finish_task_max_steps_guardr      sF    !G+&=	%	(	(GTQ/
B
 <<r   c                    d}t        j                  t              5 }| d   j                  t	        |d             ddd       j
                  j                  dk(  sJ y# 1 sw Y   %xY w)u#   state 파일 없으면 즉시 fail.ztask-finish-no-stater   Frl   Nr.   )pytestraises
SystemExitrq   r^   valuecode)r,   r>   excinfos      r   %test_finish_task_state_missing_blocksr      s_    $G	z	" Eg''GU(CDE=="""E Es    A  A))r   pytest.MonkeyPatchr   r   )r%   r   r   r   )r&   r   r>   r   r?   r   returnNone)r>   r   r   zargparse.Namespace)rz   r   r{   r   r   r   )r   r   )__doc__
__future__r   rZ   rN   importlib.utilr   rL   r   pathlibr   typingr   r   __file__resolver#   r   r   fixturer,   rU   r^   markparametrizer   r   r   r   r   r    r   r   <module>r      s   & #     
   N""$,,Q/	
   !H 	.!$.7:.	..:*6	*	2
#r   