
    +i2                       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	 ej                  j                  d e e	e      j                         j                               ddlmZmZmZmZmZmZmZmZmZ  e       Zed   Z ej8                  d      Z ej8                  d	      Zdd
ZddZ ddZ!	 	 	 	 	 	 	 	 ddZ"e#dk(  r ejH                   e!              yy)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                 L    t        j                         j                         dz   S )NZ)r   utcnow	isoformat     3scripts/canary/g4_4_zoom_in_detail_no_new_entity.pyiso8601_nowr   @   s    ??&&(3..r   c                    t        t        j                  |             }t        t        j                  |             }||z  S )u   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)promptcharspropss      r   extract_entity_setr    D   s8    
 &&v./E&&v./E5=r   c                    t        j                  d      } | j                  dt        d        | j                  dt        d        | j                  dt        d        | j                  dt        d	       | j                  d
t        dddg       | j                  dt        d        | j                  dt        d        | j                  dt        d        | j                  dt        d g d       | j                  dt        d        | j                  dt        d        | j                  dt        d	       | j	                         }t        |      }t        |       t        |      }t        |      }g }t        ||      }|t        |||      }t        ||       yi }|D ]S  }	t        |	t              s|	j                  d      }
|	j                  d      }|
|;|	|t        |
      t        |      f<   U t!        |      }t#               }d}d}i }g }|D ]  }	t        |	t              s|j%                  d       &|	j                  d      }
|	j                  d      }|
|Mt        |
      }t        |      }||f|vrj|j'                  ||f       t)        |	|||      }||	d   }|d   }d|vr|j%                  d| d| d        |d   }t        |t*              s|j%                  d| d| d!       |D cg c](  }t        |t              r|j                  d"      d#k(  r|* }}t-        |D ch c]B  }t        |t              r0t        |j                  d"      t              r|j                  d"      D c}      }|j%                  ||t/        |      |d$       |s|dz  }t#               }|D ]R  }|j                  d      }|j                  d%      }|||j%                  d| d| d&       C	 t        |      t        |      f}|j                  |      } | %|j%                  d| d| d(|d    d|d    d)	       d*| vr|j%                  d|d    d|d    d+       | d*   }!t        |!t*              s|j%                  d|d    d|d    d,       |!s |j%                  d|d    d|d    d-       |!D ]C  }"t        |"t              s|"j                  d.      }#t        |#t              s6|t5        |#      z  }E U t#               }$t7        |      D ]  \  }%}&t        |&t              s|j%                  d| d| d/|% d0       2|&j                  d.      }'t        |'t              r|'j9                         s|j%                  d| d| d/|% d1       |$t5        |'      z  }$ |$|z
  }(|(s|t;        |(      z  }t-        |(      || d2| <    |D ]$  \  }
}|
|f|vs|j%                  d3|
 d| d4       & t=               |j>                  |j@                  |||||d5|d| xr |dk(  d6d7tB         d8id9
}t        ||       tE        d:|j@                   d;|j>                   d<| d=| d>t;        |       d?tF        jH                  @       |ry|j@                  dk(  r|dkD  ryyc c}w c c}w # t0        t2        f$ r |j%                  d| d| d'       Y 0w xY w)ANzPG4.4 canary: zoom_in_detail no-new-entity detection (zoom_in_detail shots only).)descriptionz--config)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-mode)Nfiledbz--card-commit-hashz--continuity-card-snapshot-hashz--output   scene_index_shot_indexr   z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)r,   
shot_indexhas_zoom_in_detail_refref_usage_signaturer5   z3: 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total_zoom_in_detail_shotszoom_in_detail_new_entity_count"zoom_in_detail_new_entity_per_shot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: )
	timestampprompt_versionrolepinning	scene_setmetricsmeasurement_failuresexit_criteria_thresholdexit_criteria_passmeasurement_scriptsz)[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)r)   )%argparseArgumentParseradd_argumentstr
parse_argsr   r   r   r
   r   _empty_outputr	   
isinstancedictgetintr   r   appendaddr   listsortedbool	TypeError
ValueErrorr    	enumeratestriplenr   rD   rE   r   printsysstderr))parserargsrF   cp_rootcprI   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_refsr7   prior_entitiesrefprior_si	prior_shi	prior_keyprior_sceneprior_variationspvarppromptcurrent_entitiesvivarr   new_entitiess)                                            r   mainr   N   sX   $$+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&:163r7CH-.  *'2K'*uJ57 "M%& ''(ABYY}%ii&:Rc(GK/().67$8

 ()+,r) ''F83wi (1 2 &'$% ''F83wi (. /  
!T"quu['9=M'M  	 
 %&
!T"z!%%2Dc'J EE+&
 
 	!!&*9o#6	
 	 A $'5Cww}-H-I9#4$++xs7) ,- .  ]C	N;	 ,//	:K"$++xs7) ,!!~S16FH {2$++	!~S1 7" # *+;<.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 !	S9J& ''RDC5(HI ! !]--		"*:/D2J

 !5#$$$C)>!)C +CDAG 
!C2 T	
3DII; ?--. /((8'9 :--B,C D##&';#<"= >A		B ZZ	 yyK$9A$=k
&
: z* $++xs7) ,? @ s   -Z9;AZ>
['[.-[.c                `    t               | j                  | j                  |g ddi d|ddddid
S )Nr   r<   Fr@   zOscripts/canary/g4_4_zoom_in_detail_no_new_entity.py (zoom_in_detail shots only)rB   )r   rD   rE   )re   rF   rI   s      r   rR   rR   J  sO     !]--		*+/024

 !5#$#*. 
 r   __main__)returnrP   )r   rP   r   zset[str])r   rV   )re   zargparse.NamespacerF   rT   rI   rY   r   rT   )%__doc__
__future__r   rM   jsonrerb   r   pathlibr   pathinsertrP   __file__resolveparent_g4_4_commonr   r   r   r	   r
   r   r   r   r   _CONSTSr   compiler   r   r   r    r   rR   __name__exitr   r   r   <module>r      s   4 #   	 
   3tH~--/667 8
 
 
 %
& +2-+ '
 45M*/yx
  
	8 zCHHTV r   