
    jO                        d 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Z e
e      j                         j                  d   Z ee      ej"                  vr"ej"                  j%                  d ee             ddlmZ ddlmZ  e
e      j                         j                  d   dz  d	z  Zg d
Zg dZg dZddgZeez   ez   ez   Zdej<                  fdej>                  fdej@                  fdejB                  fdZ"d Z#d Z$d Z%ejL                  jO                  de      d        Z(ejL                  jO                  de      d        Z)ejL                  jO                  de      d        Z*ejL                  jO                  de      d        Z+ejL                  jO                  de      d        Z,ejL                  jO                  de      d        Z-ejL                  jO                  de      d        Z.ejL                  jO                  de      d        Z/ejL                  jO                  d e0e"jc                                     d        Z2ejL                  jO                  de      d         Z3d! Z4d" Z5d# Z6d$ Z7ejL                  jO                  de      d%        Z8ejL                  jO                  de      d&        Z9d' Z:d( Z;ejL                  jO                  de      d)        Z<d* Z=y)+u  Shadow validation regression for dry-run executor (task-2634).

규칙:
- read-only · pure function 호출만 (merge/push/PR/cron/branch-protection/admin-override 호출 0)
- frozen fixture 만 입력 (tests/fixtures/dryrun_shadow/) · live GitHub/git 의존 0
- dryrun_route 함수 본체 수정 0 (validation only)

검증 범위 (spec system_dryrun_executor_shadow_validation_spec_260523.md §7):
- 16 fixture (6 PASS + 4 HOLD + 4 CHAIR_REQUIRED + 2 UNKNOWN) 입력→출력 byte-equal
- 안전 불변식: actually_executed=False · executor_action WOULD_* 접두사 100%
- verdict 4값(PASS/HOLD/CHAIR_REQUIRED/UNKNOWN) 전부 커버
- idempotency: 동일 입력 2회 호출 → byte-identical
- HOLD sub-action 매핑 정합 (CI_PENDING/EVIDENCE_STALE/MEDIUM/THREAD)
- CHAIR_REQUIRED chair_triggers 정합 + UNKNOWN reason=INSUFFICIENT_EVIDENCE
- PASS auto_merge_10_conditions 전부 True + requires_chair_activation=True

dev6 담당: 페룬
단일소스 스펙: memory/specs/system_dryrun_executor_shadow_validation_spec_260523.md
    N)Path   )merge_ready_dryrun_executor)merge_ready_states   fixturesdryrun_shadow)shadow_pass_pr131_l3_classifier-shadow_pass_pr132_l1l2_credential_passthrough-shadow_pass_pr133_l4_wiring_mixed_remediation*shadow_pass_pr134_e2e_production_code_zero(shadow_pass_pr135_loop_boundary_resolvedshadow_pass_pr136_dryrun_only)shadow_hold_ci_pending!shadow_hold_gemini_evidence_stale)shadow_hold_gemini_medium_within_expected$shadow_hold_unresolved_medium_thread)shadow_chair_blocking_secret$shadow_chair_admin_override_required+shadow_chair_replacement_pr_runner_modified.shadow_chair_loop_boundary_critical_repetitionshadow_unknown_evidence_missing-shadow_unknown_lifecycle_incident_normal_miss
