
    dj6                       d Z ddlmZ ddlZddlZddlmZmZ ddlm	Z	m
Z
mZ ddlmZmZmZmZmZmZ dZ ej(                  d      Zd	Zd
ZdZdZ eeeeeh      ZdHdZ	 dIed	 	 	 	 	 dJdZddlmZ m!Z" dZ#dZ$dZ% ee$e%h      Z&e G d d             Z'ddddddd e(e      dddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dKdZ)e G d d             Z* e(e      d	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dLd Z+d!Z,d"Z-d#Z.d$Z/d%Z0d&Z1d'Z2d(Z3d)Z4d*Z5d+Z6d,Z7d-Z8d.Z9d/Z: eh d0      Z;e8fdd1	 	 	 dMd2Z<dNd3Z=d4Z>dOd5Z?dd1dNd6Z@de:dd7	 	 	 	 	 	 	 	 	 dPd8ZAdQd9ZBdRd:ZCdd;dSd<ZDe G d= d>             ZE	 	 	 	 	 	 	 	 dTd?ZFe G d@ dA             ZG e(e      d	 	 	 	 	 	 	 	 	 	 	 	 	 dUdBZHddddddd e(e      ddC		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dVdDZIg dEZJdIdWdFZKeLdGk(  r eM eK             y)Xu  dispatch.normal_fallback_callback_helper — ANU-owned normal/fallback
callback registration helper + post-registration owner cross-check.

task-2553+49 (§8 / §10 / 9-R.1 — 코드/파일 자동화).

The actual normal/fallback callback cron is registered via the external
``cokacdir --cron`` tool (a cron-direct path that ANU cannot file-patch,
9-R.1). So the owner=ANU-key pin is enforced at the **ANU control layer**,
which IS code-patchable:

  1. ``build_anu_owned_callback_request`` — the dispatch prompt generator /
     4-tuple registration step builds the callback registration request HERE.
     It is **fail-closed**: an owner key equal to the executor self key, or
     not a configured independent ANU key, or a non-ANU collector role, makes
     the request INVALID and NO command argv is produced (회장 §2/§8/§10).
  2. ``verify_post_registration_owner`` — after ``cokacdir --cron`` returns,
     the ANU control layer re-reads the schedule_history / registry owner
     binding and cross-checks key/chat/role. An owner that resolved to the
     executor key (or any non-ANU key) at registration time -> FAIL (회장 §8
     "등록 후 schedule_history/registry 에서 chat_id·key·role binding 교차
     검증").

Standalone, zero-mutation, Layer A / NO-CRON (9-R.1): this module performs
ZERO cron register/remove, ZERO dispatch, ZERO ``subprocess`` / ``cokacdir``
exec. It only *builds a request descriptor* and *validates* an owner binding.
The authorized session executes the (ANU-keyed) cron outside this module.
    )annotationsN)	dataclassfield)ListOptionalSequence)DEFAULT_ANU_KEYSENFORCER_SCHEMAFAILPASSenforce_callback_owner
is_anu_keyANU_CHAIR_FACING_SIDzM^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$*AUTHORITATIVE_CALLBACK_COLLECTOR_PROCESSED'AUTHORITATIVE_BUT_SESSION_DISCONTINUITY NON_AUTHORITATIVE_SELF_COLLECTORSESSION_PROPAGATION_GAPc                    | rt        | t              syt        t        j	                  | j                                     S )uL   cokacdir --session 옵션이 받는 UUID 8-4-4-4-12 hex 형태인지 검증.F)
isinstancestrbool_SESSION_ID_PATTERNmatchstrip)sids    +dispatch/normal_fallback_callback_helper.pyis_valid_session_idr   D   s.    jc*#))#))+677    )env_namec                   t        | t              r| nd}|st        j                  j	                  |      }|sy|j                         }|syt        |      r|S dS )u   chair-facing SID 해석: 명시값 > 환경변수 > None.

    값이 유효한 session UUID 가 아니면 None 을 반환 (★ 빈 문자열·미설정 동일 처리).
    N)r   r   osenvirongetr   r   )explicitr   	candidates      r   resolve_chair_facing_sidr&   K   sS     'x54IJJNN8,	!I+I69@D@r   )ExecutorSelfKeyForbidden'assert_collector_key_is_independent_anuz+dispatch.normal_fallback_callback_helper.v1normalfallbackc                      e Zd ZU dZded<   ded<   ded<   ded<   ded<   ded<   d	ed
