
    j                    
   U d Z ddl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mZm	Z	 ddl
m
Z
mZ ddlmZ ddlmZ ddlmZmZmZ dd	lmZmZmZ d
ZdZdZdZdZdZdZded<   dZ ded<    e!ee z         Z"ded<    ejF                  d      Z$d=dZ% G d de&e      Z' G d de&e      Z( G d de)      Z* G d d e)      Z+e G d! d"             Z,e G d# d$             Z-e G d% d&             Z.e G d' d(             Z/d>d)Z0dd*	 	 	 	 	 	 	 	 	 	 	 d?d+Z1e G d, d-             Z2	 	 	 	 	 	 d@d.Z3dAd/Z4dBd0Z5dBd1Z6dBd2Z7dCd3Z8ded4	 	 	 	 	 	 	 dDd5Z9	 	 	 	 dEd6Z:dFd7Z;ddd8	 	 	 	 	 	 	 	 	 	 	 dGd9Z<e3dddd:	 	 	 	 	 	 	 	 	 	 	 	 	 dHd;Z=g d<Z>y)Iu	  utils/anu_delegation_completion_callback.py — task-2595 Phase 2 구현.

ANU_DELEGATION_COMPLETION_CALLBACK 의 실행 코드 (fixture/mock 검증 한정).

Phase 1 LOCKED spec: memory/tasks/task-2595.md
(locked content sha256 = c151030d719762da35eb5cafc34a9f4c74df4ba4c5085e077bb109120ae050d5,
post-lock metadata annotation sha256 = 4ee97a3bfb2884535c172b8a69b95ec6199353e5bf89e67115732bc61d86dd1d
— LOCK 권위는 locked content hash 에 귀속, task-2595.spec-lock.json 참조).

본 모듈은 spec §3~§10 정의를 코드로 구현한다:

* §3  anu_delegation_result_v1 schema + validation
* §4  completion_callback_contract_v1 schema + validation
* §5  callback_ack_dedupe_v1 schema + validation
* §6  dual callback (normal completion + fallback stale) 모델
* §7  dedupe / ack single-winner (atomic O_CREAT|O_EXCL)
* §8  ANU-Codex post-result review hook (advisory, bounded loop 패턴 재사용)
* §9  상태 분류 7종 + 분류 우선순위 (inference drift 0 — evidence 필드 기반)
* §10 callback 실행 시 검증 항목

경계 (회장 Phase 2 §1~§3 verbatim):

* **fixture/mock 기반 구현 검증까지로 제한**. 실제 callback 운영 활성화 /
  실제 dev bot callback 등록 / 실제 fallback stale callback 등록 금지.
* watcher / polling loop / daemon / systemd 상시 감시 0 — collector 는
  one-shot 함수 호출이며 내부 루프·sleep·스케줄러 없음.
* 자동 closeout 권한 미부여 (회장 §5). collector 는 수집·검증·분류 +
  closeout *candidate* 만 생성. 실제 closeout / finish-task.sh / manual .done
  호출 없음.
* post-result review hook 의 기본 invoker 는 실제 codex 를 호출하지 않으며
  ``NoRealCodexReviewError`` 를 raise 한다. 검증은 mock invoker 로만.

이 파일은 신규 파일이며 forbidden_write_targets (dispatch.py /
scripts/finish-task.sh / task-timer.py / post-tool-use.sh /
utils/anu_codex_bounded_loop.py / replacement_pr_dry_run_* /
test_anu_codex_bounded_loop_2592.py / test_task_2591_dry_run_activation_harness.py /
task-2591.md / task-2592.md / task-2595.md) 를 일절 수정하지 않는다.
Critical 7 분류는 utils.anu_codex_bounded_loop 를 read-only import 로 재사용한다
(spec §9 priority 4 — feedback_critical_escalation_only_260508 7종 동일).
    )annotationsN)	dataclassfield)datetimetimezone)Enum)Path)CallableOptionalUnion)Signalsany_critical_7critical_7_hitsanu_delegation_result_v1completion_callback_contract_v1callback_ack_dedupe_v1
      l   L5: )normal_callback_registerednormal_callback_cron_idfallback_firedttl_expiry_ts_utcttl_exceededbot_liveness_signalbot_liveness_observedtuple[str, ...]$STALE_DISTINCTION_EVIDENCE_SPEC_KEYS)evidence_collection_failed+STALE_DISTINCTION_EVIDENCE_OPERATIONAL_KEYSzfrozenset[str]'STALE_DISTINCTION_EVIDENCE_ALLOWED_KEYSz^[\w./+\-]+\.json$c                f    | yt        | t              syt        t        j	                  |             S )u   spec §3 — ``codex_post_result_review_ref`` 계약 검사.

    True 조건: ``None`` (null) **또는** ``.json`` 으로 끝나는 marker path
    문자열(공백/괄호/'=' 등 status 문자열 토큰 불포함). 그 외 모두 False.
    TF)
