+
    +i!/                       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^2tR R	 ltR
 R lt R R lt!]"R8X  d   ]PF                  ! ] ! 4       4       R# R# )u  G4.4 canary — STRICT double-description detection (Task 4.1).

Detects co-occurrence of a mapped character ID (`C##` / `C##O##`) and a
generic person noun (`an Asian man` / `a young woman` / `a figure` etc. —
imported from `_CONTINUITY_GENERIC_PERSON_NOUNS`) within a ±50 chars
window. Generic noun list is imported from
`render_prompt_card._CONTINUITY_GENERIC_PERSON_NOUNS` (Trap #8 — module-level
constant single source).

Scope: id-mapping shots only (R2-B4 carry — `fixed_elements[i].character_name`
maps to a `C##` / `C##O##` listed in `id_policy.allowed_outlook_pairs`).

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

Override O-7 — paired-string substring carry: any double-description with the
same character ID treated as cross-card / cross-shot violation; canary
intentionally does NOT inspect cross_shot_id_substitution_rule wording.

Usage (config mode):
    python scripts/canary/g4_4_double_description.py \
        --config canary_config.json \
        --cp-root data/projects/<pid>/checkpoints/scene_detail \
        --prompt-version 19.<timestamp> \
        --role candidate \
        --output results/double_description_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_GENERIC_PERSON_NOUNSz\bC\d{2}(?:O\d{2})?\bc                   V ^8  d   QhRR/# )   returnstr )formats   ")scripts/canary/g4_4_double_description.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   intr   )r   s   "r   r   r   B   s     q qc qr   c                 R   \         P                  ! R R7      p V P                  R\        RR7       V P                  R\        RR7       V P                  R\        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. RKO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       ^# \        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  R!V9  d   VP!                  RV RV R"24       EK0  VR!,          p\        V\        4      '       g   VP!                  RV RV R#24       EKj  R$V9  d   VP!                  RV RV R%24       EK  VR$,          p\        V\*        4      '       g   VP!                  RV RV R&24       EK  R'pV F  p\        V\        4      '       g   K  VP#                  R(4      p\        V\        4      '       d	   V'       g   KL  V F  p\        V\        4      '       g   K  VP#                  R)4      pVP#                  R*4      p\        V\        4      '       d   VV8X  g>   \        V\        4      '       g   Kr  \        V\        4      '       g   K  VV V 28X  g   K  R