<   ded<   ded<    ee      Zded<   edd       Z	ddZ
y)CallbackRequestu  An owner-validated callback registration request descriptor.

    ``argv`` is the (data-only) ``cokacdir --cron`` argument vector an
    authorized session would execute. It is produced ONLY when the owner
    binding is fail-closed valid (owner == an independent ANU key, not the
    executor self key). On FAIL, ``argv`` is None — no registration is
    possible (회장 §2/§8/§10).
    r   schemaverdictkindtask_id	owner_keychat_idOptional[str]cron_idOptional[List[str]]argvdictenforcementdefault_factory	List[str]reasonsc                (    | j                   t        k(  S Nr.   r   selfs    r   okzCallbackRequest.ok       ||t##r   c                $   | j                   | j                  | j                  | j                  | j                  | j
                  | j                  | j                  t        | j                        nd | j                  t        | j                        d
S )N
r-   r.   r/   r0   r1   r2   r4   r6   r8   r<   )r-   r.   r/   r0   r1   r2   r4   r6   listr8   r<   r@   s    r   to_jsonzCallbackRequest.to_json   sh    kk||II||||||'+yy'<DO$++DLL)
 	
r   Nreturnr   rI   r7   )__name__
__module____qualname____doc____annotations__r   rF   r<   propertyrB   rG    r   r   r,   r,   t   s_     KL
ILNL
t4GY4$ $
r   r,    ANUTcokacdir_cron_directF)r4   dispatch_cron_idnormal_collector_cron_idfallback_callback_cron_idcollector_roleprompt_claims_anu_collector
entry_pathanu_keysno_fallbackanu_keys_resolvablechair_facing_session_idc                |   | t         vr2t        t        t        | ||t	        |      |di d| dt          dg
      S 	 t        |       t        ||||||	|	n| t        k(  r|nd|
|
n| t        k(  r|nd|t	        |      |||||      }|j                  t        k7  rQt        t        |j                  | ||t	        |      |d|j                         dgt        |j                        z   
      S d	d
|d|dt	        |      d|dg
}dg}t        |      }|r)|j!                  d|g       |j#                  d| d       n|j#                  d       t        t        t        | ||t	        |      |||j                         |
      S # t        $ r4}t        t        t        | ||t	        |      |di d| g
      cY d}~S d}~ww xY w)u  Build a fail-closed normal/fallback callback registration request.

    The owner pin is enforced via ``enforce_callback_owner`` BEFORE any argv
    is produced. If the owner is the executor self key / not an independent
    ANU key / collector role != ANU -> verdict FAIL and ``argv=None`` (the
    cron-direct path therefore CANNOT register an executor-owned callback,
    회장 §2/§8/§10). HOLD propagates (§6 conditional escalation).

    task-2686 ★ chair-facing session propagation: ``chair_facing_session_id``
    이 명시되거나 환경변수 ``ANU_CHAIR_FACING_SID`` 가 유효 UUID 면 PASS argv
    에 ``--session <SID>`` 을 자동 첨부 (회장 verbatim 1번 / ANCHOR-5 dogfood).
    Nzunknown callback kind z (expected )rE   u   dispatch_callback_contract.assert_collector_key_is_independent_anu fail-closed — owner_key 가 독립 ANU key (c119085addb0f8b7) 가 아님: )r0   executor_keycollector_keycollector_owner_keyrX   rV   rW   rU   r2   rY   rZ   r[   r\   r]   ui   owner enforcement did not PASS — no cron-direct registration argv produced (fail-closed, §2/§8/§10).cokacdirz--cron--atz--chatz--keyz--onceu4   owner=independent ANU key — fail-closed gate PASS.z	--sessionzchair_facing_session_id=uS    → --session argv 자동 추가 (★ task-2686 회장 verbatim 1번 propagation).u   chair_facing_session_id 미해석 (명시값/환경변수 모두 invalid) — --session argv 미첨부, fresh session spawn 가능성 잔존 (★ task-2686 SESSION_PROPAGATION_GAP 후보).)VALID_KINDSr,   HELPER_SCHEMAr   r   _dcc_assert_independent_anu_DCC_ExecutorSelfKeyForbiddenr   CALLBACK_KIND_NORMALCALLBACK_KIND_FALLBACKr.   r   rG   rF   r<   r&   extendappend)r/   r0   ra   r1   r2   promptatr4   rU   rV   rW   rX   rY   rZ   r[   r\   r]   r^   _dcc_excenfr6   propagation_reasonsresolved_sids                          r    build_anu_owned_callback_requestrt      s:   B ; L-dX[QOP
 	
(
#I.& !!%% (3 %!%99't )4 &!%;;')G$?/-C2 {{d KKLK Ls{{#$
 	
( 	
GD" ']%]+,CDL[,/0""&|n 5@ @	

 	"">	

 GKKM# } ) 
 L22:=
 	

s   E> >	F;)F60F;6F;c                      e Zd ZU ded<   ded<   ded<   ded<   ded<   ded<   ded	<    ee
      Zded<   edd       ZddZ	y)PostRegistrationOwnerCheckr   r-   r.   r0   r   expected_owner_is_anuobserved_owner_keyobserved_chat_idobserved_roler9   r;   r<   c                (    | j                   t        k(  S r>   r?   r@   s    r   rB   zPostRegistrationOwnerCheck.okL  rC   r   c           
         | j                   | j                  | j                  | j                  | j                  | j
                  | j                  t        | j                        dS )Nr-   r.   r0   rw   rx   ry   rz   r<   )	r-   r.   r0   rw   rx   ry   rz   rF   r<   r@   s    r   rG   z"PostRegistrationOwnerCheck.to_jsonP  sQ    kk||||%)%?%?"&"9"9 $ 5 5!//DLL)	
 		
r   NrH   rJ   )
rK   rL   rM   rO   r   rF   r<   rP   rB   rG   rQ   r   r   rv   rv   A  sO    KLLt4GY4$ $