CI_PENDINGGEMINI_EVIDENCE_STALEGEMINI_MEDIUM_WITHIN_EXPECTEDUNRESOLVED_MEDIUM_THREADc                     t         | z  }t        j                  |dz  j                  d            }t        j                  |dz  j                  d            }||fS )Nevidence.jsonutf-8encodingexpected.json)FIXTURE_ROOTjsonloads	read_text)namebaseevidenceexpecteds       N/home/jay/workspace/tests/regression/test_dryrun_executor_shadow_validation.py_loadr-   S   sY    $Dzz4/1<<g<NOHzz4/1<<g<NOHX    c                 :    t        j                  | d   | d         S )Nclassifier_resultpr_identity)Edryrun_route)r*   s    r,   _router4   Z   s    >>(#67-9PQQr.   c                  r   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}}t        d	 t        j                         D              }t        t              }||k(  }|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  }t        j                  d|       dz   d|iz  }	t        t        j                  |	            d }y )N   ==z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slenALL_FIXTURESpy0py1py3py6zassert %(py8)spy8c              3   V   K   | ]!  }|j                         s|j                   # y w)N)is_dirr(   ).0ps     r,   	<genexpr>z/test_all_16_fixtures_present.<locals>.<genexpr>d   s     GQAHHJ!&&Gs   ))z%(py0)s == %(py2)sdirsr+   r=   py2zshadow fixture set mismatch: 
>assert %(py4)spy4)r:   r;   
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationsortedr$   iterdir_format_assertmsg)
@py_assert2@py_assert5@py_assert4@py_format7@py_format9rH   r+   @py_assert1@py_format3@py_format5s
             r,   test_all_16_fixtures_presentr`   b   s0   |""""""""""""3"""3""""""|"""|"""""""""""""G,"6"6"8GGDl#H8CCC48CCCCCC4CCC4CCCCCC8CCC8CCCC<TFCCCCCCCr.   r(   c                 <   t         | z  }dD ]  }||z  }|j                  } |       }|st        j                  |  d| d      dz   dt	        j
                         v st        j                  |      rt        j                  |      nddt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        t        j                  |            d x}x}} y )N)r   r#   zPROVENANCE.md/z missingzO
>assert %(py6)s
{%(py6)s = %(py4)s
{%(py4)s = (%(py0)s / %(py1)s).exists
}()
}r)   fn)r=   r>   rL   r@   )
r$   existsrM   rW   rO   rP   rQ   rR   rS   rT   )r(   r)   rc   rX   @py_assert3rY   r[   s          r,   test_fixture_triplet_presentrf   i   s    $DA <r	;	!!;!#;#;;vQrd(%;;;;;;;;;;;;;;;;r;;;r;;;!;;;#;;;;;;<r.   c                 6   t        |       \  }}t        |      }||k(  }|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  }t        j                  |  d      dz   d|iz  }t        t        j                  |            d }t        j                  |d	d
      }t        j                  |d	d
      }||k(  }|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  }t        j                  |  d      dz   d|iz  }t        t        j                  |            d }y )Nr7   rG   artexprI   z: route output != expected.jsonrK   rL   FTensure_ascii	sort_keys	canon_art	canon_expz<: byte-equal mismatch on canonicalized json (sort_keys=True))r-   r4   rM   rN   rO   rP   rQ   rR   rW   rS   rT   r%   dumps)	r(   evri   rh   r]   r^   r_   rm   rn   s	            r,   &test_route_matches_expected_byte_equalrq   t   sp   DkGB
*C#:???3#??????3???3??????#???#????$>???????

3UdCI

3UdCI	!  9	                "    "    &LM    r.   c                 &   t        |       \  }}t        |      }|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   }	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}	}
y )Nactually_executedFisz%(py1)s is %(py4)sr>   rL   assert %(py6)sr@   z5assert %(py5)s
{%(py5)s = %(py0)s(%(py2)s, %(py3)s)
}
isinstancebool)r=   rJ   r?   py5)r-   r4   rM   rN   rR   rS   rT   ry   rz   rO   rP   rQ   )r(   rp   _rh   @py_assert0re   rX   r_   r[   r]   rZ   @py_format6s               r,   &test_invariant_actually_executed_falser      s    $KEB
*C"#,u,#u,,,,#u,,,#,,,u,,,,,,,-.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555555r.   c                 ,   t        |       \  }}t        |      }|d   }t        |t              }|s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dt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            d }|j                  }d} ||      }|st        j                  |  d|      d	z   dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      d
z  }	t        t        j                  |	            d x}x}}t        j                  }||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                  t              rt        j                  t              ndt        j                  |      dz  }dd|iz  }	t        t        j                  |	            d x}}y )Nexecutor_actionz5assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}ry   actionstr)r=   r>   rJ   rL   WOULD_z	: action=zN
>assert %(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.startswith
}(%(py4)s)
})r=   rJ   rL   r@   in)z<%(py0)s in %(py4)s
{%(py4)s = %(py2)s.ALL_EXECUTOR_ACTIONS
}r2   )r=   rJ   rL   rx   r@   )r-   r4   ry   r   rO   rP   rM   rQ   rR   rS   rT   
startswithrW   r2   ALL_EXECUTOR_ACTIONSrN   )
r(   rp   r|   rh   r   re   r_   r]   rY   r[   s
             r,   +test_invariant_executor_action_would_prefixr      s   $KEB
*C"#Ffc"""""""":""":""""""f"""f""""""c"""c""""""""""DXDX&D&DD4&	&(DDDDDDD6DDD6DDDDDDXDDD&DDDDDD+++6+++++6+++++++6+++6++++++Q+++Q+++++++++++r.   c                    t        |       \  }}|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	   }|j                  }d
} ||      }	|	stdt        j                  |      t        j                  |      t        j                  |      t        j                  |	      dz  }
t	        t        j
                  |
            dx}x}x}}	|d   }t        j                  t        j                  t        j                  f}||v }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t	        t        j
                  |            dx}x}}y)u[   expected.json 자체가 안전 불변식 만족 — fixture 자체가 안전 doctrine 100%.rs   Frt   rv   rw   rx   r@   Nr   r   zLassert %(py7)s
{%(py7)s = %(py3)s
{%(py3)s = %(py1)s.startswith
}(%(py5)s)
})r>   r?   r{   py7schemar   z%(py1)s in %(py4)s)r-   rM   rN   rR   rS   rT   r   r2   SCHEMA_AUTO_MERGE_CANDIDATESCHEMA_REMEDIATION_REQUIREDSCHEMA_HOLD_FOR_CHAIR)r(   r|   ri   r}   re   rX   r_   r[   rZ   @py_assert6@py_format8s              r,   0test_invariant_expected_fixture_satisfies_safetyr      sl    4[FAs"#,u,#u,,,,#u,,,#,,,u,,,,,,, !6!,,6X6,X66666!666,666X6666666666x= 	%%	%%	 =    	=    	    	     	  r.   c                    t        |       \  }}t        |      }t        |      }t        j                  |dd      }t        j                  |dd      }||k(  }|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  }t	        j                  |  d      d	z   d
|iz  }	t        t	        j                  |	            d }||k(  }|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 }y )NFrj   r7   rG   s1s2rI   z: non-deterministic outputrK   rL   a1a2zassert %(py4)s)r-   r4   r%   ro   rM   rN   rO   rP   rQ   rR   rW   rS   rT   )
r(   rp   r|   r   r   r   r   r]   r^   r_   s
             r,   test_idempotent_byte_identicalr      s
   $KEB	B	B	BUe	<B	BUe	<B88882888888288828888888888888v788888888OOO2OOOOOO2OOO2OOOOOOOOOOOOOOOOr.   c                    t        |       \  }}t        |      }|d   }t        j                  }||k(  }|st	        j
                  d|fd||f      t	        j                  |      dt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      dz  }dd|iz  }t        t	        j                  |            d x}x}}|d   }t        j                  }||k(  }|st	        j
                  d|fd	||f      t	        j                  |      d
t        j                         v st	        j                  t              rt	        j                  t              nd
t	        j                  |      dz  }dd|iz  }t        t	        j                  |            d x}x}}|d   }t        j                  }||k(  }|st	        j
                  d|fd||f      t	        j                  |      dt        j                         v st	        j                  t              rt	        j                  t              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   }|j                  } |       }t!        |      }t        j"                  }t!        |      }||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                  |      t	        j                  |      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  }t	        j$                  |       dz   d|iz  }t        t	        j                  |            d x}x}x}x}x}}|j&                  } |       }t)        |      }|st	        j$                  |  d|       dz   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                  |      t	        j                  |      d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"   }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 )#Nr   r7   )zC%(py1)s == %(py5)s
{%(py5)s = %(py3)s.SCHEMA_AUTO_MERGE_CANDIDATE
}r2   r>   r?   r{   assert %(py7)sr   verdict)z,%(py1)s == %(py5)s
{%(py5)s = %(py3)s.PASS
}Sr   )z:%(py1)s == %(py5)s
{%(py5)s = %(py3)s.ACTION_WOULD_MERGE
}requires_chair_activationTrt   rv   rw   rx   r@   auto_merge_10_conditions)z%(py7)s
{%(py7)s = %(py0)s(%(py5)s
{%(py5)s = %(py3)s
{%(py3)s = %(py1)s.keys
}()
})
} == %(py14)s
{%(py14)s = %(py9)s(%(py12)s
{%(py12)s = %(py10)s.AUTO_MERGE_10_CONDITION_KEYS
})
}setconds)	r=   r>   r?   r{   r   py9py10py12py14z
>assert %(py16)spy16u"   : PASS but 10조건 미충족 — za
>assert %(py7)s
{%(py7)s = %(py0)s(%(py5)s
{%(py5)s = %(py3)s
{%(py3)s = %(py1)s.values
}()
})
}all)r=   r>   r?   r{   r   post_merge_smoke_plandefined callback_lifecycle_artifact_planwould_generate)r-   r4   r2   r   rM   rN   rR   rO   rP   rQ   rS   rT   r   PASSACTION_WOULD_MERGEkeysr   AUTO_MERGE_10_CONDITION_KEYSrW   valuesr   )r(   rp   r|   rh   r}   rZ   rX   r~   r   re   r_   r[   r   r   @py_assert11@py_assert13@py_assert8@py_format15@py_format17s                      r,   (test_pass_routes_to_auto_merge_candidater      sL   $KEB
*Cx=9A999=99999=9999=999999A999A99999999999y>#QVV#>V####>V###>######Q###Q###V####### !9Q%9%99!%99999!%9999!999999Q999Q999%99999999*+3t3+t3333+t333+333t3333333*+EzzIz|I3|IA$B$BI$B CI CCIII CIIIIII3III3IIIIIIuIIIuIIIzIII|IIIIIIIIIIIIIIIIIIAIIIAIII$BIII CIIITIIIIIII||R|~R3~RRR4&(J5' RRRRRRR3RRR3RRRRRRuRRRuRRR|RRR~RRRRRRRRR&'	2:d:2d::::2d:::2:::d:::::::123CDLLDLLLLDLLLDLLLLLLLLLLr.   c                 f   t        |       \  }}t        |      }|d   }t        j                  }||k(  }|st	        j
                  d|fd||f      t	        j                  |      dt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      dz  }dd|iz  }t        t	        j                  |            d x}x}}|d   }t        j                  }||k(  }|st	        j
                  d|fd	||f      t	        j                  |      d
t        j                         v st	        j                  t              rt	        j                  t              nd
t	        j                  |      dz  }dd|iz  }t        t	        j                  |            d x}x}}|d   }t        j                  }||k(  }|st	        j
                  d|fd||f      t	        j                  |      dt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      dz  }dd|iz  }t        t	        j                  |            d x}x}}|d   }t        j                  }||k(  }|st	        j
                  d|fd||f      t	        j                  |      dt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      dz  }dd|iz  }t        t	        j                  |            d x}x}}|d   }t        j                   }||k(  }|st	        j
                  d|fd||f      t	        j                  |      dt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      dz  }dd|iz  }t        t	        j                  |            d x}x}}|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                  |      dz  }dd|iz  }t        t	        j                  |            d x}	x}
x}}|d   D ]  }|d   }t        j$                  }||v }|st	        j
                  d|fd||f      t	        j                  |      dt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      dz  }t	        j&                  |  d|       dz   d|iz  }t        t	        j                  |            d x}x}} y )Nr   r7   )zC%(py1)s == %(py5)s
{%(py5)s = %(py3)s.SCHEMA_REMEDIATION_REQUIRED
}r2   r   r   r   r   )z,%(py1)s == %(py5)s
{%(py5)s = %(py3)s.HOLD
}r   r   )zC%(py1)s == %(py5)s
{%(py5)s = %(py3)s.ACTION_WOULD_AUTO_REMEDIATE
}loop_boundary_guard)z@%(py1)s == %(py5)s
{%(py5)s = %(py3)s.LOOP_BOUNDARY_GUARD_TEXT
}next_recheck)z;%(py1)s == %(py5)s
{%(py5)s = %(py3)s.NEXT_RECHECK_ACTION
}auto_remediabler   >=z0%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} >= %(py7)sr:   r=   rJ   rL   r   assert %(py9)sr   remediation_planr   r   )z7%(py1)s in %(py5)s
{%(py5)s = %(py3)s.ALL_SUB_ACTIONS
}z: z
>assert %(py7)s)r-   r4   r2   r   rM   rN   rR   rO   rP   rQ   rS   rT   r   HOLDACTION_WOULD_AUTO_REMEDIATELOOP_BOUNDARY_GUARD_TEXTNEXT_RECHECK_ACTIONr:   ALL_SUB_ACTIONSrW   )r(   rp   r|   rh   r}   rZ   rX   r~   r   r]   re   r   rY   @py_format10entrys                  r,   (test_hold_routes_to_remediation_requiredr      s   $KEB
*Cx=9A999=99999=9999=999999A999A99999999999y>#QVV#>V####>V###>######Q###Q###V####### !BQ%B%BB!%BBBBB!%BBBB!BBBBBBQBBBQBBB%BBBBBBBB$%C)C)CC%)CCCCC%)CCCC%CCCCCCCCCCCC)CCCCCCCC~7!"7"77"77777"7777777777!777!777"77777777$%+3%&+!+&!++++&!++++++3+++3+++%+++&+++!+++++++'( HXG!"3"3G"33GGG"3GGGGGGGGG!GGG!GGG"3GGGvRw5GGGGGGGGHr.   c                    t        |       \  }}t        |      }t        |    \  }}|d   }||v }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  |  d|       dz   d|iz  }	t        t        j                  |	            d	x}}|d
   D 
cg c]  }
|
d   |k(  s|
 }}
t        |      }d}||k(  }|st        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  }t        j                  |  d|       dz   d|iz  }t        t        j                  |            d	x}x}}|d   d   }||k(  }|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	c c}
w )u\   spec §3 sub-action 매핑 정본 — 각 HOLD fixture 의 1차 auto_remediable item/action.r   r   )z%(py0)s in %(py3)sexpected_itemr=   r?   z
: missing 
>assert %(py5)sr{   Nr   itemr   r7   r9   r:   plan_for_itemr<   z: remediation_plan missing z
>assert %(py8)srA   r   r   )z%(py1)s == %(py3)sexpected_actionr>   r?   assert %(py5)s)r-   r4   HOLD_SUB_ACTIONrM   rN   rO   rP   rQ   rR   rW   rS   rT   r:   )r(   rp   r|   rh   r   r   rX   r]   @py_format4r~   rE   r   rY   rZ   r[   r\   r}   s                    r,   "test_hold_sub_action_mapping_exactr      s    $KEB
*C%4T%:"M? 12V=22VVV=2VVVVVV=VVV=VVV2VVVtfJ}o4VVVVVVV #$6 7V11V9;UQVMV}WW"WWWWWWWWW3WWW3WWWWWW}WWW}WWWWWWWWWtf,G$WWWWWWWWH%8%8888%888%8888888888888888 Ws   0K>Kc                    t        |       \  }}t        |      }|d   }t        j                  }||k(  }|st	        j
                  d|fd||f      t	        j                  |      dt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      dz  }dd|iz  }t        t	        j                  |            d x}x}}|d   }t        j                  }||k(  }|st	        j
                  d|fd	||f      t	        j                  |      d
t        j                         v st	        j                  t              rt	        j                  t              nd
t	        j                  |      dz  }dd|iz  }t        t	        j                  |            d x}x}}|d   }t        j                  }||k(  }|st	        j
                  d|fd||f      t	        j                  |      dt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      dz  }dd|iz  }t        t	        j                  |            d x}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  }	t	        j                  |  d      dz   d|	iz  }t        t	        j                  |            d x}}|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                  |      dz  }t	        j                  |  d      dz   d|iz  }t        t	        j                  |            d x}
x}x}}y )Nr   r7   z=%(py1)s == %(py5)s
{%(py5)s = %(py3)s.SCHEMA_HOLD_FOR_CHAIR
}r2   r   r   r   r   )z6%(py1)s == %(py5)s
{%(py5)s = %(py3)s.CHAIR_REQUIRED
}r   r   )zC%(py1)s == %(py5)s
{%(py5)s = %(py3)s.ACTION_WOULD_ESCALATE_CHAIR
}reasonnot inz%(py1)s not in %(py3)srh   r   u3   : CHAIR_REQUIRED 에 reason 필드 부재여야 함r   r{   chair_triggersr   r   r   r:   r   z: chair_triggers emptyz
>assert %(py9)sr   )r-   r4   r2   r   rM   rN   rR   rO   rP   rQ   rS   rT   r   CHAIR_REQUIREDACTION_WOULD_ESCALATE_CHAIRrW   r:   )r(   rp   r|   rh   r}   rZ   rX   r~   r   r   r]   re   r   rY   r   s                  r,   ,test_chair_required_routes_to_hold_for_chairr      s   $KEB
*Cx=3A333=33333=3333=333333A333A33333333333y>-Q--->----->---->------Q---Q----------- !BQ%B%BB!%BBBBB!%BBBB!BBBBBBQBBBQBBB%BBBBBBBB\83\\\83\\\8\\\\\\3\\\3\\\\4&([ \\\\\\\#$K3$%KK%*KKK%KKKKKK3KKK3KKK$KKK%KKKKKKtf4J,KKKKKKKKr.   c                  V   t        d      \  } }t        |       }t        j                  }|d   }||v }|st	        j
                  d|fd||f      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}}t        j                  |d	
      }d}		 |j                  d|	      }
|
dk(  rn||
|
dz    }g }d}|j                  } |       }||v }|}|sd}||v }|}|st	        j
                  d|fd||f      t	        j                  |      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      t	        j                  |      dz  }dd|iz  }|j!                  |       |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  }|j!                  |       t	        j"                  |d      i z  }t	        j$                  d|      dz   d|iz  }t        t	        j                  |            d x}x}x}x}x}x}x}}|
dz   }	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}}y )&Nr   r   r   )zM%(py2)s
{%(py2)s = %(py0)s.CHAIR_CREDENTIAL_PERMISSION_EXPANSION
} in %(py5)sr   r=   rJ   r{   r   r   Frk   r   ghp_r6   redactedz	<redacted)zD%(py3)s in %(py9)s
{%(py9)s = %(py7)s
{%(py7)s = %(py5)s.lower
}()
}nearby)r?   r{   r   r   z%(py11)spy11)z%(py14)s in %(py16)s)r   r   z%(py18)spy18r   uH   평문 ghp_ 노출 의심 (16자 윈도우 내 redacted 없음): nearby=z
>assert %(py21)spy21   z
-----BEGINr   r   rawr   r   r{   )r-   r4   r   %CHAIR_CREDENTIAL_PERMISSION_EXPANSIONrM   rN   rO   rP   rQ   rR   rS   rT   r%   ro   findlowerappend_format_booloprW   )rp   r|   rh   r]   rZ   re   r~   r   r   idxposr   rX   r   r   r}   r   @py_assert15r   @py_format12r   @py_format19@py_format20@py_format22r   s                            r,   7test_chair_blocking_secret_signals_credential_expansionr      s   01EB
*C22Kc:J6KK26KKKKK26KKKKKKK1KKK1KKK2KKK6KKKKKKKK
**Su
-C C
hhvs#"9Sr"	
z 	
V\\ 	
\^ 	
z^+ 	
{ 	
{f/D 	
 	
 	
z^ 	
 	
 		  	
 	
	6	
 	
  $ 	
 	
 		 $ 	
 	
 		 * 	
 	
 		 , 	
 	
 	
	6	
		
 	
{f 	
 	
 		 0; 	
 	
	6	
 	
  ?E 	
 	
 		 ?E 	
 	
 	
	6	
		
 	
 	
  WW]V`a	
 	
 	
 	
 	
 	
 	
 Ag  "<s""""<s"""<""""""s"""s"""""""r.   c                     t        d      \  } }t        |       }t        j                  }|d   }||v }|st	        j
                  d|fd||f      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}}t        j                  }|d   }||v }|st	        j
                  d|fd	||f      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}}d
}|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}	}y )Nr   r   r   z7%(py2)s
{%(py2)s = %(py0)s.CHAIR_CRITICAL7
} in %(py5)sr   r   r   r   )z<%(py2)s
{%(py2)s = %(py0)s.CHAIR_ADMIN_OVERRIDE
} in %(py5)sC7_OVERRIDEreport_envelopeevidence_refsr   rw   rx   r@   )r-   r4   r   CHAIR_CRITICAL7rM   rN   rO   rP   rQ   rR   rS   rT   CHAIR_ADMIN_OVERRIDErp   r|   rh   r]   rZ   re   r~   r   r}   rX   r_   r[   s               r,   2test_chair_admin_override_signals_override_triggerr    sh   89EB
*C5$4 55 55555 555555515551555555 55555555!!:S)9%::!%:::::!%:::::::1:::1:::!:::%::::::::CC 12?CC=CCCCC=CCCC=CCCCCCCCCCCr.   c                     t        d      \  } }t        |       }t        j                  }|d   }||v }|st	        j
                  d|fd||f      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}}t        j                  }|d   }||v }|st	        j
                  d|fd	||f      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}}d
}|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}	}y )Nr   r   r   r   r   r   r   r   )zC%(py2)s
{%(py2)s = %(py0)s.CHAIR_OUT_OF_EXPECTED_FILES
} in %(py5)sC7_FORBIDDEN_PATHr   r   r   rw   rx   r@   )r-   r4   r   r   rM   rN   rO   rP   rQ   rR   rS   rT   CHAIR_OUT_OF_EXPECTED_FILESr   s               r,   @test_chair_replacement_pr_runner_modified_signals_forbidden_pathr    sk   ?@EB
*C5$4 55 55555 555555515551555555 55555555((AC0@,AA(,AAAAA(,AAAAAAA1AAA1AAA(AAA,AAAAAAAAI#&7"8"II"IIIII"IIIIIII"IIIIIIIIr.   c                     t        d      \  } }t        |       }t        j                  }|d   }||v }|st	        j
                  d|fd||f      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 )	Nr   r   r   )zL%(py2)s
{%(py2)s = %(py0)s.CHAIR_AUTO_REMEDIATION_LOOP_BOUNDARY
} in %(py5)sr   r   r   r   )r-   r4   r   $CHAIR_AUTO_REMEDIATION_LOOP_BOUNDARYrM   rN   rO   rP   rQ   rR   rS   rT   )rp   r|   rh   r]   rZ   re   r~   r   s           r,   :test_chair_loop_boundary_signals_auto_remediation_boundaryr    s    BCEB
*C11JS9I5JJ15JJJJJ15JJJJJJJ1JJJ1JJJ1JJJ5JJJJJJJJr.   c                    t        |       \  }}t        |      }|d   }t        j                  }||k(  }|st	        j
                  d|fd||f      t	        j                  |      dt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      dz  }dd|iz  }t        t	        j                  |            d x}x}}|d   }t        j                  }||k(  }|st	        j
                  d|fd	||f      t	        j                  |      d
t        j                         v st	        j                  t              rt	        j                  t              nd
t	        j                  |      dz  }dd|iz  }t        t	        j                  |            d x}x}}|d   }t        j                  }||k(  }|st	        j
                  d|fd||f      t	        j                  |      dt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      dz  }dd|iz  }t        t	        j                  |            d x}x}}|d   }t        j                  }||k(  }|st	        j
                  d|fd||f      t	        j                  |      dt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      dz  }dd|iz  }t        t	        j                  |            d x}x}}|d   }g }	||	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   r7   r   r2   r   r   r   r   )z/%(py1)s == %(py5)s
{%(py5)s = %(py3)s.UNKNOWN
}r   r   )z=%(py1)s == %(py5)s
{%(py5)s = %(py3)s.ACTION_WOULD_REGATHER
}r   )zD%(py1)s == %(py5)s
{%(py5)s = %(py3)s.REASON_INSUFFICIENT_EVIDENCE
}r   )z%(py1)s == %(py4)srw   rx   r@   )r-   r4   r2   r   rM   rN   rR   rO   rP   rQ   rS   rT   r   UNKNOWNACTION_WOULD_REGATHERREASON_INSUFFICIENT_EVIDENCE)r(   rp   r|   rh   r}   rZ   rX   r~   r   re   r_   r[   s               r,   test_unknown_routes_to_regatherr    sC   $KEB
*Cx=3A333=33333=3333=333333A333A33333333333y>&QYY&>Y&&&&>Y&&&>&&&&&&Q&&&Q&&&Y&&&&&&& !<Q%<%<<!%<<<<<!%<<<<!<<<<<<Q<<<Q<<<%<<<<<<<<x=:A:::=:::::=::::=::::::A:::A::::::::::: &B& B&&&& B&&& &&&B&&&&&&&r.   c                 t   t        |       \  }}t        |      }|d   }|d   }g }|j                  }d} ||      }	|	}
|	sd}|}
t        |
      }||k(  }|sddt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |	      dz  }|j                  |       |	s+ddt        j                        iz  }|j                  |       t        j                  |d	      i z  }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z  }dd|iz  }t        t        j                  |            d x}x}x}
x}x}x}x}	x}}|d   }g }
|j                  }d} ||      }|}|sd}|}||k(  }|s3ddt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }|
j                  |       |s+ddt        j                        iz  }|
j                  |       t        j                  |
d	      i z  }t        j                  d
|fd||f      t        j                  |      |dz  }dd|iz  }t        t        j                  |            d x}x}x}x}
x}x}x}}|d   }g }
|j                  }d} ||      }|}|sd}|}||k(  }|s3ddt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }|
j                  |       |s+ddt        j                  |      iz  }|
j                  |       t        j                  |
d	      i z  }t        j                  d
|fd||f      t        j                  |      |dz  }dd|iz  }t        t        j                  |            d x}x}x}x}
x}x}x}}|d   }g }
|j                  }d} ||      }|}|sd}|}||k(  }|s3ddt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }|
j                  |       |s+ddt        j                  |      iz  }|
j                  |       t        j                  |
d	      i z  }t        j                  d
|fd||f      t        j                  |      |dz  }dd|iz  }t        t        j                  |            d x}x}x}x}
x}x}x}}|d   }g }
|j                  }d} ||      }|}|sd}|}||k(  }|s3ddt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }|
j                  |       |s+ddt        j                  |      iz  }|
j                  |       t        j                  |
d	      i z  }t        j                  d
|fd||f      t        j                  |      |dz  }dd|iz  }t        t        j                  |            d x}x}x}x}
x}x}x}}y )Nr1   prr   zA%(py12)s
{%(py12)s = %(py8)s
{%(py8)s = %(py6)s.get
}(%(py10)s)
}pi)r@   rA   r   r   z%(py15)spy15r   r7   )z3%(py1)s == %(py20)s
{%(py20)s = %(py3)s(%(py18)s)
}int)r>   r?   r   py20zassert %(py22)spy22head_sha z@%(py11)s
{%(py11)s = %(py7)s
{%(py7)s = %(py5)s.get
}(%(py9)s)
})r{   r   r   r   z%(py14)sr   )z%(py1)s == (%(py17)s))r>   py17zassert %(py19)spy19task_idbranchts_kst)r-   r4   getr  rO   rP   rM   rQ   rR   r   r   rN   rS   rT   )r(   rp   r|   rh   r  r}   rY   @py_assert7@py_assert9r   rZ   @py_assert14@py_assert19rX   @py_format13@py_format16r   @py_format21@py_format23r   r   @py_assert10re   r   r   r   @py_format18r   s                               r,   test_pr_identity_passthroughr'  -  s   $KEB
*C	M	Bt9.BFF.4.F4L.L.LA.A....9........B...B...F...4...L....L...A.........9....9.....................z?8rvv8j8vj18181R8R8?88888888r888r888v888j888188881888R888888888?888?88888888y>6bff6Y6fY/6/6/2626>66666666b666b666f666Y666/6666/6662666666666>666>66666666x=4RVV4H4VH-4-4-44=44444444R444R444V444H444-4444-444444444444=444=44444444x=4RVV4H4VH-4-4-44=44444444R444R444V444H444-4444-444444444444=444=44444444r.   c                  .   t               } t               }t               }t        D ]W  }t        |      \  }}t        |      }| j	                  |d          |j	                  |d          |j	                  |d          Y t
        j                  t
        j                  t
        j                  t
        j                  h}| |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}}t$        j&                  t$        j(                  t$        j*                  t$        j,                  h}||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}}t$        j.                  t$        j0                  t$        j2                  h}||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 )Nr   r   r   r7   z%(py0)s == %(py3)sverdicts_seenr   r   r{   actions_seenschemas_seen)r   r;   r-   r4   addr   r   r   r   r
  rM   rN   rO   rP   rQ   rR   rS   rT   r2   r   r   r   r  r   r   r   )r*  r+  r,  r(   rp   r|   rh   rX   r]   r   r~   s              r,   5test_anchor2_all_four_verdicts_covered_by_16_fixturesr.  =  sS   EM5L5L (dARj#i.)./0X'( VVQVVQ-=-=qyyII=IIIII=IIIIIII=III=IIIIIIIIIII	a;;	%%q'>'> <    <                    
 	
%%q'D'D	 <    <                    r.   c                     t         j                  dt         j                  dt         j                  dt         j                  di} t
        D ]+  }t        |      \  }}t        |      }| |d   xx   dz  cc<   - t         j                  dt         j                  dt         j                  dt         j                  di}| |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)uQ   spec §3 정본 분포 단언 — 6 PASS + 4 HOLD + 4 CHAIR_REQUIRED + 2 UNKNOWN.r   r   r      r   r   r7   r)  countsr   r   r{   N)r   r   r   r   r
  r;   r-   r4   rM   rN   rO   rP   rQ   rR   rS   rT   )	r1  r(   rp   r|   rh   rX   r]   r   r~   s	            r,   +test_shadow_fixture_count_breakdown_6_4_4_2r2  R  s    ffaA$4$4aAFF $dARjs9~!#$ ffaA,<,<aANN6NNNNN6NNNNNNN6NNN6NNNNNNNNNNNr.   c                    t        |       \  }}t        |      }t        j                  |d      }t        j                  } ||      }||k(  }|s7t        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }d	d
|iz  }	t        t        j                  |	            d x}x}}y )NFr   r7   )zK%(py5)s
{%(py5)s = %(py2)s
{%(py2)s = %(py0)s.loads
}(%(py3)s)
} == %(py7)sr%   srh   )r=   rJ   r?   r{   r   r   r   )r-   r4   r%   ro   r&   rM   rN   rO   rP   rQ   rR   rS   rT   )
r(   rp   r|   rh   r4  r]   rZ   r   r   r   s
             r,   test_artifact_json_round_tripr5  `  s    $KEB
*C

3U+A:::a==C=C44:aa=CCr.   c            	         ddl } h d}d}| j                  t        t              j	                  d            }| j                  |      D ]  }t        || j                        r|j                  D ]  }|j                  }|j                  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  }	t        j"                  d|       dz   d|	iz  }
t%        t        j&                  |
            dx}}||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  }t        j"                  d|       dz   d|iz  }t%        t        j&                  |            d} t        || j(                        r|j*                  xs d}|j                  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  }	t        j"                  d|       dz   d|	iz  }
t%        t        j&                  |
            dx}}||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  }t        j"                  d|       dz   d|iz  }t%        t        j&                  |            d}|j                  D ]	  }|r| d|j                   n|j                  }||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  }t        j"                  d|       dz   d|iz  }t%        t        j&                  |            d} t        || j,                        s|j.                  }d}t        || j0                        r|j2                  }n"t        || j4                        r|j6                  }|dv s]|j8                  sk|j8                  d   }t        || j:                        st        |j<                  t>              s|j<                  }|j                  d      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  }t        j"                  d|       dz   d|iz  }t%        t        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  }t        j"                  d |       dz   d|iz  }t%        t        j&                  |            d} y)!u   본 테스트 모듈이 GitHub/git/subprocess/network 의존 import 를 가지지 않음.

    AST 기반 정확 검사 — alias·괄호 다중 라인·from-import 전부 견고 처리 (Gemini medium round-3 대응).r   N>   httpxsocketurllibrequests
subprocesszutils.replacement_pr_runnerr    r!   .r   r   forbidden_topr   zforbidden top-level import: r   r{   )z%(py0)s not in %(py2)sforbidden_subr(   rI   zforbidden dotted import: rK   rL   r  z!forbidden from-import top-level: modzforbidden from-import dotted: fullzforbidden from-import member: )
__import__import_moduleheadzforbidden dynamic import: targetz!forbidden dynamic dotted import: ) astparser   __file__r'   walkry   Importnamesr(   splitrM   rN   rR   rO   rP   rQ   rW   rS   rT   
ImportFrommoduleCallfuncNameid	AttributeattrargsConstantvaluer   )rE  r=  r>  treenodealiasr(   r}   rX   r   r~   r]   r^   r_   r?  r@  rc   fn_namefirstrD  rC  s                        r,   #test_no_live_imports_in_this_moduler\  l  s    KM1M99T(^--w-?@D *dCJJ' zzzz#q) )>   )  	 *  6   2?  	 2?     34&9     %D0   }D  6   %  	 %  6   -1  	 -1     0v6     cnn-++#C99S>!$ $M9  $M  I %  v   -:  I -:    4C59     !+  =  v   !  I !  v   ),  I ),    16      03#a

|,$D0   }D  6   %  	 %  6   -1  	 -1     5TF;    
 chh' BG"chh'%%B.''99dii		!eS\\2z%++s7S"[[F!<<,Q/D}4 4}  v      I    v   (5  I (5   5VH=    )6 =  v   )  I )  v   17  I 17   <F8D   Q*r.   )>__doc__builtinsrO   _pytest.assertion.rewrite	assertionrewriterM   r%   syspathlibr   pytestrG  resolveparents_WORKTREE_ROOTr   pathinsertutilsr   r2   r   r   r$   PASS_FIXTURESHOLD_FIXTURESCHAIR_FIXTURESUNKNOWN_FIXTURESr;   ACTION_WOULD_WAIT_RECHECK&ACTION_WOULD_OWNER_GEMINI_REVIEW_NUDGE2ACTION_WOULD_AUTO_FIX_REGRESS_PUSH_RESOLVE_RECHECK#ACTION_WOULD_RESOLVE_THREAD_RECHECKr   r-   r4   r`   markparametrizerf   rq   r   r   r   r   r   r   listr   r   r   r   r  r  r  r  r'  r.  r2  r5  r\   r.   r,   <module>rw     sD  (   
  h'')11!4~chh&HHOOAs>*+ 2 )H~%%'//2Z?/Q &3  },~=@PP  ,Q-H-HI!I!I* 	(	<<2
 	#A$I$I-&RD .< /< .
 /
" .6 /6 ., /, .	 /	  . / /M 0M  /H 0H o&:&:&<!=>9 ?9 0L 1L#.DJK !12' 3' .5 /5*O .  / 4r.   