
    vj5                       d Z ddlmZ ddl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Z edd        ed	d
       ddlmZmZ ddlmZmZmZmZ ddlmZmZmZmZmZm Z m!Z!m"Z" ddl#m$Z%m&Z&m'Z'm(Z(m)Z) dZ$dZ*dZ+dZ,d Z-d Z.d Z/d Z0d Z1d Z2d Z3d Z4d Z5d Z6y)u   tests/regression/test_callback_runtime_enforcement_2626.py

task-2626 — CALLBACK_RUNTIME_ENFORCEMENT_WIRING regression (회장 §6, 10건).
mock-based · 실 cron 0 · 실 발사 0 · subprocess 0.
    )annotationsN)Path   c                   t         j                  j                  |       }|t        |dd      j	                  |      r|S t
        j                  j                  | t        |z        }||j                  J t
        j                  j                  |      }|t         j                  | <   |j                  j                  |       |S )N__file__ )sysmodulesgetgetattrendswith	importlibutilspec_from_file_location_ROOTloadermodule_from_specexec_module)modnamerelpathexistingspecmods        :tests/regression/test_callback_runtime_enforcement_2626.py
_load_realr      s    {{w'H*b A J J7 S>>11'57?KD 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.py)DISPATCH_CONTRACT_VIOLATIONclassify_dispatch_contract)SELF_COLLECTOR_FORBIDDENCOLLECTOR_ROLE_ANUPATH_DISPATCH_PYenforce_callback_owner)CALLBACK_KIND_FALLBACKCALLBACK_KIND_NORMALLAUNCH_FAIL_CLOSEDLAUNCH_PASSSTATUS_ANU_OWNED_READY STATUS_CALLBACK_PROMPT_TOO_LARGESTATUS_SELF_KEY_FAIL_CLOSEDlaunch_callback)ANU_KEYANU_CHAT_IDCancelClassificationRemoverResultcancel_fallback_on_successc119085addb0f8b71e41a2324a3ccdd0
6937032012z?task_id=task-2626
owner_key=c119085addb0f8b7
collector_role=ANUc            
     2   t        t        dt        t        t        t
        dd      } | j                  t        k(  sJ | j                  t        k(  sJ | j                  $t        | j                  v rt        | j                  vsJ | j                  d   dk(  sJ y)uW   ANU key + normal kind → LAUNCH_PASS, argv 에 ANU_KEY 포함, contract_fields 확인.	task-262610m/home/jay/workspacekindtask_idexecutor_key	owner_keychat_idpromptatcanonical_rootNcallback_roleCOLLECTOR_ANU)r*   r$   EXEC_SELF_KEYr+   CHATENVELOPEverdictr&   statusr'   argvcontract_fieldsdecs    r   $test_01_anu_key_normal_callback_passrK   G   s    
!",	C ;;+%%%::////88Gsxx$7MQTQYQY<YYY/?BBBr   c            
         t        t        dt        t        t        t        dd      } | j
                  t        k(  sJ | j                  t        k(  sJ | j                  J y)ua   self-key normal → verdict LAUNCH_FAIL_CLOSED, status STATUS_SELF_KEY_FAIL_CLOSED, argv is None.r4   r5   r6   r7   N)
r*   r$   rB   rC   rD   rE   r%   rF   r)   rG   rI   s    r   ,test_02_executor_self_key_normal_fail_closedrM   [   s\    
!",	C ;;,,,,::444488r   c            
     
   t        t        dt        t        t        t
        dd      } | j                  t        k(  sJ | j                  t        | j                  v sJ | j                  d   du sJ | j                  d   d	k(  sJ y)
u   ANU key + fallback kind → LAUNCH_PASS, argv 에 ANU_KEY 포함,
    fallback_safety_net_registered is True, fallback_safety_net_role_single_purpose 확인.r4   r5   r6   r7   Nfallback_safety_net_registeredT'fallback_safety_net_role_single_purpose%RECOVERY_ONLY_NO_FINAL_REPORT_TRIGGER)
r*   r#   rB   r+   rC   rD   rE   r&   rG   rH   rI   s    r   test_03_anu_key_fallback_passrR   n   s     #",	C ;;+%%%88Gsxx$777?@DHHHEF2	3	3r   c            
         t        t        dt        t        t        t        dd      } | j
                  t        k(  sJ | j                  t        k(  sJ | j                  J y)uS   fallback + self-key → LAUNCH_FAIL_CLOSED, STATUS_SELF_KEY_FAIL_CLOSED, argv None.r4   r5   r6   r7   N)