r   rv   )r[   c           
        g }t        ||      }|r||k(  r|j                  d       |s|j                  d|d       t        |      t        |      k7  r|j                  d|d|d       |dk7  r|j                  d|d	       |st        nt        }	|	t        k(  r|j                  d
       t        t        |	| ||t        |      ||      S )u)  회장 §8 — 등록 후 schedule_history/registry owner 교차검증.

    After ``cokacdir --cron`` registers the callback, the ANU control layer
    re-reads the owning schedule's key/chat/role and asserts it is an
    independent ANU binding. An owner that resolved to the executor key (or
    any non-ANU key), a chat mismatch, or a non-ANU role -> FAIL (a
    registered executor-self callback is detected post-hoc and rejected).
    Read-only; the observed values are supplied by the caller from
    schedule_history / the durable registry.
    u   post-registration owner key == executor self key — a cron-direct executor-self callback slipped through and is rejected (§8 post-reg owner cross-check / §2).zpost-registration owner key uA    is not a configured independent ANU key (§8 owner cross-check).zchat_id mismatch: registered=z
 expected=u    (§8 binding cross-check).rS   zregistered collector role=u5    != 'ANU' (§8 owner cross-check / §2 regression 5).ux   post-registration owner binding is an independent ANU key with matching chat_id and ANU role — cross-check PASS (§8).r}   )r   rm   r   r   r   rv   rg   )