isinstancestrbool_MARKER_PATH_REmatch)values    ?/home/jay/workspace/utils/anu_delegation_completion_callback.pyis_marker_path_or_nullr)   o   s/     }eS!%%e,--    c                  ,    e Zd ZdZdZdZdZdZdZdZ	dZ
y	)
Classificationu?   spec §9 — delegation completion callback 결과 분류 7종.PASSHOLD_FOR_CHAIR	BOT_STALERESULT_MISSINGCALLBACK_MISSING
CRITICAL_7DUPLICATE_CALLBACK_IGNOREDN)__name__
__module____qualname____doc__r-   r.   r/   r0   r1   r2   r3    r*   r(   r,   r,      s*    ID%NI%N)J!=r*   r,   c                      e Zd ZdZdZdZy)CallbackTypeu   spec §3/§6 — dual callback.normalfallback_staleN)r4   r5   r6   r7   NORMALFALLBACK_STALEr8   r*   r(   r:   r:      s    )F%Nr*   r:   c                      e Zd ZdZy)NoRealCodexReviewErroru  기본 post-result review invoker 호출 시 raise.

    Phase 2 는 fixture/mock 검증 task이므로 실제 codex:codex-rescue 를
    호출하지 않는다 (회장 Phase 2 §1 verbatim). 실 검토가 필요하면 명시적
    mock/실 invoker 를 주입한다.
    Nr4   r5   r6   r7   r8   r*   r(   r@   r@          r*   r@   c                      e Zd ZdZy)!RealCallbackRegistrationForbiddenu"  실제 callback cron 등록 시도 시 raise.

    회장 Phase 2 §3 verbatim — 실제 dev bot callback / fallback stale
    callback 등록 금지. 본 모듈은 cron 을 등록하지 않으며, 등록 시도 경로는
    명시적으로 차단한다 (fixture/mock 검증 한정).
    NrA   r8   r*   r(   rD   rD      rB   r*   rD   c                      e Zd ZU dZdZded<   dZded<   dZded<   dZded	<   dZ	ded
<   dZ
ded<   dZded<   dZded<   y)StaleDistinctionEvidenceu
  spec §3 ``stale_distinction_evidence`` 블록.

    spec §9.2 결정 규칙은 **이 필드들만** 근거로 한다 (inference drift 0):

    * normal_callback_registered == false AND bot_liveness_observed == false
      → BOT_STALE
    * normal_callback_registered == false AND bot_liveness_observed == true
      → CALLBACK_MISSING
    * 두 신호 모두 판정 불가 (evidence_collection_failed) → HOLD_FOR_CHAIR

    허용 key 집합은 모듈 상수 ``STALE_DISTINCTION_EVIDENCE_ALLOWED_KEYS``
    (spec §3 7 key + 운영 필요 ``evidence_collection_failed``)로 **명시
    정의**되며, ``validate_delegation_result()`` 가 (a) spec §3 7 nested
    key 전수 존재 (b) 허용 집합 외 key 거부 를 검증한다 (task-2595_2+1
    항목 2/3).
    Fr$   r   NOptional[str]r   r   r   r   noner#   r   r   r   )r4   r5   r6   r7   r   __annotations__r   r   r   r   r   r   r   r8   r*   r(   rF   rF      s_    " (-,-1]1 ND '+}+L$%%"'4'',,r*   rF   c                      e Zd ZU dZdZded<   dZded<   dZded<   dZded<   dZ	ded<   dZ
