
    Pj0U                    z   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mZ ddlmZmZmZ ddlZ ee      j)                         j*                  d   Z ee      ej0                  vr"ej0                  j3                  d ee             ddlmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z* dddZ+d	Z,d
Z-ej\                  dd       Z/ej\                  dd       Z0ej\                  dd       Z1ej\                  	 	 	 	 	 	 	 	 d d       Z2	 	 	 	 	 	 	 	 	 	 	 	 	 	 d!dZ3d"dZ4d"dZ5	 	 	 	 	 	 	 	 	 	 	 	 d#dZ6	 	 	 	 	 	 	 	 	 	 d$dZ7	 	 	 	 	 	 	 	 	 	 d$dZ8	 	 	 	 	 	 	 	 	 	 d$dZ9	 	 	 	 	 	 	 	 	 	 	 	 d#dZ:	 	 	 	 	 	 	 	 	 	 d%dZ;	 	 	 	 	 	 	 	 	 	 d%dZ<d"dZ=	 	 	 	 	 	 	 	 	 	 d$dZ>	 	 	 	 	 	 	 	 	 	 d&dZ?	 	 	 	 	 	 	 	 d'dZ@y)(u  anu_v2.tests.test_owner_trigger_pat_phase2_2553 — Phase 2 trigger-only comment writer.

회장 §명시 Phase 2 (task-2553):
  - comment body 정확히 `/gemini review` (strict equality, 다른 body fail-fast)
  - endpoint allowlist (issue comment POST 1 endpoint 외 차단)
  - merge/approve/close/reopen/push API 호출 0 정적 차단
  - audit append-only 에 token_present + token_hash 만 (token raw 0)
  - happy path: queue-head + evidence missing + dedupe clean + token loaded → comment posted

mock 패턴은 `test_merge_queue_executor_2531.py` 와 동일 — `subprocess.CompletedProcess`
mock + audit_calls list collector.
    )annotationsN)Path)AnyMappingSequence   )ACTOR_OWNER_TRIGGER_PATALLOWED_COMMENT_BODYDECISION_PASSDECISION_REJECTERR_BODY_NOT_ALLOWEDERR_ENDPOINT_NOT_ALLOWED!EVIDENCE_MISSING_FOR_CURRENT_HEADOUTCOME_FAILED
OUTCOME_OKOUTCOME_REJECTEDOWNER_PAT_ENV_NAMEOwnerTriggerPatassert_body_allowedassert_endpoint_allowedserialize_decisionwrite_decision_jsonc                4    t        j                  g | ||      S )N)args
returncodestdoutstderr)
subprocessCompletedProcess)r   r   r   s      F/home/jay/workspace/anu_v2/tests/test_owner_trigger_pat_phase2_2553.py_cpr!   2   s    &&B:f]cdd    %github_pat_FAKE_OWNER_TRIGGER_TOKEN_Xz2026-05-11T12:00:00+00:00c                     g S N r&   r"   r    gh_callsr'   :       Ir"   c                     g S r%   r&   r&   r"   r    audit_callsr*   ?   r(   r"   c                     g S r%   r&   r&   r"   r    decision_callsr,   D   r(   r"   c                P     d fd}d	fd}d
fd}t        |||ddd       S )Nc                l    j                  t        |       t        |xs i       d       t               S )Nr   env)appendlistdictr!   )r   r0   r'   s     r    	gh_runnerztrigger.<locals>.gh_runnerO   s'    dDODEur"   c                :    j                  t        |              y r%   r1   r3   recordr*   s    r    audit_writerztrigger.<locals>.audit_writerS       4<(r"   c                j    j                  t        |       t        |      d       t        | |       y Npayloadpathr1   r3   strr   r>   r?   r,   s     r    decision_writerz trigger.<locals>.decision_writerV   s(    $w-TKLGT*r"   jeon-jonghyuktaskctl-anuc                     t         S r%   	_FIXED_TSr&   r"   r    <lambda>ztrigger.<locals>.<lambda>a       i r"   r4   r9   rC   ownerrepoclockr   zSequence[str]r0   zMapping[str, str]returnsubprocess.CompletedProcessr8   Mapping[str, Any]rP   Noner>   rS   r?   r   rP   rT   )r   )r'   r*   r,   r4   r9   rC   s   ```   r    triggerrV   I   s3    )+
 !' r"   c                   |j                  t        t               | dz  }| dz  }|j                  dddt        ||      }|j
                  }	|	t        k(  }
