
    -jƄ                       d Z ddlmZ ddlZddlmc mZ ddl	Z
ddlZddlZddlZddlZddlZddlZddlmZ ddlmZ  ee      j+                         j,                  j,                  j,                  Z ee      ej2                  vr"ej2                  j5                  d ee             dFdZ edd      Z ed	d
        edd      Z edd        edd      Z edd        edd        edd        edd      Zej@                  Z!ejD                  Z#dZ$dZ%dZ&d Z'd Z( G d dejR                        Z* G d  d!e*      Z+ G d" d#e*      Z, G d$ d%e*      Z- G d& d'e*      Z. G d( d)e*      Z/ G d* d+e*      Z0 G d, d-e*      Z1 G d. d/e*      Z2 G d0 d1e*      Z3 G d2 d3e*      Z4 G d4 d5e*      Z5 G d6 d7e*      Z6d8 Z7e'e#d9d:Z8 G d; d<e*      Z9 G d= d>e*      Z: G d? d@e*      Z; G dA dBe*      Z<e=dCk(  r ej|                  dDE       yy)Gu  task-2741 — OS-level owner-proof gate (옵션 B, no-fire) 필수 regression.

회장 11 + terminal 5. 본 테스트는 실행 코드(owner_proof_pickup_gate /
attempt_owner_fire)를 직접 호출하여, hook(rule_7) 밖의 OS-level 경로에서도
sealed-key 기반 owner proof 가 rule_7 동등 self-collector 차단을 보장하고, 실
cokacdir --cron 발사가 0(no-fire)임을 입증한다.

매핑(회장 §3):
  1. ANU sealed-key proof + eligible fresh → OWNER_PICKUP_READY_NO_FIRE(argv 구성, fire 0)
  2. sealed-key 부재 → FAIL_CLOSED_NON_ANU_KEY
  3. dev self-key / executor key / 위조 env → FAIL_CLOSED_NON_ANU_KEY
  4. stale / superseded head mismatch → RESULT_NOT_PICKUP_ELIGIBLE
  5. duplicate marker → DEDUPED (fire 0)
  6. raw ANU key literal 0
  7. actual cron fire 0 (FIRE_BLOCKED_NO_APPROVAL · subprocess 0)
  8. callback schedule 직접 생성 0 (no-fire side-effect 0)
  9. ACTIVE=false 유지
 10. 명시 fresh result 1건만 대상(glob 전체 스캔 0)
 11. terminal status json 5 enum 도달·기록

★ raw ANU key literal hygiene: 본 테스트는 ANU key/executor self-key 를 모두
  callback_owner_enforcer(무수정) 에서 import 한다 — 테스트 소스에도 raw key
  literal 0.
    )annotationsN)Path)mockc                r   | t         j                  v rt         j                  |    S t        j                  j	                  | t
        |z        }g }d}||u}|}|r|j                  }d}||u}	|	}|slt        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  }|j                  |       |rt        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  }|j                  |       t        j                  |d      i z  }dd|iz  }t        t        j                   |            dx}x}x}x}x}x}	}t        j                  j#                  |      }|t         j                  | <   |j                  j%                  |       |S )u]   실 dispatch 모듈을 canonical 이름으로 직접 로드(tests/dispatch shadowing 회피).N)is not)z%(py2)s is not %(py5)sspec)py2py5z%(py7)spy7)z5%(py11)s
{%(py11)s = %(py9)s.loader
} is not %(py14)s)py9py11py14z%(py16)spy16r   zassert %(py19)spy19)sysmodules	importlibutilspec_from_file_location_ROOTloader
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprappend_format_boolopAssertionError_format_explanationmodule_from_specexec_module)modnamerelpathr   @py_assert1@py_assert4@py_assert3@py_assert0@py_assert10@py_assert13@py_assert12@py_format6@py_format8@py_format15@py_format17@py_format18@py_format20mods                    E/home/jay/workspace/tests/regression/test_os_owner_proof_gate_2741.py_loadr5   +   sI   #++{{7##>>11'57?KD7t74t77474 777774t77777747774777t77777774777777777777777477777777777777
..
)
)$
/CCKKKKC J    z dispatch.callback_owner_enforcerz#dispatch/callback_owner_enforcer.pyz(dispatch.normal_fallback_callback_helperz+dispatch/normal_fallback_callback_helper.pyz'dispatch.anu_owned_callback_enforcementz*dispatch/anu_owned_callback_enforcement.pyzdispatch.anu_collector_resultz dispatch/anu_collector_result.pyz!dispatch.anu_result_pickup_runnerz$dispatch/anu_result_pickup_runner.pyz!dispatch.anu_pickup_wake_launcherz$dispatch/anu_pickup_wake_launcher.pyzdispatch.anu_terminal_relayzdispatch/anu_terminal_relay.pyzdispatch.anu_pickup_reporterzdispatch/anu_pickup_reporter.pyzdispatch.anu_pickup_driverzdispatch/anu_pickup_driver.py0123456789abcdef(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc                     t         S N)ANU_KEY r6   r4   _anu_loaderr>   N   s    Nr6   c                     t         S r;   )HEADr=   r6   r4   _head_proberA   R   s    Kr6   c            
      4    e Zd Zd Zdedddddddd	dZd Zy)	_Basec                     t        j                  d       _         j                   fd       t        j
                  j                   j                  d       _        y )Nt2741_)prefixc                 P    t        d      j                   j                  d      S )NshutilT)ignore_errors)