ded	<   dZded
<   dZded<   dZded<   dZded<   ddZy)ForbiddenActionPostchecku/   spec §3 ``forbidden_action_postcheck`` 블록.r   intcommitpushpr_openmergegithub_writereal_write_modeauto_restoreFr$   finish_task_shmanual_doneforbidden_write_targets_changedc                N   | j                   dkD  xs | j                  dkD  xs | j                  dkD  xss | j                  dkD  xsb | j                  dkD  xsQ | j
                  dkD  xs@ | j                  dkD  xs/ | j                  du xs | j                  du xs | j                  dkD  S )Nr   T)
rM   rN   rO   rP   rQ   rR   rS   rT   rU   rV   )selfs    r(   violatedz!ForbiddenActionPostcheck.violated   s    KK!O 	8yy1}	8||a	8 zzA~	8   1$		8
 ##a'	8   1$	8 ""d*	8 4'	8 33a7	
r*   N)returnr$   )r4   r5   r6   r7   rM   rI   rN   rO   rP   rQ   rR   rS   rT   rU   rV   rY   r8   r*   r(   rK   rK      sl    9FCOD#MGSE3NL#OSL# ND K+,#S,
r*   rK   c                  2   e Zd ZU dZded<   ded<   ded<   ded<   ded<   d	Zded
<   dZded<   dZded<    ee	      Z
ded<    ee      Zded<    ee      Zded<    ee      Zded<   dZded<    ee      Zded<    ee      Zded<   d Zded!<   y")#CallbackInputu-  delegation completion callback 1회 입력 (one-shot, 루프 없음).

    모든 필드는 fixture/mock 으로 주입된다. 본 모듈은 실제 cron-history /
    marker filesystem 을 watcher/polling 으로 감시하지 않는다 — 호출자가
    수집한 스냅샷을 1회 전달한다.
    r#   task_idexecutordispatch_cron_idr:   callback_typecallback_cron_idokcron_status	completedtask_statusg        floatcron_duration_mindefault_factoryrF   stale_distinction_evidence	list[str]output_markerszdict[str, bool]required_closeout_markersrK   forbidden_action_postcheckTr$   
dev_sunsetzdict[str, str]preservation_anchorsr   signalsFchair_gatedN)r4   r5   r6   r7   rI   rc   re   rg   r   rF   rj   listrl   dictrm   rK   rn   ro   rp   r   rq   rr   r8   r*   r(   r\   r\      s     LMK"K""u";@0< 8  !&d ;NI;16t1LL;@0< 8  J+0+F.FW5GW5Kr*   r\   c                      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<    ee      Zded<   dZ	ded<    ee
      Zded<   y)CollectorResultu   collector 1회 실행 결과.r,   classificationrt   delegation_result
ack_deduper$   ack_acquiredcloseout_candidatechair_report_requiredrh   rk   critical_7_hithold_reasonsNrG   codex_post_result_review_refclassification_evidence)r4   r5   r6   r7   rI   r   rs   r}   r~   r   rt   r   r8   r*   r(   rv   rv   	  sb    '"" %d ;NI;#D9L)926 -6$)$$?T?r*   rv   c                 f    t        j                  t        j                        j	                  d      S )Nz%Y-%m-%dT%H:%M:%SZ)r   nowr   utcstrftimer8   r*   r(   _now_utcr     s!    <<%../CDDr*   )duplicate_callback_seenc                  t        |       }|j                  j                  dd       t        t	               |t        |      |j                  |dt        |xs g       dd	}	 t        j                  t        |      t        j                  t        j                  z  t        j                  z  d      }t        j0                  |dd      5 }t        j2                  ||dd       |j5                          t        j6                  |j9                                ddd       d|fS # t        $ r i }	 t        j                  |j!                  d            }n# t"        t$        f$ r i }Y nw xY w|j'                  d	t               t        |j)                  d
g             }	||	vr|	j+                  |       |	|d
<   d|d<   d|fcY S t"        $ r,}
|
j,                  t,        j.                  k(  r	d|fcY d}
~
S  d}
~
ww xY w# 1 sw Y   d|fS xY w)u  spec §7 — ack marker atomic single-winner.

    ``os.open(O_CREAT|O_EXCL|O_WRONLY)`` 로 ack marker 생성 시도.

    * 성공 (부재) → ack 기록 후 ``(True, ack_dict)``. result collection 진행.
    * 실패 (이미 존재 → ``FileExistsError``) → ``(False, ack_dict)``.
      후발 callback 은 DUPLICATE_CALLBACK_IGNORED 후 즉시 종료 (idempotent).

    normal/fallback 경합 시에도 atomic create 가 single-winner 를 보장한다.
    Tparentsexist_okzO_CREAT|O_EXCLu5   DUPLICATE_CALLBACK_IGNORED (idempotent 즉시 종료))	schemats_utcr]   ack_marker_pathwinning_callback_typewinning_callback_cron_idatomic_create_methodr   duplicate_resolutioni  utf-8encodingr   r   r   FNw   indentensure_ascii)r	   parentmkdirSCHEMA_CALLBACK_ACK_DEDUPEr   r#   r'   rs   osopenO_CREATO_EXCLO_WRONLYFileExistsErrorjsonloads	read_textOSError