r0   ra   rx   ry   rz   expected_chat_idr[   r<   owner_is_anur.   s
             r   verify_post_registration_ownerr   ]  s   ( G0(;L0L@6	

 *+=*@ AF F	
 $4 55+,<+? @(++FH	
 ((9 :: :	
 "dtG$M	
 &*--.#	 	r   z/home/jay/workspacei<  z4dispatch.normal_fallback_callback_helper.launcher.v1ANU_OWNED_READYSELF_KEY_FAIL_CLOSEDCALLBACK_PROMPT_TOO_LARGECANONICAL_ROOT_INVALIDOWNER_ENFORCEMENT_FAILEDr   FAIL_CLOSEDCOLLECTOR_ANU%RECOVERY_ONLY_NO_FINAL_REPORT_TRIGGER   10m<   >   ro   sha256r2   summaryr0   r1   report_pathresult_pathcallback_kindcanonical_rootrX   source_attributionnowc          	         ddl }||n|j                   j                         }||j                  t        dt	        |                   z   }|j                  d      S )u"  (now + delay_seconds) → cokacdir-compatible absolute timestamp.

    Returns ``"YYYY-MM-DD HH:MM:SS"`` (local time, naive — matches cokacdir
    server local timezone). ``now`` accepts a ``datetime`` for testability;
    defaults to ``datetime.now()`` (no tz conversion — cokacdir parses server
    local time).

    task-2661 Phase 2b: cokacdir live runtime rejects second-suffix `--at`
    values (e.g. ``"10s"``) — absolute timestamp is the only sub-minute form
    accepted. Fallback (``DEFAULT_AT_FALLBACK="10m"``) is untouched.
    r   N)seconds%Y-%m-%d %H:%M:%S)datetimer   	timedeltamaxintstrftime)delay_secondsr   _dtbasetargets        r   "build_absolute_at_for_normal_delayr     sP       #S\\5E5E5GDCMM#a]1C*DMEEF??.//r   c                   | rt        | t              sy| j                         }|syd|v r	d|v rd|v ry|j                         ry|d   j	                         }|dd }|r!|j                  ddd      j                         sy	 t        |      }|d	k(  rt        |      S |d
k(  rt        |dz        S |dk(  rt        |dz        S |dk(  rt        |dz        S y# t        $ r Y yw xY w)uK   cokacdir relative-time string → seconds. Absolute / unparseable → None.N -:.rR      smr   hi  diQ )	r   r   r   isdigitlowerreplacefloat
ValueErrorr   )ro   r   unitbodyns        r   parse_at_secondsr     s    ZC(

A
axC1H 	yy{R5;;=DSb6Dt||CQ/779$K s{1vs{1r6{s{1t8}s{1u9~  s   C 	C#"C#r   c                    | rt        | t              syddl}	 |j                  j                  | j	                         t
               y# t        $ r Y yw xY w)z6True iff ``at`` parses as cokacdir absolute timestamp.Fr   NT)r   r   r   strptimer   _ABSOLUTE_AT_PATTERNr   )ro   r   s     r   is_absolute_atr     sI    ZC(bhhj*>? s   .A 	AAc                   t        |       syddl}||n|j                  j                         }|j                  j                  | j	                         t
              }t        ||z
  j                               S )zHSeconds from ``now`` to absolute ``at``. None if ``at`` is not absolute.Nr   )r   r   r   r   r   r   r   total_seconds)ro   r   r   r   r   s        r   absolute_at_delay_secondsr     s]    " #S\\5E5E5GD\\""288:/CDF,,.//r   )reasonthreshold_secondsr   c               b   t        |      rt        ||      }nt        |      }dd|| dd}| t        k7  rd|d<   |S |d|d<   |S t        |      s|d	k  rd
|d<   d|d<   d|d|d<   |S ||k  rd|d<   |S |r t	        |      j                         rd|d<   |S d
|d<   d|d<   d| d| d|d<   |S )u   normal kind + delay>threshold + reason 없음 → warning 발급.

    절대시각 ``at`` 도 (target - now) 로 환산하여 lint 한다.
    fallback kind / threshold 이내 / reason 제공 시 warning=False.
    r   FOKrR   )warningcoder   r/   messageSKIP_NON_NORMALr   SKIP_UNPARSEDr   Tr   %UNSUPPORTED_SUB_MINUTE_RELATIVE_DELAYznormal callback delay z^ (< 60s) must use absolute timestamp (cokacdir live runtime rejects relative sub-minute forms)r   WITHIN_THRESHOLDREASON_PROVIDEDNORMAL_DELAY_REASON_REQUIREDzs > uL   s threshold · reason 누락 (★ task-2661 Phase 2b lint · enforce 아님))r   r   r   rj   r   r   )r/   ro   r   r   r   secsouts          r   lint_normal_callback_delayr     s    b(5#C ##'F
|%F
 "$)I=F$RF +H I 	I 
  (F
#f+##%'F
C	N0CK
 d+<*= >: 	; 	N Jr   c                >    t        | xs dj                  d            S )u&   callback prompt 의 UTF-8 byte 길이.rR   zutf-8)lenencode)rn   s    r   callback_prompt_utf8_bytesr   Q  s    "$$W-..r   c                   | xs dj                         D cg c]#  }|j                         s|j                         % }}|sy|D ]5  }d|vr y|j                  dd      d   j                         }|t        vs5 y yc c}w )u   prompt 가 envelope-only 인가 — 모든 비공백 line 이
    `key=value` 형태이고 key 가 ENVELOPE_ALLOWED_KEYS 에 속하면 True
    (자유 지시문 금지, 회장 §5.6 envelope-only).rR   F=r   r   T)