|
st        j                  d|
fd|	t        f      d	t        j                         v st        j                  |      rt        j                  |      nd	t        j                  |	      d
t        j                         v st        j                  t              rt        j                  t              nd
dz  }dd|iz  }t        t        j                  |            d x}	}
|j                  }	t!        |      }|	|k(  }
|
s7t        j                  d|
fd|	|f      d	t        j                         v st        j                  |      rt        j                  |      nd	t        j                  |	      dt        j                         v st        j                  t               rt        j                  t               nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            d x}	x}
}t#        |      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t"              rt        j                  t"              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}|d   }|d   }ddddd d!t$         g}
||
k(  }|slt        j                  d|fd"||
f      t        j                  |      t        j                  |
      d#z  }dd|iz  }t        t        j                  |            d x}x}}
|d$   d%   }|t        k(  }|st        j                  d|fd&|t        f      t        j                  |      d't        j                         v st        j                  t              rt        j                  t              nd'd(z  }d)d*|iz  }t        t        j                  |            d x}}|d$   d+   }|t        k(  }|st        j                  d|fd&|t        f      t        j                  |      d't        j                         v st        j                  t              rt        j                  t              nd'd(z  }d)d*|iz  }t        t        j                  |            d x}}|j&                  }	 |	       }
|
sd,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/   }|t.        k(  }|st        j                  d|fd&|t.        f      t        j                  |      d0t        j                         v st        j                  t.              rt        j                  t.              nd0d(z  }d)d*|iz  }t        t        j                  |            d x}}|d1   }d}
||
k(  }|slt        j                  d|fd"||
f      t        j                  |      t        j                  |
      d#z  }dd|iz  }t        t        j                  |            d x}x}}
|d2   }d3}
||
k(  }|slt        j                  d|fd"||
f      t        j                  |      t        j                  |
      d#z  }dd|iz  }t        t        j                  |            d x}x}}
|d4   }|t0        k(  }|st        j                  d|fd&|t0        f      t        j                  |      d5t        j                         v st        j                  t0              rt        j                  t0              nd5d(z  }d)d*|iz  }t        t        j                  |            d x}}t#        |      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t"              rt        j                  t"              ndd6t        j                         v st        j                  |      rt        j                  |      nd6t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}|d   }|d7   }|t        k(  }|st        j                  d|fd&|t        f      t        j                  |      d
t        j                         v st        j                  t              rt        j                  t              nd
d(z  }d)d*|iz  }t        t        j                  |            d x}}|d8   }d9}
||
u }|slt        j                  d:|fd;||
f      t        j                  |      t        j                  |
      d#z  }dd|iz  }t        t        j                  |            d x}x}}
|d<   }|s8d=d>t        j                  |      iz  }t        t        j                  |            d }|d<   }	t#        |	      }
d?}|
|k(  }|st        j                  d|fd@|
|f      dt        j                         v st        j                  t"              rt        j                  t"              ndt        j                  |	      t        j                  |
      t        j                  |      dAz  }dd|iz  }t        t        j                  |            d x}	x}