ValueError
setdefaultgetappenderrnoEEXISTfdopendumpflushfsyncfileno)ack_pathr]   r   r   r   pathackfdexistingseenexcfs               r(   try_acquire_ackr      s   $ >DKKdT2,*t9!6!<!<$< 0#'(?(E2#FCCWWSY

RYY 6 DeL* 
2sW	- 		#q7		
 #;1  !	zz$..'."BCH$ 	H	H&@AHLL!:B?@#4/KK01.2*+C 	'( x   99$3< #;s]   "AD# 
AG9#G6/%EG6E)&G6(E))AG6G6
 G1*G60G11G69Hc                  H    e Zd ZU dZded<   ded<   ded<   ded<   dZded	<   y
)PostResultReviewu7   spec §8 — post-result review 결과 (advisory only).r#   verdictr$   advisoryexecution_performedauto_closeout_authority_granted noteN)r4   r5   r6   r7   rI   r   r8   r*   r(   r   r   a  s$    ALN%))D#Nr*   r   c                    t        d      )u   기본 invoker — 실제 codex:codex-rescue 를 호출하지 않는다.

    Phase 2 = fixture/mock 검증 task (회장 §1). 항상
    ``NoRealCodexReviewError`` 를 raise 한다. 검증은 mock invoker 로만.
    u   Phase 2 = fixture/mock 검증 task. 실제 codex:codex-rescue post-result review 호출 금지 (회장 Phase 2 §1 verbatim). mock invoker 를 주입하라.)r@   )rx   rw   s     r(    no_real_codex_post_result_reviewr   l  s     !	] r*   c                <    |D cg c]  }|| vsd|  c}S c c}w )Nzmissing:r8   )dkeysks      r(   _missingr   }  s"    $(7qAQJhqcN777s   	c                >   g }| j                  d      t        k7  r|j                  dt                |t        | d      z  }| j                  d      }|J|t        j
                  j                  t        j                  j                  fvr|j                  d|        | j                  d      }|4|t        D ch c]  }|j                   c}vr|j                  d|        d| v r0| j                  d      }t        |      s|j                  d	|       d
| v rp| j                  d
      }t        |t              s|j                  d       |S |t        D cg c]  }||vrd|  c}z  }||D cg c]  }|t        vrd|  c}z  }|S c c}w c c}w c c}w )uM   spec §3 anu_delegation_result_v1 구조 검증. errors 빈 리스트 = PASS.r   schema!=)r   r]   r^   r_   r`   ra   rc   re   rg   rj   rl   rm   rn   ro   rp   r   rw   evidence_pathsr   r`   zcallback_type invalid:rw   zclassification invalid:r   z5codex_post_result_review_ref:not_marker_path_or_null:rj   z%stale_distinction_evidence:not_a_dictz#stale_distinction_evidence.missing:z+stale_distinction_evidence.unspecified_key:)r   SCHEMA_DELEGATION_RESULTr   r   r:   r=   r'   r>   r,   r)   r"   rt   r   r    )r   errorsctclscrefsder   s           r(   validate_delegation_resultr     s   FuuX22!9 :;<
h		
 F0 
	B	~"!!##))%  	.rd34
%% 
!C
3&G1qww&GG/u56 &*ee23%c*MMG' $q(ee01#t$MMAB M =C< 6aS9 F CC >aSA F
 M= 'H&s   ;FF5Fc                T   g }| j                  d      t        k7  r|j                  dt                |t        | d      z  }| j                  d      t        k7  r*|j                  dt         d| j                  d              | j                  d      dur|j                  d	       |S )
