+
    +i2                       R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RIH	t	 ]P                  P                  ^ ]! ]	! ]4      P                  4       P                  4      4       ^ RIHtHtHtHtHtHtHtHtHt ]! 4       t]R,          t]P8                  ! R4      t]P8                  ! R4      tR	 R
 ltR R lt R R lt!R R lt"]#R8X  d   ]PH                  ! ]!! 4       4       R# R# )u  G4.4 canary — STRICT zoom_in_detail no-new-entity detection (Task 4.2).

Detects entities (`C##` / `C##O##` / `P##`) introduced in current shot's
t2i_prompt that are absent in the prior shot's t2i_prompt referenced via
`previous_shot_refs[i].ref_usage == "zoom_in_detail"`. Any new entity
(character or prop) is a violation.

Override O-7 — paired-string substring carry: zoom_in_detail body-part
cross-reference is asserted via `_CONTINUITY_ID_POLICY_CROSS_REF_LITERAL`
(`id_policy.body_part_focus_rule`). This canary does NOT inspect the literal
itself but cross-card paired drift is enforced by unit + integration tests.

Scope: shots with at least one `previous_shot_refs[i].ref_usage ==
"zoom_in_detail"` (R2-B4 carry).

Exit criteria (analyzer, OUT-OF-BAND):
  candidate.metrics.zoom_in_detail_new_entity_count == 0  (STRICT, Override O-1)

Usage (config mode):
    python scripts/canary/g4_4_zoom_in_detail_no_new_entity.py \
        --config canary_config.json \
        --cp-root data/projects/<pid>/checkpoints/scene_detail \
        --prompt-version 19.<timestamp> \
        --role candidate \
        --output results/zoom_in_detail_candidate.json
)annotationsN)datetime)Path)	_load_scenes_or_fail_validate_scene_preflightbuild_pinning_scene_setemit_outputload_cp_manifestload_pinning_from_argsrender_prompt_card_importsresolve_cp_rootvalidate_pinning'_CONTINUITY_ID_POLICY_CROSS_REF_LITERALz\bC\d{2}(?:O\d{2})?\bz
\bP\d{2}\bc                   V ^8  d   QhRR/# )   returnstr )formats   "3scripts/canary/g4_4_zoom_in_detail_no_new_entity.py__annotate__r   @   s     / /S /    c                 V    \         P                  ! 4       P                  4       R ,           # )Z)r   utcnow	isoformatr   r   r   iso8601_nowr   @   s    ??&&(3..r   c                    V ^8  d   QhRRRR/# )r   promptr   r   zset[str]r   )r   s   "r   r   r   D   s      s x r   c                    \        \        P                  V 4      4      p\        \        P                  V 4      4      pW,          # )uz   t2i_prompt 안 모든 C##/C##O##/P## entity ID set (full-text scan).

CLAUDE.md no-truncation carry — full prompt scan.
)set_CHAR_ID_REGEXfindall_PROP_ID_REGEX)r   charspropss   &  r   extract_entity_setr&   D   s6    
 &&v./E&&v./E=r   c                   V ^8  d   QhRR/# )r   r   intr   )r   s   "r   r   r   N   s     y yc yr   c                     \         P                  ! R R7      p V P                  R\        RR7       V P                  R\        RR7       V P                  R\        RR7       V P                  R\        RR	7       V P                  R