r*   r#   rB   rC   rD   rE   r%   rF   r)   rG   rI   s    r   .test_04_executor_self_key_fallback_fail_closedrT      s\    
#",	C ;;,,,,::444488r   c                    d| dz  }|j                  t        j                  ddi      d       | dz  }|j                  dd       | d	z  }|j                  d
d       | dz  }|j                  t        j                  dt        t        ddd      d       | dz  }ddfd
}t        d|||||d|d
      }|j                  t        j                  k(  sJ |j                  du sJ |j                         sJ y)uS   durable evidence + dispatch-fired marker → fake remover 로 cancel → CANCELLED.fb-cron-2626ztask-2626.result.jsonrF   okutf-8encodingztask-2626.mdz# report
okzcollector.markerdonezdispatch-fired.jsonr4   fallbackfallback_callback_cron_idr<   anu_keyfallback_roler9   callback_policy_azfallback_cancelled.jsonTdry_runc               ,    | k(  sJ t        dd      S )Nremovedfake)rF   detail)r.   )cron_idrd   targets     r   fake_removerzGtest_05_normal_success_fallback_cancel_on_success.<locals>.fake_remover   s    &   If==r   )
r9   target_cron_iddispatch_fired_marker_pathresult_json_pathreport_pathcollector_result_marker_pathfallback_cancelled_marker_pathnormal_collector_successremoverrd   N)
write_textjsondumpsr,   CANCEL_ANU_KEYr/   classificationr-   	CANCELLEDfallback_cancelledexists)	tmp_pathresult_jsonreportcollector_markermarker	fb_markerrk   rJ   rj   s	           @r   1test_05_normal_success_fallback_cancel_on_successr      s:   F44K4::x&67'J&F
nw7"449--F


"-3&)!+	"
 	    44I)- > %#)$%5'0!%C !5!?!????!!T)))r   c                D  
 d}| dz  }|j                  t        j                  ddi      d       | dz  }|j                  dd       | dz  }|j                  d	d       | d
z  }|j                  t        j                  d|t        t        ddd      d       | dz  }|j                  dd       | dz  }g 
dd
fd
}t        d|||||||d|d      }	|	j                  t        j                  k(  sJ |	j                  du sJ 
g k(  sJ |j                         rJ y)uh   cancel lock 선점 시 fallback 뒤늦은 발화 → ALREADY_FIRED, remover 미호출, 마커 미생성.rV   zr.jsonrF   rW   rX   rY   zr.mdzc.markerr[   zd.jsonr4   r\   r]   ra   zcancel.lockzheld-by-normal-successzfb.jsonTrc   c               >    j                  |        t        d      S )Nrf   )rF   )appendr.   )ri   rd   rf   s     r   rk   zPtest_06_fallback_fires_after_success_noop_no_ledger_append.<locals>.fake_remover   s    wI..r   )r9   rl   rm   rn   ro   rp   rq   cancel_lock_pathrr   rs   rd   FN)rt   ru   rv   r,   rw   r/   rx   r-   ALREADY_FIREDcron_remove_invokedr{   )r|   rj   r}   r~   r   r   lockr   rk   rJ   rf   s             @r   :test_06_fallback_fires_after_success_noop_no_ledger_appendr      sh   FX%K4::x&67'JF
dW-*,9 F