p M	  V'       g   K   M	  VP!                  RVR+VR,V/4       V'       g   EK  V
^,          p
^ p\-        V4       EFJ  w  p p!\        V!\        4      '       g   VP!                  RV RV R-V  R.24       K:  V!P#                  R/4      p"\        V"\        4      '       d   V"P/                  4       '       g   VP!                  RV RV R-V  R024       K  V"P1                  4       p#\2        P5                  V"4       F  p$V$P7                  4       p%V$P9                  4       p&\;        ^ V%\<        ,
          4      p'\?        \A        V"4      V&\<        ,           4      p(V#V'V( p)\B         F$  p*V*P1                  4       V)9   g   K  V^,          p K  	  K  	  EKM  	  VV,          pVVV R1V 2&   EK`  	  V F)  w  ppVV3V	9  g   K  VP!                  R2V RV R324       K+  	  R4\E        4       R5VPF                  R6VPH                  R7TR8TR9R:V
R;VR<VR=\+        \B        4      /R>TR?^ R@V'       * ;'       d    V^ 8H  RARBRC//
p\        Wq4       \K        RDVPH                   REVPF                   RFV
 RGV RH\A        V4       RI2\L        PN                  RJ7       V'       d   ^# VPH                  R8X  d
   V^ 8  d   ^# ^ # )Lue   G4.4 canary: double-description detection (id-mapping shots only — Trap #8 module-level constants).)descriptionz--configN)typedefaultz--pidz	--cp-rootz/Directory containing scene_detail manifest.json)r!   r"   helpz--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--outputzscene entry is not dictscene_index_shot_indexrender_prompt_cardcontinuity_elements_usedfixed_elementss_shz5: continuity_elements_used.fixed_elements key missingz2: continuity_elements_used.fixed_elements not list	id_policyz*: render_prompt_card.id_policy key missingz': render_prompt_card.id_policy not dictallowed_outlook_pairsz-: id_policy.allowed_outlook_pairs key missingz*: id_policy.allowed_outlook_pairs not listFcharacter_namecharacter_id
outlook_id
shot_indexhas_fixed_element_id_mapping_vz: variation not a dict
t2i_promptz': 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_shots_with_id_mappingdouble_description_countdouble_description_per_shotgeneric_person_nouns_usedmeasurement_failuresexit_criteria_thresholdexit_criteria_passmeasurement_scriptsdouble_description\   scripts/canary/g4_4_double_description.py (id-mapping shots only — Override O-7 / Trap #8)z[g4_4_double_description] role=z prompt_version=z
  total_shots_with_id_mapping=z
  double_description_count=z
  measurement_failures: zH
Exit criteria (STRICT): candidate.metrics.double_description_count == 0)file)NrI   db)(argparseArgumentParseradd_argumentr   
parse_argsr
   r   r   r	   r   _empty_outputr   r   set
isinstancedictappendgetr   addr   list	enumeratestriplower	_ID_REGEXfinditerstartendmax_WINDOW_CHARSminlenr   r   r:   r;   printsysstderr)+parserargsr<   cp_rootcprC   scenesoutpinning_set
seen_in_cpr?   r@   rA   scene_set_outscenesishisi_intshi_int
variationsrpccer,   r/   allowed_pairshas_id_mappingfer1   opcidoid
shot_countvivarpromptprompt_lowermatchid_startid_end	win_startwin_endwindownouns+                                              r   mainr   B   s   $$JF 
d;
c48
>	   *tD
[)	   ,3E
5CN
)TB
$	   ,3E
)T   
t<D$T*GWd#G	'	"B&(!";F~D+?@C)'2K'*uJ"# 24 "M%&& ''(ABYY}%ii&:Rc(GK/().67$8

 ()+,2% ''F83wi (- . ,-.$// ''F83wi (* + c! ''F83wi (  $	)T** ''F83wi (  ")3 ''F83wi (  !"9:-.. ''F83wi (  
  Bb$''VV$45Nnc22.#!"d++ff^,ff\*sC((^s-BsC(("3,,&SE#-7%)N $ ~+ !. 	6'*N
 	 #q(#
 ,GBc4(($++xs7)2bT1GH WW\*Ffc**&,,..$++xs7)2bT 2( )  "<<>L"++F3 ;;=8m#;<	c&k6M+AB%i8<Dzz|v-"a
 = 4! -8 	!J. =G#vhay$9:E J !	S9J& ''RDC5(HI ! 	[]$--		7])+F&(@)+F'0*	
 	 4!1$$FF)AQ)F E 
'C6 	
)$)) 5--. /))D(E F&&>%? @##&';#<"= >:		; ZZ	 yyK$<q$@r   c               (    V ^8  d   QhRRRRRRRR/# )r   rf   zargparse.Namespacer<   rR   rC   rV   r   r   )r   s   "r   r   r   6  s0      
  
	r   c                    R \        4       RV P                  RV P                  RVR. RR^ R^ R/ R	\        \        4      /R
VR^ RRRRR//
# )r9   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   rD   rE   FrF   rG   rH   )r   r:   r;   rV   r   )rf   r<   rC   s   &&&r   rO   rO   6  sz     	[]$--		7R)1&)2'0*	
 	 4!1e E 
# r   __main__)$__doc__
__future__r   rK   jsonrerc   r   pathlibr   pathinsertr   __file__resolveparent_g4_4_commonr   r   r   r   r	   r
   r   r   r   _CONSTSr   compilerZ   r_   r   r   rO   __name__exitr   r   r   <module>r      s   6 #   	 
   3tH~--/667 8
 
 
 %
&#*+M#N   JJ/0	/qh> zHHTV r   