\        RRR.R7       V P                  R\        RR7       V P                  R\        RR7       V P                  R\        RR7       V P                  R\        R. RJOR7       V P                  R\        RR7       V P                  R\        RR7       V P                  R\        RR	7       V P	                  4       p\        V4      p\        V4       \        V4      p\        V4      p. p\        WE4      pVf   \        WV4      p\        Wq4       ^# / pV F_  p	\        V	\        4      '       g   K  V	P                  R4      p
V	P                  R4      pV
e   Vf   KG  W\        V
4      \        V4      3&   Ka  	  \!        V4      p\#        4       p^ p^ p/ p. pV EF  p	\        V	\        4      '       g   VP%                  R4       K-  V	P                  R4      p
V	P                  R4      pV
e   Vf   KY  \        V
4      p\        V4      pVV3V9  d   Kz  VP'                  VV34       \)        V	VVV4      pVf   K  V	R,          pVR,          pRV9  d   VP%                  RV RV R24       K  VR,          p\        V\*        4      '       g   VP%                  RV RV R24       EK  V Uu. uF5  p\        V\        4      '       g   K  VP                  R4      R 8X  g   K3  VNK7  	  pp\-        V Uu0 uFS  p\        V\        4      '       g   K  \        VP                  R4      \        4      '       g   KB  VP                  R4      kKU  	  up4      pVP%                  RVR!VR"\/        V4      R#V/4       V'       g   EK  V^,          p\#        4       pV EF  pVP                  R4      pVP                  R!4      pVe   Vf   VP%                  RV RV R$24       KH   \        V4      \        V4      3pTP                  T4      p T f/   TP%                  RT RT R&T^ ,           RT^,           R'2	4       K  R(T 9  d)   TP%                  RT^ ,           RT^,           R)24       K  T R(,          p!\        T!\*        4      '       g*   TP%                  RT^ ,           RT^,           R*24       EK  T!'       g*   TP%                  RT^ ,           RT^,           R+24       EKJ  T! FV  p"\        T"\        4      '       g   K  T"P                  R,4      p#\        T#\        4      '       g   KD  T\5        T#4      ,          pKX  	  EK  	  \#        4       p$\7        V4       F  w  p%p&\        V&\        4      '       g   VP%                  RV RV R-V% R.24       K9  V&P                  R,4      p'\        V'\        4      '       d   V'P9                  4       '       g   VP%                  RV RV R-V% R/24       K  V$\5        V'4      ,          p$K  	  V$V,
          p(V('       g   EKw  V\;        V(4      ,          p\-        V(4      VV R0V 2&   EK  	  V F'  w  rW3V9  g   K  VP%                  R1V
 RV R224       K)  	  R3\=        4       R4VP>                  R5VP@                  R6TR7TR8R9VR:VR;V/R<TR=^ R>V'       * ;'       d    V^ 8H  R?R@RA\B         RB2//
p\        Wq4       \E        RCVP@                   RDVP>                   REV RFV RG\;        V4       RH2\F        PH                  RI7       V'       d   ^# VP@                  R8X  d
   V^ 8  d   ^# ^ # u upi u upi   \0        \2        3 d    TP%                  RT RT R%24        EK  i ; i)KzPG4.4 canary: zoom_in_detail no-new-entity detection (zoom_in_detail shots only).)descriptionz--configN)typedefaultz--pidz	--cp-rootz--prompt-versionT)r+   requiredz--role	candidatebaseline)r+   r,   choicesz--scene-index-listz--shot-index-list-per-scenez--model-routingz--prompt-source-modez--card-commit-hashz--continuity-card-snapshot-hashz--outputscene_index_shot_indexzscene entry is not dictrender_prompt_cardcontinuity_elements_usedprevious_shot_refss_shz9: continuity_elements_used.previous_shot_refs key missingz6: continuity_elements_used.previous_shot_refs not list	ref_usagezoom_in_detail
shot_indexhas_zoom_in_detail_refref_usage_signaturez3: zoom_in_detail ref missing scene_index/shot_indexz=: zoom_in_detail ref scene_index/shot_index not int-coerciblez: zoom_in_detail prior sz not found in CPt2i_variationsz: t2i_variations key missingz: t2i_variations not listz: t2i_variations empty
t2i_prompt_vz: variation not a dictz': t2i_prompt missing, empty, or not str_z
pinning (sz ): not present in CP data.scenes	timestampprompt_versionrolepinning	scene_setmetricstotal_zoom_in_detail_shotszoom_in_detail_new_entity_count"zoom_in_detail_new_entity_per_shotmeasurement_failuresexit_criteria_thresholdexit_criteria_passmeasurement_scriptszoom_in_detail_no_new_entityut   scripts/canary/g4_4_zoom_in_detail_no_new_entity.py (zoom_in_detail shots only — Override O-7 paired ref literal: )z)[g4_4_zoom_in_detail_no_new_entity] role=z prompt_version=z
  total_zoom_in_detail_shots=z#
  zoom_in_detail_new_entity_count=z
  measurement_failures: zO
Exit criteria (STRICT): candidate.metrics.zoom_in_detail_new_entity_count == 0)file)NrP   db)%argparseArgumentParseradd_argumentr   
parse_argsr
   r   r   r	   r   _empty_outputr   
