
    4j;                       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mZ ddl	m
Z
 ddlmZ  ee      j                         j                  j                  Zedz  Zedz  Zd	Zd
ZdZdZdZdZeeeefZh dZddZdddZdddZddZ	 d	 	 	 	 	 ddZddd	 	 	 	 	 	 	 d dZ 	 d!	 	 	 	 	 d"dZ!d#dZ"dd$dZ#e$dk(  r ejJ                   e#              yy)%uT  scripts/validate_fallback_acceptance_2553plus58.py

task-2553+58 (TRACK C) — FALLBACK_ACCEPTANCE_CRITERION_FOR_NEXT_PILOT.

Spec: memory/tasks/task-2553+58.md
(sha256 976d904dbe05971fad694ca0409d0cdbcd6cdc31434ac156371770ed9ea40f71).

회장 §2 verbatim 기준:

  normal callback durable-success 이후 bound fallback 은
    (a) cancel-on-success 로 제거되거나
    (b) registry 에 NON_BLOCKING 으로 명시 마크되어야 한다.
  아무 마크 없이 fallback 이 발화한 뒤 DUPLICATE_CALLBACK_IGNORED 로만
  처리되는 것은 안전성 OK 지만 운영 품질 PASS 로 보지 않는다.

이 모듈은 위 기준의 **실 entrypoint** 다 (문서-only 금지 — §3/§8).

  * ``evaluate_fallback_acceptance``      — fallback disposition observation
                                            1건을 기준 a/b/anti-pattern 으로
                                            판정 (real decision logic).
  * ``validate_non_blocking_mark``        — registry NON_BLOCKING 마크를
                                            schemas/non_blocking_fallback_schema.json
                                            (draft-07) 으로 검증.
  * ``check_criteria_schema_coherence``   — criteria JSON ↔ schema 정합
                                            (criteria/schema 정합, §3).
  * ``main``                              — 실 산출물(criteria·schema)에 대해
                                            정합 검사 + self-sample 판정을
                                            stdout JSON 으로 출력. **파일 write 0**
                                            (read-only — §4 expected_files
                                            allowlist 외 write 0).

순수/오프라인: network·git mutation·cron·dispatch·cokacdir·subprocess·
파일 write 0. fallback/dead-man/fixed-time 진행 트리거 0.
    )annotationsN)Path)Any)Draft7Validatorz/memory/events/fallback_acceptance_criteria.json)schemas/non_blocking_fallback_schema.jsonc119085addb0f8b7l   L5: OPERATIONAL_PASSOPERATIONAL_QUALITY_FAILNOT_APPLICABLESAFETY_FAIL>   	NO-ACTION	NO_ACTIONDUPLICATE_CALLBACK_IGNOREDc                ^    t        j                  t        |       j                  d            S )zCRead-only JSON load. No write side effects anywhere in this module.zutf-8)encoding)jsonloadsr   	read_textpaths    F/home/jay/workspace/scripts/validate_fallback_acceptance_2553plus58.py	load_jsonr   G   s#    ::d4j**G*<==    c                (    t        | xs t              S N)r   CRITERIA_PATHr   s    r   load_criteriar   L   s    T*]++r   c                (    t        | xs t              S r   )r   SCHEMA_PATHr   s    r   load_schemar    P   s    T([))r   c                v    t        j                  t        |       j                               j	                         S r   )hashlibsha256r   
read_bytes	hexdigestr   s    r   	sha256_ofr&   T   s'    >>$t*//12<<>>r   c                ,   |
t               }t        | t              sddgfS t        |      }t	        |j                  |       d       }|D cg c]7  }dj                  d |j                  D              xs d d|j                   9 }}| |fS c c}w )	uq  Validate a registry NON_BLOCKING mark against the draft-07 schema.

    Returns ``(ok, errors)``. ``ok`` is True only when the mark is a dict
    that fully validates (additionalProperties:false, const owner/chat = ANU,
    classification ∈ {NON_BLOCKING, LEGACY_PENDING}, the decouple/trigger
    invariants). A malformed / non-ANU / non-dict mark → ok=False.
    Fzmark is not an objectc                ,    t        | j                        S r   )listabsolute_path)es    r   <lambda>z,validate_non_blocking_mark.<locals>.<lambda>i   s    43H r   )key/c              3  2   K   | ]  }t        |        y wr   )str).0ps     r   	<genexpr>z-validate_non_blocking_mark.<locals>.<genexpr>l   s     4qCF4s   z<root>z: )	r    
isinstancedictr   sortediter_errorsjoinr*   message)markschema	validatorerrorsr+   msgss         r   validate_non_blocking_markr?   Y   s     ~dD!.///'Id#)HF
  884AOO44@
AAII;OD  Ht	s   <Bcriteriar;   c          
        