"-3&)!+	"
 	    m#DOO,wO?9$IG)- / %#)$%5'0!%C !5!C!CCCC""e+++b==!!!!r   c                 l    t        dddd      } | j                  t        k(  sJ | j                  du sJ y)ud   result 존재 + normal·fallback 둘 다 부재 → DISPATCH_CONTRACT_VIOLATION + recovery_required.r4   FT)r9   normal_callback_presentfallback_presentresult_presentN)r   rx   r   recovery_required)recs    r   <test_07_result_present_normal_and_fallback_missing_violationr      sC    
$ %	C !<<<<  D(((r   c                     t        t        dt        t        t        dddd	      } | j
                  t        k(  sJ | j                  t        k(  r| j                  J | j                  d   d	kD  sJ y)
u]   3900 bytes 초과 prompt → STATUS_CALLBACK_PROMPT_TOO_LARGE, LAUNCH_FAIL_CLOSED, argv None.r4   a  task_id=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxr5   r6   F)	r8   r9   r:   r;   r<   r=   r>   r?   require_envelopeNcallback_prompt_utf8_bytesi<  )r*   r$   rB   r+   rC   rF   r(   rE   r%   rG   rH   rI   s    r   !test_08_callback_prompt_too_larger   
  sr    
!"&,
C ::9999;;,,1AAA;<tCCCr   c            
        t        t        dt        t        t        t
        dd      } | j                  dk(  sJ | j                  du sJ | j                  t        k(  sJ t        t        dt        t        t        t
        dd      }|j                  t        k(  sJ d|j                  v sd	|j                  j                         v sJ |j                  J y
)u   canonical_root 빈값 → 교정(canonical_root_corrected=True, verdict PASS).
    canonical_root='/tmp/evil' → LAUNCH_FAIL_CLOSED, canonical root invalid.r4   r5   r   r7   r6   Tz	/tmp/evilCANONICAL_ROOTinvalidN)r*   r$   rB   r+   rC   rD   r?   canonical_root_correctedrE   r&   r%   rF   lowerrG   )dec_correcteddec_evils     r   7test_09_canonical_root_missing_corrected_or_fail_closedr     s     $!"	M ''+@@@@11T999  K/// !""	H 1111x.)x?T?T?V2VVV==   r   c                    t        dt        t        t        t        dddt        dt              } t
        | j                  v sJ t        t        dt        t        t        t        dd	      }|j                  t        k(  r|j                  J y
)u   enforce_callback_owner self-collector → SELF_COLLECTOR_FORBIDDEN.
    launch_callback self-key → LAUNCH_FAIL_CLOSED, argv None.r4   NCFBDT)r9   r:   collector_keycollector_owner_keycollector_rolenormal_collector_cron_idr^   dispatch_cron_idr<   prompt_claims_anu_collector
entry_pathr5   r6   r7   N)r"   rB   r    rC   r!   r   classificationsr*   r$   rD   rE   r%   rG   )enfrJ   s     r   (test_10_self_collector_attempt_forbiddenr   C  s     !"#))!%"&$(#C $s':'::::
!",	C ;;,,1AAA1Ar   )r   strr   r   )7__doc__
__future__r   importlib.utilr   ru   r	   pathlibr   pytestr   resolveparentsr   r   pathinsertr   !anu_v3.dispatch_callback_contractr   r    dispatch.callback_owner_enforcerr   r    r!   r"   (dispatch.normal_fallback_callback_helperr#   r$   r%   r&   r'   r(   r)   r*   )utils.completion_callback_fallback_cancelr+   rw   r,   r-   r.   r/   rB   rC   rD   rK   rM   rR   rT   r   r   r   r   r   r    r   r   <module>r      s   
 #   
  X ((+u:SXXHHOOAs5z"	 -/T U 
57d e 	 	 	  "N
C(&0&*^/"h	)D( !JBr   