x}}|dB   }|t2        k(  }|st        j                  d|fd&|t2        f      t        j                  |      dCt        j                         v st        j                  t2              rt        j                  t2              ndCd(z  }d)d*|iz  }t        t        j                  |            d x}}|j5                         D ]L  }t!        |      }t        |v}	|	s/t        j                  dD|	fdEt        |f      d't        j                         v st        j                  t              rt        j                  t              nd'dt        j                         v st        j                  t               rt        j                  t               nddFt        j                         v st        j                  |      rt        j                  |      ndFt        j                  |      dGz  }dHdI|iz  }t        t        j                  |            d x}	}O y )JNzowner_trigger_audit.jsonlzowner_trigger_decision.jsonQ   deadbeefr   	pr_numberhead_shaqueue_positiongemini_evidence_stateaudit_log_pathdecision_json_path==z/%(py2)s
{%(py2)s = %(py0)s.outcome
} == %(py4)soutr   py0py2py4assert %(py6)spy6)zS%(py2)s
{%(py2)s = %(py0)s.decision_path
} == %(py7)s
{%(py7)s = %(py4)s(%(py5)s)
}rA   decision_pathrf   rg   rh   py5py7assert %(py9)spy9   z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slenr'   rf   py1py3rj   assert %(py8)spy8r   apiz-XPOST3/repos/jeon-jonghyuk/taskctl-anu/issues/81/commentsz-fbody=z%(py1)s == %(py4)sru   rh   r0   GH_TOKENz%(py1)s == %(py3)s_FAKE_TOKENru   rv   assert %(py5)srm   GITHUB_TOKENzAassert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}utf-8encodingdecisionr   r[   
dedupe_key81#deadbeeftsrH   r*   outcometoken_presentTisz%(py1)s is %(py4)s
token_hashassert %(py1)sru      )z0%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} == %(py7)s)rf   rg   rh   rn   actorr	   not in)z4%(py0)s not in %(py5)s
{%(py5)s = %(py2)s(%(py3)s)
}value)rf   rg   rv   rm   assert %(py7)srn   )setenvr   r   trigger_gemini_reviewr   r   r   
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationrk   rA   rs   r
   existsjsonloads	read_textr   rH   r	   values)tmp_pathrV   r'   r*   r,   monkeypatch
audit_pathrk   rd   @py_assert1@py_assert3@py_format5@py_format7@py_assert6@py_format8@py_format10@py_assert2@py_assert5@py_assert4@py_format9call@py_assert0@py_format4@py_format6decision_datar8   @py_format2r   s                               r    %test_phase2_happy_path_comment_postedr   f   sr    );777J<<M

'
'?!( ( C ;;$;*$$$$;*$$$$$$3$$$3$$$;$$$$$$*$$$*$$$$$$$2M 22 22222 222222232223222222222222222222M222M222 22222222x=A=A=A33xx=AA;D< tV=*+, <    	<    	    	     	  ;z"1"k1111"k111"111111k111k1111111;~&5&+5555&+555&555555+555+5555555 !!!!!!!!!=!!!=!!!!!!!!!!!!!JJ}666HIM$5$5555$555$5555555555555555%++%++++%+++%++++++++++&7-7&-7777&-777&777-7777777+)++++)+++++++++)+++)+++++++ { q q    q      3   3      {   {      q       ^F)*
****
*********
***
*******/"*d*"d****"d***"***d*******,l#*3#$**$****$******3***3***#***$**********'?5?55555?5555?555555555555555555 -"%e*,{*,,,,{*,,,,,,{,,,{,,,,,,#,,,#,,,,,,e,,,e,,,*,,,,,,,-r"   c            	     ~   t        t               dD ]  } t        j                  t              5 }t        |        d d d        j
                  }t        |      }t        |v }|sCt        j                  d|fdt        |f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd	|iz  }t        t        j                  |            d x}x}} y # 1 sw Y   yxY w)
N)z/gemini  reviewz /gemini reviewz/gemini review z/Gemini reviewz/gemini review
z/gemini review pleasez/gemini-review inzK%(py0)s in %(py7)s
{%(py7)s = %(py2)s(%(py5)s
{%(py5)s = %(py3)s.value
})
}r   rA   excrf   rg   rv   rm   rn   ro   rp   )r   r
   pytestraisesRuntimeErrorr   rA   r   r   r   r   r   r   r   r   r   )badr   r   r   r   r   r   s          r    /test_phase2_assert_body_allowed_strict_equalityr      s    ,-	 6 ]]<( 	%C$	%+.995s9~5#~5555#~555555#555#555555s555s555555355535559555~55555556	% 	%s   F22F<	c            	        t        dddd       g d} | D ]  }t        j                  t              5 }t        |ddd       ddd       j                  }t        |      }t        |v }|sCt        j                  d|fdt        |f      d	t        j                         v st        j                  t              rt        j                  t              nd	d
t        j                         v st        j                  t
              rt        j                  t
              nd
dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}} y# 1 sw Y   yxY w)uB   endpoint 가 정확히 issue comments POST path 일 때만 허용.r{   rD   rE   rX   )z//repos/jeon-jonghyuk/taskctl-anu/pulls/81/mergez1/repos/jeon-jonghyuk/taskctl-anu/pulls/81/reviewsz3/repos/jeon-jonghyuk/taskctl-anu/issues/82/commentsz+/repos/other/taskctl-anu/issues/81/commentsz2/repos/jeon-jonghyuk/other-repo/issues/81/commentsz4/repos/jeon-jonghyuk/taskctl-anu/git/refs/heads/mainNr   r   r   rA   r   r   ro   rp   )r   r   r   r   r   rA   r   r   r   r   r   r   r   r   r   )forbidden_endpointsepr   r   r   r   r   r   s           r    7test_phase2_assert_endpoint_allowed_only_issue_commentsr      s   = " :]]<( 	LC#BK	L/2yy93y>9'>9999'>999999'999'99999939993999999s999s999y999>9999999:	L 	Ls   F88G	c                   |j                  t        t               | dz  }| dz  }|j                  dddt        ||      }|j
                  }|t        k(  }	|	st        j                  d|	fd|t        f      d	t        j                         v st        j                  |      rt        j                  |      nd	t        j                  |      d