__import__rmtreetmpselfs   r4   <lambda>z_Base.setUp.<locals>.<lambda>Y   s!    
8 4 ; ;DHHTX ; Y r6   zowner_pickup_gate_index.jsonl)tempfilemkdtemprL   
addCleanupospathjoinledgerrM   s   `r4   setUpz_Base.setUpW   s=    ##84YZggll488-LMr6   	task-2741FTN)	task_idhead_shaauthoritativeowner_pickup_requiredowner_key_proof_presentschedule_created_by_executorcallback_fired_by_executorextrafnamec       	           |||||||d}
|r|
j                  |       t        j                  j                  | j                  |	xs | d      }t        |dd      5 }t        j                  |
|d       d d d        |S # 1 sw Y   |S xY w)N)rY   rZ   r[   r\   r]   r^   r_   z.result.jsonwutf-8encodingFensure_ascii)updaterS   rT   rU   rL   openjsondump)rN   rY   rZ   r[   r\   r]   r^   r_   r`   ra   payloadpfs                r4   _write_resultz_Base._write_result\   s      *%:'>,H*D
 NN5!GGLL5#Dwi|,DE!S7+ 	6qIIgqu5	6	6s   B  B
c                    |j                  dt               |j                  dt               |j                  d| j                         t	        j
                  |fi |S )Nsealed_key_loader
head_probededupe_ledger_path)
setdefaultr>   rA   rV   gate_modowner_proof_pickup_gate)rN   rT   kws      r4   _gatez_Base._gater   sH    
);7
lK0
*DKK8//;;;r6   )__name__
__module____qualname__rW   r@   rp   ry   r=   r6   r4   rC   rC   V   s,    N
 (3T$).33816d ,<r6   rC   c                      e Zd Zd Zd Zy)Test01ReadyNoFirec                   | j                         }t        j                  d      5 }| j                  |t              }d d d        | j                  j                  t        j                         | j                  |j                         | j                  |j                  t               | j                  t        |j                        dkD         | j                  |j                         | j!                  |j"                         j%                          | j                  |j&                         | j                  |j(                  d       | j!                  |j*                  d          y # 1 sw Y   2xY w)Nsubprocess.runexecutor_keyr   ANUr]   )rp   r   patchry   EXECUTOR_KEYassertEqualstatusrv   GATE_OWNER_PICKUP_READY_NO_FIRE