u   spec §4 completion_callback_contract_v1 구조 검증.

    회장 §3 verbatim — dispatch.py 미수정. ``dispatch_py_untouched`` 가
    True 가 아니면 contract 위반.
    r   r   )callback_chat_idcallback_key_ref"callback_register_command_templateregister_timingregister_failure_fallbackdispatch_py_untouchedr   zcallback_chat_id!=:r   Tu/   dispatch_py_untouched must be true (회장 §3))r   #SCHEMA_COMPLETION_CALLBACK_CONTRACTr   r   ANU_CALLBACK_CHAT_IDr   r   s     r(   %validate_completion_callback_contractr     s     FuuX==!D EFG
h		

 
F 	uu $88 !5 6a>P8Q7RS	
 	uu$%T1GHMr*   c                    g }| j                  d      t        k7  r|j                  dt                |t        | d      z  }|S )u.   spec §5 callback_ack_dedupe_v1 구조 검증.r   r   )r   r]   r   r   r   r   r   r   )r   r   r   r   r   s     r(   validate_callback_ack_deduper     sM    FuuX44!; <=>
h			
 F Mr*   c                6    t         t        | dt         dddddS )u   spec §4 — dispatch prompt 에 봇이 등록할 normal completion callback
    contract 템플릿 생성. **실제 cron 을 등록하지 않는다** (schema 산출만).
    u   cokacdir --cron "<task_id> 완료. ANU result collector 실행: cron-history/marker/anchor 수집·검증·분류" --at "<즉시>" --chat z --key <anu-key>u-   dev bot 정상 종료 직전 마지막 행동uP   봇이 본 cron 등록 못하고 죽으면 §6 fallback stale callback 안전망T)r   r   r   r   r   r   r   )r   r   )r   s    r(   "build_completion_callback_contractr     s6    
 60,*++;= K^!% r*   )task_ttl_hoursttl_margin_minc               2    ||nt         }| |dz  z   |dz  z   S )u  spec §14 / 회장 §6 verbatim — fallback stale callback 발화 시각 계산.

    기본 = dispatch_ts + bot_max_ttl + 10m.
    task별 TTL 명시 시 = dispatch_ts + task_ttl + 10m.
    **계산만 한다 — 실제 cron 을 등록하지 않는다** (회장 Phase 2 §3).
    g      @g      N@)DEFAULT_BOT_MAX_TTL_HOURS)dispatch_ts_epochr   r   	ttl_hourss       r(   compute_fallback_stale_at_epochr     s0     )4:S  y611NT4IIIr*   c                   d| j                   | j                  | j                  | j                  d}| j                  rd|d<   t        j
                  |fS | j                   du r%| j                  du rd|d<   t        j                  |fS | j                   du r%| j                  du rd|d<   t        j                  |fS d	|d<   t        j
                  |fS )
uo   spec §9.2 결정 규칙 — 단일 분기 (추론 0, 필드 기반).

    반환: (분류, evidence dict)
    u
   spec_§9.2)ruler   r   r   r   u(   evidence_undeterminable→HOLD_FOR_CHAIRbranchFu&   no_normal_cb + no_liveness→BOT_STALETu*   no_normal_cb + liveness→CALLBACK_MISSINGu(   normal_cb_registered→not_fallback_only)r   r   r   r   r,   r.   r/   r1   )r   evs     r(   _classify_fallback_staler   "  s     &)&D&D"66!$!:!:&)&D&D