t        j                         v st        j                  t              rt        j                  t              nd
dz  }
dd|
iz  }t        t        j                  |            d x}}	d}|j                  }||v }|st        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  }t        t        j                  |            d x}x}}t!        |      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t               rt        j                  t               nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}t#        j$                  |j'                  d            }|d   }|t(        k(  }|st        j                  d|fd|t(        f      t        j                  |      dt        j                         v st        j                  t(              rt        j                  t(              ndd z  }d!d"|iz  }t        t        j                  |            d x}}|d   d#   }d$}	||	u }|slt        j                  d%|fd&||	f      t        j                  |      t        j                  |	      d'z  }
dd|
iz  }t        t        j                  |            d x}x}}	y )(Naudit.jsonldecision.jsonrX   rY   r   rZ   ra   rc   rd   r   re   ri   rj   not_queue_headr   z.%(py1)s in %(py5)s
{%(py5)s = %(py3)s.reason
}ru   rv   rm   r   rn   r   rr   rs   r'   rt   rw   rx   r   r   r   r   r   r   r   rm   r   Fr   r   r~   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   reasonrs   r   r   r   r   )r   rV   r'   r*   r   r   rk   rd   r   r   r   r   r   r   r   r   r   r   r   r   r   s                        r    #test_phase2_non_queue_head_rejectedr      s    );7M)J.M

'
'?!( ( C ;;*;*****;*******3***3***;******************)szz)z))))z)))))))))s)))s)))z)))))))x=A=A=A33xx=AJJ}666HIM$7$7777$777$7777777777777777q>/*3e3*e3333*e333*333e3333333r"   c                *   |j                  t        t               | dz  }| dz  }|j                  dddd||      }|j                  }|t
        k(  }|st        j                  d|fd	|t
        f      d
t        j                         v st        j                  |      rt        j                  |      nd
t        j                  |      dt        j                         v st        j                  t
              rt        j                  t
              nddz  }	dd|	iz  }
t        t        j                  |
            d x}}d}|j                  }||v }|st        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  }t        t        j                  |            d x}x}}t        |      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }
dd|
iz  }t        t        j                  |            d x}x}}y )Nr   r   rX   rY   r   present_for_current_headrZ   ra   rc   rd   r   re   ri   rj   evidence_not_missingr   r   r   r   rn   rr   rs   r'   rt   rw   rx   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rs   )r   rV   r'   r   r   rk   rd   r   r   r   r   r   r   r   r   r   r   r   s                     r    )test_phase2_evidence_not_missing_rejectedr      s    );7M)J.M

'
'8!( ( C ;;*;*****;*******3***3***;******************!/SZZ/!Z////!Z///!//////S///S///Z///////x=A=A=A33xx=Ar"   c                
   |j                  t        t               | dz  }| dz  }|j                  dddt        ||      }|j
                  }|t        k(  }|st        j                  d|fd|t        f      d	t        j                         v st        j                  |      rt        j                  |      nd	t        j                  |      d
t        j                         v st        j                  t              rt        j                  t              nd
dz  }	dd|	iz  }
t        t        j                  |
            d x}}t        |      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }
dd|
iz  }t        t        j                  |            d x}x}}|j!                  t#        j$                  dt        d      dz   d       |j                  dddt        ||      }|j
                  }|t&        k(  }|st        j                  d|fd|t&        f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dt        j                         v st        j                  t&              rt        j                  t&              nddz  }	dd|	iz  }