assertTruereadyassertIsInstanceargvlistlenfire_blockedassertFalseactiveassert_not_calledr]   schedule_owner_proofeligibility)rN   rn   srunress       r4   test_ready_argv_built_no_firez/Test01ReadyNoFire.test_ready_argv_built_no_fire{   s    ZZ() 	;T**Q\*:C	;X%M%MN		"chh-CHH)*(()$ 3341159)BCD	; 	;s   E..E8c                    | j                  ddd      }| j                  |t              }| j                  |j                  t
        j                         | j                  |j                  d       y )Nr   zEXECUTOR-CLAIMED)collector_roler   r`   r   )rp   ry   r   r   r   rv   r   r   rN   rn   r   s      r4   ,test_owner_proof_label_not_from_result_fieldz>Test01ReadyNoFire.test_owner_proof_label_not_from_result_field   sc    ?Q&S Tjjj6X%M%MN1159r6   N)rz   r{   r|   r   r   r=   r6   r4   r~   r~   z   s    E":r6   r~   c                      e Zd Zd Zy)Test02SealedKeyMissingc                .   | j                         }d d d fD ]z  }| j                  ||t              }| j                  |j                  t
        j                         | j                  |j                         | j                  |j                         | y )Nc                      y r;   r=   r=   r6   r4   rO   zETest02SealedKeyMissing.test_missing_key_fail_closed.<locals>.<lambda>       r6   c                      y)N r=   r=   r6   r4   rO   zETest02SealedKeyMissing.test_missing_key_fail_closed.<locals>.<lambda>   r   r6   c                      y)Nz   r=   r=   r6   r4   rO   zETest02SealedKeyMissing.test_missing_key_fail_closed.<locals>.<lambda>   r   r6   rr   r   )rp   ry   r   r   r   rv   GATE_FAIL_CLOSED_NON_ANU_KEYassertIsNoner   r   r]   )rN   rn   r   r   s       r4   test_missing_key_fail_closedz3Test02SealedKeyMissing.test_missing_key_fail_closed   sz     #Z? 	:F**Q&|*TCSZZ)N)NOchh'S889		:r6   N)rz   r{   r|   r   r=   r6   r4   r   r      s    :r6   r   c                  $    e Zd Zd Zd Zd Zd Zy)Test03NonAnuKeyFailClosedc                    | j                         }| j                  |d t              }| j                  |j                  t
        j                         | j                  |j                         y )Nc                     t         S r;   DEV_SELF_KEYr=   r6   r4   rO   z=Test03NonAnuKeyFailClosed.test_dev_self_key.<locals>.<lambda>       l r6   r   )	rp   ry   r   r   r   rv   r   r   r   r   s      r4   test_dev_self_keyz+Test03NonAnuKeyFailClosed.test_dev_self_key   sW     jj.B&2  4X%J%JK#((#r6   c                    | j                         }| j                  |d t              }| j                  |j                  t
        j                         y )Nc                     t         S r;   )r   r=   r6   r4   rO   z=Test03NonAnuKeyFailClosed.test_executor_key.<locals>.<lambda>   r   r6   r   )rp   ry   r   r   r   rv   r   r   s      r4   test_executor_keyz+Test03NonAnuKeyFailClosed.test_executor_key   sE     jj.B&2  4X%J%JKr6   c                    | j                         }| j                  |t        t              }| j	                  |j
                  t        j                         y )Nr   )rp   ry   r>   r<   r   r   rv   r   r   s      r4   ,test_runtime_key_equals_executor_even_if_anuzFTest03NonAnuKeyFailClosed.test_runtime_key_equals_executor_even_if_anu   s>     jjkjPX%J%JKr6   c                |   | j                  dddd      }t        j                  j                  t        j
                  dddd      5  | j                  |d t        	      }d d d        | j                  j                  t        j                         | j                  |j                         y # 1 sw Y   OxY w)
Nr   )r   owner_key_prooffired_byr   1)COLLECTOR_ROLEOWNER_IS_ANUF)clearc                     t         S r;   r   r=   r6   r4   rO   zLTest03NonAnuKeyFailClosed.test_forged_env_text_not_trusted.<locals>.<lambda>   s    , r6   r   )rp   r   r   dictrS   environry   r   r   r   rv   r   r   r   r   s      r4    test_forged_env_text_not_trustedz:Test03NonAnuKeyFailClosed.test_forged_env_text_not_trusted   s    :?38&: ; ZZ__RZZE:=*?FK  M 	8**Q2F*6  8C	8 	X%J%JK#((#	8 	8s   
B22B;N)rz   r{   r|   r   r   r   r   r=   r6   r4   r   r      s    $LL
$r6   r   c                      e Zd Zd Zy)Test03bEligibilitySelfCollectorc                4   t        d      t        d      t        d      t        d      t        d      f}|D ]Z  } | j                  di |}| j                  |t              }| j	                  |j
                  t        j                  | d	
       \ y )NT)r[   Fr\   )r]   )r^   )r_   r   u"    는 적격 아님이어야 한다msgr=   )r   rp   ry   r   r   r   rv   GATE_RESULT_NOT_PICKUP_ELIGIBLE)rN   casesrx   rn   r   s        r4   "test_self_collector_fields_blockedzBTest03bEligibilitySelfCollector.test_self_collector_fields_blocked   s    t$u-.d3D1
  	LB"""(R(A**Q\*:CSZZ)Q)Q$&4'I!J  L	Lr6   N)rz   r{   r|   r   r=   r6   r4   r   r      s    Lr6   r   c                      e Zd Zd Zd Zy)Test04Stalec                    | j                  t              }| j                  |t              }| j	                  |j
                  t        j                         | j                  |j                         y )NrZ   r   )
rp   
STALE_HEADry   r   r   r   rv   r   r   r   r   s      r4   test_stale_head_mismatchz$Test04Stale.test_stale_head_mismatch   sS    
3jjj6X%M%MN#((#r6   c                    | j                  d      }| j                  |t              }| j                  |j                  t
        j                         y )Nr   r   r   )rp   ry   r   r   r   rv   r   r   s      r4   test_missing_head_shaz!Test04Stale.test_missing_head_sha   sA    +jjj6X%M%MNr6   N)rz   r{   r|   r   r   r=   r6   r4   r   r      s    $Or6   r   c                      e Zd Zd Zy)Test05Dedupec           	        | j                         }t        | j                  dd      5 }|j                  t	        j
                  t        j                  dt        d      dz          d d d        | j                  |t              }| j                  |j                  t        j                         | j                  |j                         | j!                  |j"                         y # 1 sw Y   xY w)Nrc   rd   re   rX   eventrY   rZ   
r   )rp   rj   rV   writerk   dumpsrv   GATE_LEDGER_EVENTr@   ry   r   r   r   GATE_DEDUPEDr   dedupe_marker_presentr   r   )rN   rn   ro   r   s       r4   test_duplicate_marker_dedupedz*Test05Dedupe.test_duplicate_marker_deduped   s     $++sW5 	SGGDJJ)C)C+6D J KMQR S	S jjj6X%:%:;112#((#	S 	Ss   >C''C0N)rz   r{   r|   r   r=   r6   r4   r   r      s    $r6   r   c                      e Zd Zd Zd Zy)Test06RawKeyHygienec                    t         dz  dz  j                  d      }t        t              j                  d      }| j	                  t
        |d       | j	                  t
        |d       y )Ndispatchanu_result_pickup_runner.pyrd   u+   runner 소스에 raw ANU key literal 금지u.   테스트 소스에 raw ANU key literal 금지)r   	read_textr   __file__assertNotInr<   )rN   
runner_srctest_srcs      r4   test_no_raw_key_in_sourcesz.Test06RawKeyHygiene.test_no_raw_key_in_sources   sX    j(+HHSST[\
>++G4*.[\(,\]r6   c                v   | j                         }| j                  |t              }t        j                  |j                         d      }| j                  t        |d       |j                  xs g D ]  }| j                  t        |d        | j                  t        j                  |j                         y )Nr   Frg   u'   gate 출력 json 에 raw ANU key 금지u   argv 에 raw ANU key 금지)rp   ry   r   rk   r   to_jsonr   r<   r   assertInrv   OWNER_PICKUP_KEY_PLACEHOLDER)rN   rn   r   blobtoks        r4   test_no_raw_key_in_outputz-Test06RawKeyHygiene.test_no_raw_key_in_output   s     jjj6zz#++-e<$(QRHHN 	JCWc+HI	J 	h;;SXXFr6   N)rz   r{   r|   r   r   r=   r6   r4   r   r      s    ^Gr6   r   c                      e Zd Zd Zd Zy)Test07NoCronFirec                p   | j                         }t        j                  d      5 }t        j                  d      5 }| j                  |t              }t
        j                  |      }t
        j                  |d      }|j                          |j                          d d d        d d d        | j                  j                  t
        j                         | j                  |j                         | j                  j                  t
        j                         y # 1 sw Y   xY w# 1 sw Y   xY w)Nr   zsubprocess.Popenr   T)approved)rp   r   r   ry   r   rv   attempt_owner_firer   r   r   GATE_FIRE_BLOCKED_NO_APPROVALr   r   )rN   rn   r   spopenr   firedfired2s          r4   test_fire_blocked_no_approvalz.Test07NoCronFire.test_fire_blocked_no_approval  s     ZZ() 	'T

-.	'28**Q\*:C//4E00t0DF""$$$&	' 	' 	x'M'MN**+(N(NO	' 	' 	' 	's#   D,A$D  D, D)	%D,,D5c                    | j                         }| j                  |t              }| j                  t              5  t
        j                  |dd       d d d        y # 1 sw Y   y xY w)Nr   T)r   r   )rp   ry   r   assertRaisesRuntimeErrorrv   r   r   s      r4   !test_fire_never_reaches_real_callz2Test07NoCronFire.test_fire_never_reaches_real_call  s^     jjj6|, 	I''d4'H	I 	I 	Is   AA(N)rz   r{   r|   r   r   r=   r6   r4   r   r     s    PIr6   r   c                      e Zd Zd Zd Zy)Test08NoScheduleCreationc                   | j                         }| j                  t        j                  j	                  | j
                               | j                  |t              }| j                  |j                  t        j                         | j                  t        j                  j	                  | j
                        d       y )Nr   u?   gate 가 marker/schedule 기록을 만들면 안 된다(fire 0))rp   r   rS   rT   existsrV   ry   r   r   r   rv   r   r   s      r4   test_gate_writes_no_markerz3Test08NoScheduleCreation.test_gate_writes_no_marker  s     45jjj6X%M%MN4Z	\r6   c                    t         dz  dz  j                  d      }| j                  d|       | j                  d|       y )Nr   r   rd   zimport globz	glob.glob)r   r   r   )rN   r   s     r4   test_no_glob_in_runner_sourcez6Test08NoScheduleCreation.test_no_glob_in_runner_source$  s>    j(+HHSST[\

3j1r6   N)rz   r{   r|   r  r  r=   r6   r4   r   r     s    \2r6   r   c                      e Zd Zd Zy)Test09ActiveFalsec                    | j                         }| j                  |t              }| j                  |j                         t
        j                  |      }| j                  |j                         y )Nr   )rp   ry   r   r   r   rv   r   )rN   rn   r   r   s       r4   #test_active_false_on_ready_and_firez5Test09ActiveFalse.test_active_false_on_ready_and_fire,  sV     jjj6$++C0&r6   N)rz   r{   r|   r  r=   r6   r4   r  r  +  s    'r6   r  c                      e Zd Zd Zd Zy)Test10ExplicitSingleResultc                   | j                  dd      }| j                  dd       | j                  dd       | j                  |t              }| j                  |j                  d       | j                  |j
                  |       y )	NrX   task-2741.result.jsonrY   ra   z	task-9001ztask-9001.result.jsonz	task-9002ztask-9002.result.jsonr   )rp   ry   r   r   rY   result_json_path)rN   targetr   s      r4   !test_only_explicit_path_processedz<Test10ExplicitSingleResult.test_only_explicit_path_processed6  s|    ##K?V#W;6MN;6MNjjlj;k2--v6r6   c                6   | j                  dd       t        j                  j                  | j                  d      }| j                  |t              }| j                  |j                  t        j                         | j                  |j                         y )Nz	task-9003ztask-9003.result.jsonr  r  r   )rp   rS   rT   rU   rL   ry   r   r   r   rv   r   r   r   )rN   missingr   s      r4   &test_nonexistent_path_no_glob_fallbackzATest10ExplicitSingleResult.test_nonexistent_path_no_glob_fallback?  sm    ;6MN'',,txx)@Ajj|j<X%M%MN#((#r6   N)rz   r{   r|   r  r  r=   r6   r4   r
  r
  5  s    7$r6   r
  c                      e Zd Zd Zy)Test11TerminalEnumc           	        i }| j                         }| j                  |t              }|j                         d   ||j                  <   | j                  |d t              }|j                         d   ||j                  <   | j                  dt
        d      }| j                  |t              }|j                         d   ||j                  <   t        | j                  dd	
      5 }|j                  t        j                  t        j                  dt        d      dz          d d d        | j                  |t              }|j                         d   ||j                  <   t        j                  |t        t         t"        j$                  j'                  | j(                  d      t              }t        j+                  |      }|j                         d   ||j                  <   | j-                  t/        |j1                               t/        t        j2                               |j5                         D ]  \  }}| j-                  ||        y # 1 sw Y   /xY w)Nr   r   c                      y r;   r=   r=   r6   r4   rO   zSTest11TerminalEnum.test_all_five_terminals_reachable_and_recorded.<locals>.<lambda>S  r   r6   r   z
task-2741sztask-2741s.result.json)rY   rZ   ra   rc   rd   re   rX   r   r   zfresh_ledger.jsonl)rr   rs   rt   r   )rp   ry   r   r   r   r   rj   rV   r   rk   r   rv   r   r@   rw   r>   rA   rS   rT   rU   rL   r   r   setkeysGATE_TERMINAL_STATUSESitems)	rN   seenp_readyrp_stalero   r_okkvs	            r4   .test_all_five_terminals_reachable_and_recordedzATest11TerminalEnum.test_all_five_terminals_reachable_and_recordedJ  s    $$&JJw\J:X.QXX JJw,\JZX.QXX $$\J+C % EJJw\J:X.QXX $++sW5 	SGGDJJ)C)C+6D J KMQR S	S JJw\J:X.QXX //{{!ww||DHH6JK% 0 ' ''-X.QXXTYY[)3x/N/N+OPJJL 	#DAqQ"	#	S 	Ss   *>IIN)rz   r{   r|   r#  r=   r6   r4   r  r  I  s    ##r6   r  c                     g fd} | fS )ud   callback_launch_fn 스파이(no-fire stub). 호출 인자를 calls 에 기록만 한다(실 cron 0).c                T    j                  |       t        j                  dd       S )NLAUNCH_ENFORCED_STUB)verdict
audit_pathr   typesSimpleNamespace)_result_json_pathrx   callss     r4   _fnz_spy_callback.<locals>._fn{  s$    R$$-CPTUUr6   r=   )r.  r-  s    @r4   _spy_callbackr/  w  s    EV #:r6   )r   r   c               <    t         j                  ||t        |       S )uX   owner-gate subcommand 와 동일한 owner_proof_pickup_gate 를 bound 한 owner_gate_fn.)rr   r   rs   rt   )rv   build_owner_gate_fnrA   )rV   r   r   s      r4   _bound_gater2    s&    '' !!	 (  r6   c                  6    e Zd Zd Zd Zd Zd Zd Zd Zd Z	y)	Test01wPickupOnceGateBlocksFirec          	         t         j                  |t        t        t        j
                  j                  | j                  d      ||      S )Ncb4tuple.jsonlrr   r   ledger_pathcallback_launch_fnowner_gate_fn)rv   pickup_oncer>   r   rS   rT   rU   rL   )rN   rn   gatespys       r4   _pickupz'Test01wPickupOnceGateBlocksFire._pickup  s@    ##)%TXX/?@" $ 
 	
r6   c                z   | j                  d      }t               \  }}| j                  |t        | j                        |      }| j                  |j                  t        j                         | j                  |g d       | j                  |j                  d       | j                  |j                  d       y )NFr   r<  r=  u=   gate 미PASS 시 callback_launch_fn 미호출이어야 한다u-   gate 미PASS 시 callback/wake argv 미구성u-   gate 미PASS 시 owner launch label 미기록)rp   r/  r>  r2  rV   r   r'  rv   PICKUP_OWNER_GATE_BLOCKEDr   r   callback_launch_verdictrN   rn   r-  r=  r   s        r4   +test_not_eligible_blocks_callback_launch_fnzKTest01wPickupOnceGateBlocksFire.test_not_eligible_blocks_callback_launch_fn  s    U;"_
sll1;t{{#;lEh&H&HI$cd#(($ST#557fgr6   c                   | j                  t              }t               \  }}| j                  |t	        | j
                        |      }| j                  |j                  t        j                         | j                  |g        y )Nr   r@  )
rp   r   r/  r>  r2  rV   r   r'  rv   rA  rC  s        r4   $test_stale_blocks_callback_launch_fnzDTest01wPickupOnceGateBlocksFire.test_stale_blocks_callback_launch_fn  sg    
3"_
sll1;t{{#;lEh&H&HI#r6   c                   | j                         }t               \  }}t        | j                  d       }| j	                  |||      }| j                  |j                  t        j                         | j                  |g        y )Nc                     t         S r;   r   r=   r6   r4   rO   z\Test01wPickupOnceGateBlocksFire.test_non_anu_key_blocks_callback_launch_fn.<locals>.<lambda>  s    | r6   )r   r@  )	rp   r/  r2  rV   r>  r   r'  rv   rA  )rN   rn   r-  r=  r<  r   s         r4   *test_non_anu_key_blocks_callback_launch_fnzJTest01wPickupOnceGateBlocksFire.test_non_anu_key_blocks_callback_launch_fn  sj     "_
s4;;/CDll14Sl1h&H&HI#r6   c                   | j                         }t               \  }}| j                  |t        | j                        |      }| j                  |j                  t        j                         | j                  t        |      dd       y )Nr@     u9   gate PASS 면 fire 경로 진행(callback_launch_fn 1회))rp   r/  r>  r2  rV   assertNotEqualr'  rv   rA  r   r   rC  s        r4   (test_gate_pass_allows_callback_launch_fnzHTest01wPickupOnceGateBlocksFire.test_gate_pass_allows_callback_launch_fn  sk      "_
sll1;t{{#;lECKK)K)KLUQ(cdr6   c           	        | j                         }t               \  }}t        j                  |t        t
        t        j                  j                  | j                  d      |      }| j                  |j                  t        j                  d       | j                  |g d       | j                  |j                  d       | j                  |j                  d       y )Nr6  rr   r   r8  r9  uN   callback_launch_fn 주입 + owner_gate_fn 부재 → fail-closed 여야 한다u8   gate 미주입 시 callback_launch_fn 호출 0(우회 0)u.   gate 미주입 시 wake/callback argv 구성 0u.   gate 미주입 시 owner launch label 기록 0)rp   r/  rv   r;  r>   r   rS   rT   rU   rL   r   r'  rA  r   r   rB  rC  s        r4   1test_callback_launch_fn_without_gate_fails_closedzQTest01wPickupOnceGateBlocksFire.test_callback_launch_fn_without_gate_fails_closed  s      "_
s""<TXX/?@" # $ 	h&H&Hi	k$^_#(($TU#557ghr6   c           	        | j                         }t        j                  |t        t        t
        j                  j                  | j                  d            }| j                  |j                  t        j                  d       y )Nzcb4tuple_prim.jsonl)rr   r   r8  uG   fire executor 미주입 primitive 는 fail-closed 아님(현행 보존))rp   rv   r;  r>   r   rS   rT   rU   rL   rL  r'  rA  r   s      r4   3test_primitive_without_callback_launch_fn_preservedzSTest01wPickupOnceGateBlocksFire.test_primitive_without_callback_launch_fn_preserved  sh      ""<TXX/DE # G 	CKK)K)Ke	gr6   N)
rz   r{   r|   r>  rD  rF  rI  rM  rP  rR  r=   r6   r4   r4  r4    s)    
h$$ei 	gr6   r4  c                  6    e Zd ZdeddZed        Zd Zd Zy)Test02wSharedGatePolicyT)r\   rZ   c               6    | j                  ||ddddd      S )Nresult_json_writtenSID-2741r   schedule_idr   completion_signalcollector_envelope)r\   rZ   r`   )rp   )rN   r\   rZ   s      r4   _write_driver_resultz,Test02wSharedGatePolicy._write_driver_result  s6    !!"7((=9C<A*CD " E 	Er6   c                 X    t        j                  t        j                  dddddg       S )Nr   	OWNER_ANUrW  T)outcomerY  query_ok)r'  classificationowner_resolutionreasons)r*  r+  _OCEVERDICT_AUTHORITATIVE)_kws    r4   _authoritative_verifyz-Test02wSharedGatePolicy._authoritative_verify  s0    $$..r)4Z*.09;= 	=r6   c                   | j                  ddd      }| j                  |t              }| j                  |j                  t
        j                         | j                  |j                         t               \  }}t
        j                  |t        t        t        j                  j                  | j                  d      |t!        | j"                              }| j                  |j$                  t
        j&                         | j                  |g        | j)                  d      }t               \  }}t*        j-                  || j                  |t!        | j"                        | j.                  t        t        j                  j                  | j                  d	      d
