
    " jHz              
      H   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mZ ddlmZmZmZ ddlZ ee      j'                         j(                  d   Z ee      e
j.                  vr"e
j.                  j1                  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)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1 dFdGdZ2d	d
dddde%ddd		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dHdZ3ddddd	 	 	 	 	 	 	 	 	 	 	 dIdZ4ejj                  dJd       Z6ejj                  dKd       Z7ejj                  dLd       Z8ejj                  dMd       Z9dNdZ:dNdZ;dOdZ<	 	 	 	 	 	 dOdZ=	 	 	 	 	 	 dOdZ>dOd Z?dNd!Z@dNd"ZAdNd#ZBdNd$ZCdNd%ZDdNd&ZEdNd'ZF	 	 	 	 dNd(ZG	 	 	 	 dNd)ZHdPd*ZIdPd+ZJdPd,ZKdPd-ZLdNd.ZMdQd/ZN	 	 	 	 dNd0ZO	 	 	 	 dNd1ZPdNd2ZQdNd3ZR	 	 	 	 dNd4ZS	 	 	 	 dNd5ZTdPd6ZUdOd7ZVdQd8ZWdOd9ZX	 	 	 	 dNd:ZYdQd;ZZdQd<Z[	 	 	 	 dQd=Z\dOd>Z]dQd?Z^dQd@Z_dQdAZ`dQdBZadQdCZbdQdDZc	 	 	 	 dQdEZdy)Ru  anu_v2.tests.test_merge_queue_executor_2531 — 9 회귀 (회장 §명시 9 기능 1:1).

회귀 케이스 (회장 §명시):
  1. queue_head_evaluate                      — head task 자동 평가 PASS
  2. expected_files_diff_gate_match           — expected_files == PR diff PASS
  3. expected_files_diff_gate_mismatch        — 불일치 시 BLOCK (비critical)
  4. forbidden_path_gate                      — forbidden_paths hit 시 Critical 7종
  5. ci_gemini_clean_sha_lock                 — 모든 gate + CLEAN + SHA lock 검증
  6. bot_identity_squash_merge                — GH_TOKEN process-local injection (mock gh)
  7. post_merge_smoke                         — 회귀 재실행 PASS
  8. downstream_stale_revalidation            — 다른 OPEN PR evidence 재검증 호출 횟수
  9. critical_7_classification + non_critical_auto
                                              — Critical 7종 분류 + 비critical self-resolve