t        t        j                  |
            d x}}d}|j(                  }||v }|st        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  }t        t        j                  |            d x}x}}t        |      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }
dd|
iz  }t        t        j                  |            d x}x}}y )"Nr   r   rX   rY   r   rZ   ra   rc   out1r   re   ri   rj   rq   rr   rs   r'   rt   rw   rx   r   r   r   
r   r   out2r   duplicate_triggerr   r   r   r   rn   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rs   
write_textr   dumpsr   r   )r   rV   r'   r   r   rk   r   r   r   r   r   r   r   r   r   r   r   r   r   s                      r    %test_phase2_duplicate_trigger_blockedr      s1    );7M)J.M ((?!( ) D <<%<:%%%%<:%%%%%%4%%%4%%%<%%%%%%:%%%:%%%%%%%x=A=A=A33xx=A
 

-JGH4O   ((?!( ) D <<+<+++++<+++++++4+++4+++<++++++++++++++++++-$++-+----+---------$---$---+-------x=A=A=A33xx=Ar"   c                   |j                  t        t               | dz  }| dz  }|j                  t	        j
                  dt        d      dz   d       |j                  dd	d
t        ||      }|j                  }|t        k(  }|st        j                  d|fd|t        f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dt        j                         v st        j                  t              rt        j                  t              nddz  }	dd|	iz  }
t!        t        j"                  |
            dx}}t%        |      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t$              rt        j                  t$              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }
dd|
iz  }t!        t        j"                  |            dx}x}}y)uC   update-branch 후 새 head 면 dedupe stale — 새 trigger 허용.r   r   z	81#OLDSHAr   r   r   r   rX   NEWSHAr   rZ   ra   rc   rd   r   re   ri   rj   Nrq   rr   rs   r'   rt   rw   rx   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rs   )r   rV   r'   r   r   rk   rd   r   r   r   r   r   r   r   r   s                  r    'test_phase2_new_head_allows_new_triggerr   )  s    );7M)J.M 

+*EFM  
 
'
'?!( ( C ;;$;*$$$$;*$$$$$$3$$$3$$$;$$$$$$*$$$*$$$$$$$x=A=A=A33xx=Ar"   c                p   |j                  t        d       |j                  dd       |j                  dd       | dz  }| dz  }|j                  dd	d
t        ||      }|j
                  }|t        k(  }	|	st        j                  d|	fd|t        f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dt        j                         v st        j                  t              rt        j                  t              nddz  }
dd|
iz  }t        t        j                  |            d x}}	d}|j                  }||v }|st        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  }t        t        j                  |            d x}x}}t!        |      }d
}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t               rt        j                  t               nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}|d   }|d    }d}	||	u }|slt        j                  d!|fd"||	f      t        j                  |      t        j                  |	      d#z  }
dd|
iz  }t        t        j                  |            d x}x}}	|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}}	d}t"        j$                  } ||      }||v}|s
t        j                  d'|fd(||f      t        j                  |      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                  |      d+z  }d,d-|iz  }t        t        j                  |            d x}x}x}}d}|j                  }||v}|st        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  }t        t        j                  |            d x}x}}y )/NF)raisingr   ghp_LEAKABLE_BOTr   r   r   rX   rY   r   rZ   ra   rc   rd   r   re   ri   rj   token_missingr   r   r   r   rn   rr   rs   r'   rt   rw   rx   r   r   r   r~   r   r   r}   r   )zO%(py1)s not in %(py8)s
{%(py8)s = %(py5)s
{%(py5)s = %(py3)s.dumps
}(%(py6)s)
}r   r8   )ru   rv   rm   rj   rx   zassert %(py10)spy10)z2%(py1)s not in %(py5)s
{%(py5)s = %(py3)s.reason
})delenvr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rs   r   r   )r   rV   r'   r*   r   r   rk   rd   r   r   r   r   r   r   r   r   r   r   r   r8   @py_assert7@py_format11s                         r    "test_phase2_token_missing_rejectedr   G  s    )59z#56~'9:M)J.M

'
'?!( ( C ;;*;*****;*******3***3***;******************(cjj(?j((((?j(((?((((((c(((c(((j(((((((x=A=A=A33xx=A_F/"+e+"e++++"e+++"+++e+++++++,%2%2%%%%2%%%%%%2%%%%%%%7TZZ7Z%77%77777%7777777777T777T777Z777777777777%77777777/SZZ/Z////Z/////////S///S///Z///////r"   c                
   |j                  t        t               d-d}d.fd}d/fd}t        |||ddd       }| d	z  }| d