d	      }	| j                  |g d       | j                  |	j$                  t*        j0                         | j3                  d|	j4                  xs dd       y )Nz
task-2741aFztask-2741a.result.json)rY   r\   ra   r   z
cb_b.jsonlr7  r   z
cb_c.jsonl        rK  rootr9  r:  	verify_fnr   r8  
stable_secreadiness_retriesu=   process_one 도 gate 미PASS 시 callback_launch_fn 미호출u   owner_proof_pickup_gate 미PASSr   uL   process_one 의 fire 차단 사유가 gate 미PASS 로 surface 돼야 한다)rp   ry   r   r   r   rv   r   r   r   r/  r;  r>   rS   rT   rU   rL   r2  rV   r'  rA  r]  drv_modprocess_onerh  VERDICT_FIRE_FAILEDr   error)
rN   p_agcalls_bspy_bres_bp_ccalls_cspy_crecs
             r4   3test_ineligible_blocks_across_all_three_entrypointszKTest02wSharedGatePolicy.test_ineligible_blocks_across_all_three_entrypoints  s      U'? ! AJJsJ68#K#KL! '$$;\TXX|<$K4L % N 	(J(JK"% ''e'D&!!dhh$%dkk200%TXX|<a " 1 	"&efg&A&AB7#))/rd	fr6   c                4   | j                  dd      }t               \  }}t        j                  |t        t
        t        j                  j                  | j                  d      |t        | j                              }| j                  |j                  t        j                         | j                  t!        |      d       | j#                         }t               \  }}t$        j'                  || j                  |t        | j                        | j(                  t
        t        j                  j                  | j                  d      dd		      }| j                  t!        |      dd
       | j                  |j                  t$        j*                  d       y )Nz