splitlinesr   splitENVELOPE_ALLOWED_KEYS)rn   lnlineskeys       r   is_envelope_onlyr   V  s     $*<R";";"=LBRXXZLEL b=hhsAq!'')++  Ms
   A?A?require_envelopec                  t        |       }t        | xs d      }|t        kD  }t        |       }g }d}d}|r$d}t        }|j                  d| dt         d       |r|sd}|dk(  rd}|j                  d	       |||||||d
S )u   callback prompt 검증: UTF-8 ≤3900 bytes + envelope-only.
    반환 dict: ok, utf8_bytes, chars, too_large, envelope_only, status, reasons.rR   r   TFzcallback prompt z	 bytes > u5    (CALLBACK_PROMPT_TOO_LARGE fail-closed, §5.5/§10).ENVELOPE_VIOLATIONu5   callback prompt 가 envelope-only 가 아님 (§5.6).)rB   
utf8_byteschars	too_largeenvelope_onlystatusr<   )r   r   CALLBACK_PROMPT_MAX_BYTESr    STATUS_CALLBACK_PROMPT_TOO_LARGErm   )	rn   r   utf8r   r   env_onlyr<   r   rB   s	            r   validate_callback_promptr   f  s     &f-D"E00I'HGF	B1tfI.G-H IC C	
 T>)FNOuW r   c                      e Zd ZU ded<   ded<   ded<   ded<   ded<   ded<   ded<   ded	<   d
ed<   ded<   ded<   dZded<    ee      Zded<   edd       Z	ddZ
y)LaunchDecisionr   r-   r.   r   r/   r0   r1   r2   r   r   canonical_root_correctedr5   r6   r7   contract_fieldsNzOptional[dict]requestr9   r;   r<   c                (    | j                   t        k(  S r>   )r.   LAUNCH_PASSr@   s    r   rB   zLaunchDecision.ok  s    ||{**r   c                x   | j                   | j                  | j                  | j                  | j                  | j
                  t        | j                        | j                  | j                  | j                  t        | j                        nd | j                  | j                  t        | j                        dS )Nr-   r.   r   r/   r0   r1   r2   r   r   r6   r   r   r<   )r-   r.   r   r/   r0   r1   r   r2   r   r   r6   rF   r   r   r<   r@   s    r   rG   zLaunchDecision.to_json  s    kk||kkII||4<<("11(,(E(E'+yy'<DO$#33||DLL)
 	
r   rH   rJ   )rK   rL   rM   rO   r   r   rF   r<   rP   rB   rG   rQ   r   r   r   r     sm    KLK
ILNL""
"G^"t4GY4+ +
r   r   c           
         t        |       t        | xs d      ||t        t        |      t        |xs d      t        |      t        d	S )u'   회장 §10 callback contract 9 fields.rR   )	r   callback_prompt_charscallback_cron_idcallback_registration_statuscallback_roleenvelope_only_compliancefallback_prompt_utf8_bytesfallback_safety_net_registered'fallback_safety_net_role_single_purpose)r   r   CALLBACK_ROLE_COLLECTOR_ANUr   FALLBACK_ROLE_SINGLE_PURPOSEcallback_promptr/   r4   r   r   fallback_promptfallback_registereds          r   _contract_fieldsr    sO    
 'A&Q!$_%:!;#(.4$($7&@AVTV&W*./B*C3O
 
r   c                  r    e Zd ZU dZded<   ded<   ded<   ded<   ded<   d	ed
<    ee      Zded<   ddZy)SessionPropagationVerdictu  task-2686 ★ classifier 4 enum 출력 데이터클래스.

    회장 verbatim 6번: envelope chair_facing_session_id / collector_session_id /
    delivery_session_id 3 field 정합성 + ANU owner 검증 mismatch 시
    AUTHORITATIVE_BUT_SESSION_DISCONTINUITY 강제 분류.
    r   r-   classificationr3   r^   collector_session_iddelivery_session_idr   observed_owner_is_anur9   r;   r<   c           	         | j                   | j                  | j                  | j                  | j                  t        | j                        t        | j                        dS )Nr-   r  r^   r  r  r  r<   )	r-   r  r^   r  r  r   r  rF   r<   r@   s    r   rG   z!SessionPropagationVerdict.to_json  sQ    kk"11'+'C'C$($=$=#'#;#;%)$*D*D%EDLL)
 	