z  }	|j	                  dddt
        ||	      }
|
j                  }|t        k(  }|st        j                  d|fd|t        f      dt        j                         v st        j                  |
      rt        j                  |
      ndt        j                  |      dt        j                         v st        j                  t              rt        j                  t              nddz  }dd|iz  }t        t        j                  |            d x}}|
j                   }t        |v}|st        j                  d|fdt        |f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |
      rt        j                  |
      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            d x}}d}|
j                   }||v }|st        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  }t        t        j                  |            d x}x}}d   }t"        j$                  } ||      }t        |v}|sCt        j                  d|fd t        |f      dt        j                         v st        j                  t              rt        j                  t              nd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                  |      d"z  }d#d$|iz  }t        t        j                  |            d x}x}}|d%   }d&}||u }|slt        j                  d'|fd(||f      t        j                  |      t        j                  |      d)z  }dd|iz  }t        t        j                  |            d x}x}}|d*   }|s8d+d,t        j                  |      iz  }t        t        j                  |            d }y )0Nc                ,    t        ddt         d      S )Nrq   z401 unauthorized: token=z expired)r   r   )r!   r   r/   s     r    
failing_ghz?test_phase2_gh_runner_failure_redacts_token.<locals>.failing_ght  s    -k](C
 	
r"   r8   c                :    j                  t        |              y r%   r6   r7   s    r    r9   zAtest_phase2_gh_runner_failure_redacts_token.<locals>.audit_writer{  r:   r"   c                j    j                  t        |       t        |      d       t        | |       y r<   r@   rB   s     r    rC   zDtest_phase2_gh_runner_failure_redacts_token.<locals>.decision_writer~  (    $w-TKLGT*r"   rD   rE   c                     t         S r%   rG   r&   r"   r    rI   z=test_phase2_gh_runner_failure_redacts_token.<locals>.<lambda>  rJ   r"   rK   r   r   rX   rY   r   rZ   ra   rc   rd   r   re   ri   rj   r   z2%(py0)s not in %(py4)s
{%(py4)s = %(py2)s.reason
}r   z***REDACTED***r   r   r   r   rn   r   zO%(py0)s not in %(py7)s
{%(py7)s = %(py4)s
{%(py4)s = %(py2)s.dumps
}(%(py5)s)
}r   rl   ro   rp   r   Tr   r   r~   r   r   ru   rO   rR   rU   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r*   r,   r   r   r9   rC   tr   rk   rd   r   r   r   r   r   r   r   r   r   r8   r   r   r   s    ``                     r    +test_phase2_gh_runner_failure_redacts_tokenr   l  s$    );7
)+ 	!'	A M)J.M

!
!?!( " C ;;(;.((((;.((((((3(((3(((;((((((.(((.(((((((!jj(;j((((;j((((((;(((;((((((c(((c(((j((((((()szz)z))))z)))))))))s)))s)))z)))))))_F"jj0j00;00000;0000000;000;000000d000d000j00000000000000000000/"*d*"d****"d***"***d*******,r"   c                   |j                  t        t               dd}d fd}d!fd}t        |||ddd       }| d	z  }| d
z  }	|j	                  dddt
        ||	      }
|
j                  }|t        k(  }|st        j                  d|fd|t        f      dt        j                         v st        j                  |
      rt        j                  |
      ndt        j                  |      dt        j                         v st        j                  t              rt        j                  t              nddz  }dd|iz  }t        t        j                  |            d x}}|
j                   }t        |v}|st        j                  d|fdt        |f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |
      rt        j                  |
      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            d x}}d   }t"        j$                  } ||      }t        |v}|sCt        j                  d|fdt        |f      dt        j                         v st        j                  t              rt        j                  t              nd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                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}y )"Nc                &    t        dt               )Nzconnect failed with creds )OSErrorr   r/   s     r    