task-2741pztask-2741p.result.jsonr  zcb_pb.jsonlr7  rK  zcb_pc.jsonlrj  rk  u1   process_one gate PASS 면 callback_launch_fn 1회u-   gate PASS 시 fire 차단(FIRE_FAILED) 아님)rp   r/  rv   r;  r>   r   rS   rT   rU   rL   r2  rV   rL  r'  rA  r   r   r]  rp  rq  rh  rr  )	rN   p_brv  rw  rx  ry  rz  r{  r|  s	            r4   2test_eligible_passes_across_pickup_and_process_onezJTest02wSharedGatePolicy.test_eligible_passes_across_pickup_and_process_one  s>      =U V&$$;\TXX}=$K4L % N 	EMM8+M+MNWq) '')&!!dhh$%dkk200%TXX}=a " 1 	Wq*]^CKK)D)DK	Mr6   N)	rz   r{   r|   r@   r]  staticmethodrh  r}  r  r=   r6   r4   rT  rT    s.    <@4 E = =!fFMr6   rT  c                  $    e Zd Zd Zd Zd Zd Zy)Test03wMandatoryGateFailClosedc          	         t         j                  ||t        t        j                  j                  | j                  d      |      S )Nzcb_mand.jsonlrO  )rv   r;  r   rS   rT   rU   rL   )rN   rn   r   r=  s       r4   _pickup_no_gatez.Test03wMandatoryGateFailClosed._pickup_no_gate,  s:    ##lTXX?" $ $ 	$r6   c                t   t         d d fD ]  }| j                         }t               \  }}| j                  |||      }| j	                  |j
                  t        j                  d       | j	                  |g d       | j                  |j                  d       | j                  |j                  d        y )	Nc                     t         S r;   r   r=   r6   r4   rO   zQTest03wMandatoryGateFailClosed.test_fail_closed_key_independent.<locals>.<lambda>5  s    \ r6   c                      y r;   r=   r=   r6   r4   rO   zQTest03wMandatoryGateFailClosed.test_fail_closed_key_independent.<locals>.<lambda>5  r   r6   )r   r=  u/   owner_gate_fn 부재 → key 무관 fail-closedr   u%   callback_launch_fn 호출 0(우회 0)u   wake/callback argv 구성 0u!   owner proof launch label 기록 0)r>   rp   r/  r  r   r'  rv   rA  r   r   rB  )rN   r   rn   r-  r=  r   s         r4    test_fail_closed_key_independentz?Test03wMandatoryGateFailClosed.test_fail_closed_key_independent3  s    "%9\K 	`F""$A&JE3&&qS&ACS[[(*L*L!R  TUB(OPchh(EFc99;^_	`r6   c                   | j                         }t        j                  j                  | j                  d      }t               \  }}t        j                  |t        t        ||      }| j                  |j                  t        j                         | j                  t        j                  j                  |      d       | j                  |j                   d       | j                  |j"                  d       | j                  t        j                  j                  t        j                  j                  | j                  d                   y )Nzcb_noside.jsonlrO  u%   fail-closed 시 dedupe ledger write 0u(   fail-closed 시 collector_result write 0u#   fail-closed 시 done marker write 0ztask-2741.pickup.done)rp   rS   rT   rU   rL   r/  rv   r;  r>   r   r   r'  rA  r   r  r   closeout_pathmarker_path)rN   rn   rV   _r=  r   s         r4   'test_fail_closed_before_any_side_effectzFTest03wMandatoryGateFailClosed.test_fail_closed_before_any_side_effect?  s      dhh(9:3""<3 # 8 	h&H&HI/1XY#++-WX#//+PQTXX?V(WXYr6   c                   | j                  ddddd      }t               \  }}g fd}t        j                  || j                  ||d t
        j                  t        t        j                  j                  | j                  d      d	d

      }| j                  |j                  t        j                  d       | j                  g d       | j                  |g d       y )NrV  rW  r   rX  rZ  r   c                 \    j                  | |f       t        j                  ddgd      S )N