본 회귀는 anu_v2/* 모듈만 import 한다 (one-way isolation).
    )annotationsN)Path)AnyMappingSequence   )AUTO_MERGE_ALLOWEDAUTO_MERGE_SUCCESSBLOCKED_WITH_REASONCI_FAILURE_BLOCKCRITICAL_BLOCK_OVERRIDECRITICAL_CODESCRITICAL_FORBIDDEN_PATHCRITICAL_GEMINI_SCOPE_EXPANSIONCRITICAL_POST_MERGE_SMOKEDIFF_CONTAMINATIONFORBIDDEN_GIT_FLAGSGEMINI_COMPLETEDGEMINI_SCOPE_EXPANSIONGEMINI_UNRESOLVEDGEMINI_UNRESOLVED_BLOCKHEAD_SHA_LOCK_BROKENMERGE_STATE_NOT_CLEANNON_CRITICAL_AUTO_RESOLVEDWAITING_FOR_PREDECESSORGateOutcomeMergeQueueExecutorPRMetaassert_no_forbidden_git_flagsload_task_spec_from_mdc                4    t        j                  g | ||      S )Nargs
returncodestdoutstderr)
subprocessCompletedProcess)r$   r%   r&   s      B/home/jay/workspace/anu_v2/tests/test_merge_queue_executor_2531.py_cpr*   =   s    &&B:f]cdd    Q   deadbeefztask/task-2531-dev4main)anu_v2/__init__.pyanu_v2/merge_queue_executor.pyanu_v2/tests/__init__.py.anu_v2/tests/test_merge_queue_executor_2531.pyTCLEAN	numberhead_shahead_refbase_refchanged_filesci_required_all_successgemini_statusmerge_state_statusqueue_predecessors_openc        	        <    t        | |||t        |      ||||	      S )Nr4   )r   tupler4   s	            r)   _make_prr@   A   s1    " M* 7#- 7
 
r+   	task-2531 F)task_idexpected	forbiddencherryc               T   d|z   dddg}|D ]  }|j                  d| d        |r-|j                  d       |D ]  }|j                  d| d        |j                  d|rd	nd
        |j                  d       | | dz  }|j                  dj                  |      d       |S )Nz#  z```yamlzexpected_files:z  - ""zforbidden_paths:zcherry_pick_allowed: truefalsez```z.md
utf-8encoding)append
write_textjoin)tmp_pathrC   rD   rE   rF   bodyfps           r)   _write_task_mdrW   _   s     7NB	+<=D "eA3aL!"&' 	&AKK%s!%	&KK'&g'FGHKKgYc?"ALL47L3Hr+   c                     g S NrB   rB   r+   r)   gh_callsrZ   z       Ir+   c                     g S rY   rB   rB   r+   r)   pytest_callsr]      r[   r+   c                     g S rY   rB   rB   r+   r)   audit_callsr_      r[   r+   c                L    fd}d }fd}fd}t        |||||       S )Nc                l    j                  t        |       t        |xs i       d       t               S Nr#   envrP   listdictr*   r#   rd   rZ   s     r)   	gh_runnerzexecutor.<locals>.gh_runner   '    dDODEur+   c                     t               S rY   r*   _argss    r)   
git_runnerzexecutor.<locals>.git_runner   	    ur+   c                :    j                  t        |              yNr   )rP   r?   )r#   r]   s    r)   pytest_runnerzexecutor.<locals>.pytest_runner   s    E$K(r+   c                :    j                  t        |              y rY   rP   rg   )recordr_   s    r)   audit_writerzexecutor.<locals>.audit_writer   s    4<(r+   ri   ro   rs   rw   task_md_root)r   )rS   rZ   r]   r_   ri   ro   rs   rw   s    ```    r)   executorrz      s5    ) #! r+   c                   t        d      }| j                  |      }|j                  }|syddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        t        j                  |            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}}|j                  }d}||k(  }|st        j                  d|fd||f      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=   *assert %(py2)s
{%(py2)s = %(py0)s.passed
}outpy0py2==z0%(py2)s
{%(py2)s = %(py0)s.decision
} == %(py4)sr	   r   r   py4assert %(py6)spy6queue_head_confirmedz.%(py2)s
{%(py2)s = %(py0)s.reason
} == %(py5)sr   r   py5assert %(py7)spy7)r@   evaluate_queue_headpassed@py_builtinslocals
@pytest_ar_should_repr_global_name	_safereprAssertionError_format_explanationdecisionr	   _call_reprcomparereason)rz   prr~   @py_assert1@py_format3@py_assert3@py_format5@py_format7@py_assert4@py_format6@py_format8s              r)   test_1_queue_head_evaluate_passr      sR   	!	,B

&
&r
*C:::33:<<-<-----<-------3---3---<------------------::///://///:///////3///3///:///////////r+   c                   t        d      }| j                  |      }|j                  }| }|syddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        t        j                  |            d x}}|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}
}	y )Nr   r|   .assert not %(py2)s
{%(py2)s = %(py0)s.passed
}r~   r   r   r   r   r   r   r   z2 predecessorin)z.%(py1)s in %(py5)s
{%(py5)s = %(py3)s.reason
}py1py3r   r   r   )r@   r   r   r   r   r   r   r   r   r   r   r   r   r   )rz   r   r~   r   r   @py_format4r   r   @py_assert0r   @py_assert2r   r   s                r)   "test_1_queue_head_evaluate_waitingr      sU   	!	,B

&
&r
*Czzz>>ssz<<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2222(cjj(?j((((?j(((?((((((c(((c(((j(((((((r+   c                |   t        |      }t        |      }t               }| j                  ||      }|j                  }|syddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        t        j                  |            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}}y )
Nr}   r~   r   r   r   r	   r   r   r   )rW   r    r@   check_expected_files_diffr   r   r   r   r   r   r   r   r   r	   r   )rz   rS   mdspecr   r~   r   r   r   r   r   s              r)   %test_2_expected_files_diff_gate_matchr      s    		!B!"%D	B

,
,T2
6C:::33:<<-<-----<-------3---3---<------------------r+   c                   t        |      }t        |      }d}t        |      }| j                  ||      }|j                  }| }|syddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }	t        t        j                  |	            d x}}|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                  d   }||v }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }
d
d|
iz  }t        t        j                  |            d x}x}}y )N)r/   r0   r1   r2   utils/merge_queue_executor.pyr9   r   r~   r   r   r   r   r   r   r   r   extrar   z%(py1)s in %(py4)sr   r   )rW   r    r@   r   r   r   r   r   r   r   r   r   r   r   r   r   )rz   rS   r   r   contaminatedr   r~   r   r   r   r   r   r   r   s                 r)   (test_3_expected_files_diff_gate_mismatchr      sb    
	!B!"%DL 
	-B

,
,T2
6Czzz>>ssz<<-<-----<-------3---3---<------------------*@cii.@@*.@@@@@*.@@@@*@@@.@@@@@@@@r+   c                   t        |dd      }t        |      }t        d      }| j                  ||      }|j                  }| }|syddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        t        j                  |            d x}}|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                  }|syddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        t        j                  |            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$                  d   }||v }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}}y )N)r0   )utils/**zdispatch/**z
scripts/**)rD   rE   )r0   utils/foo.pyr   r   r~   r   r   r   r   r   r   r   /assert %(py2)s
{%(py2)s = %(py0)s.is_critical
}z5%(py2)s
{%(py2)s = %(py0)s.critical_code
} == %(py4)sr   r   hitsr   r   r   )rW   r    r@   check_forbidden_pathsr   r   r   r   r   r   r   r   r   r   r   is_criticalcritical_coder   r   )rz   rS   r   r   r   r~   r   r   r   r   r   r   r   r   s                 r)   #test_4_forbidden_path_gate_criticalr      s,    
4;
B
 ""%D	 R	SB

(
(r
2Czzz>>ssz<<.<.....<.......3...3...<..................???33?7 77777 777777737773777777777 7777 77777777.SYYv..>.....>....>...........r+   c                ~   t        |d      }t        |      }t               }| j                  ||      }|j                  }|syddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        t        j                  |            d }y )N)r   )rE   r}   r~   r   )rW   r    r@   r   r   r   r   r   r   r   r   r   )rz   rS   r   r   r   r~   r   r   s           r)    test_4_forbidden_path_gate_cleanr      sv    	M	:B!"%D	B

(
(r
2C:::33:r+   c                T   t        d      }| j                  |d      }|j                  }|syddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        t        j                  |            d }y )Nabc123r6   head_sha_at_lockr}   r~   r   )
r@   check_ci_gemini_clean_sha_lockr   r   r   r   r   r   r   r   )rz   r   r~   r   r   s        r)   (test_5_ci_gemini_clean_sha_lock_all_passr      sf    	8	$B

1
1"x
1
PC:::33:r+   c                `   t        d      }| j                  |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}}|j                  }| }|syddt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      dz  }t        t	        j                  |            d x}}y )NF)r:   r-   r   r   r   r~   r   r   r   r   3assert not %(py2)s
{%(py2)s = %(py0)s.is_critical
}r   )r@   r   r   r   r   r   r   r   r   r   r   r   r   rz   r   r~   r   r   r   r   r   s           r)   'test_5_ci_gemini_clean_sha_lock_ci_failr      s    	%	0B

1
1"z
1
RC<<+<+++++<+++++++3+++3+++<++++++++++++++++++ssr+   c                ^   t        t              }| j                  |d      }|j                  }|syddt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        t        j                  |            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}}y )Nr;   r-   r   r   r~   r   r   r   r   r   r   r   )r@   r   r   r   r   r   r   r   r   r   r   r   r   r   rz   r   r~   r   r   r   r   r   s           r)   )test_5_ci_gemini_scope_expansion_criticalr      s    	 6	7B

1
1"z
1
RC???33?? ????? ???????3???3????????? ???? ????????r+   c                h   t        t              }| j                  |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}}|j                  }| }|syddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        t        j                  |            d x}}y )Nr   r-   r   r   r   r~   r   r   r   r   r   r   )r@   r   r   r   r   r   r   r   r   r   r   r   r   r   r   s           r)   /test_5_ci_gemini_unresolved_blocks_non_criticalr     s    	 1	2B

1
1"z
1
RC<<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2222ssr+   c                V   t        d      }| j                  |d      }|j                  }|syddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        t        j                  |            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}}y )NBLOCKEDr<   r-   r   r   r~   r   r   r   r   r   r   r   )r@   r   r   r   r   r   r   r   r   r   r   r   r   r   s           r)   -test_5_ci_gemini_merge_state_blocked_criticalr     s    	Y	/B

1
1"z
1
RC???33?7 77777 777777737773777777777 7777 77777777r+   c                `   t        d      }| j                  |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}}|j                  }| }|syddt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      dz  }t        t	        j                  |            d x}}y )NDIRTYr   r-   r   r   r   r~   r   r   r   r   r   r   )r@   r   r   r   r   r   r   r   r   r   r   r   r   r   s           r)   /test_5_ci_gemini_merge_state_dirty_non_criticalr     s    	W	-B

1
1"z
1
RC<<0<00000<000000030003000<000000000000000000ssr+   c                l   t        d      }| j                  |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}}|j                  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}}|j                  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 )Nnewshar   oldshar   r   r   r~   r   r   r   r   lockedz%(py1)s == %(py4)sr   current)r@   r   r   r   r   r   r   r   r   r   r   r   r   )	rz   r   r~   r   r   r   r   r   r   s	            r)   %test_5_ci_gemini_head_sha_lock_brokenr     sM   	8	$B

1
1"x
1
PC<</</////<///////3///3///<//////////////////99X*(*(****(******(*******99Y+8+8++++8++++++8+++++++r+   c                   |j                  dd       |j                  dd       |j                  dd       t        d      }| j                  |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}}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 }g 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   }||v }	|	slt        j                  d |	fd!||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}	}d"}|d   }||v }	|	slt        j                  d |	fd!||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}	}|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$   }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   }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        |      }|t        z  }| }|sd%d&t        j                         v st        j                  t              rt        j                  t              nd&t        j                  |      t        j                  |      d't        j                         v st        j                  t              rt        j                  t              nd'd(z  }t        t        j                  |            d x}x}x}}y ))NBOT_GITHUB_TOKENghs_BOT_FAKE_TOKENPATHz/sentinel/path:/usr/binGH_TOKENghs_OWNER_LEAKEDr,   r5   r-   r   r   r   r~   r
   r   r   r      z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slenrZ   r   r   r   r   assert %(py8)spy8r   r#      )r   merge81r   r   --squashr   r   --match-head-commitrd   GITHUB_TOKENz<assert not (%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} & %(py5)s)setr   )r   r   r   r   )setenvr@   execute_bot_squash_merger   r
   r   r   r   r   r   r   r   r   r   r   r   )rz   rZ   monkeypatchr   r~   r   r   r   r   r   @py_assert5r   @py_format9callr   @py_assert6@py_assert7r   s                     r)   2test_6_bot_identity_squash_merge_injects_bot_tokenr    s
    )+?@v89z#56		B

+
+B
+
LC<<-<-----<-------3---3---<------------------x=A=A=A33xx=AA;D<44444444444444444444444%f%:%%%%:%%%:%%%%%%%%%% 0DL0 L0000 L000 000L0000000;z":&::"&:::::"&::::":::&::::::::;~&>*>>&*>>>>>&*>>>>&>>>*>>>>>>>>;v;";;";;;;;";;;;;;;";;;;;;;;L8L!8!$778788888888888888L888!888888$7888$78888888r+   c                z   |j                  dd       t               }| j                  |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}}|j                  }|syddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        t        j                  |            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}}y )Nr   Fraisingr-   r   r   r   r~   r   r   r   r   r   r   r   r   )delenvr@   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )	rz   r   r   r~   r   r   r   r   r   s	            r)   .test_6_bot_identity_blocked_when_token_missingr	  7  s~    )59	B

+
+B
+
LC<<.<.....<.......3...3...<..................???33?7 77777 777777737773777777777 7777 77777777r+   c            	         dD ]6  } t        j                  t        d      5  t        dddd| g       d d d        8 y # 1 sw Y   CxY w)N)z--adminz--forcez--force-with-leasez-fz--rebaseFORBIDDEN_GIT_FLAG_BLOCKEDmatchr   r   r   r   pytestraisesRuntimeErrorr   flags    r)   .test_6_bot_identity_rejects_admin_force_rebaser  B  sT    N S]]</KL 	S)4$
D*QR	S 	SS	S 	Ss	   =A	c                     dD ]5  } t        j                  t        d      5  t        ddd| g       ddd       7 y# 1 sw Y   BxY w)u[   Security-High 회귀: `--admin=true`, `--force-with-lease=ref` 등 값 포함형도 차단.)z--admin=truez	--force=1z--force-with-lease=refs/xz--rebase=preserver  r  r   r   r   Nr  r  s    r)   /test_6_assert_no_forbidden_git_flags_value_formr  H  sR    _ G]]</KL 	G)4$*EF	G 	GG	G 	Gs	   <A	c                     dD ]4  } t        j                  t        d      5  t        dd| g       ddd       6 y# 1 sw Y   AxY w)uN   Security-High 회귀: 단축 결합 (`-af`, `-fa`) 도 `-f` 포함 시 차단.)z-afz-faz-xfyr  r  r   r   Nr  )combineds    r)   3test_6_assert_no_forbidden_git_flags_combined_shortr  O  sP    * E]]</KL 	E)4(*CD	E 	EE	E 	Es	   ;A	c                     t        g d       y)u=   정상 인자는 통과해야 한다 (false positive 방지).)
r   r   r   r   r   r   z	--subjectz[task-2531] somethingz-RzJeon-Jonghyuk/dev_workspaceN)r   rB   r+   r)   5test_6_assert_no_forbidden_git_flags_allows_safe_argsr  V  s    ! # r+   c                z   | j                  dg      }|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
g}||k(  }|st        j                  d|fd||f      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}}y )Nr2   smoke_test_pathsr   r   r~   r
   r   r   r   )r2   )z%(py0)s == %(py3)sr]   )r   r   assert %(py5)sr   )run_post_merge_smoker   r
   r   r   r   r   r   r   r   r   )
rz   r]   r~   r   r   r   r   r   r   r   s
             r)   test_7_post_merge_smoke_passr!  _  s    

'
'JK ( C <<-<-----<-------3---3---<------------------OPP<PPPPP<PPPPPPP<PPP<PPPPPPPPPPPr+   c                   d }fd}d }fd}t        |||||       }|j                  dg      }|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                  }	|	sydd
t        j                         v st	        j                  |      rt	        j                  |      nd
t	        j                  |	      dz  }t        t	        j                  |            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}	}
|j                  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 )Nc                      y)Nr   rB   rm   s    r)   failing_pytestz@test_7_post_merge_smoke_fail_is_critical.<locals>.failing_pytesth  s    r+   c                l    j                  t        |       t        |xs i       d       t               S rb   re   rh   s     r)   ri   z;test_7_post_merge_smoke_fail_is_critical.<locals>.gh_runnerk  rj   r+   c                     t               S rY   rl   rm   s    r)   ro   z<test_7_post_merge_smoke_fail_is_critical.<locals>.git_runnero  rp   r+   c                :    j                  t        |              y rY   ru   recr_   s    r)   rw   z>test_7_post_merge_smoke_fail_is_critical.<locals>.audit_writerr      49%r+   rx   zanu_v2/tests/x.pyr  r   r   r~   r   r   r   r   r   r   r   r   pytest_exit_coder   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )rS   rZ   r_   r$  ri   ro   rw   exr~   r   r   r   r   r   r   r   s    ``             r)   (test_7_post_merge_smoke_fail_is_criticalr-  g  s   & 
$!
B 
!
!4G3H
!
IC<<.<.....<.......3...3...<..................???33?9 99999 999999939993999999999 9999 9999999999'(-A-(A----(A---(---A-------r+   c                   |j                  dd       |j                  dd       | j                  dg d      }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        }	t        |	      }
|
sddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |	      t        j                  |
      d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}}|D ]  }|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   }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   }d}||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}}d%}||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}}|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(   }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   }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 ))Nr   ghs_BOT_DOWNSTREAMr   z/usr/binrA   )R   S   T   merged_task_iddownstream_pr_numbersr   r   r   r   resultsr   r   r   c              3  &   K   | ]	  }|d      ywokNrB   .0rs     r)   	<genexpr>zItest_8_downstream_stale_revalidation_invokes_gh_per_pr.<locals>.<genexpr>  s     (1qw(s   ,assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}allr   rZ   r#   r   r   r   r   r   r   r   commentr   )z%(py1)s in %(py3)srT   r   r   r  r   zevidence revalidationrd   r   r   )r   revalidate_downstreamr   r   r   r   r   r   r   r   r   r?  )rz   rZ   r   r6  r   r   r   r   r   r   r   r   r  r   rT   r   r   s                    r)   6test_8_downstream_stale_revalidation_invokes_gh_per_prrD    s<    )+?@vz*,,"* - G w<1<1<133ww<1(((3(((((((((3(((3((((((((((((((x=A=A=A33xx=A  1F|A&$&$&&&&$&&&&&&$&&&&&&&F|A+)+)++++)++++++)+++++++F|B"{d""""{d"""{""""""d"""d"""""""&.&$....&$...&......$...$.......E{:&>*>>&*>>>>>&*>>>>&>>>*>>>>>>>>E{>*B.BB*.BBBBB*.BBBB*BBB.BBBBBBBBE{6"0j0"j0000"j000"000j00000001r+   c                P   |j                  dd       | j                  dddg      }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        }	t        |	      }
|
sddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |	      t        j                  |
      dz  }t        t        j                  |            dx}	}
d |D        }	t        |	      }
|
sddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |	      t        j                  |
      d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)uG   Security-High 회귀: BOT 토큰 미주입 시 owner_pat 사용 차단.r   Fr  rA   r0  r1  r3  r   r   r   r   r6  r   r   r   Nc              3  (   K   | ]
  }|d       ywr8  rB   r:  s     r)   r=  zItest_8_downstream_revalidate_blocks_when_token_missing.<locals>.<genexpr>  s     ,q1T7{,s   r>  r?  r   c              3  ,   K   | ]  }|d    dk(    yw)r   bot_token_unavailableNrB   r:  s     r)   r=  zItest_8_downstream_revalidate_blocks_when_token_missing.<locals>.<genexpr>  s     G!q{55Gs   r   rZ   )r  rC  r   r   r   r   r   r   r   r   r   r?  )rz   rZ   r   r6  r   r   r   r   r   r   r   r   s               r)   6test_8_downstream_revalidate_blocks_when_token_missingrI    s    )59,,"!2h - G w<1<1<133ww<1,G,,3,,,,,,,,,3,,,3,,,,,,,,,,,,,,GwGG3GGGGGGGGG3GGG3GGGGGGGGGGGGGGx=A=A=A33xx=Ar+   c                   t        t        dt              }| j                  } ||      }|t        k(  }|s;t	        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                  |      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}x}}|j                  }|t        v }|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}}y )NrE   )r   r   r   r   zV%(py5)s
{%(py5)s = %(py2)s
{%(py2)s = %(py0)s.classify_failure
}(%(py3)s)
} == %(py7)srz   criticalr   r   r   r   r   r   assert %(py9)spy9r   )z5%(py2)s
{%(py2)s = %(py0)s.critical_code
} in %(py4)sr   r   r   r   )r   r   r   classify_failurer   r   r   r   r   r   r   r   r   r   )
rz   rL  r   r   r  r   @py_format10r   r   r   s
             r)   0test_9_classify_critical_7_returns_critical_coderR    sS   $-H
 $$I$X.I.2IIIII.2IIIIIII8III8III$IIIIIIXIIIXIII.IIIIII2IIII2IIIIIIII!!3!^3333!^33333383338333!333333^333^3333333r+   c                   t        t        d      }| j                  } ||      }|t        k(  }|s;t	        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                  |      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}x}}y )Nmismatchr   r   r   rK  rz   non_critr   rM  rN  rO  )r   r   rP  r   r   r   r   r   r   r   r   r   )rz   rV  r   r   r  r   rQ  s          r)   2test_9_classify_non_critical_returns_auto_resolvedrW    s    $6zJH$$L$X.L.2LLLLL.2LLLLLLL8LLL8LLL$LLLLLLXLLLXLLL.LLLLLL2LLLL2LLLLLLLLr+   c                   t        t        ddgdgd      }| j                  |      }|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}
}	|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   }|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}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}y ) Nexpected_files_mismatcha.pyb.py)missingr   )r   r   r   r   r   r~   r   r   r   r   r   r   r   r_   r   r   r   r   kindnon_critical_auto_resolvedr   r   r   )z%(py1)s == %(py3)sr   rB  r  r   r   )r   r   auto_handle_non_criticalr   r   r   r   r   r   r   r   r   r   r   )rz   r_   rV  r~   r   r   r   r   r   r   r   r   r)  r   r   r   s                   r)   >test_9_auto_handle_non_critical_writes_audit_and_self_resolvesr`    sP    #(!(fX6H
 
+
+H
5C<<5<55555<555555535553555<555555555555555555{ q q    q      3   3      {   {      q       
a.Cv;666;66666;6666;66666666666z?0?00000?0000?000000000000000000x=555=55555=5555=55555555555r+   c                j   t        t        d      }| j                  |      }|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
)uS   WAITING_FOR_PREDECESSOR 는 정상 대기 상태 → audit 노이즈 방지 (skip).z2 predecessors still openrU  r   r   r~   r   r   r   r   Nr   r   r   r_   r   r   r   )r   r   r_  r   r   r   r   r   r   r   r   r   r   r   )rz   r_   waitingr~   r   r   r   r   r   r   r   r   s               r)   .test_9_waiting_for_predecessor_skips_audit_logrc    s6    (*G 
+
+G
4C<<5<55555<555555535553555<555555555555555555{ q q    q      3   3      {   {      q       r+   c                 <   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                  t              rt        j                  t              ndt        j                  |       t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x} x}}y	)
uK   회장 §명시: Critical 7종 외 분류 일체 금지 → 정확히 7개.   r   r   r   r   r   r   r   N)
r   r   r   r   r   r   r   r   r   r   )r   r   r   r   r   s        r)   'test_9_critical_codes_are_exactly_sevenrf    s    ~#!#!####!######3###3######~###~######!#######r+   c                   t        |       t        d      }| j                  |d      }|j                  }|syddt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        t        j                  |            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}}|j                  }d}	||	k(  }|st        j                  d|fd||	f      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 )N
locked-shar   r   r   r}   r~   r   r   r   r	   r   r   r   all_4_gates_passr   r   r   r   )rW   r@   evaluater   r   r   r   r   r   r   r   r   r	   r   r   )rz   rS   r   r~   r   r   r   r   r   r   r   r   s               r)   #test_integration_full_evaluate_passrl    s_   8	<	(B


rL

AC:::33:<<-<-----<-------3---3---<------------------::+++:+++++:+++++++3+++3+++:+++++++++++r+   c                P   ddl m} d}d} |||      }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      d	z  }d
d|iz  }t        t        j                  |            dx}x}x}x}}d}d} |||      }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      d	z  }d
d|iz  }t        t        j                  |            dx}x}x}x}}d}d} |||      }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      d	z  }d
d|iz  }t        t        j                  |            dx}x}x}x}}d}d} |||      }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      d	z  }d
d|iz  }t        t        j                  |            dx}x}x}x}}d}d} |||      }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      d	z  }d
d|iz  }t        t        j                  |            dx}x}x}x}}d}d} |||      }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      d	z  }d
d|iz  }t        t        j                  |            dx}x}x}x}}d}d} |||      }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      d	z  }d
d|iz  }t        t        j                  |            dx}x}x}x}}d}d} |||      }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      d	z  }d
d|iz  }t        t        j                  |            dx}x}x}x}}y)uA   `**/foo.py` 패턴이 루트 파일 `foo.py` 도 매칭하는지.r   )_glob_matchz	**/foo.pyzfoo.pyTis)z9%(py6)s
{%(py6)s = %(py0)s(%(py2)s, %(py4)s)
} is %(py9)srn  )r   r   r   r   rO  zassert %(py11)spy11Nza/foo.pyz
a/b/foo.pyzfoo.txtFz
utils/*.pyz
utils/x.pyzutils/sub/x.pyr   zutils/a/b/x.py)
anu_v2.merge_queue_executorrn  r   r   r   r   r   r   r   r   )	rS   rn  r   r   r   @py_assert8r  rQ  @py_format12s	            r)   %test_glob_match_double_star_root_fileru    s   7"5H5;{H-55-5555-555555;555;555{555H555-5555555555"7J7;{J/747/47777/4777777;777;777{777J777/77747777777"9L9;{L19T91T99991T999999;999;999{999L9991999T9999999"7I7;{I.7%7.%7777.%777777;777;777{777I777.777%7777777#:\:;|\2:d:2d::::2d::::::;:::;:::|:::\:::2:::d:::::::#?%5?;|%56?%?6%????6%??????;???;???|???%5???6???%???????!8<8;z<08D80D88880D888888;888;888z888<8880888D8888888!<#3<;z#34<<4<<<<4<<<<<<;<<<;<<<z<<<#3<<<4<<<<<<<<<<<r+   c                   |j                   dz  }|j                  dd       	 t        d      }| j                  |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}}|j                  }|syddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }	t        t        j                  |	            d}|j                  d       y# |j                  d       w xY w)uY   branch 명에 `..` 가 들어와도 task_md_root 외부 파일을 가리키지 않는다.z	leaked.mdz7expected_files:
  - "x.py"
forbidden_paths:
  - "y.py"
rM   rN   z"task/task-../../../etc/passwd-dev4)r7   r-   ri  r   r   r~   r   r   r   r   Nr   r   T)
missing_ok)parentrQ   r@   rk  r   r   r   r   r   r   r   r   r   r   r   unlink)
rz   rS   leakedr   r~   r   r   r   r   r   s
             r)   ,test_evaluate_path_traversal_branch_rejectedr{    s4    __{*F
I  'CD2
C ||2|22222|2222222s222s222|222222222222222222ss&&s   F)G   G4c                   |j                  dd       |j                  dd       |j                  dd       t        d      }| j                  |d	
       |d   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   }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\   High Gemini 회귀: env={...} 로 PATH 누락되면 gh 가 없어 fail 했던 패턴 박제.r   ghs_BOTr   z/x/y/zHOMEz/home/agentc   r   r-   r   rA  rd   r   r   r   r   r   Nr   r   )r   r@   r   r   r   r   r   r   )
rz   rZ   r   r   env_usedr   r   r   r   r   s
             r)   )test_bot_squash_merge_does_not_strip_pathr    s    )95vx(v}-		B%%b:%F|E"HF'x'x''''x''''''x'''''''F,},},,,,},,,,,,},,,,,,,J,9,9,,,,9,,,,,,9,,,,,,,N#0y0#y0000#y000#000y0000000r+   c                   | dz  }|j                  dd       t        |      }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}|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}|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}|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)u^   파일명에 `#` 이 포함된 인용 항목이 주석 시작점으로 오인되지 않는지.task-2531.mdu   expected_files:
  - "src/C#_file.cs"
  - "docs/note.md" # 후행 주석
  - bare_path.py # 비인용도 주석 절단 동작