raising_ghzAtest_phase2_gh_runner_exception_redacts_token.<locals>.raising_gh  s    2;-@AAr"   r8   c                :    j                  t        |              y r%   r6   r7   s    r    r9   zCtest_phase2_gh_runner_exception_redacts_token.<locals>.audit_writer  r:   r"   c                j    j                  t        |       t        |      d       t        | |       y r<   r@   rB   s     r    rC   zFtest_phase2_gh_runner_exception_redacts_token.<locals>.decision_writer  r   r"   rD   rE   c                     t         S r%   rG   r&   r"   r    rI   z?test_phase2_gh_runner_exception_redacts_token.<locals>.<lambda>  rJ   r"   rK   r   r   rX   rY   r   rZ   ra   rc   rd   r   re   ri   rj   r   r   r   r   r   r   rl   ro   rp   rO   rR   rU   r   )r   r*   r,   r   r   r9   rC   r   r   rk   rd   r   r   r   r   r8   r   r   r   s    ``                r    -test_phase2_gh_runner_exception_redacts_tokenr    s7    );7B)+ 	!'	A M)J.M

!
!?!( " C ;;(;.((((;.((((((3(((3(((;((((((.(((.(((((((!jj(;j((((;j((((((;(((;((((((c(((c(((j(((((((_F"jj0j00;00000;0000000;000;000000d000d000j00000000000000000000r"   c            	         dd} dd}d	d}dD ]7  \  }}t        j                  t              5  t        | ||||       ddd       9 y# 1 sw Y   DxY w)
uD   owner / repo 에 path traversal / 빈 값 등 입력 시 ValueError.c                    t               S r%   )r!   r/   s     r    noop_ghz8test_phase2_invalid_owner_repo_rejected.<locals>.noop_gh  s	    ur"   c                     y r%   r&   )r8   s    r    
noop_auditz;test_phase2_invalid_owner_repo_rejected.<locals>.noop_audit      r"   c                     y r%   r&   r=   s     r    noop_decisionz>test_phase2_invalid_owner_repo_rejected.<locals>.noop_decision  r  r"   ))r   rM   )rL   r   )zowner/../etcrM   )rL   zrepo with space)z../ownerrM   )r4   r9   rC   rL   rM   NrO   rR   rU   )r   r   
ValueErrorr   )r  r  r
  rL   rM   s        r    'test_phase2_invalid_owner_repo_rejectedr    se     t ]]:& 	!' -	 		 	s   A

A	c                   |j                  t        t               | dz  }| dz  }|j                  dddt        ||       t        |      }d}||k(  }|st        j                  d|fd	||f      d
t        j                         v st        j                  t
              rt        j                  t
              nd
dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            dx}x}}|d   d   }d}dj                  |      }|D ]  }||v}|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d} dt         }||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}}y) uW   모든 happy-path trigger 호출의 args 가 issue comments POST 외 다른 fragment 0.r   r   rX   rY   r   rZ   rq   ra   rr   rs   r'   rt   rw   rx   Nr   )z/mergesz/reviewsz/pulls/z
/branches/z	/git/refsz/merge r   z%(py0)s not in %(py2)sfragflatrf   rg   assert %(py4)srh   r|   r   )z%(py1)s in %(py3)sr   r   rm   )r   r   r   r   r   rs   r   r   r   r   r   r   r   r   joinr
   )r   rV   r'   r   r   rk   r   r   r   r   r   r   	forbiddenr  r  r   @py_format3r   r   r   r   s                        r    -test_phase2_security_only_one_endpoint_calledr    s    );7M)J.M!!?!( "  x=A=A=A33xx=AA;vDWI88D>D  4t4tt44  '()1)T1111)T111)111111T111T1111111r"   c                	   |j                  t        t               | dz  }| dz  }|j                  dddt        ||       |d   }t        j                  |d	      }t        |v}|st        j                  d
|fdt        |f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      nddz  }	dd|	iz  }
t        t        j                  |
            d}|d   }d}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }
