
    רj                     j   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
  e
e      j                         j                  d   Z ee      ej                   vr"ej                   j#                  d ee             ddlmZ edz  dz  dz  d	z  Zedz  dz  d
z  dz  Zde
fdZd Zd Zd Zd Zd Zd Zd Zy)u  ANU 직접 polling violation guard — task-2643 Track D.

PR #145 task-2642 박제 승격 (회장 verbatim · task md 7 acceptance):

1. bzaona6au 사건 명령 재현 → hook 가 반드시 deny
2. deny reason = "ANU_DIRECT_CI_POLLING_FORBIDDEN" 고정
3. deny payload 에 allowed_alternative="delegated_watcher_contract" 포함
4. deny payload 에 next_steps 안내 (watcher contract 가이드 포함)
5. fixture PROVENANCE 가 incident_ts_kst + 정책 feedback md 경로 명시
6. fixture evidence 가 정책 출처 + 이벤트 박제 경로 reference 포함
7. cross-link Track C fixture (`pr_145_bzaona6au_violation_replay`) 존재 + 동일 사건 박제

본 task-2643 의 PR scope 는 origin/main 에서 분기되므로 PR #145 산출물에 직접
경로 의존성을 두지 않는다. 대신 fixture 내부 박제 (evidence/PROVENANCE) 로 사건을
정합한다 (회장 verbatim · PR #145 혼합 0).
    N)Path   )evaluate_tool_calltestsfixturesforbidden_bash_patternbzaona6au_violation_replaypr_open_watcher_wrapper!pr_145_bzaona6au_violation_replaybasec                     t        j                  | dz  j                  d            }t        j                  | dz  j                  d            }||fS )Nzevidence.jsonutf-8encodingzexpected.json)jsonloads	read_text)r   evidenceexpecteds      i/home/jay/workspace/.worktrees/task-2643-dev6/tests/regression/test_anu_direct_polling_violation_guard.py_load_fixturer   $   sO    zz4/1<<g<NOHzz4/1<<g<NOHX    c                  D   t        t              \  } }t        | 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	)
u0   1. bzaona6au 사건 명령 재현 → hook deny.	tool_calldecisiondeny==z%(py1)s == %(py4)spy1py4assert %(py6)spy6Nr   BZAONA6AU_FIXTUREr   
@pytest_ar_call_reprcompare	_safereprAssertionError_format_explanationr   _r   @py_assert0@py_assert3@py_assert2@py_format5@py_format7s           r   ,test_acceptance_1_bzaona6au_replay_is_deniedr3   *   sr     12KHa!(;"78HJ)6)6))))6))))))6)))))))r   c                  D   t        t              \  } }t        | 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	)
z12. deny reason = ANU_DIRECT_CI_POLLING_FORBIDDEN.r   reasonANU_DIRECT_CI_POLLING_FORBIDDENr   r   r    r#   r$   Nr%   r,   s           r   3test_acceptance_2_deny_reason_is_canonical_constantr7   1   sv     12KHa!(;"78HHB!BB!BBBBB!BBBBBBB!BBBBBBBBr   c                  D   t        t              \  } }t        | 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	)
z43. allowed_alternative = delegated_watcher_contract.r   allowed_alternativedelegated_watcher_contractr   r   r    r#   r$   Nr%   r,   s           r   -test_acceptance_3_allowed_alternative_presentr;   8   sw     12KHa!(;"78H)*J.JJ*.JJJJJ*.JJJJ*JJJ.JJJJJJJJr   c                  	   t        t              \  } }t        | d         }|j                  dg       }g }t	        |t
              }|}|rt        |      }d}||k\  }	|	}|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  }
|j                  |
       |rt        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  }|j                  |       t        j                  |d      i z  }dd|iz  }t        t        j                   |            dx}x}x}x}x}	}dj#                  |      }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}}g }d}||v }|}|sd}||v }|}|sXt        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                  |       |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  }d$d%|iz  }t        t        j                   |            dx}x}x}x}x}}y)&u4   4. next_steps 가 watcher contract 작성을 안내.r   