B %%A8--r22
%%.33L3LPU3U?8(("--
%%.33L3LPT3TC8//44=BxL))2..r*   c                   dg i}|d   j                  d       |sd|d<   t        j                  g g |fS | j                  }|d   j                  d       | j                  t
        j                  k(  xr |j                  du xr |j                  du }|rCt        |      \  }}d|j                   |d<   ||d	<   |t        j                  k(  rd
gng }||g |fS |d   j                  d       | j                  j                         D 	cg c]  \  }}	|	dur| }
}}	|
r/d|d<   |
|d<   t        j                  |
D cg c]  }d| 	 c}g |fS |d   j                  d       t        | j                         }t#        | j                         rd|d<   ||d<   t        j$                  g ||fS |d   j                  d       | j&                  }| j(                  j                         D cg c]  \  }}|dk7  s| }}}g }|j+                         r|j                  d       |r#|j                  ddj-                  |      z          | j.                  r|j                  d       | j0                  dur|j                  d       |rd|d<   ||d<   t        j                  |g |fS d|d<   t        j2                  g g |fS c c}	}w c c}w c c}}w )u  spec §9 분류 우선순위 적용.

    반환: (classification, hold_reasons, critical_7_hit, classification_evidence)

    우선순위 (spec §9):
      1. ack 이미 존재(중복) → DUPLICATE_CALLBACK_IGNORED
      2. fallback-only fire + TTL 초과 → §9.2 BOT_STALE/CALLBACK_MISSING/HOLD
      3. callback fire 했으나 필수 marker 부재 → RESULT_MISSING
      4. Critical 7 hit → CRITICAL_7
      5. forbidden action 위반 또는 chair-gated → HOLD_FOR_CHAIR
      6. 전부 미해당 → PASS
    priority_checkedz	1:ack_dupz1:DUPLICATE_CALLBACK_IGNOREDmatchedz2:fallback_stale_distinctionFTz2:stale_distinction&fallback_stale_evidence_undeterminablez3:result_missingz3:RESULT_MISSINGmissing_required_markerszmissing_required_marker:z4:critical_7z4:CRITICAL_7r}   z5:forbidden_or_chair_gatedr&   #forbidden_action_postcheck_violatedzpreservation_anchor_mismatch:,rr   dev_not_sunsetz5:HOLD_FOR_CHAIRr~   z6:PASS)r   r,   r3   rj   r`   r:   r>   r   r   r   r'   r.   rm   itemsr0   r   rq   r   r2   rn   rp   rY   joinrr   ro   r-   )inprz   evidencer   fallback_onlyr   sub_evreasonsnamepresentmissing_markersmc7facastatusanchor_mismatchr~   s                     r(   classifyr
  >  s&    )"-H  ''4<992r8LL

(
(C  ''(FG\888 	%**e3	%$ 
 .s3V "399+.(.$% n333 66 	
 Wb(++  ''(:; !::@@BD'$ 	O 
 0/>+,))5DE's+E	
 	
  ''7		%Bckk",%'!"))2r8<<  ''(DE

(
(C3399;av?PO  !L
||~AB+chh.GG	
 M*
~~T!,-0#/ --|RJJ #HYR22_ F s   J69J<$K2Kr   r   c               l   i dt         dt               d| j                  d| j                  d| j                  d| j
                  j                  d| j                  d| j                  d	| j                  d
| j                  dt        j                  | j                        dt        | j                        dt!        | j"                        dt        j                  | j$                        d| j&                  dt!        | j(                        d||j                  t        |xs g       |dS )u5   spec §3 anu_delegation_result_v1 marker dict 생성.r   r   r]   r^   r_   r`   ra   rc   re   rg   rj   rl   rm   rn   ro   rp   r   )rw   r   r   )r   r   r]   r^   r_   r`   r'   ra   rc   re   rg   dataclassesasdictrj   rs   rl   rt   rm   rn   ro   rp   )r   rw   r   r   r   s        r(   build_delegation_resultr    ss   *(* 	3;; 	CLL	
 	C00 	**00 	C00 	s 	s 	S22 	%k&8&8**'
 	$s112 	$T#*G*G%H  	%k&8&8**'
!& 	cnn'( 	S%=%= >)* 	'(D+, )..~34*1 r*   )post_result_review_fnr   r   post_result_review_marker_pathc               X   t        || j                  | j                  | j                  |      \  }}t	        | |      \  }}	}
}|s>t        | ||j                  dt        |            d|      }t        |||dddg g d|
      S d}d}t        | ||j                  dt        |            |      }d}	  |||      }|j                  durt        |	      dgz   }	t        j                  }|j                  durt        |	      dgz   }	t        j                  }|r|t!        |      }n%t!        |      j"                  | j                   dz  }|j"                  j%                  dd       dt'               | j                  |j(                  t+        |j,                        dt/        j0                  |      d}|j3                  t5        j6                  |dd      d       t        |      }nd}t        | ||j                  dt        |            ||      }|t        j8                  k(  }|t        j:                  t        j<                  t        j                  t        j>                  t        j@                  fv }t        |||d|||