forbidden_paths:
  - "legacy/#archive/**"
rM   rN   zsrc/C#_file.csr   z6%(py1)s in %(py5)s
{%(py5)s = %(py3)s.expected_files
}r   r   r   r   Nzdocs/note.mdzbare_path.pyzlegacy/#archive/**z7%(py1)s in %(py5)s
{%(py5)s = %(py3)s.forbidden_paths
}rQ   r    expected_filesr   r   r   r   r   r   r   r   forbidden_pathsrS   r   r   r   r   r   r   r   s           r)   0test_yaml_parser_allows_hash_in_quoted_filenamesr  %  s   	N	"BMM	'    ""%D2t222222222222222222t222t222222222220T000>00000>0000>000000T000T000000000000T000>00000>0000>000000T000T0000000000074#7#77#77777#777777777747774777#77777777r+   c                   |j                  dd       fd}fd}t        |d d ||       }t               }|j                  |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}	}
|j                  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>   cp.stderr 가 None 이어도 TypeError 없이 처리하는지.r   r}  c                    j                  t        |       t        |xs i       d       t        j                  g dd d       S )Nrc   r   r"   rP   rf   rg   r'   r(   rh   s     r)   gh_runner_nonezAtest_bot_squash_merge_handles_none_stderr.<locals>.gh_runner_none<  s8    dDODE**qVZ[[r+   c                :    j                  t        |              y rY   ru   r(  s    r)   rw   z?test_bot_squash_merge_handles_none_stderr.<locals>.audit_writerA  r*  r+   c                     t               S rY   rl   _as    r)   <lambda>z;test_bot_squash_merge_handles_none_stderr.<locals>.<lambda>F      su r+   c                      yrr   rB   r  s    r)   r  z;test_bot_squash_merge_handles_none_stderr.<locals>.<lambda>G      r+   rx   r-   r   r   r   r~   r   r   r   r   Nr&   rH   r   r   )r   r   r@   r   r   r   r   r   r   r   r   r   r   r   r   rS   rZ   r_   r   r  rw   r,  r   r~   r   r   r   r   r   r   s    ``            r)   )test_bot_squash_merge_handles_none_stderrr  8  s.   )95\
& 
 $#!