WAKE_BUILTxr   )r'  r   sha256r)  )arx   pickup_callss     r4   _spy_pickupzdTest03wMandatoryGateFailClosed.test_driver_process_one_fail_closed_without_gate.<locals>._spy_pickupY  s-    B(((SERTUUr6   zcb_drv_mand.jsonlrj  rK  )	rl  	pickup_fnr9  r:  rm  r   r8  rn  ro  uG   driver 가 gate 부재 fire-capable 주입을 fail-closed 해야 한다u   pickup_fn 미호출(fire 0)u$   callback_launch_fn 미호출(fire 0))rp   r/  rp  rq  rL   rT  rh  r   rS   rT   rU   r   r'  rr  )rN   rpr-  r=  r  r|  r  s         @r4   0test_driver_process_one_fail_closed_without_gatezOTest03wMandatoryGateFailClosed.test_driver_process_one_fail_closed_without_gateO  s     (=9C<A*CD   E #_
s	V !!TXX!"-CC%TXX/BCa " 1 	g&A&Ab	dr+HI$JKr6   N)rz   r{   r|   r  r  r  r  r=   r6   r4   r  r  +  s    $
`Z Lr6   r  c                      e Zd Zd Zd Zd Zy)%Test11wDefaultSealedLoaderNoNameErrorc                V    | j                  t        t        j                        d       y )NuY   _default_sealed_key_loader 는 정의돼 있어야 한다(Gemini CRITICAL false positive))r   callablerv   _default_sealed_key_loaderrM   s    r4   #test_default_loader_symbol_callablezITest11wDefaultSealedLoaderNoNameError.test_default_loader_symbol_callablen  s    !D!DEs	ur6   c                $   | j                         }	 t        j                  |t        | j                  t
              }| j                  j                  t        j                         y # t        $ r}| j                  d|        Y d }~Md }~ww xY w)N)rs   rt   r   z&_default_sealed_key_loader NameError: )rp   rv   rw   rA   rV   r   	NameErrorfailr   r   r  )rN   rn   r   excs       r4   %test_gate_default_loader_no_nameerrorzKTest11wDefaultSealedLoaderNoNameError.test_gate_default_loader_no_nameerrorr  s      	F22kdkk) 3 +C
 	cjj("A"AB  	FII>seDEE	Fs   +A( (	B1B

Bc                    | j                         }	 t        j                  |d t        j                  j                  | j                  d             y # t        $ r}| j                  d|        Y d }~y d }~ww xY w)Nc                      y r;   r=   r=   r6   r4   rO   zdTest11wDefaultSealedLoaderNoNameError.test_pickup_once_default_loader_no_nameerror.<locals>.<lambda>  r   r6   z
cb_n.jsonl)rr   r8  z2pickup_once _default_sealed_key_loader NameError: )	rp   rv   r;  rS   rT   rU   rL   r  r  )rN   rn   r  s      r4   ,test_pickup_once_default_loader_no_nameerrorzRTest11wDefaultSealedLoaderNoNameError.test_pickup_once_default_loader_no_nameerror~  so      	R  l-/WW\\$((L-Q ! S 	RIIJ3%PQQ	Rs   AA 	A;A66A;N)rz   r{   r|   r  r  r  r=   r6   r4   r  r  m  s    u
CRr6   r  __main__   )	verbosity)r$   strr%   r  )?__doc__
__future__r   builtinsr   _pytest.assertion.rewrite	assertionrewriter   importlib.utilr   rk   rS   r   rP   r*  unittestpathlibr   r   r   resolveparentr   r  rT   insertr5   _ENFre  rv   rp  ANU_KEY_2553r<   EXECUTOR_SELF_KEY_EXAMPLEr   r   r@   r   r>   rA   TestCaserC   r~   r   r   r   r   r   r   r   r   r  r
  r  r/  r2  r4  rT  r  r  rz   mainr=   r6   r4   <module>r     sC  0 #      	 
     X ''..55u:SXXHHOOAs5z"	 /1VW 02_ `68de %'I J46\] )+Q R #%E F $&G H
,.M
N 

--! 
 <H  <H: :8:U :$ $FLe L"
O% 
O	$5 	$G% G&Iu I.2u 2"' '$ $($# $#\ #.L Hge HgXLMe LMd>LU >LDRE R8 zHMMA r6   