t               
t               | j                  d      | j                  d      dfd}| j                  d      dur |t        dd	      S | j                  d
      du }t	              xr | j                  d      du }|r|s |t
        dd	      S | j                  d      du }| j                  d      du xr | }| j                  d      }d}	g }
d}|Zt        |      \  }}
t        |t              xr* |j                  d      k(  xr |j                  d      k(  }t	        |xr |      }	g }|r|j                  d       |	r|j                  d       |r |t        |||	|
|      S | j                  d      }|r|t        v rd}d}n|sd}d}nd}d} |t        ||||	|
|d      S )uE  REAL entrypoint — 회장 §2 기준 판정 (mock 아님).

    ``observation`` keys:
      task_id (str)
      fallback_cron_id (str|None)
      fallback_bound (bool)
      normal_callback_durable_success (bool)
      normal_success_unchanged (bool)            -- safety invariant
      cancel_on_success_applied (bool)           -- criterion (a)
      fallback_fired (bool)
      fallback_handling (str|None)               -- DUPLICATE_CALLBACK_IGNORED…
      registry_non_blocking_mark (dict|None)     -- criterion (b)

    Returns a verdict dict (verdict ∈ VERDICTS).
    Ntask_idfallback_cron_idc           	     z    d| g j                  d      j                  d      d}|j                  |       |S )Nz+task-2553+58.fallback_acceptance_verdict.v1r;   $id)r;   verdictrC   rD   satisfied_criterioncriteria_schemanonblocking_schema_id)getupdate)rG   extraoutrA   fb_cronr;   rC   s      r   _vz(evaluate_fallback_acceptance.<locals>._v   sD    C '#%'||H5%+ZZ%6
 	

5
r   normal_success_unchangedT NORMAL_SUCCESS_DECOUPLE_VIOLATEDu   normal_success_unchanged != true — 디커플 절대불변 위반; 기준 a/b 평가 이전 fail-closed (§5/safety_invariant).)reasondetailnormal_callback_durable_successfallback_bound'NO_DURABLE_SUCCESS_OR_NO_BOUND_FALLBACKu   durable-success 미선행 또는 bound fallback 부재 — 정당 recovery / 적용 대상 아님 (applicability.out_of_scope).fallback_firedcancel_on_success_appliedregistry_non_blocking_markFab)rH   criterion_acriterion_bmark_schema_errorsmark_binding_okfallback_handlingDUPLICATE_IGNORED_ONLY_NO_MARKu   마크 없이 fallback 발화 후 DUPLICATE_CALLBACK_IGNORED/NO-ACTION 로만 처리 — 회장 §2 anti_pattern. 안전성 OK 이나 운영 품질 PASS 아님.UNMARKED_NO_CANCEL_NO_NONBLOCKus   cancel-on-success 미적용·NON_BLOCKING 마크 부재 — 미발화여도 운영 품질 미충족(legacy 잔여).%UNMARKED_FALLBACK_NONIDLE_DISPOSITIONue   마크 없이 fallback 발화·idle 처리 아님 — 운영 품질 미충족 (마크/제거 부재).u>   OK (normal_success_unchanged=true) — 차단성 결함 아님)rS   rT   r]   r^   r_   r`   safety)rG   r0   rM   r   returnr5   )r   r    rK   r   boolr   r?   r4   r5   appendr	   _IDLE_HANDLINGr
   )observationrA   r;   rP   durableboundfiredcrit_ar:   crit_bmark_errors
binding_ok	schema_ok	satisfiedhandlingrS   rT   rO   rC   s    ``              @@r   evaluate_fallback_acceptanceru   s   s=   *  ?~ooi(Goo01G  12$>5K
 	
 oo?@DHGMGkoo.>?4GE<S
 	
 OO,-5E 	34<JU 
 ??78DFKJ!;D&!I	;tT" 8#w.8+,7 	
 i.J/I )*&
 	
 23H^+1h 	 16 	
 9& 	  &"O	 	r   c           	     \   | 