B 
B

%
%b:
%
FC<<.<.....<.......3...3...<..................99X$"$"$$$$"$$$$$$"$$$$$$$r+   c                   |j                  dd       fd}fd}t        |d d ||       }t               }|j                  |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}	}
|j                  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)uT   cp.stdout 이 None (returncode=0) 인 성공 케이스에서도 TypeError 없는지.r   r}  c                    j                  t        |       t        |xs i       d       t        j                  g dd d       S )Nrc   r   r"   r  rh   s     r)   r  zLtest_bot_squash_merge_handles_none_stdout_on_success.<locals>.gh_runner_noneX  s8    dDODE**qVZ[[r+   c                :    j                  t        |              y rY   ru   r(  s    r)   rw   zJtest_bot_squash_merge_handles_none_stdout_on_success.<locals>.audit_writer\  r*  r+   c                     t               S rY   rl   r  s    r)   r  zFtest_bot_squash_merge_handles_none_stdout_on_success.<locals>.<lambda>a  r  r+   c                      yrr   rB   r  s    r)   r  zFtest_bot_squash_merge_handles_none_stdout_on_success.<locals>.<lambda>b  r  r+   rx   r-   r   r   r   r~   r
   r   r   r   Nr%   rH   r   r   )r   r   r@   r   r   r
   r   r   r   r   r   r   r   r   r   r  s    ``            r)   4test_bot_squash_merge_handles_none_stdout_on_successr  R  s0    )95\& 
 $#!