r   NrJ   )	rK   rL   rM   rN   rO   r   rF   r<   rG   rQ   r   r   r  r    s@     K**''&&t4GY4	
r   r  c           	        g }t        | t              r | j                         r| j                         nd}t        |t              r |j                         r|j                         nd}t        |t              r |j                         r|j                         nd}	t        |t              rt        ||      nd}
|r0||k(  r+|j	                  d       t        t        t        |||	d|      S |
s/|j	                  d|d       t        t        t        |||	d|      S |rt        |      s+|j	                  d       t        t        t        |||	d|      S g }|r||k7  r|j	                  d	| d
|        |	r|	|k7  r|j	                  d|	 d
|        |rN|j	                  ddj                  |      z          |j	                  d       t        t        t        |||	d|      S |j	                  d       t        t        t        |||	d|      S )u  envelope 3 session field + owner 관측치를 4 enum 으로 분류.

    분류 우선순위 (회장 verbatim 6번 강제):
      1. observed_owner_key == executor_key → ``NON_AUTHORITATIVE_SELF_COLLECTOR``
      2. observed_owner_key ∉ anu_keys → ``NON_AUTHORITATIVE_SELF_COLLECTOR``
         (★ self-key 가 아니더라도 ANU 가 아니면 동일 분류 — task-2680 doctrine)
      3. chair_facing_session_id 누락 또는 invalid → ``SESSION_PROPAGATION_GAP``
      4. envelope 3 SID 중 하나라도 chair_facing 과 불일치 (collector/delivery
         가 명시되었으나 chair_facing 과 다른 UUID) → ``AUTHORITATIVE_BUT_
         SESSION_DISCONTINUITY``
      5. 그 외 ANU + 3 SID 일치 → ``AUTHORITATIVE_CALLBACK_COLLECTOR_PROCESSED``
    NFu   observed_owner_key == executor_key — self-key callback (ANCHOR-2 key authority ≠ session continuity, but self-key 우선 분류).r	  zobserved_owner_key=uH    ∉ anu_keys — NON_AUTHORITATIVE_SELF_COLLECTOR (task-2680 doctrine).u   chair_facing_session_id 누락/invalid — fresh collector session spawn 가능성 (SESSION_PROPAGATION_GAP, task-2686 ANCHOR-1).Tzcollector_session_id=z != chair_facing_session_id=zdelivery_session_id=zSsession id mismatch detected (ANU key authoritative but session routing diverged): z; u   → AUTHORITATIVE_BUT_SESSION_DISCONTINUITY (회장 verbatim 6번 강제 분류, ANCHOR-1 key authority ≠ session continuity).u   ANU owner + chair_facing_session_id 일치 (collector/delivery 가 있다면 동일) — AUTHORITATIVE_CALLBACK_COLLECTOR_PROCESSED.)r   r   r   r   rm   r  rg   SESSION_PROPAGATION_SELF_KEYr   r   join!SESSION_PROPAGATION_DISCONTINUITYSESSION_PROPAGATION_OK)r^   r  r  rx   ra   r[   r<   	chair_sidcollector_siddelivery_sidobserved_is_anu
mismatchess               r   classify_session_propagationr    sl   * G3=>UWZ3[`w`}`}`'--/  FJI4>?SUX4Y^r^x^x^z(..0  AEM2<=PRU2V[n[t[t[v&,,.  }ALBLM_adBej!3X>kpO0L@Q	
 ) 7$-!. ,"'
 	
 !"4!7 8E E	
 ) 7$-!. ,"'
 	
 /	:M	
 ) 2$-!. ,"&
 	
 J)3#M?2NykZ	
 	1"<.0LYKX	
 *,0IIj,AB	
 	M	
 ) <$-!. ,"&
 	
 NN	L %- )*(" r   )	r   r4   rU   rV   rW   r   r   r[   r^   c                4   g }d}|st         }d}|j                  d       nd|t         k7  r[t        || |t        t	        |      |xs dd      }t        t        t        t        | ||t        |      |dd|d|dt         d	g
      S t        ||      }|d   rLt        || |t        |d   |xs dd      }t        t        t        t        | ||t        |      ||d||d   
      S |	xs | d}	|