t               } |
t               }i }	 t        j                  |       d|d<   | j                  d      dk(  |d<   | j                  di       }|j                  d      d	k(  xr |j                  d
      d	k(  |d<   |j                  d      |j                  d      cxk(  xr dk(  nc |d<   | j                  di       }|j                  d      dk(  xr |j                  d      dk(  |d<   t        | j                  dg             t        t              k(  |d<   |j                  di       }|j                  di       j                  d      t        k(  |d<   |j                  di       j                  d      t        k(  |d<   |j                  di       j                  d      du |d<   |j                  d i       j                  d      du |d!<   |j                  d"i       j                  d      du |d#<   | j                  d$i       j                  d%d&      j                  d'      |d(<   t        |j                               }d)||t        t        j                  t                     t        t"        j                  t                     d*S # t        $ r	 d|d<   Y tw xY w)+uA   criteria JSON 과 NON_BLOCKING schema 의 정합을 검사한다.Tschema_is_valid_draft07Fr;   z#anu.fallback_acceptance_criteria.v1criteria_schema_tagr^   
schema_refr   rF   criterion_b_schema_ref_matchesschema_titletitle*task-2553+58.non_blocking_fallback_mark_v1 criterion_b_schema_title_matches
entrypointmodulez2scripts/validate_fallback_acceptance_2553plus58.pyfunctionru    entrypoint_points_to_this_moduleverdictsverdict_enum_consistent
properties	owner_keyconstschema_owner_is_anu_constchat_idschema_chat_is_anu_constrQ   schema_decouple_const_trueprogress_trigger#schema_progress_trigger_const_falserY   !schema_cancel_applied_const_falseanti_patternoperational_quality FAIL%criteria_anti_pattern_is_quality_failz)task-2553+58.criteria_schema_coherence.v1)r;   coherentcheckscriteria_pathschema_path)r   r    r   check_schema	ExceptionrK   r6   VERDICTSANU_KEYANU_CHAT_ID
startswithallvaluesr0   r   relative_to	WORKSPACEr   )rA   r;   r   cbeppropsr   s          r   check_criteria_schema_coherencer      s     ?~ F2$$V,,0()
 	X"GG  ! 
mR	(B
| KK 	MJJu!LL +,
 	~&**W"5 	87	8 -. 
lB	'B
xPP 	AFF:"@@ -. )/Z$)		)F$%
 JJ|R(E		+r"&&w/7: &' 			)R $$W-< %& 			,b155g>$F '( 			$b)--g6%? 01 			-r266w?5H ./ 	^R(,,-BBG	F	 23
 6==?#H=]66yAB;229=> _  2,1()2s   J J+*J+c                     dddddd} dddt         t        ddddd	dd
dddd}t        i | ddd      t        i | d|i      t        i | dd
d      gS )uL   판정 로직이 실제로 동작함을 보이는 self-sample (mock 아님).ztask-2553+58zF0683510-FBT)rC   rD   rV   rU   rQ   r}   NON_BLOCKINGz2026-05-18 22:10 KSTANUz2self-sample: durable-success registry line presentr   F)r;   rC   rD   r   r   "bound_after_normal_durable_successclassificationmarked_at_kstmarked_by_collector_rolebasisrQ   expected_on_firer   cancel_on_success_eligiblerY   )rY   rX   rZ   )rX   ra   )r   r   ru   )base
valid_marks     r   _self_sampler   ?  s     ")+/$(D ?!).2(/$)E$(8!&*%*J$ 	%PtP$%P	
 	%>t>1:>	
 	%"&%A	
 r   c                "   t        j                  d      }|j                  dd       |j                  |       }t	               }t               }t        ||      }d|t               D cg c]  }|d   	 c}t        t              t        t              dd	}|j                  r$t        t        |j                        ||
      |d<   t        t        j                   |dd             |d   xr |d   t"        t"        t$        gk(  }|rdS dS c c}w )NzQtask-2553+58 fallback acceptance criterion validator (read-only; no file writes).)descriptionz--observationu@   평가할 fallback disposition observation JSON 경로 (선택).)helpztask-2553+58.validate_report.v1rG   r   )r;   	coherenceself_sample_verdictscriteria_sha256schema_sha256writes_performedr@   observation_verdictF   )ensure_asciiindentr   r      )argparseArgumentParseradd_argument
parse_argsr   r    r   r   r&   r   r   rj   ru   r   printr   dumpsr	   r
   )	argvapargsrA   r;   r   vreportoks	            r   mainr   j  s   		 	 '
B OOO   ==DH]F/&AI 47C~ F!9 F$]3";/F (Dd&&'(6)
$% 
$**V%
:;	:	 
6*@#A F $B
 1! !Gs   )D__main__)r   
str | Pathrf   r   r   )r   zstr | Path | Nonerf   r5   )r   r   rf   r0   )r:   r   r;   dict | Nonerf   ztuple[bool, list[str]])rj   r5   rA   r   r;   r   rf   r5   )NN)rA   r   r;   r   rf   r5   )rf   z
list[dict])r   zlist[str] | Nonerf   int)&__doc__
__future__r   r   r"   r   syspathlibr   typingr   
jsonschemar   __file__resolveparentr   r   r   r   r   r	   r
   r   r   r   ri   r   r   r    r&   r?   ru   r   r   r   __name__exit r   r   <module>r      sY  !D #    
   &N""$++22	MMEE
 & 5 ! 	 J>
,*? &*
": !	@@ @ 	@
 
@J 9=DD*5D	DP(V"J zCHHTV r   