B 
B

%
%b:
%
FC<<-<-----<-------3---3---<------------------99X$"$"$$$$"$$$$$$"$$$$$$$r+   c                   |dz  }|j                  dd       t        ddd      }| j                  |d	      }|j                  }|syd
dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        t        j                  |            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}}y)u   Security-High 회귀: forbidden_path (Critical) 가 queue/diff (non-critical) 보다
    먼저 평가되어, 비critical 우선 실패로 보안 검사가 누락되지 않는다.r  zexpected_files:
  - "anu_v2/__init__.py"
  - "anu_v2/merge_queue_executor.py"
  - "anu_v2/tests/__init__.py"
  - "anu_v2/tests/test_merge_queue_executor_2531.py"
forbidden_paths:
  - "utils/**"
rM   rN   rh  r   )r/   r0   r1   r2   zutils/forbidden.py)r6   r=   r9   ri  r   r~   r   Nr   r   r   r   r   r   )rQ   r@   rk  r   r   r   r   r   r   r   r   r   r   r   )
rz   rS   r   r   r~   r   r   r   r   r   s
             r)   &test_evaluate_critical_gates_run_firstr  l  s!    
N	"BMM	   	 
 !


B 

rL

AC???33?7 77777 777777737773777777777 7777 77777777r+   c                   | dz  }|j                  dd       t        |      }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}|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}|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)uS   YAML 작은따옴표 인용 항목도 큰따옴표와 동일하게 추출되는지.r  zWexpected_files:
  - 'src/single quoted.py'
  - "src/double quoted.py"
  - bare/path.py
