+
    ,i,                    z   R t ^ RIH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R R ltR	 R
 ltR R ltR R lt]R8X  d   ]P>                  ! ]! 4       4       R# R# )u  G4.4 canary — STRICT atmosphere_reference no-layout-import detection (Task 4.3).

Detects 7 furniture / wall / layout tokens (`furniture` / `wall position` /
`room layout` / `same chair` / `same table` / `same wall` / `same window`)
inside `t2i_prompt` of shots with at least one
`previous_shot_refs[i].ref_usage == "atmosphere_reference"` (Override O-11
multi-ref filter — atmosphere co-presence with `exact_background` still
triggers; false-positive baseline >0 → P1 follow-up).

Token list imported from
`render_prompt_card._CONTINUITY_FURNITURE_LAYOUT_TOKENS` (Trap #8 —
module-level constant single source).

Override O-17 — regex brittleness: this regex/substring-based detector is a
1차 detector only. If baseline >0 (e.g. natural usage like "the wall position
is preserved" — a rationale, not an import), escalate to LLM-validator
(gpt-5.4-mini judge) as P1 follow-up. `feedback_no_regex_postprocessing.md`
carry.

Scope: shots where `any(ref.ref_usage == "atmosphere_reference" for ref in
previous_shot_refs)` (R2-B4 carry / Override O-11).

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

Usage (config mode):
    python scripts/canary/g4_4_atmosphere_no_layout_import.py \
        --config canary_config.json \
        --cp-root data/projects/<pid>/checkpoints/scene_detail \
        --prompt-version 19.<timestamp> \
        --role candidate \
        --output results/atmosphere_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_FURNITURE_LAYOUT_TOKENSc                   V ^8  d   QhRR/# )   returnstr )formats   "2scripts/canary/g4_4_atmosphere_no_layout_import.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	list[str]r   )r   s   "r   r   r   B   s       	 r   c                    . pV P                  4       p\         F+  pVP                  4       V9   g   K  VP                  V4       K-  	  V# )u   7 furniture/layout token 중 prompt 안 등장 list 반환.

Case-insensitive literal substring match — full-text scan
(CLAUDE.md no-truncation carry). Override O-17: 1차 detector only —
LLM-validator escalation P1 follow-up.
)lowerr   append)r   foundprompt_lowertokens   &   r   find_layout_importsr%   B   s?     E<<>L4;;=L(LL 5 Lr   c                   V ^8  d   QhRR/# )r   r   intr   )r   s   "r   r   r   Q   s     P Pc P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. RIO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. 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  \,        ;QJ d    R V 4       F  '       g   K   RM	  R M! R V 4       4      p\,        ;QJ d    R! V 4       F  '       g   K   RM	  R M! R! V 4       4      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R%VR&V/4       V'       g   EK  V
^,          p
V'       d
   V^,          p^ p. p\1        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 P3                  4       '       g   VP!                  RV RV R'V R*24       K  \5        V 4      p!V\7        V!4      ,          pVP9                  V!4       K  	  VV,          pR+VR,VR%V/VV R-V 2&   EK  	  V F)  w  ppVV3V	9  g   K  VP!                  R.V RV R/24       K+  	  R0\;        4       R1VP<                  R2VP>                  R3TR4TR5R6V
R7VR8VR9VR:\+        \@        4      /R;TR<^ R=V'       * ;'       d    V^ 8H  R>R?R@//
p\        Wq4       \C        RAVP>                   RBVP<                   RCV
 RDV REV RF\7        V4       RG2\D        PF                  RH7       V'       d   ^# VP>                  R8X  d
   V^ 8  d   ^# ^ # u upi )Ju   G4.4 canary: atmosphere_reference no-layout-import detection (Override O-11 multi-ref filter — Override O-17 regex 1차 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--outputzscene entry is not dictscene_index_shot_index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 listc              3  z   "   T F1  p\        V\        4      ;'       d    VP                  R 4      R8H  x  K3  	  R# 5i)	ref_usageatmosphere_referenceN