next_steps   z.%(py6)s
{%(py6)s = %(py2)s(%(py3)s, %(py4)s)
}
isinstancelist)py2py3r"   r$   )>=)z3%(py11)s
{%(py11)s = %(py8)s(%(py9)s)
} >= %(py14)slen)py8py9py11py14z%(py16)spy16r   zassert %(py19)spy19N zwatcher contractinz%(py1)s in %(py3)sjoinedr!   rB   assert %(py5)spy5callbackdispatch)z%(py3)s in %(py5)s)rB   rR   z%(py7)spy7)z%(py10)s in %(py12)s)py10py12z%(py14)srH   zassert %(py17)spy17)r   r&   r   getr?   r@   rD   @py_builtinslocalsr'   _should_repr_global_namer)   appendr(   _format_boolopr*   r+   join)r   r-   r   r=   @py_assert1@py_assert5r.   @py_assert10@py_assert13@py_assert12r2   @py_format15@py_format17@py_format18@py_format20rO   r0   @py_format4@py_format6@py_assert4@py_assert9@py_assert11@py_format8@py_format13@py_format16s                            r   3test_acceptance_4_next_steps_guide_watcher_contractrq   ?   s    12KHa!(;"78HlB/J@:j$'@'@'C
O@q@Oq,@@@@@@@:@@@:@@@@@@j@@@j@@@@@@$@@@$@@@'@@@@'@@@Oq@@@@@@C@@@C@@@@@@
@@@
@@@O@@@q@@@@@@@@@@@@@@XXj!F''''''''''''''''''''''''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777777777777777777777r   c                     t         dz  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  }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}|| 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)uA   5. PROVENANCE 가 incident ts + 정책 feedback md 경로 명시.zPROVENANCE.mdr   r   
2026-05-23rL   rN   provrP   rQ   rR   N	bzaona6au6feedback_anu_direct_polling_violation_pr_145_260523.md)
r&   r   r'   r(   r)   rZ   r[   r\   r*   r+   )rt   r.   r0   ri   rj   s        r   4test_acceptance_5_fixture_provenance_traces_incidentrw   J   s(   /::G:LD<4<4<44;$;$;$$CKCtKKKKCtKKKCKKKKKKtKKKtKKKKKKKr   c                     t        t              \  } }| j                  di       }g }|j                  }d}d} |||      }|j                  }d}	 ||	      }
|
}|
sd}t	        |      }||v }|}|sddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      t        j                  |      t        j                  |	      t        j                  |
      dz  }|j                  |       |