rM   rN   zsrc/single quoted.pyr   r  r   r   r   r   Nzsrc/double quoted.pyzbare/path.py)rQ   r    r  r   r   r   r   r   r   r   r   r  s           r)   'test_yaml_parser_supports_single_quotesr    s   	N	"BMM	    ""%D!8T%8%88!%88888!%8888!888888T888T888%88888888!8T%8%88!%88888!%8888!888888T888T888%888888880T000>00000>0000>000000T000T00000000000r+   c                   | dz  }|j                  dd       t        |      }|j                  }d}||u }|st        j                  d|fd||f      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)uL   cherry_pick_allowed 행 끝 주석 (`true # 사유...`) 이 매칭되는지.r  u]   ```yaml
expected_files:
  - "a.py"
cherry_pick_allowed: true   # 명시적 허용 사유
```
rM   rN   Tro  z;%(py2)s
{%(py2)s = %(py0)s.cherry_pick_allowed
} is %(py5)sr   r   r   r   NrQ   r    cherry_pick_allowedr   r   r   r   r   r   r   r   rS   r   r   r   r   r   r   r   s           r)   .test_cherry_pick_allowed_with_trailing_commentr        	N	"BMM	
    ""%D##+t+#t++++#t++++++4+++4+++#+++t+++++++r+   c                   | dz  }|j                  dd       t        |      }|j                  }d}||u }|st        j                  d|fd||f      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)uN   본문 prose 에 'cherry_pick_allowed' 단어가 있어도 YAML 값만 신뢰.r  u   ## description
이 task 는 절대 cherry_pick_allowed: true 같은 정책을 허용하지 않는다.

```yaml
expected_files:
  - "a.py"