isinstancedictget.0rs   & r   	<genexpr>main.<locals>.<genexpr>   sA      
  q$ = =k"&<<=   ;;Fc              3  z   "   T F1  p\        V\        4      ;'       d    VP                  R 4      R8H  x  K3  	  R# 5i)r8   exact_backgroundNr:   r>   s   & r   rA   rB      s8      '
 q$LLAEE+$6:L$LLrC   r8   
shot_indexhas_atmosphere_referenceexact_bg_co_presentref_usage_signature_vz: variation not a dict
t2i_promptz': t2i_prompt missing, empty, or not strcounttokens_z
pinning (sz ): not present in CP data.scenes	timestampprompt_versionrolepinning	scene_setmetrics total_atmosphere_reference_shotsatmosphere_multi_ref_shotsatmosphere_layout_import_count!atmosphere_layout_import_per_shotfurniture_layout_tokens_usedmeasurement_failuresexit_criteria_thresholdexit_criteria_passmeasurement_scriptsatmosphere_no_layout_importu   scripts/canary/g4_4_atmosphere_no_layout_import.py (atmosphere_reference shots only — Override O-11 multi-ref filter, Override O-17 regex 1차 only)z([g4_4_atmosphere_no_layout_import] role=z prompt_version=z$
  total_atmosphere_reference_shots=z
  atmosphere_multi_ref_shots=z7 (P1 follow-up if >0)
  atmosphere_layout_import_count=z
  measurement_failures: zN
Exit criteria (STRICT): candidate.metrics.atmosphere_layout_import_count == 0)file)Nr_   db)$argparseArgumentParseradd_argumentr   
parse_argsr
   r   r   r	   r   _empty_outputr   r   setr;   r<   r!   r=   r'   addr   listanysorted	enumeratestripr%   lenextendr   rP   rQ   r   printsysstderr)"parserargsrR   cp_rootcprZ   scenesoutpinning_set
seen_in_cptotal_atmosphere_shotsrV   rW   rX   scene_set_outscenesishisi_intshi_int
variationsrpccerefshas_atmospherehas_exact_bg_co_presencer@   rI   
shot_countshot_layout_tokensvivarr   layoutss"                                     r   mainr   Q   s|   $$R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)'2K'*uJ!"%&"9;% "M%&& ''(ABYY}%ii&:Rc(GK/().67$8

 ()+,r) ''F83wi (1 2 &'$%% ''F83wi (. /   
 
 
 
 

 $'3 '
'
333 '
'
 $
  %&
!T" '1!%%2Dc'J AEE+&
  	6'&!#;!#6
 	 !## '!+&
(* ,GBc4(($++xs7)2bT1GH WW\*Ffc**&,,..$++xs7)2bT 2( ) )&1G#g,&J%%g. -" 	'*4&Z(!#;D
)VHAgY*?@u B !	S9J& ''RDC5(HI ! 	[]$--		7].0F(*D,.L/1*D3-

 	 4!1$$LL)G1)L)9 
-C> 	
2499+ >--. /..D-E F((B'C D, *
* +##&';#<"= >@		A ZZ yyK$BQ$FW&
s   W
!"W
W
c               (    V ^8  d   QhRRRRRRRR/# )r   rs   zargparse.NamespacerR   r<   rZ   rh   r   r   )r   s   "r   r   r   $  s0      
  
	r   c                    R \        4       RV P                  RV P                  RVR. RR^ R^ R^ R	/ R
\        \        4      /RVR^ RRRRR//
# )rO   rP   rQ   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   Fr]   r^   uf   scripts/canary/g4_4_atmosphere_no_layout_import.py (atmosphere_reference shots only — Override O-11))r   rP   rQ   rh   r   )rs   rR   rZ   s   &&&r   re   re   $  s     	[]$--		7R.(!,a/*D3-
 	 4!1e)F 
% r   __main__) __doc__
__future__r   ra   rp   r   pathlibr   pathinsertr   __file__resolveparent_g4_4_commonr   r   r   r   r	   r
   r   r   r   _CONSTSr   r   r%   r   re   __name__exitr   r   r   <module>r      s    B #  
   3tH~--/667 8
 
 
 %
&&-)' #
/Pf@ zHHTV r   