dd|
iz  }t        t        j                  |            dx}x}}|d   }|s8ddt        j                  |      iz  }t        t        j                  |            d}|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}}|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}}|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}}|d!   }|t        k(  }|st        j                  d|fd"|t        f      t        j                  |      d#t        j                         v st        j                  t              rt        j                  t              nd#d$z  }d%d&|iz  }t        t        j                  |            dx}}|d'   }|t         k(  }|st        j                  d|fd"|t         f      t        j                  |      d(t        j                         v st        j                  t               rt        j                  t               nd(d$z  }d%d&|iz  }t        t        j                  |            dx}}y))uE   audit record 안의 모든 값에 token raw 0 (직렬화 후 검증).r   r   rX   rY   r   rZ   r   T)	sort_keysr   r  r   
serializedr  r  rh   Nr   r   r   r~   ri   rj   r   r   ru   r[   ra   r}   r\   r   r   r   r   r   r   r   rm   r   r	   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r	   )r   rV   r*   r   r   rk   r8   r  r   r  r   r   r   r   r   r   r   r   s                     r    'test_phase2_audit_record_token_raw_zeror    s    );7M)J.M!!?!( "  _FFd3Jj((((;j((((((;(((;((((((j(((j(((((((/"*d*"d****"d***"***d*******,+$"$"$$$$"$$$$$$"$$$$$$$*+++++++++++++++++++,0=0=0000=000000=0000000)*
****
*********
***
*******'?5?55555?5555?555555555555555555r"   c                R   ddl m} |j                  t        t               | dz  }| dz  }|j                  dddt        ||       |j                  d	      }t        |v}|st        j                  d
|fdt        |f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }	t        t        j                  |	            d}t!        j"                  |      }
|
d   }|t$        k(  }|st        j                  d|fd|t$        f      t        j                  |      dt        j                         v st        j                  t$              rt        j                  t$              nddz  }dd|iz  }t        t        j                  |            dx}} ||
d   |
d   |
d   |
d   |
d   |
d   |
d   |
d          }t!        j&                  t)        |            }t        |v}|st        j                  d
|fdt        |f      dt        j                         v st        j                  t              rt        j                  t              ndd!t        j                         v st        j                  |      rt        j                  |      nd!dz  }dd|iz  }	t        t        j                  |	            d}y)"u   decision JSON 박제 결과에 token raw 0 (PASS 케이스).

    decision 파일 내용 + serialize_decision 회로 둘 다 검증.
    r   )OwnerTriggerDecisionr   r   rX   rY   rZ   r   r   r   r  r   decision_textr  r  rh   Nr   ra   r   r   r   r   rm   r[   r\   r   r^   r]   r   r   )r[   r\   r   r   r^   r]   r   r   serialized_again)anu_v2.owner_trigger_patr  r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   rV   r   r  r   rk   r  r   r  r   r>   r   r   r   r   reconstructedr  s                    r    1test_phase2_serialize_decision_no_token_in_outputr"  +  s    >);7M)J.M!!?!( "  "++W+=Mm++++;m++++++;+++;++++++m+++m+++++++jj'G:/-////-/////////-///-///////(+&$$x %&=>/0<(4=	M zz"4]"CD.....;.......;...;..................r"   )r   r   r   )r   intr   rA   r   rA   rP   rQ   )rP   list[dict[str, Any]])r'   r$  r*   r$  r,   r$  rP   r   )r   r   rV   r   r'   r$  r*   r$  r,   r$  r   pytest.MonkeyPatchrP   rT   )rP   rT   )r   r   rV   r   r'   r$  r*   r$  r   r%  rP   rT   )
r   r   rV   r   r'   r$  r   r%  rP   rT   )
r   r   r*   r$  r,   r$  r   r%  rP   rT   )
r   r   rV   r   r*   r$  r   r%  rP   rT   )r   r   rV   r   r   r%  rP   rT   )A__doc__
__future__r   builtinsr   _pytest.assertion.rewrite	assertionrewriter   r   r   syspathlibr   typingr   r   r   r   __file__resolveparentsWORKSPACE_ROOTrA   r?   insertr   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r!   r   rH   fixturer'   r*   r,   rV   r   r   r   r   r   r   r   r   r   r  r  r  r  r"  r&   r"   r    <module>r5     s   #     
  ) )  h'')11!4~chh&HHOOAs>*+    *e 6'	       "% ) 	 86-6-6- #6- &	6-
 )6- $6- 
6-t6$:*444 #4 &	4
 $4 
4> # $	
 
0((( #( $	(
 
(V # $	
 
<!0!0!0 #!0 &	!0
 $!0 
!0J2 2 %2  )2  $	2 
 
2 l*1*1%*1 )*1 $	*1
 
*1\:222 #2 $	2
 
2<666 &6 $	6
 
6@(/(/(/ $(/ 
	(/r"   