cherry_pick_allowed: false
```
rM   rN   Fro  r  r   r   r   r   Nr  r  s           r)   3test_cherry_pick_allowed_ignores_prose_outside_yamlr    s    	N	"BMM	   
 ""%D##,u,#u,,,,#u,,,,,,4,,,4,,,#,,,u,,,,,,,r+   c                   | dz  }|j                  dd       t        |      }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}|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}|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}|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)uL   fenced code block 내부 들여쓰기된 expected_files 도 추출되는지.r  z`## meta
```yaml
  expected_files:
    - "a.py"
    - "b.py"
  forbidden_paths:
    - "x/**"
```
rM   rN   rZ  r   r  r   r   r   r   Nr[  x/**)not in)z:%(py1)s not in %(py5)s
{%(py5)s = %(py3)s.expected_files
}r  r  r  s           r)   /test_extract_block_indented_yaml_in_fenced_coder    s   	N	"BMM	   
 ""%D(T(((6(((((6((((6((((((T(((T((((((((((((T(((6(((((6((((6((((((T(((T(((((((((((,,,,6,,,,,6,,,,6,,,,,,,,,,,,,,,,,,,,)T)))6)))))6))))6))))))T)))T)))))))))))r+   c                   | dz  }|j                  dd       t        |      }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}|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}|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}|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)u\   리스트 중간 빈 줄/주석 라인이 있어도 이후 항목이 누락되지 않는지.r  u`   expected_files:
  - "a.py"

  # 중간 주석
  - "b.py"
  - "c.py"
forbidden_paths:
  - "x/**"
rM   rN   rZ  r   r  r   r   r   r   Nr[  zc.pyr  r  r  r  s           r)   5test_extract_block_tolerates_blank_lines_and_commentsr    s   	N	"BMM	   
 ""%D(T(((6(((((6((((6((((((T(((T((((((((((((T(((6(((((6((((6((((((T(((T((((((((((((T(((6(((((6((((6((((((T(((T((((((((((()T)))6)))))6))))6))))))T)))T)))))))))))r+   c                   | dz  }|j                  dd       t        |      }|j                  }d}||u }|st        j                  d|fd||f      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)uT   들여쓰기된 cherry_pick_allowed (YAML 블록 내부) 가 정상 매칭되는지.r  zC```yaml
expected_files:
  - "a.py"
  cherry_pick_allowed: true
```
rM   rN   Tro  r  r   r   r   r   Nr  r  s           r)   /test_cherry_pick_allowed_indented_in_yaml_blockr    r  r+   c                   |j                  dd       fd}fd}t        |d d ||       }t               }|j                  |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}	}
|j                  d   }	t        |	t               }|sddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |	      dt        j                         v st        j                  t               rt        j                  t               ndt        j                  |      dz  }t        t        j                  |            dx}	}d}|j                  d   }
||
v }|slt        j                  d|fd||
f      t        j                  |      t        j                  |
      dz  }dd|iz  }t        t        j                  |            dx}x}}
y)uH   gh_runner 가 bytes stdout/stderr 반환 시 str 로 정규화되는지.r   r}  c                    j                  t        |       t        |xs i       d       t        j                  g ddd      S )Nrc   r   s   ok-bytess   fail-bytes-한r"   r  rh   s     r)   gh_runner_byteszDtest_bot_squash_merge_handles_bytes_streams.<locals>.gh_runner_bytes  s>    dDODE**'A
 	
r+   c                :    j                  t        |              y rY   ru   r(  s    r)   rw   zAtest_bot_squash_merge_handles_bytes_streams.<locals>.audit_writer  r*  r+   c                     t               S rY   rl   r  s    r)   r  z=test_bot_squash_merge_handles_bytes_streams.<locals>.<lambda>
  r  r+   c                      yrr   rB   r  s    r)   r  z=test_bot_squash_merge_handles_bytes_streams.<locals>.<lambda>  r  r+   rx   r-   r   r   r   r~   r   r   r   r   Nr&   z5assert %(py5)s
{%(py5)s = %(py0)s(%(py2)s, %(py3)s)
}
isinstancestr)r   r   r   r   z
fail-bytesr   r   r   )r   r   r@   r   r   r   r   r   r   r   r   r   r   r   r   r  r  )rS   rZ   r_   r   r  rw   r,  r   r~   r   r   r   r   r   r   r   r   s    ``              r)   +test_bot_squash_merge_handles_bytes_streamsr    s    )95
& 
!$#!
B 
B

%
%b:
%
FC<<.<.....<.......3...3...<..................ii)/:)3////////:///:///)//////3///3//////////.399X..<.....<....<...........r+   )r   rH   rH   )r$   intr%   r  r&   r  returnzsubprocess.CompletedProcess)r5   r  r6   r  r7   r  r8   r  r9   Sequence[str]r:   boolr;   r  r<   r  r=   r  r  r   )rS   r   rC   r  rD   r  rE   r  rF   r  r  r   )r  zlist[dict[str, Any]])r  zlist[Sequence[str]])r  zlist[Mapping[str, Any]])rS   r   r  r   )rz   r   r  None)rz   r   rS   r   r  r  )r  r  )rS   r   r  r  )e__doc__
__future__r   builtinsr   _pytest.assertion.rewrite	assertionrewriter   r'   syspathlibr   typingr   r   r   r  __file__resolveparentsWORKSPACE_ROOTr  pathinsertrr  r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r*   r@   rW   fixturerZ   r]   r_   rz   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r	  r  r  r  r  r!  r-  rD  rI  rR  rW  r`  rc  rf  rl  ru  r{  r  r  r  r  r  r  r  r  r  r  r  r  rB   r+   r)   <module>r     sr  " #     
  ) )  h'')11!4~chh&HHOOAs>*+      :e )$ %))%#$  	
  ! "   !  !B   "  	   
6        20).A A,0A	A(/ /,0/	/$@8,9 9	908 8	8SGEQ.:1 1	14 	"4M
6 6	6$! !	!$,= '(1 1	1&8&%4%%	%48B1 ,-$*,**,//	/r+   