|	||
      S # t        $ r d}t        d	dddd
      }Y w xY w)u  spec §2 5~11단계 / §7 / §8 / §9 / §10 — one-shot 결과 회수.

    호출 1회 = callback 1회. 내부에 루프 / sleep / scheduler / watcher 없음
    (회장 §3 verbatim — long-running watcher / polling loop / daemon 금지).

    절차:
      1. (§7) ack atomic single-winner 시도. loser → 즉시 DUPLICATE 종료.
      2. (§9) evidence 필드 기반 분류 (inference drift 0).
      3. (§8) post-result review hook 실행 (advisory, 기본 invoker 는 실제
         codex 호출 금지 — mock 주입 필요). 자동 closeout 권한 미부여.
      4. (§3) anu_delegation_result_v1 marker dict 생성.
      5. (§10) PASS → closeout *candidate* only (자동 closeout 권한 X).
         CRITICAL_7 / RESULT_MISSING / HOLD → 회장 보고 flag.
    )r]   r   r   r   r   Nr  F)
rw   rx   ry   rz   r{   r|   r}   r~   r   r   )r   TSKIPPED_NO_REAL_CODEXuq   기본 invoker — 실제 codex 호출 금지 (회장 Phase 2 §1). mock 주입 시에만 advisory 판정 산출.)r   r   r   r   r   z9BOUNDARY_VIOLATION:post_result_review_execution_performedz2BOUNDARY_VIOLATION:auto_closeout_authority_grantedz.post-result-review.jsonr   anu_post_result_review_v1)r   r   r]   rw   r   r   reviewr   r   r   r   )!r   r]   r`   ra   r
  r  r   r#   rv   r@   r   r   rs   r,   r.   r   r	   r   r   r   r'   r$   r   r  r  
write_textr   dumpsr-   r2   r0   r/   r1   )r   r   r  r   r   r  acquiredr   rw   r~   c7_hitcls_evrx   
review_refr  interimreview_performedreview_marker_pathreview_markerr{   r|   s                        r(   !run_completion_callback_collectorr     s   4 $!//!$!5!5 7MHc 4<C3J0NL&&3GG%s8}5)-)
 )/$"')-$*
 	
 !%J)-F%!3x=1%	G 
&w? !!.L)G-
 
 (66--U:L)@-
 
 (66 )5!%&D!E X%%[[M!9:;  	!!''t'D1j{{,22V__-/4!((0
 	%%JJ}QUC 	& 	
 +,

 0!3x=1%/% (>+>+>>*!!%%%%  ''/  %+-3!%/ & S " 
 !!+ %,1<
	
s   2	J
 
J)(J))r,   r:   r@   rD   rF   rK   r\   rv   r   r   r   r   DEFAULT_TTL_MARGIN_MINr   r   r   r   r    r)   r   r   r   r   r   r   r  r   r
  r   )r'   objectrZ   r$   )rZ   r#   )r   Union[str, Path]r]   r#   r   r:   r   r#   r   Optional[list[str]]rZ   ztuple[bool, dict])rx   rt   rw   r,   rZ   r   )r   rt   r   r   rZ   rk   )r   rt   rZ   rk   )r   r#   rZ   rt   )r   rf   r   zOptional[float]r   rL   rZ   rf   )r   rF   rZ   ztuple[Classification, dict])r   r\   rz   r$   rZ   z1tuple[Classification, list[str], list[str], dict])r   r\   rw   r,   r   r#   r   rG   r   r$  rZ   rt   )r   r\   r   r#  r  z2Callable[[dict, Classification], PostResultReview]r   r$  r   r$  r  zOptional[Union[str, Path]]rZ   rv   )?r7   
__future__r   r  r   r   r   rer   r   r   r   enumr   pathlibr	   typingr
   r   r   utils.anu_codex_bounded_loopr   r   r   r   r   r   r!  r   r   r   rI   r   	frozensetr    compiler%   r)   r#   r,   r:   RuntimeErrorr@   rD   rF   rK   r\   rv   r   r   r   r   r   r   r   r   r   r   r   r
  r  r   __all__r8   r*   r(   <module>r/     s  'R #    	 	 ( '   , ,  6 &G #5     " 9 $o @ +_  ;D(12; '  "**23
. 	>S$ 	>&3 &\   - - -< 
 
 
@   B @ @ @$E 48;; ; (	;
 "; 1; ;B   -;"8BJ:*0 '+0	JJ $J 	J
 J*/	!/ /8\3N 37*."	""" "
 #0" (" 
"\ 	)37*.AE[	[[	[ 1[ ([ %?[ [|r*   