xs | d}
|xs | d}|| t        k(  r|
n|}t        | |||t        |      ||||	|
|||      }| t        k(  xr |j                  }|j                  rt        }t         }|j                  d       nUt        }||k(  rt"        }|j                  d       nt$        }|j                  d       |j'                  |j(                         t        || |||d   |xs d|      }t        t        ||| ||t        |      |||j*                  ||j-                         |      S )uo  단일 callback/fallback 런타임 launcher (회장 §3 launcher 단일화).

    fail-closed 순서: canonical root → prompt byte/envelope → owner enforce
    (build_anu_owned_callback_request 경유). owner==executor self-key 면
    SELF_KEY_FAIL_CLOSED (argv=None). ANU key 만 PASS.
    실 cron 발사/ subprocess 0 — argv(데이터)만 생성한다.
    FTu<   canonical_root 미지정 → /home/jay/workspace 로 교정.rR   r   Nzcanonical_root=z != u    → fail-closed (§5.9).)r-   r.   r   r/   r0   r1   r2   r   r   r6   r   r<   r   r   r   r<   z
::dispatchz::normalz
::fallback)r/   r0   ra   r1   r2   rn   ro   r4   rU   rV   rW   r[   r^   u7   owner=ANU key — launcher PASS, ANU-owned argv 생성.uK   owner_key == executor self key → SELF_KEY_FAIL_CLOSED (argv=None, §5.3).u3   owner enforcement FAIL → fail-closed (argv=None).r   )CANONICAL_ROOTrm   r  STATUS_CANONICAL_ROOT_INVALIDr   r   LAUNCHER_SCHEMALAUNCH_FAIL_CLOSEDr   r   r   rj   rt   rk   rB   STATUS_ANU_OWNED_READYr   STATUS_SELF_KEY_FAIL_CLOSEDSTATUS_OWNER_ENFORCEMENT_FAILEDrl   r<   r6   rG   )r/   r0   ra   r1   r2   rn   ro   r   r4   rU   rV   rW   r   r   r[   r^   r<   root_correctedcfpvreqr   r   r.   s                           r   launch_callbackr!  O  sv   4 G N'UV	>	)"w0*62+1ru	N
 ",>0tWW)Er&~&8^<N O0 0 12 	2 
"&;K	LB	+"w3_-+1ru	N
 ",>3$W)Nr2i=B 	B (AgYj+A7OgYh;O 9 Sy
=S/37K/K+1 	
 +7S\&R*:!9"; 7C  #99Dcff
vv'PQ$$0FNNhi4FNNPQs{{#	T76)?;Pb/
1B T9c'l%XXr3;;='	S Sr   ),rg   r
   rj   rk   rf   r,   rt   rv   r   r  r   r  r   r!  r   r   r   r  r  r   r  r   r  r   r   DEFAULT_AT_NORMAL_DELAY_SECONDSDEFAULT_AT_FALLBACK%NORMAL_DELAY_REASON_THRESHOLD_SECONDSr   r   r   r   r   ANU_CHAIR_FACING_SID_ENVr  r  r  r   SESSION_PROPAGATION_ENUMr   r&   r  r  mainc                4   dd l }dd l}dd l}|j                  d      }|j	                  dd      }|j                  d      }|j                  ddt        t              	       |j                  d