st        j                  d	fd
f      t        j                  |      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }|j                  |       t        j                  |d      i z  }dd|iz  }t        t        j                  |            dx}x}x}x}x}x}x}x}	x}
x}x}}d}t	        |      }||v }|st        j                  d	|fd||f      t        j                  |      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}| j                  }d}d} |||      }|j                  }d} ||      }	|	sddt        j                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      t        j                  |      t        j                  |      t        j                  |	      dz  }t        t        j                  |            dx}x}x}x}x}x}}	| j                  }d} ||      }d}||k(  }|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)$uH   6. fixture evidence 가 정책 출처/이벤트 박제 경로를 참조.contextpolicy_source z5feedback_anu_no_direct_ci_watch_use_handoff_260523.md+feedback_anu_no_direct_ci_watch_use_handoffz%(py16)s
{%(py16)s = %(py12)s
{%(py12)s = %(py10)s
{%(py10)s = %(py4)s
{%(py4)s = %(py2)s.get
}(%(py6)s, %(py8)s)
}.endswith
}(%(py14)s)
}ctx)rA   r"   r$   rE   rV   rW   rH   rI   rL   )z5%(py19)s in %(py24)s
{%(py24)s = %(py21)s(%(py22)s)
}str)rJ   py21py22py24z%(py26)spy26r>   zassert %(py29)spy29Nrv   )z0%(py1)s in %(py6)s
{%(py6)s = %(py3)s(%(py4)s)
})r!   rB   r"   r$   zassert %(py8)srE   incident_ts_kstrs   zassert %(py14)s
{%(py14)s = %(py10)s
{%(py10)s = %(py8)s
{%(py8)s = %(py2)s
{%(py2)s = %(py0)s.get
}(%(py4)s, %(py6)s)
}.startswith
}(%(py12)s)
}r   )py0rA   r"   r$   rE   rV   rW   rH    violation_task_id_in_claude_coderu   r   zI%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.get
}(%(py4)s)
} == %(py9)sr   rA   r"   r$   rF   assert %(py11)srG   )r   r&   rY   endswithr~   rZ   r[   r'   r\   r)   r]   r(   r^   r*   r+   
startswith)r   r-   r}   r`   r/   ra   @py_assert7rl   rm   rc   @py_assert15r.   @py_assert18@py_assert23@py_assert20rf   @py_format25@py_format27@py_format28@py_format30r0   r2   @py_format9re   @py_assert8@py_format10@py_format12s                              r   =test_acceptance_6_fixture_evidence_references_policy_archivesr   R   s    12KHa
,,y"
%CC377 C? CB C7?B' C'00 C?C0? C  C 	6C:=c(C	6(	BC C<BFC C*B*B  C C9B  C C9B  C C9B # C C9B %' C C9B ( C C9B 1 C C9B 	@C C9B C C<BFC<B C1B1BC	6(C C9B	6C C<BFC C*B*B#C C9B#C C<BFC C*B*BcC C9BcC C9B(C C C<BFC<BC4BNC C C C/B/BC C C C C DOs3xOCxOOOOCxOOOCOOOOOOsOOOsOOOOOO3OOO3OOOxOOOOOOO<<G)G2G<)2.G.99G,G9,GGGGGGGG8GGG8GGG<GGG)GGG2GGG.GGG9GGG,GGGGGGGGGGG<<J:J<:;J{J;{JJJJ;{JJJJJJ8JJJ8JJJ<JJJ:JJJ;JJJ{JJJJJJJJr   c                     t         j                  }  |        }|st        j                  dt                dz   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        t               \  }}|d   }d}||k(  }|slt        j                  d|fd	||f      t        j                  |      t        j                  |      d
z  }dd|iz  }t        t        j                  |            dx}x}}|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}}|j                  } d} | |      }d}	||	k(  }
|
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)u`   7. Track C `pr_145_bzaona6au_violation_replay` 가 동일 사건을 PR-open level 에서 박제.z$missing Track C cross-link fixture: zC
>assert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.is_dir
}()
}TRACK_C_CROSSLINK_FIXTURE)r   rA   r"   Nviolation_task_idru   r   r   r    r#   r$   inputowneranu_mainexception_classOwnerImpersonationErrorcross_link_track_d_fixturezAtests/fixtures/forbidden_bash_pattern/bzaona6au_violation_replay/r   r   r   r   rG   )r   is_dirr'   _format_assertmsgrZ   r[   r\   r)   r*   r+   r   r(   rY   )r`   r/   r1   evr   r.   r0   r2   ra   r   r   r   r   s                r   Atest_acceptance_7_track_c_crosslink_fixture_replays_same_incidentr   b   s   $++ +- -   //H.IJ     %    %    ,    .      !!:;LB!"1k1"k1111"k111"111k1111111g;w-:-:----:------:-------%&C*CC&*CCCCC&*CCCC&CCC*CCCCCCCC112N2N	O 2N     	   	   	   2   	3   O      r   )__doc__builtinsrZ   _pytest.assertion.rewrite	assertionrewriter'   r   syspathlibr   __file__resolveparents_WTr~   pathinserthooks.pre_tool_use_anu_guardr   r&   r   r   r3   r7   r;   rq   rw   r   r    r   r   <module>r      s   "   
 
8n&&q)s8388HHOOAs3x  ; 'MJ!99<XX  'MJ!::=`` 
 *CK8LK r   