isinstancedictgetr(   r   r    appendaddr   listsortedbool	TypeError
ValueErrorr&   	enumeratestriplenr   rB   rC   r   printsysstderr))parserargsrD   cp_rootcprJ   scenesoutscene_shot_lookupscenesishipinning_set
seen_in_cptotal_zoom_shotszoom_new_entity_countzoom_new_entity_per_shotscene_set_outsi_intshi_int
variationsrpccerefsr	zoom_refsr<   prior_entitiesrefprior_si	prior_shi	prior_keyprior_sceneprior_variationspvarppromptcurrent_entitiesvivarr   new_entitiess)                                            r   mainr   N   s   $$+F 
d;
c48
#t<
*tD
[)	   ,3E
5CN
)TB
$	   ,3E
)T   
t<D$T*GWd#G	'	"B&(!";F~D+?@C 68%&&YY}%ii&:163r7CH-.  *'2K'*uJ57 "M%&& ''(ABYY}%ii&:Rc(GK/().67$8

 ()+,r) ''F83wi (1 2 &'$%% ''F83wi (. /  
!T" '(uu['9=M'M A 	 
 %&
!T" '1!%%2Dc'J AEE+&
 
 	6'$d9o!#6	
 	 A $'5Cww}-H-I9#4$++xs7) ,- .  ]C	N;	 ,//	:K"$++xs7) ,!!~S16FH {2$++	!~S1 7" # *+;<.55$++	!~S1 7   #$++	!~S1 7  (!$--((<0gs++"&8&AAN )Y h &)U ,GBc4(($++xs7)2bT1GH WW\*Ffc**&,,..$++xs7)2bT 2( )  26 :: - (.8<!S%66!>D?$xq	%:;I R !	9J& ''RDC5(HI ! 	[]$--		7](*:-/D02J

 	 4!1$$CC)>!)C*CDAG 
!C2 	
3DII; ?--. /((8'9 :--B,C D##&';#<"= >A		B ZZ	 yyK$9A$=k
&
: z* $++xs7) ,? @ s6   <__1__

"_

_

-_)_=<_=c               (    V ^8  d   QhRRRRRRRR/# )r   rh   zargparse.NamespacerD   rX   rJ   r\   r   r   )r   s   "r   r   r   J  s0      
  
	r   c                v    R \        4       RV P                  RV P                  RVR. RR^ R^ R/ /R	VR
^ RRRRR//
# )rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   FrM   rN   zOscripts/canary/g4_4_zoom_in_detail_no_new_entity.py (zoom_in_detail shots only))r   rB   rC   )rh   rD   rJ   s   &&&r   rV   rV   J  sl     	[]$--		7R(!-q0"

 	 4!1e*. 
 r   __main__)%__doc__
__future__r   rR   jsonrere   r   pathlibr   pathinsertr   __file__resolveparent_g4_4_commonr   r   r   r   r	   r
   r   r   r   _CONSTSr   compiler!   r#   r   r&   r   rV   __name__exitr   r   r   <module>r      s   4 #   	 
   3tH~--/667 8
 
 
 %
& +2-+ '
 45M*/yx8 zHHTV r   