d       |j                  dd       |j                  dd       |j                  dd       |j                  dd       |j                  dd        |j                  dd        d}|j                  |dd        |j                  dd       |j                  dd d       |j                  ddd d       |j                  |       }|j                  }	|	)|j                  t        k(  rt        t              }	nt        }	t!        |j                  |	|j"                         }
|
j%                  d!      r/|j&                  j)                  d"|
j%                  d#d$       d%       t+        |j                  |j,                  |j.                  |j0                  |j2                  |j4                  |	|j6                  |j8                  |j:                   |j<                  &      }t?        |jA                  |jC                         d'(             |jD                  rdS d)S )*Nr   z(dispatch.normal_fallback_callback_helper)progcmdT)destrequiredlaunchz--kind)r,  choicesz	--task-id)r,  z--executor-keyz--owner-keyz	--chat-idz--promptre   )defaultz--canonical-rootz	--cron-idr4   )r+  r/  z--no-require-envelope
store_true)actionz--delay-reasonuP   normal callback delay>60s 시 lint warning 억제용 reason (★ enforce 아님))r/  helpz--chair-facing-sidr^   u@   ANU 본 세션 SID (cokacdir --session 옵션에 자동 첨부).)r+  r/  r2  )r   r   z[task-2661 lint warning] r   rR   
)r/   r0   ra   r1   r2   rn   ro   r   r4   r   r^   F)ensure_ascii   )#argparsejsonsysArgumentParseradd_subparsers
add_parseradd_argumentsortedrf   
parse_argsro   r/   rj   r   r"  r#  r   delay_reasonr#   stderrwriter!  r0   ra   r1   r2   rn   r   r4   no_require_enveloper^   printdumpsrG   rB   )r6   r6  _json_sysapsublp
_cron_flagaat_valuelintdecs               r   r'  r'    s9   //		 	 &P	 	QB




6C		!BOOHtVK5HOIOOK$O/OO$tO4OOMDO1OOK$O/OOJO. OOFDO)OO&O5&JOOJYO=OO+LOAOO$dk  m OO&O	   	dAttH66))9:YZH*H%affhq~~NDxx	'2(>'?rB	
 VVQYYQ^^++qyyh''222 ! 9 9;C 
%++ckkm%+
891Ar   __main__)r   r3   rI   r   r>   )r$   r3   r   r   rI   r3   )&r/   r   r0   r   ra   r   r1   r   r2   r   rn   r   ro   r   r4   r3   rU   r   rV   r3   rW   r3   rX   r   rY   r   rZ   r   r[   Sequence[str]r\   r   r]   r   r^   r3   rI   r,   )r0   r   ra   r   rx   r   ry   r   rz   r   r   r   r[   rP  rI   rv   )r   r   rI   r   )ro   r   rI   zOptional[int])ro   r   rI   r   )
r/   r   ro   r   r   r3   r   r   rI   r7   )rn   r   rI   r   )rn   r   rI   r   )rn   r   r   r   rI   r7   )r   r   r/   r   r   r   r   r   r   r   r   r   rI   r7   )r^   r3   r  r3   r  r3   rx   r   ra   r   r[   rP  rI   r  )"r/   r   r0   r   ra   r   r1   r   r2   r   rn   r   ro   r   r   r3   r4   r3   rU   r3   rV   r3   rW   r3   r   r3   r   r   r[   rP  r^   r3   rI   r   )r6   r5   rI   r   )NrN   
__future__r   r!   redataclassesr   r   typingr   r   r    dispatch.callback_owner_enforcerr	   r
   r   r   r   r   r%  compiler   r  r  r  r   	frozensetr&  r   r&   !anu_v3.dispatch_callback_contractr'   ri   r(   rh   rg   rj   rk   rf   r,   tuplert   rv   r   r  r   r  r  r  r   r  r  r   r  r   r   r"  r#  r$  r   r   r   r   r   r   r   r   r   r   r   r  r  r  r!  __all__r'  rK   
SystemExitrQ   r   r   <module>r\     sP  6 # 	 	 ( + +  2  !bjj'  F $M !A 3 $% 	&  8 #A -AA A 	A:
 > # -/EFG %
 %
 %
b ".2/3(,,#$45 $-1'a
a a 	a
 a a a 	a a a ,a  -a a "&a a  !a" #a$ %a& +'a( )aH 
 
 
F $$45:: : 	:
 : : : :  :D '  H + 4 #>   8 "< " - F  #%  (* % " #   90 	00 		06D + 	 /3 0" !B4
44 	4
 4 
4n/
  GK : "
 "
 "
J$(;>*.37" 
 
 
F $$45u*u (u '	u
 u u u uB %)!&*.2/3%)!#$45-1#jS
jS jS 	jS
 jS jS jS 	jS "jS jS $jS ,jS  -jS #jS jS  !jS" +#jS$ %jSZ/d3l z
TV
 r   