§
    †YÇj/¨  ã                   óN  — d Z ddlZddlmc mZ ddlZddlZddl	Z	ddl
Z
ddlZddlmZ ej        dk    rC	 ej                             d¬¦  «         ej                             d¬¦  «         n# e$ r Y nw xY w ee¦  «                             ¦   «         j        j        Zedz  Zedz  Zed	z  Zed
z  Zedz  Zedz  Zedz  Zedz  Zedz  Zedz  Z edz  Z!edz  Z"dZ#ddddddddddddddddœZ$ e%e$ &                    ¦   «         ¦  «        Z'g d¢Z(g d¢Z) G d„ d ej*        ¦  «        Z+ G d!„ d"ej*        ¦  «        Z, G d#„ d$ej*        ¦  «        Z- G d%„ d&ej*        ¦  «        Z. G d'„ d(ej*        ¦  «        Z/ G d)„ d*ej*        ¦  «        Z0 G d+„ d,ej*        ¦  «        Z1 G d-„ d.ej*        ¦  «        Z2e3d/k    rs ej4        d0¬1¦  «        Z5ej6         7                    ej8        e3         ¦  «        Z9e5 :                    e9¦  «        Z; ej<        e; =                    ¦   «         rdnd2¦  «         dS dS )3u§  
=============================================================================
KIEU STORY AI CINEMA â€” TIER 5 ADVERSARIAL COVERAGE HARDENING (CHALLENGER 1)
=============================================================================
Test Suite: test_tier5_creative_hardening.py
Scope: Features F1 through F7 (Creative, Directives, Screenplay & Prompts)
Agent: teamwork_preview_challenger (Tier 5 Challenger 1 - Creative & Directives)

Adversarial Stress Verification Targets:
- F1: EP01 Screenplay & Pacing Expansion (188 shots, 15 scenes C01-C15, 3-Act structure)
- F2: Ä�áº¡m TiÃªn Grave 3-Beat Sequence (C05-A/B/C, 27 shots, anti-premature-weeping)
- F3: Anti-Male-Tears Script Purge (0% male crying, feudal stoicism across 188 shots)
- F4: Character & Acting Directives in Bibles (Kiá»�u-VÃ¢n 4-axis twin, pure East Asian Sai Nha)
- F5: 2-Step Sweet-Spot Start Frame Protocol (Gemini Banana 720p, zero reverse physics)
- F6: Lip-Sync & Off-Screen Dialogue Guard (Mandatory closed-lips on off-screen/VO)
- F7: EP01 188-Shot AI Prompt Registry Consistency & Asset Integrity

Empirical Gap Discovery Objectives:
1. Audit ThÃºy VÃ¢n age & twin status consistency across bibles, screenplay, and prompts.
2. Audit filesystem integrity for all 83 character_asset_ref paths in Muse prompts.
3. Audit production orchestrator start-frame resolution fallback vulnerability.
=============================================================================
é    N)ÚPathÚwin32úutf-8©ÚencodingÚ	FilmMakerÚ02_AI_PromptsÚ00_Project_BibleÚ	04_AssetsÚ05_Production_PipelineÚtestsz6TAP_01_XUAN_SAC_THE_NGUYEN_VA_GIONG_BAO_DOAN_TRUONG.mdzINDEX_VA_DANH_MUC_CANH_QUAY.mdzgemini_banana_prompts.jsonzmuse_ai_video_prompts.jsonzCHARACTER_BIBLE.mdzUNIVERSAL_ACTING_DIRECTIVES.mduñ   Quy táº¯c Ã¢m thanh: Tuyá»‡t Ä‘á»‘i KHÃ”NG sinh nháº¡c ná»�n (no music/BGM), khÃ´ng Ã¢m thanh Ä‘iá»‡n tá»­, khÃ´ng táº¡p Ã¢m rÃ¨ nhiá»…u. Chá»‰ sinh Ã¢m thanh mÃ´i trÆ°á»�ng tá»± nhiÃªn (foley, ambience) vÃ  thoáº¡i nhÃ¢n váº­t chÃ¢n thá»±c.é   é   é   é   é   é   é   é
   )é   é   é   é   é   r   é   r   é	   r   é   r   é   r   r   )õ   KIM TRá»ŒNGu   Kim Trá»�ngzKim sinhu
   chÃ ng Kimõ   VÆ¯Æ NG QUANõ   VÆ°Æ¡ng Quanõ   VÆ¯Æ NG Ã”NGu   VÆ°Æ¡ng Ã”ngu   VÆ°Æ¡ng viÃªn ngoáº¡iu	   cá»¥ Ã´ngu
   Tá»ª Háº¢Iu
   Tá»« Háº£iu
   THÃšC SINHu
   ThÃºc Sinhu
   THÃšC Ã”NGu
   ThÃºc Ã”ngu   MÃƒ GIÃ�M SINHu   MÃ£ GiÃ¡m Sinhu
   Sá»ž KHANHu
   Sá»Ÿ Khanhu   Há»’ TÃ”N HIáº¾Nu   Há»“ TÃ´n Hiáº¿nu   Báº C Háº NHu   Báº¡c Háº¡nhu   VIÃŠN QUAN SAI NHAu   ViÃªn quan sai nhau   TOÃ�N SAI NHAu   ToÃ¡n sai nhau
   LÃ�NH Lá»†u
   LÃ­nh lá»‡)õ   khÃ³cõ	   rÆ¡i lá»‡õ   giá»�t lá»‡u   ngáº¥n lá»‡u   Ä‘áº§m Ä‘Ã¬aõ   chÃ¢u sau   nÆ°á»›c máº¯tõ   rÆ¡i nÆ°á»›c máº¯tõ
   gÃ o khÃ³cõ
   khÃ³c thanõ   khÃ³c ngáº¥tõ   khÃ³c rá»‘ngu   náº¥c ngháº¹nõ
   sá»¥t sÃ¹iu   thÃºt thÃ­tu   chÃ¢u tuÃ´nu	   lá»‡ rÆ¡iu
   lá»‡ trÃ nu   Ä‘áº«m lá»‡u	   á»©a lá»‡ÚweepÚweepingÚtearÚtearsÚcryingc                   óB   — e Zd Zed„ ¦   «         Zd„ Zd„ Zd„ Zd„ Zd„ Z	dS )Ú'TestTier5F1ScreenplayExpansionAndPacingc                 ó°   — |                       t                               ¦   «         dt          › �¦  «         t                               d¬¦  «        | _        d S )NzMissing TAP_01 screenplay at r   r   )Ú
assertTrueÚ
TAP01_PATHÚexistsÚ	read_textÚ
screenplay©Úclss    ú<C:\Projects\KieuStory\tests\test_tier5_creative_hardening.pyÚ
setUpClassz2TestTier5F1ScreenplayExpansionAndPacing.setUpClassa   sG   € à�Š•z×(Ò(Ñ*Ô*Ð,XÍJÐ,XÐ,XÑYÔYÐYÝ#×-Ò-°wÐ-Ñ?Ô?ˆŒˆˆó    c                 óJ  — t          j        dt           j        ¦  «        }t          |                     | j        ¦  «        ¦  «        }|                      t          |¦  «        t          dt          › dt          |¦  «        › �¦  «         i }|D ]@}t          | 
                    d¦  «        ¦  «        }|                     |d¦  «        dz   ||<   ŒAt                               ¦   «         D ]<\  }}|                     |d¦  «        }|                      ||d|d›d	|› d
|› �¦  «         Œ=dS )zRF1.1: Assert exact 188 shots across all 15 scenes with matching scene shot quotas.zD#####\s+Shot\s+(\d+):\s+`?(ep01_scene(\d+)_shot(\d+))`?\s+\((\d+)s\)zExpected exactly z shots in TAP_01, found r   r   r   zScene Ú02dz shot count mismatch: expected z, found N)ÚreÚcompileÚ
IGNORECASEÚlistÚfinditerr9   ÚassertEqualÚlenÚTOTAL_EXPECTED_SHOTSÚintÚgroupÚgetÚEXPECTED_SCENE_COUNTSÚitems)ÚselfÚshot_patternÚmatchesÚscene_shotsÚmÚsc_numÚexp_cntÚ
actual_cnts           r<   Ú6test_f1_01_exact_188_shots_and_15_scenes_in_screenplayz^TestTier5F1ScreenplayExpansionAndPacing.test_f1_01_exact_188_shots_and_15_scenes_in_screenplayf   sE  € õ ”zØSÝŒMñ
ô 
ˆõ �|×,Ò,¨T¬_Ñ=Ô=Ñ>Ô>ˆØ×ÒÝ�‰LŒLÕ.Ø\Õ 4Ð\Ð\ÍcÐRYÉlÌlÐ\Ð\ñ	
ô 	
ð 	
ð ˆØð 	Að 	AˆAÝ˜Ÿš ™œ‘_”_ˆFØ"-§/¢/°&¸!Ñ"<Ô"<¸qÑ"@ˆK˜ÑÐå4×:Ò:Ñ<Ô<ð 	ð 	‰OˆF�GØ$Ÿš¨°Ñ3Ô3ˆJØ×ÒØ˜GØa˜ÐaÐaÐaÀGÐaÐaÐU_ÐaÐañô ð ð ð	ð 	r>   c           	      ó(  — t          j        d| j        t           j        ¦  «        }g }t	          dd¦  «        D ]B}t
          |         }t	          d|dz   ¦  «        D ]}|                     d|d›d|d›�¦  «         Œ ŒC|                      ||d¦  «         dS )	zZF1.2: Assert strict contiguous sequencing from ep01_scene01_shot01 to ep01_scene15_shot06.z1#####\s+Shot\s+\d+:\s+`?(ep01_scene\d+_shot\d+)`?r   é   Ú
ep01_scener@   Ú_shotzCScreenplay shot IDs do not match strict sequential contiguous orderN)rA   Úfindallr9   ÚIÚrangerL   ÚappendrF   )rN   Úshot_idsÚexpected_seqÚscÚcntÚshs         r<   Ú.test_f1_02_strict_contiguous_shot_id_numberingzVTestTier5F1ScreenplayExpansionAndPacing.test_f1_02_strict_contiguous_shot_id_numbering€   sÅ   € å”:ÐRÐTXÔTcÕegÔeiÑjÔjˆØˆÝ˜˜2‘,”,ð 	Hð 	HˆBÝ'¨Ô+ˆCÝ˜A˜s Q™wÑ'Ô'ð Hð H�Ø×#Ò#Ð$F°Ð$FÐ$FÐ$F¸bÐ$FÐ$FÐ$FÑGÔGÐGÐGðHð 	×ÒØ�lØRñ	
ô 	
ð 	
ð 	
ð 	
r>   c                 ó”  — t          j        d| j        t           j        ¦  «        }|                      t          |¦  «        dd¦  «         d„ |D ¦   «         }|                      t          |¦  «        dd|› �¦  «         t          d„ |D ¦   «         ¦  «        }|                      |dd	|› d
�¦  «         |                      |dd¦  «         dS )z`F1.3: Assert every single shot specifies exactly (10s), total runtime = 1880s (31m20s >= 1500s).z<#####\s+Shot\s+\d+:\s+`?ep01_scene\d+_shot\d+`?\s+\((\d+)s\)é¼   z+All 188 shots must define explicit durationc                 ó   — g | ]
}|d k    ¯|‘ŒS )Ú10© ©Ú.0Úds     r<   ú
<listcomp>zgTestTier5F1ScreenplayExpansionAndPacing.test_f1_03_duration_invariant_10s_all_shots.<locals>.<listcomp>’   s   € Ð5Ð5Ð5˜¨1°ª9¨9�1¨9¨9¨9r>   r   z*Found shots with duration other than 10s: c              3   ó4   K  — | ]}t          |¦  «        V — Œd S ©N)rI   rj   s     r<   ú	<genexpr>zfTestTier5F1ScreenplayExpansionAndPacing.test_f1_03_duration_invariant_10s_all_shots.<locals>.<genexpr>”   s(   è è € Ð7Ð7¨�S ™VœVÐ7Ð7Ð7Ð7Ð7Ð7r>   iÜ  zTotal duration zs must be >= 1500siX  z/Total runtime must be exactly 1880s (188 x 10s)N)rA   r[   r9   r\   rF   rG   ÚsumÚassertGreaterEqual)rN   Ú	durationsÚnon_10sÚtotal_durations       r<   Ú+test_f1_03_duration_invariant_10s_all_shotszSTestTier5F1ScreenplayExpansionAndPacing.test_f1_03_duration_invariant_10s_all_shotsŽ   s×   € å”JÐ^Ð`dÔ`oÕqsÔquÑvÔvˆ	Ø×Ò�˜Y™œ¨Ð.[Ñ\Ô\Ð\Ø5Ð5˜iÐ5Ñ5Ô5ˆØ×Ò�˜W™œ qÐ*`ÐW^Ð*`Ð*`ÑaÔaÐaÝÐ7Ð7¨YÐ7Ñ7Ô7Ñ7Ô7ˆØ×Ò °Ð6jÈÐ6jÐ6jÐ6jÑkÔkÐkØ×Ò˜¨Ð/aÑbÔbÐbÐbÐbr>   c                 ó"  — |                       | j        dd¦  «         |                       | j        dd¦  «         |                       | j        dd¦  «         t          dd¦  «        D ])}d	|› d
�}|                       | j        |d|d›d�¦  «         Œ*dS )z[F1.4: Assert explicit Act 1, 2, 3 dividers and valid cinematic sluglines for all 15 scenes.u   Há»’I\s*1\bzAct 1 divider missingu   Há»’I\s*2\bzAct 2 divider missingu   Há»’I\s*3\bzAct 3 divider missingr   rX   u   Cáº¢NH\s*0?ú\bzSlugline for Scene r@   z missingN)ÚassertRegexr9   r]   )rN   ra   Úpatterns      r<   Ú5test_f1_04_three_act_structure_and_slugline_integrityz]TestTier5F1ScreenplayExpansionAndPacing.test_f1_04_three_act_structure_and_slugline_integrity˜   s´   € à×Ò˜œ¨.Ð:QÑRÔRÐRØ×Ò˜œ¨.Ð:QÑRÔRÐRØ×Ò˜œ¨.Ð:QÑRÔRÐRå˜˜2‘,”,ð 	_ð 	_ˆBØ+ RÐ+Ð+Ð+ˆGØ×Ò˜Tœ_¨gÐ7]ÈRÐ7]Ð7]Ð7]Ð7]Ñ^Ô^Ð^Ð^ð	_ð 	_r>   c                 óŒ  — t          d„ t          dd¦  «        D ¦   «         ¦  «        }t          d„ t          dd¦  «        D ¦   «         ¦  «        }t          d„ t          dd¦  «        D ¦   «         ¦  «        }|                      |dz  d	d
¦  «         |                      |dz  d	d¦  «         |                      |dz  dd¦  «         dS )zeF1.5: Assert proportional pacing balance across 3 acts (Act 1 >= 500s, Act 2 >= 500s, Act 3 >= 350s).c              3   ó0   K  — | ]}t           |         V — Œd S ro   ©rL   ©rk   Úis     r<   rp   z`TestTier5F1ScreenplayExpansionAndPacing.test_f1_05_pacing_balance_across_acts.<locals>.<genexpr>§   s(   è è € ÐGÐG°aÕ.¨qÔ1ÐGÐGÐGÐGÐGÐGr>   r   r   c              3   ó0   K  — | ]}t           |         V — Œd S ro   r~   r   s     r<   rp   z`TestTier5F1ScreenplayExpansionAndPacing.test_f1_05_pacing_balance_across_acts.<locals>.<genexpr>¨   s(   è è € ÐHÐH°aÕ.¨qÔ1ÐHÐHÐHÐHÐHÐHr>   r   c              3   ó0   K  — | ]}t           |         V — Œd S ro   r~   r   s     r<   rp   z`TestTier5F1ScreenplayExpansionAndPacing.test_f1_05_pacing_balance_across_acts.<locals>.<genexpr>©   s(   è è € ÐIÐI°aÕ.¨qÔ1ÐIÐIÐIÐIÐIÐIr>   rX   r   iô  zAct 1 runtime < 500szAct 2 runtime < 500si^  zAct 3 runtime < 350sN)rq   r]   rr   )rN   Ú
act1_shotsÚ
act2_shotsÚ
act3_shotss       r<   Ú%test_f1_05_pacing_balance_across_actszMTestTier5F1ScreenplayExpansionAndPacing.test_f1_05_pacing_balance_across_acts¢   sÍ   € õ
 ÐGÐG½5ÀÀA¹;¼;ÐGÑGÔGÑGÔGˆ
ÝÐHÐH½5ÀÀB¹<¼<ÐHÑHÔHÑHÔHˆ
ÝÐIÐI½5ÀÀR¹=¼=ÐIÑIÔIÑIÔIˆ
à×Ò 
¨R¡°Ð6LÑMÔMÐMØ×Ò 
¨R¡°Ð6LÑMÔMÐMØ×Ò 
¨R¡°Ð6LÑMÔMÐMÐMÐMr>   N)
Ú__name__Ú
__module__Ú__qualname__Úclassmethodr=   rV   rd   rv   r{   r†   ri   r>   r<   r3   r3   _   s†   € € € € € àð@ð @ñ „[ð@ðð ð ð4
ð 
ð 
ðcð cð cð_ð _ð _ðNð Nð Nð Nð Nr>   r3   c                   óB   — e Zd Zed„ ¦   «         Zd„ Zd„ Zd„ Zd„ Zd„ Z	dS )ÚTestTier5F2DamTienGraveSequencec                 ór  — t                                d¬¦  «        | _        | j                             d¦  «        }| j                             d¦  «        }g }d}| }||k    }|}|rd}| }	||	k    }
|
}|
r||k    }|}|�st	          j        d|fd||f¦  «        dt          j        ¦   «         v st	          j        |¦  «        rt	          j	        |¦  «        ndt	          j	        |¦  «        d	œz  }d
d|iz  }| 
                    |¦  «         |�rCt	          j        d|
fd||	f¦  «        dt          j        ¦   «         v st	          j        |¦  «        rt	          j	        |¦  «        ndt	          j	        |¦  «        dœz  }dd|iz  }| 
                    |¦  «         |
r¶t	          j        d|fd||f¦  «        dt          j        ¦   «         v st	          j        |¦  «        rt	          j	        |¦  «        nddt          j        ¦   «         v st	          j        |¦  «        rt	          j	        |¦  «        nddœz  }dd|iz  }| 
                    |¦  «         t	          j        |d¦  «        i z  }dd|iz  }t          t	          j        |¦  «        ¦  «        ‚d x}x}x}x}x}x}
x}x}	}| j        ||…         | _        d S )Nr   r   õ   #### Cáº¢NH 05:õ   #### Cáº¢NH 06:r   )ú!=)z%(py2)s != -%(py5)sÚ
sc05_start)Úpy2Úpy5z%(py8)sÚpy8)z%(py10)s != -%(py13)sÚ
sc06_start)Úpy10Úpy13z%(py16)sÚpy16)ú>)z%(py18)s > %(py20)s)Úpy18Úpy20z%(py22)sÚpy22r   zassert %(py25)sÚpy25)r6   r8   r9   ÚfindÚ
@pytest_arÚ_call_reprcompareÚ@py_builtinsÚlocalsÚ_should_repr_global_nameÚ	_safereprr^   Ú_format_boolopÚAssertionErrorÚ_format_explanationÚ	sc05_text)r;   r‘   r•   Ú@py_assert1Ú@py_assert4Ú@py_assert6Ú@py_assert3Ú@py_assert0Ú@py_assert12Ú@py_assert14Ú@py_assert11Ú@py_assert19Ú@py_format7Ú@py_format9Ú@py_format15Ú@py_format17Ú@py_format21Ú@py_format23Ú@py_format24Ú@py_format26s                       r<   r=   z*TestTier5F2DamTienGraveSequence.setUpClassµ   sA  € å#×-Ò-°wÐ-Ñ?Ô?ˆŒØ”^×(Ò(Ð):Ñ;Ô;ˆ
Ø”^×(Ò(Ð):Ñ;Ô;ˆ
ØPÐP˜aÐP˜a˜RÐPˆz˜RÒÐPÐPÐPÐPÐP°1ÐP°1°"ÐP J°"Ò$4ÐPÐPÐPÐPÐP¸ÀjÒ9PÐPÐPÐPÐPÑPÕPÔPÐPÐPÐPÐPˆz˜RÐPÑPÔPÐPÕPÔPÑPÔPÐPÐPÕPÔPˆzÑPÔPÐPÕPÔPˆzÑPÔPÐPÐPÕPÔP˜aÑPÔPÐPÐPÑPÐPÐPÐPÐPÐPÑPÐPÐP×PÒPÐPÑPÔPÐPÐPÑPÕPÔPÐPÐPÐPÐP J°"ÐPÑPÔPÐPÕPÔPÑPÔPÐPÐPÕPÔP JÑPÔPÐPÕPÔP JÑPÔPÐPÐPÕPÔP°1ÑPÔPÐPÐPÑPÐPÐPÐPÐPÐPÑPÐPÐP×PÒPÐPÑPÔPÐPÐPÐPÕPÔPÐPÐPÐPÐP¸ÀjÐPÑPÔPÐPÕPÔPÑPÔPÐPÐPÕPÔP¸ÑPÔPÐPÕPÔP¸ÑPÔPÐPÐPÐPÕPÔPÑPÔPÐPÐPÕPÔPÀjÑPÔPÐPÕPÔPÀjÑPÔPÐPÐPÐPÐPÑPÐPÐPÐPÐPÐPÑPÐPÐP×PÒPÐPÑPÔPÐPÕPÔPÐPÐPÑPÔPÐPÑPÐPÐPÐPÐPÐPÑPÐPÕPÕPÔPÐPÑPÔPÑPÔPÐPÐPÐPÐPÐPÐPÐPÐPÐPÐPÐPÐPÐPÐPÐPÐPÐPÐPÐPØœ z°*Ð'<Ô=ˆŒˆˆr>   c                 óÂ  — | j                              d¦  «        }| j                              d¦  «        }| j                              d¦  «        }|                      |dk    o|dk    o|dk    d¦  «         |                      ||cxk     o|k     nc d¦  «         | j         ||…         }| j         ||…         }| j         |d…         }t          j        d|¦  «        }t          j        d|¦  «        }t          j        d|¦  «        }	t          t          t          |¦  «        ¦  «        ¦  «        }
t          t          t          |¦  «        ¦  «        ¦  «        }t          t          t          |	¦  «        ¦  «        ¦  «        }|                      t          |
¦  «        d	d
t          |
¦  «        › �¦  «         |                      t          |¦  «        ddt          |¦  «        › �¦  «         |                      t          |¦  «        ddt          |¦  «        › �¦  «         |                      t          |
¦  «        t          |¦  «        z   t          |¦  «        z   d¦  «         dS )z]F2.1: Assert Scene 05 is partitioned into C05-A (8 shots), C05-B (7 shots), C05-C (12 shots).õ   PHÃ‚N Ä�Oáº N 05-Aõ   PHÃ‚N Ä�Oáº N 05-Bõ   PHÃ‚N Ä�Oáº N 05-Céÿÿÿÿz"3-beat headers missing in Scene 05z8Beat headers must follow chronological order A -> B -> CNzep01_scene05_shot\d+r   z*Beat C05-A must have 8 shots (01-08), got r   z*Beat C05-B must have 7 shots (09-15), got r   z+Beat C05-C must have 12 shots (16-27), got r   )
r¨   rž   r5   rA   r[   ÚsortedrD   ÚsetrF   rG   )rN   Úpos_aÚpos_bÚpos_cÚtext_aÚtext_bÚtext_cÚshots_aÚshots_bÚshots_cÚunique_aÚunique_bÚunique_cs                r<   Ú/test_f2_01_three_beat_partition_shot_allocationzOTestTier5F2DamTienGraveSequence.test_f2_01_three_beat_partition_shot_allocation½   s$  € à”×#Ò#Ð$8Ñ9Ô9ˆØ”×#Ò#Ð$8Ñ9Ô9ˆØ”×#Ò#Ð$8Ñ9Ô9ˆØ�Š˜ šÐC¨°ªÐC¸ÀºÐEiÑjÔjÐjØ�Š˜ Ð-Ð-Ò-Ð-¨Ò-Ð-Ð-Ð-Ð/iÑjÔjÐjà”  e Ô,ˆØ”  e Ô,ˆØ”   Ô'ˆå”*Ð4°fÑ=Ô=ˆÝ”*Ð4°fÑ=Ô=ˆÝ”*Ð4°fÑ=Ô=ˆõ �$�s 7™|œ|Ñ,Ô,Ñ-Ô-ˆÝ�$�s 7™|œ|Ñ,Ô,Ñ-Ô-ˆÝ�$�s 7™|œ|Ñ,Ô,Ñ-Ô-ˆà×Ò�˜X™œ¨Ð+gÕX[Ð\dÑXeÔXeÐ+gÐ+gÑhÔhÐhØ×Ò�˜X™œ¨Ð+gÕX[Ð\dÑXeÔXeÐ+gÐ+gÑhÔhÐhØ×Ò�˜X™œ¨Ð,iÕZ]Ð^fÑZgÔZgÐ,iÐ,iÑjÔjÐjØ×Ò�˜X™œ­¨X©¬Ñ6½¸X¹¼ÑFÈÑKÔKÐKÐKÐKr>   c                 ó¶  ‡
— | j                              d¦  «        }| j                              d¦  «        }| j                              d¦  «        }| j         ||…         }| j         ||…         }g d¢}|D �]}|                     ¦   «         D ]rŠ
d‰
v rlt          j        dt          j        |¦  «        z   dz   ‰
t          j        ¦  «        r4t          ˆ
fd„dD ¦   «         ¦  «        s|                      d	‰
› d
�¦  «         Œs|                     ¦   «         D ]rŠ
d‰
v rlt          j        dt          j        |¦  «        z   dz   ‰
t          j        ¦  «        r4t          ˆ
fd„dD ¦   «         ¦  «        s|                      d‰
› d
�¦  «         Œs�Œ| j         |d…         }t          t          j        d|t          j        ¦  «        ¦  «        }	|  
                    |	d¦  «         dS )u_   F2.2: Assert ThÃºy Kiá»�u does NOT weep in Beat A (stroll) or Beat B (inquiry), only in Beat C.r»   r¼   r½   )r$   r'   r#   r&   u   nÆ°á»›c máº¯t giÃ n giá»¥aõ   Kiá»�urx   c              3   óD   •K  — | ]}|‰                      ¦   «         v V — Œd S ro   ©Úlower©rk   ÚnegÚlines     €r<   rp   zeTestTier5F2DamTienGraveSequence.test_f2_02_anti_premature_weeping_in_beats_a_and_b.<locals>.<genexpr>ä   ó0   øè è € ÐmÐm°s˜s d§j¢j¡l¤lÐ2ÐmÐmÐmÐmÐmÐmr>   )u   chÆ°a khÃ³cõ   khÃ´ng khÃ³cõ   khÃ´ng rÆ¡iz+Premature weeping detected in Beat C05-A: 'ú'c              3   óD   •K  — | ]}|‰                      ¦   «         v V — Œd S ro   rÑ   rÓ   s     €r<   rp   zeTestTier5F2DamTienGraveSequence.test_f2_02_anti_premature_weeping_in_beats_a_and_b.<locals>.<genexpr>è   rÖ   r>   z+Premature weeping detected in Beat C05-B: 'Nu*   (?:nÆ°á»›c máº¯t|rÆ¡i lá»‡|khÃ³c|chÃ¢u sa)uA   Beat C05-C must contain Kiá»�u's grief and tears for Ä�áº¡m TiÃªn)r¨   rž   Ú
splitlinesrA   ÚsearchÚescaper\   ÚanyÚfailÚboolr5   )rN   rÁ   rÂ   rÃ   rÄ   rÅ   Úweep_kwsÚkwrÆ   Úhas_c_weepingrÕ   s             @r<   Ú2test_f2_02_anti_premature_weeping_in_beats_a_and_bzRTestTier5F2DamTienGraveSequence.test_f2_02_anti_premature_weeping_in_beats_a_and_b×   s  ø€ à”×#Ò#Ð$8Ñ9Ô9ˆØ”×#Ò#Ð$8Ñ9Ô9ˆØ”×#Ò#Ð$8Ñ9Ô9ˆà”  e Ô,ˆØ”  e Ô,ˆàiÐiÐiˆØð 	Yñ 	YˆBØ×)Ò)Ñ+Ô+ð Yð Y�Ø˜tÐ#Ð#­¬	°%½"¼)ÀB¹-¼-Ñ2GÈ%Ñ2OÐQUÕWYÔW[Ñ(\Ô(\Ð#ÝÐmÐmÐmÐmÐ>lÐmÑmÔmÑmÔmð YØŸ	š	Ð"WÐPTÐ"WÐ"WÐ"WÑXÔXÐXøØ×)Ò)Ñ+Ô+ð Yð Y�Ø˜tÐ#Ð#­¬	°%½"¼)ÀB¹-¼-Ñ2GÈ%Ñ2OÐQUÕWYÔW[Ñ(\Ô(\Ð#ÝÐmÐmÐmÐmÐ>lÐmÑmÔmÑmÔmð YØŸ	š	Ð"WÐPTÐ"WÐ"WÐ"WÑXÔXÐXøñYð
 ”   Ô'ˆÝ�RœYÐ'TÐV\Õ^`Ô^bÑcÔcÑdÔdˆØ�Š˜Ð'jÑkÔkÐkÐkÐkr>   c           
      óN  — | j                              ¦   «         }t          |d¦  «        D ]z\  }}d|v sd|v rmdD ]j}|                      t	          j        dt	          j        |¦  «        z   dz   |t          j        ¦  «        od|                     ¦   «         vd|› d|› �¦  «         ŒkŒ{d	S )
u_   F2.3: Assert VÆ°Æ¡ng Quan remains 100% stoic without tears throughout all 27 shots of Scene 05.r   r    r!   )r$   r'   r*   r(   r&   rx   õ   khÃ´ngu.   VÆ°Æ¡ng Quan breaks stoicism in Scene 05 line ú: N)	r¨   rÛ   Ú	enumerateÚassertFalserA   rÜ   rÝ   r\   rÒ   )rN   ÚlinesÚidxrÕ   râ   s        r<   Ú4test_f2_03_vuong_quan_stoic_accompaniment_in_scene05zTTestTier5F2DamTienGraveSequence.test_f2_03_vuong_quan_stoic_accompaniment_in_scene05ï   sÏ   € à”×)Ò)Ñ+Ô+ˆÝ" 5¨!Ñ,Ô,ð 	ð 	‰IˆC�Ø Ð%Ð%¨¸4Ð)?Ð)?Øgð ð �BØ×$Ò$Ýœ	 %­"¬)°B©-¬-Ñ"7¸%Ñ"?ÀÅrÄtÑLÔLÐmÐQYÐae×akÒakÑamÔamÐQmØVÈÐVÐVÐPTÐVÐVñô ð ð øð	ð 	r>   c                 óN  — t          j        d| j        t           j        ¦  «        }t          j        d| j        t           j        ¦  «        }t          j        d| j        t           j        ¦  «        }|                      |¦  «         |                      |¦  «         |                      |¦  «         |                      |                     ¦   «         |                     ¦   «         d¦  «         |                      |                     ¦   «         |                     ¦   «         d¦  «         dS )z[F2.4: Assert narrative beats follow strict chronological order: stroll -> inquiry -> grief.u-   (tiá»ƒu khÃª|suá»‘i nhá»�|bÆ°á»›c láº§n theo)u0   (sÃ¨ sÃ¨ náº¥m Ä‘áº¥t|hÆ°Æ¡ng khÃ³i váº¯ng tanh)uF   (Ä‘au Ä‘á»›n thay pháº­n Ä‘Ã n bÃ |báº¡c má»‡nh cÅ©ng lÃ  lá»�i chung)z Stroll beat must precede inquiryzInquiry beat must precede griefN)rA   rÜ   r¨   r\   ÚassertIsNotNoneÚ
assertLessÚstart)rN   Ú
pos_strollÚpos_inquiryÚ	pos_griefs       r<   Ú-test_f2_04_strict_chronological_beat_orderingzMTestTier5F2DamTienGraveSequence.test_f2_04_strict_chronological_beat_orderingú   sô   € å”YÐOÐQUÔQ_ÕacÔaeÑfÔfˆ
Ý”iÐ SÐUYÔUcÕegÔeiÑjÔjˆÝ”IÐgÐimÔiwÕy{Ôy}Ñ~Ô~ˆ	à×Ò˜ZÑ(Ô(Ð(Ø×Ò˜[Ñ)Ô)Ð)Ø×Ò˜YÑ'Ô'Ð'Ø�Š˜
×(Ò(Ñ*Ô*¨K×,=Ò,=Ñ,?Ô,?ÐAcÑdÔdÐdØ�Š˜×)Ò)Ñ+Ô+¨Y¯_ª_Ñ->Ô->Ð@aÑbÔbÐbÐbÐbr>   c           	      óz  — | j                              d¦  «        }| j         d|…         }| j         |d…         }|                      t          t	          j        d|t          j        ¦  «        ¦  «        d¦  «         |                      t          t	          j        d|t          j        ¦  «        ¦  «        d¦  «         dS )u`   F2.5: Assert supernatural footprints in moss ('dáº¥u hÃ i in rÃªu') occur exclusively in Beat C.r½   Nu   (dáº¥u hÃ i|dáº¥u giÃ y).*rÃªuz:Supernatural footprints appeared prematurely before Beat Cz3Beat C must feature supernatural footprints in moss)r¨   rž   ré   rà   rA   rÜ   r\   r5   )rN   rÃ   Útext_before_crÆ   s       r<   Ú8test_f2_05_supernatural_manifestation_confined_to_beat_czXTestTier5F2DamTienGraveSequence.test_f2_05_supernatural_manifestation_confined_to_beat_c  s°   € à”×#Ò#Ð$8Ñ9Ô9ˆØœ v¨ vÔ.ˆØ”   Ô'ˆà×ÒÝ•”Ð<¸mÍRÌTÑRÔRÑSÔSØHñ	
ô 	
ð 	
ð 	�ŠÝ•”Ð<¸fÅbÄdÑKÔKÑLÔLØAñ	
ô 	
ð 	
ð 	
ð 	
r>   N)
r‡   rˆ   r‰   rŠ   r=   rÍ   rä   rì   rô   r÷   ri   r>   r<   rŒ   rŒ   ³   s�   € € € € € àð>ð >ñ „[ð>ðLð Lð Lð4lð lð lð0	ð 	ð 	ð
cð 
cð 
cð
ð 
ð 
ð 
ð 
r>   rŒ   c                   óB   — e Zd Zed„ ¦   «         Zd„ Zd„ Zd„ Zd„ Zd„ Z	dS )Ú#TestTier5F3AntiMaleTearsScriptPurgec                 ó‚   — t                                d¬¦  «        | _        | j                             ¦   «         | _        d S )Nr   r   )r6   r8   r9   rÛ   rê   r:   s    r<   r=   z.TestTier5F3AntiMaleTearsScriptPurge.setUpClass  s3   € å#×-Ò-°wÐ-Ñ?Ô?ˆŒØ”N×-Ò-Ñ/Ô/ˆŒ	ˆ	ˆ	r>   c           	      ó   ‡‡— g }t          | j        d¦  «        D ]¼\  }Št          D ]¯}|‰v r©t          D ]¡}t	          j        dt	          j        |¦  «        z   dz   ‰t          j        ¦  «        rg‰                     ¦   «         Št          ˆfd„dD ¦   «         ¦  «        }t          ˆfd„dD ¦   «         ¦  «        }|s|s| 
                    |||‰f¦  «         Œ¢Œ°Œ½|                      t          |¦  «        dd|› �¦  «         d	S )
zSF3.1: Zero active crying/weeping cues across all 188 shots for all male characters.r   rx   c              3   ó    •K  — | ]}|‰v V — Œ	d S ro   ri   )rk   rÔ   Ú
line_lowers     €r<   rp   zjTestTier5F3AntiMaleTearsScriptPurge.test_f3_01_zero_active_male_crying_in_all_188_shots.<locals>.<genexpr>*  s8   øè è € ð -ð -À3¨S°JÐ->ð -ð -ð -ð -ð -ð -r>   )
u   tuyá»‡t Ä‘á»‘i khÃ´ngrØ   r×   u   khÃ´ng cÃ³ biá»ƒu hiá»‡nz0%u   rÃ¡o hoáº£nhúanti-male-tearsu	   khÃ´ rÃ¡ou   cáº¯n rÄƒngõ   nÃ©nc              3   ó    •K  — | ]}|‰v V — Œ	d S ro   ri   )rk   ÚfemrÕ   s     €r<   rp   zjTestTier5F3AntiMaleTearsScriptPurge.test_f3_01_zero_active_male_crying_in_all_188_shots.<locals>.<genexpr>/  s'   øè è € Ð3~Ð3~ÀC°C¸4°KÐ3~Ð3~Ð3~Ð3~Ð3~Ð3~r>   )rÏ   u   ThÃºy Kiá»�uu   nÃ ngu   VÆ°Æ¡ng BÃ r   z2Detected active male crying violations in TAP_01: N)rè   rê   ÚMALE_CHARACTERSÚWEEPING_KEYWORDSrA   rÜ   rÝ   r\   rÒ   rÞ   r^   rF   rG   )	rN   Ú
violationsrë   rR   râ   Ú
is_negatedÚis_female_subjectrÕ   rý   s	          @@r<   Ú3test_f3_01_zero_active_male_crying_in_all_188_shotszWTestTier5F3AntiMaleTearsScriptPurge.test_f3_01_zero_active_male_crying_in_all_188_shots   s\  øø€ àˆ
Ý" 4¤:¨qÑ1Ô1ð 	Fð 	F‰IˆC�Ý$ð Fð F�Ø˜�9�9Ý.ð Fð F˜Ýœ9 U­R¬Y°r©]¬]Ñ%:¸UÑ%BÀDÍ"Ì$ÑOÔOð 
Fà)-¯ª©¬˜JÝ),ð -ð -ð -ð -ð Kð -ñ -ô -ñ *ô *˜Jõ
 14Ð3~Ð3~Ð3~Ð3~ÐK}Ð3~Ñ3~Ô3~Ñ0~Ô0~Ð-Ø#-ð FÐ6Gð FØ *× 1Ò 1°3¸¸2¸tÐ2DÑ EÔ EÐ EøøðFð 	×ÒÝ�
‰OŒO˜QØMÀÐMÐMñ	
ô 	
ð 	
ð 	
ð 	
r>   c                 ó¬  — | j                              d¦  «        }| j                              d¦  «        }| j         ||…         }|                     ¦   «         }t          |d¦  «        D ]k\  }}d|v rbdD ]_}||                     ¦   «         v rGd|                     ¦   «         vr1d|                     ¦   «         vr|                      d|› d	|› �¦  «         Œ`Œld
S )uY   F3.2: Verify Kim Trá»�ng maintains feudal stoicism without tears during parting Scene 11.u   #### Cáº¢NH 11:u   #### Cáº¢NH 12:r   r   )r$   r'   r#   ræ   rþ   u-   Kim Trá»�ng breaks stoicism in Scene 11 line rç   N©r9   rž   rÛ   rè   rÒ   rß   )rN   Ú
sc11_startÚ
sc12_startÚ	sc11_textrê   rë   rÕ   râ   s           r<   Ú-test_f3_02_kim_trong_parting_stoicism_scene11zQTestTier5F3AntiMaleTearsScriptPurge.test_f3_02_kim_trong_parting_stoicism_scene118  sû   € à”_×)Ò)Ð*;Ñ<Ô<ˆ
Ø”_×)Ò)Ð*;Ñ<Ô<ˆ
Ø”O J¨zÐ$9Ô:ˆ	à×$Ò$Ñ&Ô&ˆÝ" 5¨!Ñ,Ô,ð 	að 	a‰IˆC�Ø Ð$Ð$ØFð að a�BØ˜TŸZšZ™\œ\Ð)Ð)¨h¸d¿jºj¹l¼lÐ.JÐ.JÐO`Ðhl×hrÒhrÑhtÔhtÐOtÐOtØŸ	š	Ð"_ÐRUÐ"_Ð"_ÐY]Ð"_Ð"_Ñ`Ô`Ð`øøð		að 	ar>   c           
      óº  — | j                              d¦  «        }| j                              d¦  «        }| j         ||…         }|                     ¦   «         }t          |d¦  «        D ]r\  }}dD ]j}||v rddD ]a}||                     ¦   «         v rId|                     ¦   «         vr3d|                     ¦   «         vr|                      |› d|› d	|› �¦  «         ŒbŒkŒsd
S )ui   F3.3: Verify VÆ°Æ¡ng Quan and VÆ°Æ¡ng Ã”ng under torture/chains in Scenes 13 & 14 maintain stoic dignity.u   #### Cáº¢NH 13:õ   #### Cáº¢NH 15:r   )r"   r    )r)   r+   r(   r,   r*   ræ   rþ   z3 breaks feudal stoic dignity in arrest scenes line rç   Nr	  )	rN   Ú
sc13_startÚ
sc15_startÚsc13_14_textrê   rë   rÕ   rR   râ   s	            r<   Ú?test_f3_03_vuong_quan_and_vuong_ong_arrest_stoicism_scenes13_14zcTestTier5F3AntiMaleTearsScriptPurge.test_f3_03_vuong_quan_and_vuong_ong_arrest_stoicism_scenes13_14E  s  € à”_×)Ò)Ð*;Ñ<Ô<ˆ
Ø”_×)Ò)Ð*;Ñ<Ô<ˆ
Ø” z°*Ð'<Ô=ˆà×'Ò'Ñ)Ô)ˆÝ" 5¨!Ñ,Ô,ð 	nð 	n‰IˆC�Ø5ð nð n�Ø˜�9�9Øhð nð n˜Ø §¢¡¤Ð-Ð-°(À$Ç*Â*Á,Ä,Ð2NÐ2NÐSdÐlp×lvÒlvÑlxÔlxÐSxÐSxØ ŸIšI¨Ð&lÐ&lÐ_bÐ&lÐ&lÐfjÐ&lÐ&lÑmÔmÐmøøð	nð	nð 	nr>   c                 óz  — d| j         | j                              d¦  «        | j                              d¦  «        …                              ¦   «         v }d| j         | j                              d¦  «        d…                              ¦   «         v }|                      |d¦  «         |                      |d¦  «         dS )	z[F3.4: Verify female crying is permitted and present in grief scenes (Scene 05, 11, 14, 15).r$   rŽ   r�   r%   r  Nu,   Kiá»�u weeping must be present in Scene 05-Cu*   Kiá»�u weeping must be present in Scene 15)r9   rž   rÒ   r5   )rN   Ú	sc05_weepÚ	sc15_weeps      r<   Ú.test_f3_04_female_crying_distinction_permittedzRTestTier5F3AntiMaleTearsScriptPurge.test_f3_04_female_crying_distinction_permittedS  sÍ   € à 4¤?°4´?×3GÒ3GÐHYÑ3ZÔ3ZÐ[_Ô[j×[oÒ[oð  qBñ  \Cô  \Cð  4Cô  $D÷  $Jò  $Jñ  $Lô  $Lð  Lˆ	Ø! T¤_°T´_×5IÒ5IÐJ[Ñ5\Ô5\Ð5]Ð5]Ô%^×%dÒ%dÑ%fÔ%fÐfˆ	Ø�Š˜	Ð#QÑRÔRÐRØ�Š˜	Ð#OÑPÔPÐPÐPÐPr>   c                 ób  — d| j                              ¦   «         v pd| j                              ¦   «         v }d| j                              ¦   «         v }d| j                              ¦   «         v }|                      |d¦  «         |                      |d¦  «         |                      |d¦  «         dS )	uq   F3.5: Verify presence of codified stoic expressions (cÆ¡ máº·t Ä‘anh, quai hÃ m báº¡nh, Ã¡nh máº¯t trÄ©u náº·ng).u   quai hÃ m báº¡nhu   hÃ m báº¡nhu   trÄ©u náº·ngrÿ   z.Screenplay must contain jaw clench expressionsz.Screenplay must contain heavy gaze expressionsz5Screenplay must contain compressed breath expressionsN)r9   rÒ   r5   )rN   Ú
has_clenchÚ	has_heavyÚ
has_breaths       r<   Ú2test_f3_05_feudal_stoic_micro_expressions_presencezVTestTier5F3AntiMaleTearsScriptPurge.test_f3_05_feudal_stoic_micro_expressions_presenceZ  s©   € à'¨4¬?×+@Ò+@Ñ+BÔ+BÐBÐnÀmÐW[ÔWf×WlÒWlÑWnÔWnÐFnˆ
Ø" d¤o×&;Ò&;Ñ&=Ô&=Ð=ˆ	Ø˜tœ×4Ò4Ñ6Ô6Ð6ˆ
Ø�Š˜
Ð$TÑUÔUÐUØ�Š˜	Ð#SÑTÔTÐTØ�Š˜
Ð$[Ñ\Ô\Ð\Ð\Ð\r>   N)
r‡   rˆ   r‰   rŠ   r=   r  r  r  r  r  ri   r>   r<   rù   rù     s†   € € € € € àð0ð 0ñ „[ð0ð
ð 
ð 
ð0að að aðnð nð nðQð Qð Qð]ð ]ð ]ð ]ð ]r>   rù   c                   óB   — e Zd Zed„ ¦   «         Zd„ Zd„ Zd„ Zd„ Zd„ Z	dS )Ú/TestTier5F4CharacterAndActingDirectivesInBiblesc                 óJ  — t           j        } |¦   «         }|s•ddt          j        ¦   «         v st	          j        t           ¦  «        rt	          j        t           ¦  «        ndt	          j        |¦  «        t	          j        |¦  «        dœz  }t          t	          j        |¦  «        ¦  «        ‚d x}}t          j        } |¦   «         }|s•ddt          j        ¦   «         v st	          j        t          ¦  «        rt	          j        t          ¦  «        ndt	          j        |¦  «        t	          j        |¦  «        dœz  }t          t	          j        |¦  «        ¦  «        ‚d x}}t            
                    d¬¦  «        | _        t           
                    d¬¦  «        | _        d S )NúAassert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}ÚCHAR_BIBLE_PATH©Úpy0r’   Úpy4ÚACTING_DIRECTIVES_PATHr   r   )r!  r7   r¡   r¢   rŸ   r£   r¤   r¦   r§   r%  r8   Ú
char_bibleÚacting_directives©r;   r©   r¬   Ú@py_format5s       r<   r=   z:TestTier5F4CharacterAndActingDirectivesInBibles.setUpClassi  s“  € åÔ%Ð'Ð%Ð%Ñ'Ô'Ð'Ð'Ð'Ð'Ð'Õ'Ô'Ñ'Ô'Ð'Ð'Õ'Ô'�Ñ'Ô'Ð'Õ'Ô'�Ñ'Ô'Ð'Ð'Õ'Ô'Ð%Ñ'Ô'Õ'Ô'Ð'Ñ'Ô'Ð'Ð'Ñ'Ð'Õ'Õ'Ô'Ð'Ñ'Ô'Ñ'Ô'Ð'Ð'Ð'Ð'Ð'Ý%Ô,Ð.Ð,Ð,Ñ.Ô.Ð.Ð.Ð.Ð.Ð.Õ.Ô.Ñ.Ô.Ð.Ð.Õ.Ô.Õ%Ñ.Ô.Ð.Õ.Ô.Õ%Ñ.Ô.Ð.Ð.Õ.Ô.Ð,Ñ.Ô.Õ.Ô.Ð.Ñ.Ô.Ð.Ð.Ñ.Ð.Õ.Õ.Ô.Ð.Ñ.Ô.Ñ.Ô.Ð.Ð.Ð.Ð.Ð.Ý(×2Ò2¸GÐ2ÑDÔDˆŒÝ 6× @Ò @È'Ð @Ñ RÔ RˆÔÐÐr>   c           	      óÆ   — |                       d| j        ¦  «         |                      t          t	          j        d| j        t          j        ¦  «        ¦  «        ¦  «         dS )zLF4.1: Assert Anti-Male-Tears directive codified across both bible documents.zANTI-MALE-TEARS DIRECTIVEu)   Nam nhÃ¢n tuyá»‡t Ä‘á»‘i khÃ´ng rÆ¡i lá»‡N)ÚassertInr'  r5   rà   rA   rÜ   r\   ©rN   s    r<   Ú1test_f4_01_anti_male_tears_codification_in_bibleszaTestTier5F4CharacterAndActingDirectivesInBibles.test_f4_01_anti_male_tears_codification_in_biblesp  sQ   € à�ŠÐ1°4Ô3IÑJÔJÐJØ�Š��RœYÐ'SÐUYÔUkÕmoÔmqÑrÔrÑsÔsÑtÔtÐtÐtÐtr>   c                 óF   — dD ]}|                       || j        ¦  «         ŒdS )zJF4.2: Assert 4 male stoic micro-expressions codified in Acting Directives.)z
Jaw ClenchzHeavy Downward GazezDistant StarezDeep Compressed BreathN©r+  r'  )rN   Úterms     r<   Ú.test_f4_02_male_stoic_micro_expressions_matrixz^TestTier5F4CharacterAndActingDirectivesInBibles.test_f4_02_male_stoic_micro_expressions_matrixu  s5   € àdð 	8ð 	8ˆDØ�MŠM˜$ Ô 6Ñ7Ô7Ð7Ð7ð	8ð 	8r>   c                 ó  — |                       d| j        ¦  «         |                       d| j        ¦  «         |                       d| j        ¦  «         |                       d| j        ¦  «         |                       d| j        ¦  «         dS )uK   F4.3: Assert Kiá»�u-VÃ¢n 4-axis twin matrix codified in CHARACTER_BIBLE.md.uE   MA TRáº¬N Ä�á»�I CHIáº¾U 4 TRá»¤C SONG SINH THÃšY KIá»€U & THÃšY VÃ‚Nu   1. Tháº§n ThÃ¡i (Aura)u   2. TÃ­nh CÃ¡ch (Personality)u/   3. TrÃ­ Tuá»‡ & TÃ i NÄƒng (Intellect & Talent)u   4. Giá»�ng NÃ³i (Voice Timbre)N)r+  r&  r,  s    r<   Ú5test_f4_03_kieu_van_4_axis_twin_dynamics_codificationzeTestTier5F4CharacterAndActingDirectivesInBibles.test_f4_03_kieu_van_4_axis_twin_dynamics_codificationz  s}   € à�ŠÐ]Ð_cÔ_nÑoÔoÐoØ�ŠÐ.°´Ñ@Ô@Ð@Ø�ŠÐ4°d´oÑFÔFÐFØ�ŠÐGÈÌÑYÔYÐYØ�ŠÐ6¸¼ÑHÔHÐHÐHÐHr>   c                 óÚ  — |                       d| j        ¦  «         |                       d| j                             ¦   «         ¦  «         |                       d| j                             ¦   «         ¦  «         |                       d| j                             ¦   «         ¦  «         |                       d| j                             ¦   «         ¦  «         |                       d| j        ¦  «         dS )zWF4.4: Assert Sai Nha costume and 0% Western/modern gear codified in CHARACTER_BIBLE.md.u^   LÃ­nh Sai Nha (LÃ­nh Lá»‡ Nha MÃ´n Trung Cá»• - Tuyá»‡t Ä�á»‘i Thuáº§n Ã� Ä�Ã´ng & Cá»• Phong)u    nÃ³n dáº¥u sÆ¡n son chÃ³p nhá»�nu   gáº­y son bá»‹t Ä‘á»“ngu   xÃ­ch sáº¯t rá»‰ sÃ©tu#   Ã¡o cháº½n náº¹p váº¡t lÃ­nh trÃ¡ngu,   0% QuÃ¢n phá»¥c & Phá»¥ kiá»‡n hiá»‡n Ä‘áº¡iN)r+  r&  rÒ   r,  s    r<   Ú8test_f4_04_sai_nha_pure_east_asian_medieval_codificationzhTestTier5F4CharacterAndActingDirectivesInBibles.test_f4_04_sai_nha_pure_east_asian_medieval_codification‚  sÑ   € à�ŠÐvÐx|ô  yHñ  	Iô  	Ið  	IØ�ŠÐ8¸$¼/×:OÒ:OÑ:QÔ:QÑRÔRÐRØ�ŠÐ/°´×1FÒ1FÑ1HÔ1HÑIÔIÐIØ�ŠÐ-¨t¬×/DÒ/DÑ/FÔ/FÑGÔGÐGØ�ŠÐ;¸T¼_×=RÒ=RÑ=TÔ=TÑUÔUÐUØ�ŠÐDÀdÄoÑVÔVÐVÐVÐVr>   c                 ór   — |                       d| j        ¦  «         |                       d| j        ¦  «         dS )zVF4.5: Assert _v<N> naming and closed-lips clause syntax codified in acting directives.z	_v<N>.mp4ux   [KHÃ“A KHáº¨U HÃŒNH Báº®T BUá»˜C]: Ä�Ã´i mÃ´i nhÃ¢n váº­t trong khung hÃ¬nh khÃ©p cháº·t tá»± nhiÃªn, khÃ´ng máº¥p mÃ¡y.Nr/  r,  s    r<   Ú8test_f4_05_video_versioning_and_closed_lips_codificationzhTestTier5F4CharacterAndActingDirectivesInBibles.test_f4_05_video_versioning_and_closed_lips_codification‹  sR   € à�Š�k 4Ô#9Ñ:Ô:Ð:Ø�Šð  Qð  SWô  Siñ  	jô  	jð  	jð  	jð  	jr>   N)
r‡   rˆ   r‰   rŠ   r=   r-  r1  r3  r5  r7  ri   r>   r<   r  r  g  s‰   € € € € € àðSð Sñ „[ðSðuð uð uð
8ð 8ð 8ð
Ið Ið IðWð Wð Wðjð jð jð jð jr>   r  c                   óB   — e Zd Zed„ ¦   «         Zd„ Zd„ Zd„ Zd„ Zd„ Z	dS )Ú&TestTier5F5SweetSpotStartFrameProtocolc                 ó  — t           j        } |¦   «         }|s•ddt          j        ¦   «         v st	          j        t           ¦  «        rt	          j        t           ¦  «        ndt	          j        |¦  «        t	          j        |¦  «        dœz  }t          t	          j        |¦  «        ¦  «        ‚d x}}t          j
        t                                d¬¦  «        ¦  «        | _        | j                             di ¦  «        | _        d S )Nr   ÚBANANA_JSON_PATHr"  r   r   Úep01_start_frames)r;  r7   r¡   r¢   rŸ   r£   r¤   r¦   r§   ÚjsonÚloadsr8   Úbanana_datarK   Ú	banana_sfr(  s       r<   r=   z1TestTier5F5SweetSpotStartFrameProtocol.setUpClass–  sñ   € åÔ&Ð(Ð&Ð&Ñ(Ô(Ð(Ð(Ð(Ð(Ð(Õ(Ô(Ñ(Ô(Ð(Ð(Õ(Ô(ÕÑ(Ô(Ð(Õ(Ô(ÕÑ(Ô(Ð(Ð(Õ(Ô(Ð&Ñ(Ô(Õ(Ô(Ð(Ñ(Ô(Ð(Ð(Ñ(Ð(Õ(Õ(Ô(Ð(Ñ(Ô(Ñ(Ô(Ð(Ð(Ð(Ð(Ð(Ýœ*Õ%5×%?Ò%?ÈÐ%?Ñ%QÔ%QÑRÔRˆŒØœ×+Ò+Ð,?ÀÑDÔDˆŒˆˆr>   c                 ól  — |                       t          | j        ¦  «        d¦  «         g }| j                             ¦   «         D ]H\  }}|                     d¦  «        dk    r*|                     ||                     d¦  «        f¦  «         ŒI|                       t          |¦  «        dd|› �¦  «         dS )zTF5.1: Assert 100% of EP01 start frames specify exact sweet-spot 1280x720 resolution.rf   Ú
resolutionÚ1280x720r   zShots with invalid resolution: N)rF   rG   r@  rM   rK   r^   )rN   Úinvalid_resÚkÚvs       r<   Ú:test_f5_01_gemini_banana_resolution_1280x720_all_188_shotszaTestTier5F5SweetSpotStartFrameProtocol.test_f5_01_gemini_banana_resolution_1280x720_all_188_shotsœ  sµ   € à×Ò�˜Tœ^Ñ,Ô,¨cÑ2Ô2Ð2ØˆØ”N×(Ò(Ñ*Ô*ð 	=ð 	=‰DˆAˆqØ�uŠu�\Ñ"Ô" jÒ0Ð0Ø×"Ò" A q§u¢u¨\Ñ':Ô':Ð#;Ñ<Ô<Ð<øØ×Ò�˜[Ñ)Ô)¨1Ð.]ÐP[Ð.]Ð.]Ñ^Ô^Ð^Ð^Ð^r>   c                 ó6  — g }| j                              ¦   «         D ]U\  }}|                     d¦  «        r&t          |                     d¦  «        ¦  «        dk     r|                     |¦  «         ŒV|                      t          |¦  «        dd|› �¦  «         dS )zMF5.2: Assert start frames combine character anchors with environment anchors.Úenvironment_anchorr   r   z$Shots missing environmental anchor: N)r@  rM   rK   rG   r^   rF   )rN   Úno_envrE  rF  s       r<   Ú*test_f5_02_contextual_environment_blendingzQTestTier5F5SweetSpotStartFrameProtocol.test_f5_02_contextual_environment_blending¥  sž   € àˆØ”N×(Ò(Ñ*Ô*ð 	!ð 	!‰DˆAˆqØ—5’5Ð-Ñ.Ô.ð !µ#°a·e²eÐ<PÑ6QÔ6QÑ2RÔ2RÐUVÒ2VÐ2VØ—’˜aÑ Ô Ð øØ×Ò�˜V™œ aÐ)XÐPVÐ)XÐ)XÑYÔYÐYÐYÐYr>   c                 óR  ‡— d„ | j         D ¦   «         }|                      t          |¦  «        d¦  «         g d¢}|D ]j}| j         |                              dd¦  «                             ¦   «         Š|                      t          ˆfd„|D ¦   «         ¦  «        d|› d‰› �¦  «         Œkd	S )
z_F5.3: Assert outdoor scene start frames (Scene 04, 05, 06) do not use raw indoor studio frames.c                 óJ   ‡— g | ]Št          ˆfd „dD ¦   «         ¦  «        ¯‰‘Œ S )c              3   ó    •K  — | ]}|‰v V — Œ	d S ro   ri   )rk   ra   rE  s     €r<   rp   zyTestTier5F5SweetSpotStartFrameProtocol.test_f5_03_no_raw_studio_portraits_in_outdoor_scenes.<locals>.<listcomp>.<genexpr>¯  s'   øè è € Ð9nÐ9nÀb¸"À¸'Ð9nÐ9nÐ9nÐ9nÐ9nÐ9nr>   )Úscene04Úscene05Úscene06)rÞ   ©rk   rE  s    @r<   rm   zoTestTier5F5SweetSpotStartFrameProtocol.test_f5_03_no_raw_studio_portraits_in_outdoor_scenes.<locals>.<listcomp>¯  s<   ø€ ÐoÐoÐo˜qµcÐ9nÐ9nÐ9nÐ9nÐLmÐ9nÑ9nÔ9nÑ6nÔ6nÐo˜ÐoÐoÐor>   é   )u   suá»‘iu   cá»�u   má»™u   ngoáº¡i cáº£nhu	   Ä‘Æ°á»�ngu   cáº§uu   liá»…uu   báº¿nu   ngoÃ iÚduongÚngoaiÚhoiÚ
thanh_minhÚsuoiÚtieu_kheÚmoÚbenÚcayrI  Ú c              3   ó    •K  — | ]}|‰v V — Œ	d S ro   ri   )rk   ÚwÚenvs     €r<   rp   znTestTier5F5SweetSpotStartFrameProtocol.test_f5_03_no_raw_studio_portraits_in_outdoor_scenes.<locals>.<genexpr>¸  s'   øè è € Ð2Ð2 �A˜�HÐ2Ð2Ð2Ð2Ð2Ð2r>   zOutdoor shot z' missing outdoor environmental anchor: N)r@  ÚassertGreaterrG   rK   rÒ   r5   rÞ   )rN   Úoutdoor_shotsÚoutdoor_kwsÚsr`  s       @r<   Ú4test_f5_03_no_raw_studio_portraits_in_outdoor_scenesz[TestTier5F5SweetSpotStartFrameProtocol.test_f5_03_no_raw_studio_portraits_in_outdoor_scenes­  sÙ   ø€ àoÐo D¤NÐoÑoÔoˆØ×Ò�3˜}Ñ-Ô-¨rÑ2Ô2Ð2ð
ð 
ð 
ˆð ð 	ð 	ˆAØ”. Ô#×'Ò'Ð(<¸bÑAÔA×GÒGÑIÔIˆCØ�OŠOÝÐ2Ð2Ð2Ð2 kÐ2Ñ2Ô2Ñ2Ô2ØO ÐOÐOÈ#ÐOÐOñô ð ð ð	ð 	r>   c                 óî   — | j                              ¦   «         D ]Z\  }}|                     dd¦  «        }|                      d|d|› d�¦  «         |                      d|v pd|v pd|v d|› d	�¦  «         Œ[d
S )zPF5.4: Assert negative prompts guard against reverse physics and backward motion.Úpromptr]  ú--noúShot z missing negative prompt clausezreverse motionÚ	backwardsu   chuyá»ƒn Ä‘á»™ng tá»± nhiÃªnz missing reverse motion guardN)r@  rM   rK   r+  r5   )rN   rE  rF  rg  s       r<   Ú>test_f5_04_directional_motion_vectors_and_zero_reverse_physicszeTestTier5F5SweetSpotStartFrameProtocol.test_f5_04_directional_motion_vectors_and_zero_reverse_physics¼  s©   € à”N×(Ò(Ñ*Ô*ð 	ð 	‰DˆAˆqØ—U’U˜8 RÑ(Ô(ˆFØ�MŠM˜& &Ð*T°!Ð*TÐ*TÐ*TÑUÔUÐUØ�OŠOØ  FÐ*Ðo¨k¸VÐ.CÐoÐGeÐioÐGoØ8˜Ð8Ð8Ð8ñô ð ð ð	ð 	r>   c                 óì   — | j                              di ¦  «        }|                     dd¦  «        }|                      d|¦  «         |                      d|¦  «         |                      d|¦  «         dS )z]F5.5: Assert Banana prompt for twin scenes specifies twin resemblance and 16yo noble maidens.Úep01_scene03_shot01rg  r]  z#Twin sisters Thuy Kieu and Thuy Vanzboth 16yo noble maidensztwin facial resemblanceN)r@  rK   r+  )rN   Úc03_s01rg  s      r<   Ú)test_f5_05_twin_two_shot_prompt_in_bananazPTestTier5F5SweetSpotStartFrameProtocol.test_f5_05_twin_two_shot_prompt_in_bananaÆ  sr   € à”.×$Ò$Ð%:¸BÑ?Ô?ˆØ—’˜X rÑ*Ô*ˆØ�ŠÐ;¸VÑDÔDÐDØ�ŠÐ/°Ñ8Ô8Ð8Ø�ŠÐ/°Ñ8Ô8Ð8Ð8Ð8r>   N)
r‡   rˆ   r‰   rŠ   r=   rG  rK  re  rk  ro  ri   r>   r<   r9  r9  ”  s�   € € € € € àðEð Eñ „[ðEð
_ð _ð _ðZð Zð Zðð ð ðð ð ð9ð 9ð 9ð 9ð 9r>   r9  c                   óB   — e Zd Zed„ ¦   «         Zd„ Zd„ Zd„ Zd„ Zd„ Z	dS )Ú+TestTier5F6LipSyncAndOffScreenDialogueGuardc                 óD  — t           j        } |¦   «         }|s•ddt          j        ¦   «         v st	          j        t           ¦  «        rt	          j        t           ¦  «        ndt	          j        |¦  «        t	          j        |¦  «        dœz  }t          t	          j        |¦  «        ¦  «        ‚d x}}t          j
        t                                d¬¦  «        ¦  «        | _        d„ | j                             di ¦  «                             ¦   «         D ¦   «         | _        d S )Nr   ÚMUSE_JSON_PATHr"  r   r   c                 óD   — i | ]\  }}|                      d ¦  «        ¯||“ŒS ©Úep01_©Ú
startswith©rk   rE  rF  s      r<   ú
<dictcomp>zJTestTier5F6LipSyncAndOffScreenDialogueGuard.setUpClass.<locals>.<dictcomp>Ø  s3   € ÐqÐqÐq¡  1Ð[\×[gÒ[gÐhoÑ[pÔ[pÐq�q˜!ÐqÐqÐqr>   Úmotion_prompts)rs  r7   r¡   r¢   rŸ   r£   r¤   r¦   r§   r=  r>  r8   Ú	muse_datarK   rM   Úpromptsr(  s       r<   r=   z6TestTier5F6LipSyncAndOffScreenDialogueGuard.setUpClassÔ  s  € åÔ$Ð&Ð$Ð$Ñ&Ô&Ð&Ð&Ð&Ð&Ð&Õ&Ô&Ñ&Ô&Ð&Ð&Õ&Ô&�~Ñ&Ô&Ð&Õ&Ô&�~Ñ&Ô&Ð&Ð&Õ&Ô&Ð$Ñ&Ô&Õ&Ô&Ð&Ñ&Ô&Ð&Ð&Ñ&Ð&Õ&Õ&Ô&Ð&Ñ&Ô&Ñ&Ô&Ð&Ð&Ð&Ð&Ð&Ýœ
¥>×#;Ò#;ÀWÐ#;Ñ#MÔ#MÑNÔNˆŒØqÐq¨¬×(9Ò(9Ð:JÈBÑ(OÔ(O×(UÒ(UÑ(WÔ(WÐqÑqÔqˆŒˆˆr>   c                 ó¤  ‡— g }| j                              ¦   «         D ]b\  }}t          |t          ¦  «        r|n|                     dd¦  «        Št          ˆfd„dD ¦   «         ¦  «        r|                     |¦  «         Œc|                      t          |¦  «        dd¦  «         g }|D ]€}t          | j         |         t          ¦  «        r| j         |         n | j         |                              dd¦  «        Št          ˆfd„dD ¦   «         ¦  «        s|                     |¦  «         Œ�|  	                    t          |¦  «        d	d
|› �¦  «         dS )zMF6.1: Assert 100% of off-screen/VO dialogue shots enforce closed-lips clause.Úmotion_promptr]  c              3   óD   •K  — | ]}|‰                      ¦   «         v V — Œd S ro   rÑ   )rk   r0  Útexts     €r<   rp   z}TestTier5F6LipSyncAndOffScreenDialogueGuard.test_f6_01_closed_lips_clause_in_all_offscreen_vo_muse_prompts.<locals>.<genexpr>ß  s0   øè è € Ð{Ð{¨D�4˜4Ÿ:š:™<œ<Ð'Ð{Ð{Ð{Ð{Ð{Ð{r>   )õ   tá»« xau   ngoÃ i khungúv.o.u   ngÆ°á»�i dáº«n chuyá»‡núo.s.r   z*Expected >= 15 off-screen/VO shots in EP01c              3   óD   •K  — | ]}|‰                      ¦   «         v V — Œd S ro   rÑ   ©rk   r_  r�  s     €r<   rp   z}TestTier5F6LipSyncAndOffScreenDialogueGuard.test_f6_01_closed_lips_clause_in_all_offscreen_vo_muse_prompts.<locals>.<genexpr>æ  s0   øè è € Ð}Ð}¨Q�q˜DŸJšJ™LœLÐ(Ð}Ð}Ð}Ð}Ð}Ð}r>   )õ   khÃ³a kháº©u hÃ¬nhõ   khÃ©p cháº·túlips closedõ   khÃ´ng máº¥p mÃ¡yr   z,Off-screen shots missing closed-lips guard: N)
r}  rM   Ú
isinstanceÚstrrK   rÞ   r^   rr   rG   rF   )rN   Úoffscreen_shotsrE  rF  Úmissing_guardr�  s        @r<   Ú>test_f6_01_closed_lips_clause_in_all_offscreen_vo_muse_promptszjTestTier5F6LipSyncAndOffScreenDialogueGuard.test_f6_01_closed_lips_clause_in_all_offscreen_vo_muse_promptsÚ  sg  ø€ àˆØ”L×&Ò&Ñ(Ô(ð 	*ð 	*‰DˆAˆqÝ" 1¥cÑ*Ô*ÐJ�1�1°·²°oÀrÑ0JÔ0JˆDÝÐ{Ð{Ð{Ð{Ð4zÐ{Ñ{Ô{Ñ{Ô{ð *Ø×&Ò& qÑ)Ô)Ð)øà×Ò¥ OÑ 4Ô 4°bÐ:fÑgÔgÐgØˆØ ð 	(ð 	(ˆAÝ&0°´¸a´Å#Ñ&FÔ&FÐt�4”< ”?�?ÈDÌLÐYZÌO×L_ÒL_Ð`oÐqsÑLtÔLtˆDÝÐ}Ð}Ð}Ð}Ð2|Ð}Ñ}Ô}Ñ}Ô}ð (Ø×$Ò$ QÑ'Ô'Ð'øà×Ò�˜]Ñ+Ô+¨QÐ0nÐ_lÐ0nÐ0nÑoÔoÐoÐoÐor>   c                 óö   ‡— | j                              di ¦  «        }t          |t          ¦  «        r|n|                     dd¦  «        Š|                      t          ˆfd„dD ¦   «         ¦  «        d¦  «         dS )u]   F6.2: Assert Scene 08 Shot 02 Kim Trá»�ng enforces closed lips when Kiá»�u speaks off-screen.Úep01_scene08_shot02r  r]  c              3   óD   •K  — | ]}|‰                      ¦   «         v V — Œd S ro   rÑ   r†  s     €r<   rp   zpTestTier5F6LipSyncAndOffScreenDialogueGuard.test_f6_02_scene08_shot02_kim_trong_hairpin_guard.<locals>.<genexpr>ð  s0   øè è € ÐnÐn a��T—Z’Z‘\”\Ð!ÐnÐnÐnÐnÐnÐnr>   )rˆ  õ
   khÃ©p mÃ´ir‰  rŠ  uB   Scene 08 Shot 02 Kim Trá»�ng hairpin shot must enforce closed lipsN)r}  rK   r‹  rŒ  r5   rÞ   )rN   Úc08_s02r�  s     @r<   Ú1test_f6_02_scene08_shot02_kim_trong_hairpin_guardz]TestTier5F6LipSyncAndOffScreenDialogueGuard.test_f6_02_scene08_shot02_kim_trong_hairpin_guardë  s†   ø€ à”,×"Ò"Ð#8¸"Ñ=Ô=ˆÝ$ W­cÑ2Ô2ÐXˆwˆw¸¿ºÀOÐUWÑ8XÔ8XˆØ�ŠÝÐnÐnÐnÐnÐ+mÐnÑnÔnÑnÔnØPñ	
ô 	
ð 	
ð 	
ð 	
r>   c                 ó~  — | j                              ¦   «         D ]¢\  }}t          |t          ¦  «        r|n|                     dd¦  «        }d|                     ¦   «         v rZ|                      d|¦  «         |                      d|                     ¦   «         v od|                     ¦   «         v d|› d�¦  «         Œ£d	S )
zKF6.3: Assert standardized closed-lips syntax format across guarded prompts.r  r]  r‡  u   KHÃ“A KHáº¨U HÃŒNH Báº®T BUá»˜Crˆ  rŠ  ri  z) missing essential closed-lips componentsN)r}  rM   r‹  rŒ  rK   rÒ   r+  r5   )rN   rE  rF  r�  s       r<   Ú)test_f6_03_standardized_syntax_compliancezUTestTier5F6LipSyncAndOffScreenDialogueGuard.test_f6_03_standardized_syntax_complianceô  sÃ   € à”L×&Ò&Ñ(Ô(ð 	ð 	‰DˆAˆqÝ" 1¥cÑ*Ô*ÐJ�1�1°·²°oÀrÑ0JÔ0JˆDØ# t§z¢z¡|¤|Ð3Ð3Ø—’Ð?ÀÑFÔFÐFØ—’Ø" d§j¢j¡l¤lÐ2ÐZÐ7JÈdÏjÊjÉlÌlÐ7ZØH˜AÐHÐHÐHñô ð øð		ð 	r>   c                 ó<  ‡— d„ | j                              ¦   «         D ¦   «         }|D ]t}t          j        | j         |         d¬¦  «                             ¦   «         Šd‰v sd‰v sd‰v r3|                      t          ˆfd„dD ¦   «         ¦  «        d	|› d
�¦  «         ŒudS )zZF6.4: Assert shots with poetry narration V.O. enforce closed lips on on-screen characters.c                 óh   — g | ]/\  }}d t          j        |¦  «                             ¦   «         v ¯-|‘Œ0S )rƒ  )r=  ÚdumpsrÒ   ry  s      r<   rm   zcTestTier5F6LipSyncAndOffScreenDialogueGuard.test_f6_04_voiceover_shots_lip_lock.<locals>.<listcomp>  s:   € ÐZÐZÐZ™$˜!˜Q¸&ÅDÄJÈqÁMÄM×DWÒDWÑDYÔDYÐ:YÐ:Y�AÐ:YÐ:YÐ:Yr>   F)Úensure_asciiu   khuÃ´n máº·tu   cáº­n cáº£nhu   nhÃ¢n váº­tc              3   ó    •K  — | ]}|‰v V — Œ	d S ro   ri   r†  s     €r<   rp   zbTestTier5F6LipSyncAndOffScreenDialogueGuard.test_f6_04_voiceover_shots_lip_lock.<locals>.<genexpr>  s'   øè è € Ð_Ð_ a˜˜T˜	Ð_Ð_Ð_Ð_Ð_Ð_r>   )rˆ  r“  rŠ  zVO shot z) missing lip lock for on-screen characterN)r}  rM   r=  rš  rÒ   r5   rÞ   )rN   Úvo_shotsrE  r�  s      @r<   Ú#test_f6_04_voiceover_shots_lip_lockzOTestTier5F6LipSyncAndOffScreenDialogueGuard.test_f6_04_voiceover_shots_lip_lockÿ  sÉ   ø€ àZÐZ $¤,×"4Ò"4Ñ"6Ô"6ÐZÑZÔZˆØð 	ð 	ˆAÝ”:˜dœl¨1œo¸EÐBÑBÔB×HÒHÑJÔJˆDØ Ð%Ð%¨¸4Ð)?Ð)?À=ÐTXÐCXÐCXØ—’ÝÐ_Ð_Ð_Ð_Ð+^Ð_Ñ_Ô_Ñ_Ô_ØK˜qÐKÐKÐKñô ð øð	ð 	r>   c                 óÄ  — g }| j                              ¦   «         D ]‰\  }}t          |t          ¦  «        r|n|                     dd¦  «        }d|                     ¦   «         v rAd|                     ¦   «         vr+d|                     ¦   «         vr|                     |¦  «         ŒŠ|                      t          |¦  «        d¦  «         |D ]”}t          | j         |         t          ¦  «        r| j         |         n | j         |                              dd¦  «        }|  	                    d|                     ¦   «         v pd|                     ¦   «         v d	|› d
�¦  «         Œ•dS )z[F6.5: Assert direct on-screen dialogue permits natural lip movement without erroneous lock.r  r]  z	on-screenr‚  r„  r   u   mÃ´i máº¥p mÃ¡yu   kháº©u hÃ¬nhzDirect dialogue shot z( should describe natural speech movementN)
r}  rM   r‹  rŒ  rK   rÒ   r^   ra  rG   r5   )rN   Údirect_shotsrE  rF  r�  s        r<   Ú1test_f6_05_on_screen_dialogue_allows_lip_movementz]TestTier5F6LipSyncAndOffScreenDialogueGuard.test_f6_05_on_screen_dialogue_allows_lip_movement
  s_  € àˆØ”L×&Ò&Ñ(Ô(ð 	'ð 	'‰DˆAˆqÝ" 1¥cÑ*Ô*ÐJ�1�1°·²°oÀrÑ0JÔ0JˆDØ˜dŸjšj™lœlÐ*Ð*¨yÀÇ
Â
ÁÄÐ/LÐ/LÐQWÐ_c×_iÒ_iÑ_kÔ_kÐQkÐQkØ×#Ò# AÑ&Ô&Ð&øà×Ò�3˜|Ñ,Ô,¨aÑ0Ô0Ð0Øð 	ð 	ˆAÝ&0°´¸a´Å#Ñ&FÔ&FÐt�4”< ”?�?ÈDÌLÐYZÌO×L_ÒL_Ð`oÐqsÑLtÔLtˆDØ�OŠOØ! T§Z¢Z¡\¤\Ð1ÐS°^ÀtÇzÂzÁ|Ä|Ð5SØS¨ÐSÐSÐSñô ð ð ð	ð 	r>   N)
r‡   rˆ   r‰   rŠ   r=   r�  r•  r—  rž  r¡  ri   r>   r<   rq  rq  Ò  s~   € € € € € àðrð rñ „[ðrð
pð pð pð"
ð 
ð 
ð	ð 	ð 	ð	ð 	ð 	ðð ð ð ð r>   rq  c                   óB   — e Zd Zed„ ¦   «         Zd„ Zd„ Zd„ Zd„ Zd„ Z	dS )Ú$TestTier5F7PromptRegistryConsistencyc                 óÚ  — t          j        t                               d¬¦  «        ¦  «        | _        t          j        t
                               d¬¦  «        ¦  «        | _        t                               d¬¦  «        | _        t          t          t          t          j        d| j        t          j        ¦  «        ¦  «        ¦  «        ¦  «        | _        t          t          | j                             di ¦  «                             ¦   «         ¦  «        ¦  «        | _        t          d„ | j                             di ¦  «                             ¦   «         D ¦   «         ¦  «        | _        d S )Nr   r   zep01_scene\d{2}_shot\d{2}r<  c                 ó<   — g | ]}|                      d ¦  «        ¯|‘ŒS ru  rw  rR  s     r<   rm   zCTestTier5F7PromptRegistryConsistency.setUpClass.<locals>.<listcomp>(  s-   € Ð tÐ tÐ t qÐ^_×^jÒ^jÐkrÑ^sÔ^sÐ t Ð tÐ tÐ tr>   r{  )r=  r>  r;  r8   r?  rs  r|  r6   r9   r¿   rD   rÀ   rA   r[   r\   Úscreenplay_shotsrK   ÚkeysÚbanana_shotsÚ
muse_shotsr:   s    r<   r=   z/TestTier5F7PromptRegistryConsistency.setUpClass   s  € åœ*Õ%5×%?Ò%?ÈÐ%?Ñ%QÔ%QÑRÔRˆŒÝœ
¥>×#;Ò#;ÀWÐ#;Ñ#MÔ#MÑNÔNˆŒÝ#×-Ò-°wÐ-Ñ?Ô?ˆŒå%¥d­3­r¬zÐ:VÐX[ÔXfÕhjÔhlÑ/mÔ/mÑ+nÔ+nÑ&oÔ&oÑpÔpˆÔÝ!¥$ s¤×':Ò':Ð;NÐPRÑ'SÔ'S×'XÒ'XÑ'ZÔ'ZÑ"[Ô"[Ñ\Ô\ˆÔÝÐ tÐ t¨C¬M×,=Ò,=Ð>NÐPRÑ,SÔ,S×,XÒ,XÑ,ZÔ,ZÐ tÑ tÔ tÑuÔuˆŒˆˆr>   c                 óv  — |                       t          | j        ¦  «        d¦  «         |                       t          | j        ¦  «        d¦  «         |                       t          | j        ¦  «        d¦  «         |                       | j        | j        ¦  «         |                       | j        | j        ¦  «         dS )zYF7.1: Assert exact 1-to-1 bijection of all 188 shots across screenplay, Banana, and Muse.rf   N)rF   rG   r¦  r¨  r©  r,  s    r<   Ú;test_f7_01_188_shots_exact_bijection_screenplay_banana_musez`TestTier5F7PromptRegistryConsistency.test_f7_01_188_shots_exact_bijection_screenplay_banana_muse*  s¡   € à×Ò�˜TÔ2Ñ3Ô3°SÑ9Ô9Ð9Ø×Ò�˜TÔ.Ñ/Ô/°Ñ5Ô5Ð5Ø×Ò�˜Tœ_Ñ-Ô-¨sÑ3Ô3Ð3Ø×Ò˜Ô.°Ô0AÑBÔBÐBØ×Ò˜Ô.°´Ñ@Ô@Ð@Ð@Ð@r>   c                 ó\  — | j                              di ¦  «        }g }| j        D ]_}t          ||         t          ¦  «        r||         n||                              dd¦  «        }t
          |vr|                     |¦  «         Œ`|                      t          |¦  «        dd|› �¦  «         dS )z]F7.2: Assert 100% of EP01 motion prompts in Muse terminate with the exact Audio Guard clause.r{  r  r]  r   z!Shots missing exact audio guard: N)	r|  rK   r©  r‹  rŒ  ÚMANDATORY_AUDIO_GUARDr^   rF   rG   )rN   r{  Ú
missing_agrE  r�  s        r<   Ú9test_f7_02_audio_guard_in_100_percent_muse_motion_promptsz^TestTier5F7PromptRegistryConsistency.test_f7_02_audio_guard_in_100_percent_muse_motion_prompts2  sº   € àœ×+Ò+Ð,<¸bÑAÔAˆØˆ
Ø”ð 	%ð 	%ˆAÝ(2°>À!Ô3DÅcÑ(JÔ(JÐz�> !Ô$Ð$ÐP^Ð_`ÔPa×PeÒPeÐfuÐwyÑPzÔPzˆDÝ$¨DÐ0Ð0Ø×!Ò! !Ñ$Ô$Ð$øà×Ò�˜Z™œ¨!Ð-]ÐQ[Ð-]Ð-]Ñ^Ô^Ð^Ð^Ð^r>   c                 ó   — | j                              di ¦  «        }g }| j        D ]A}||                              dd¦  «        }|› d�}||k    r|                     |||f¦  «         ŒB|                      t          |¦  «        dd|› �¦  «         dS )zFF7.3: Assert all target video filenames strictly end with _10s_v1.mp4.r{  Útarget_video_filer]  z_10s_v1.mp4r   z%Target video file naming mismatches: N)r|  rK   r©  r^   rF   rG   )rN   r{  Úinvalid_namingrE  ÚtargetÚexpecteds         r<   Ú.test_f7_03_target_video_file_versioning_formatzSTestTier5F7PromptRegistryConsistency.test_f7_03_target_video_file_versioning_format=  s°   € àœ×+Ò+Ð,<¸bÑAÔAˆØˆØ”ð 	=ð 	=ˆAØ# AÔ&×*Ò*Ð+>ÀÑCÔCˆFØÐ(Ð(Ð(ˆHØ˜Ò!Ð!Ø×%Ò% q¨&°(Ð&;Ñ<Ô<Ð<øà×Ò�˜^Ñ,Ô,¨aÐ1iÐYgÐ1iÐ1iÑjÔjÐjÐjÐjr>   c                 óˆ  — d„ | j         D ¦   «         }|D ]­}| j        d         |                              dd¦  «        }d|                     ¦   «         v sd|                     ¦   «         v rX|                      d|¦  «         |                      d|¦  «         |                      d	|¦  «         |                      d
|¦  «         Œ®dS )zYF7.4: Assert Scene 13 & 14 prompts strictly prohibit modern/western elements for Sai Nha.c                 ó"   — g | ]}d |v sd|v ¯
|‘ŒS )Úscene13Úscene14ri   rR  s     r<   rm   ztTestTier5F7PromptRegistryConsistency.test_f7_04_sai_nha_feudal_costume_enforcement_in_scene13_14.<locals>.<listcomp>K  s&   € Ð[Ð[Ð[ ¸)Àq¸.¸.ÈIÐYZÈNÈN˜!ÈNÈNÈNr>   r<  rg  r]  zsai nhaÚbailiffrh  zmodern clothingzwestern featureszmodern police uniformN)r¨  r?  rK   rÒ   r+  )rN   Úsc13_14_bananarE  rg  s       r<   Ú;test_f7_04_sai_nha_feudal_costume_enforcement_in_scene13_14z`TestTier5F7PromptRegistryConsistency.test_f7_04_sai_nha_feudal_costume_enforcement_in_scene13_14I  sÍ   € à[Ð[ TÔ%6Ð[Ñ[Ô[ˆØð 	?ð 	?ˆAØÔ%Ð&9Ô:¸1Ô=×AÒAÀ(ÈBÑOÔOˆFØ˜FŸLšL™NœNÐ*Ð*¨i¸6¿<º<¹>¼>Ð.IÐ.IØ—’˜f fÑ-Ô-Ð-Ø—’Ð/°Ñ8Ô8Ð8Ø—’Ð0°&Ñ9Ô9Ð9Ø—’Ð5°vÑ>Ô>Ð>øð	?ð 	?r>   c                 ó¾   — d„ | j         D ¦   «         }|                      t          |¦  «        d¦  «         |                      t          |¦  «        | j        ¦  «         dS )zZF7.5: Assert synchronization between ep01_start_frames sub-dict and top-level prompt keys.c                 ó<   — g | ]}t          j        d |¦  «        ¯|‘ŒS )z^ep01_scene\d{2}_shot\d{2}$)rA   ÚmatchrR  s     r<   rm   zqTestTier5F7PromptRegistryConsistency.test_f7_05_banana_top_level_and_sub_dict_synchronization.<locals>.<listcomp>V  s+   € Ð_Ð_Ð_˜!µ2´8Ð<ZÐ\]Ñ3^Ô3^Ð_�AÐ_Ð_Ð_r>   rf   N)r?  rF   rG   r¿   r¨  )rN   Útop_keyss     r<   Ú8test_f7_05_banana_top_level_and_sub_dict_synchronizationz]TestTier5F7PromptRegistryConsistency.test_f7_05_banana_top_level_and_sub_dict_synchronizationT  s[   € à_Ð_˜tÔ/Ð_Ñ_Ô_ˆØ×Ò�˜X™œ¨Ñ,Ô,Ð,Ø×Ò� Ñ)Ô)¨4Ô+<Ñ=Ô=Ð=Ð=Ð=r>   N)
r‡   rˆ   r‰   rŠ   r=   r«  r¯  rµ  r¼  rÁ  ri   r>   r<   r£  r£    s„   € € € € € àðvð vñ „[ðvðAð Að Að	_ð 	_ð 	_ð
kð 
kð 
kð	?ð 	?ð 	?ð>ð >ð >ð >ð >r>   r£  c                   óP   — e Zd ZdZed„ ¦   «         Zed„ ¦   «         Zd„ Zd„ Zd„ Z	dS )Ú TestTier5AdversarialGapDiscoveryz 
    Dedicated test cases that adversarially uncover and document empirical gaps
    across the implementation artifacts without breaking build automation.
    c                 ó   — ddg dœ| _         d S )Nz2026-10-08T08:30:00Zz1teamwork_preview_challenger (Tier 5 Challenger 1))Ú	timestampÚauditorÚgaps)Ú
gap_reportr:   s    r<   r=   z+TestTier5AdversarialGapDiscovery.setUpClassd  s   € ð 0ØJØð
ð 
ˆŒˆˆr>   c                 óª   — t           dz  }t          |dd¬¦  «        5 }t          j        | j        |dd¬¦  «         d d d ¦  «         d S # 1 swxY w Y   d S )Nz$tier5_creative_hardening_report.jsonr_  r   r   Fr   )r›  Úindent)Ú	TESTS_DIRÚopenr=  ÚdumprÈ  )r;   Úreport_pathÚfs      r<   ÚtearDownClassz.TestTier5AdversarialGapDiscovery.tearDownClassl  s±   € åÐ"HÑHˆÝ�+˜s¨WÐ5Ñ5Ô5ð 	G¸ÝŒI�c”n a°eÀAÐFÑFÔFÐFð	Gð 	Gð 	Gñ 	Gô 	Gð 	Gð 	Gð 	Gð 	Gð 	Gð 	Gð 	Gøøøð 	Gð 	Gð 	Gð 	Gð 	Gð 	Gs   �AÁAÁAc                 óL  ‡— t                                d¬¦  «        }t                               d¬¦  «        }t          j        t
                               d¬¦  «        ¦  «        }g }t          |                     ¦   «         d¦  «        D ]X\  }Št          j	        d‰t          j
        ¦  «        r3t          ˆfd„dD ¦   «         ¦  «        r|                     |‰dœ¦  «         ŒYg }|                     ¦   «         D ]RŠt          j	        d‰t          j
        ¦  «        r0t          ˆfd„d	D ¦   «         ¦  «        r|                     ‰¦  «         ŒSg }|                     d
i ¦  «                             ¦   «         D ]t\  }}	|                     d¦  «        sŒt!          |	t"          ¦  «        r|	n|	                     dd¦  «        }
d|
v r(d|
v sd|
v r |                     ||
dd…         dœ¦  «         Œudddddt%          |¦  «        |t%          t          j        d|t          j
        ¦  «        ¦  «        ||dœddœ}| j        d                              |¦  «         |                      t%          |¦  «        ddgd|› �¦  «         |                      t%          |¦  «        ddgd |› �¦  «         dS )!z²
        GAP AUDIT 1: Discover discrepancies between Director Directive / Character Bible
        (identical twin sisters, both 16yo) and Screenplay / Prompt Registries.
        r   r   r   u
   ThÃºy VÃ¢nc              3   óD   •K  — | ]}|‰                      ¦   «         v V — Œd S ro   rÑ   ©rk   ÚagerÕ   s     €r<   rp   ziTestTier5AdversarialGapDiscovery.test_gap_01_kieu_van_age_and_twin_inconsistency_audit.<locals>.<genexpr>}  sI   øè è € ð  <Að  <AÐTW¸CÀ4Ç:Â:Á<Ä<Ð<Oð  <Að  <Að  <Að  <Að  <Að  <Ar>   )Ú15tõ	   15 tuá»•iu   mÆ°á»�i lÄƒm)Úline_numr�  c              3   óD   •K  — | ]}|‰                      ¦   «         v V — Œd S ro   rÑ   rÓ  s     €r<   rp   ziTestTier5AdversarialGapDiscovery.test_gap_01_kieu_van_age_and_twin_inconsistency_audit.<locals>.<genexpr>‚  s1   øè è € Ð;pÐ;pÐTW¸CÀ4Ç:Â:Á<Ä<Ð<OÐ;pÐ;pÐ;pÐ;pÐ;pÐ;pr>   )rÕ  rÖ  r{  rv  r  r]  rÖ  rÕ  Néx   )Úshot_idr  zGAP-CREATIVE-01uH   ThÃºy VÃ¢n Age & Twin Status Inconsistency across Screenplay and PromptsÚHIGHuZ   ORIGINAL_REQUEST.md Directive Update (2026-10-08T05:21:27Z) & CHARACTER_BIBLE.md Â§1 & Â§3u©  Director Directive mandates ThÃºy Kiá»�u and ThÃºy VÃ¢n are identical twins, both 16yo at film start. However, TAP_01 screenplay retains 4 occurrences of '15 tuá»•i' / '15t' (lines 18, 389, 402, 664) with 0 mentions of 'song sinh'. INDEX_VA_DANH_MUC_CANH_QUAY.md retains Scene 03 as 'ThÃºy VÃ¢n (15t)'. Muse motion prompt ep01_scene03_shot02 retains 'ThÃºy VÃ¢n (15 tuá»•i)' while referencing 'thuy_van_maiden_16yo_720p.png'.z	song sinh)Útap01_15yo_countÚtap01_occurrencesÚtap01_song_sinh_mentionsÚindex_occurrencesÚmuse_occurrencesuÐ   Update TAP_01 lines 18, 389, 402, 664 and INDEX Scene 03 to 'ThÃºy VÃ¢n (16 tuá»•i, song sinh cÃ¹ng ThÃºy Kiá»�u)'. Update Muse ep01_scene03_shot02 motion_prompt from '(15 tuá»•i)' to '(16 tuá»•i song sinh)'.©Úgap_idÚtitleÚseverityÚrule_violatedÚdescriptionÚfindingsÚremediationrÇ  r   r   zUnexpected TAP_01 count: zUnexpected Muse prompt count: )r6   r8   Ú
INDEX_PATHr=  r>  rs  rè   rÛ   rA   rÜ   r\   rÞ   r^   rK   rM   rx  r‹  rŒ  rG   r[   rÈ  r+  )rN   Útap01rë   r|  rÝ  Úidx_numÚidx_occurrencesrà  rE  rF  r�  Ú	gap_entryrÕ   s               @r<   Ú5test_gap_01_kieu_van_age_and_twin_inconsistency_auditzVTestTier5AdversarialGapDiscovery.test_gap_01_kieu_van_age_and_twin_inconsistency_auditr  sþ  ø€ õ
 ×$Ò$¨gÐ$Ñ6Ô6ˆÝ×"Ò"¨GÐ"Ñ4Ô4ˆÝ”J�~×7Ò7ÀÐ7ÑIÔIÑJÔJˆ	àÐÝ& u×'7Ò'7Ñ'9Ô'9¸1Ñ=Ô=ð 	Nð 	N‰MˆG�TÝŒy˜¨­b¬dÑ3Ô3ð N½ð  <Að  <Að  <Að  <AÐ[ð  <Añ  <Aô  <Añ  9Aô  9Að NØ!×(Ò(°gÀtÐ)LÐ)LÑMÔMÐMøàˆØ—N’NÑ$Ô$ð 	-ð 	-ˆDÝŒy˜¨­b¬dÑ3Ô3ð -½Ð;pÐ;pÐ;pÐ;pÐ[oÐ;pÑ;pÔ;pÑ8pÔ8pð -Ø×&Ò& tÑ,Ô,Ð,øàÐØ—M’MÐ"2°BÑ7Ô7×=Ò=Ñ?Ô?ð 	Uð 	U‰DˆAˆqØ—<’< Ñ(Ô(Ð2¨(Ý" 1¥cÑ*Ô*ÐJ�1�1°·²°oÀrÑ0JÔ0JˆDØ˜tÐ#Ð#¨¸Ð)<Ð)<ÀÈÀÀØ ×'Ò'°AÈÈTÈcÈTÌ
Ð(SÐ(SÑTÔTÐTøð (Ø_ØØyðMõ %(Ð(9Ñ$:Ô$:Ø%6Ý,/µ´
¸<ÈÕPRÔPTÑ0UÔ0UÑ,VÔ,VØ%4Ø$4ðð ðoð'
ð 
ˆ	ð. 	Œ˜Ô×&Ò& yÑ1Ô1Ð1ð 	�Š•cÐ+Ñ,Ô,¨q°!¨fÐ6eÐRcÐ6eÐ6eÑfÔfÐfØ�Š•cÐ*Ñ+Ô+¨a°¨VÐ5hÐVfÐ5hÐ5hÑiÔiÐiÐiÐir>   c                 ó>  — t          j        t                               d¬¦  «        ¦  «        }|                     di ¦  «        }g }|                     ¦   «         D ]h\  }}|                     d¦  «        sŒ|                     d¦  «        }|r6t          |z  }|                     ¦   «         s| 	                    ||dœ¦  «         Œii }|D ]:}	|	d         }t          |¦  «        j        }
|                     |
d¦  «        d	z   ||
<   Œ;d
ddddt          |¦  «        › d�t          |¦  «        |dddddœdœddœ}| j        d          	                    |¦  «         |                      t          |¦  «        ddg¦  «         |                      t          |¦  «        ddg¦  «         dS )ze
        GAP AUDIT 2: Discover dead character_asset_ref paths in muse_ai_video_prompts.json.
        r   r   r{  rv  Úcharacter_asset_ref)rÚ  Úmissing_pathrñ  r   r   zGAP-CREATIVE-02zG27 Broken Character Asset Reference Paths in muse_ai_video_prompts.jsonrÛ  zFPROJECT.md Interface Contract M2 <-> M3/M4 & File Workspace ConventionzKOut of 83 shots defining character_asset_ref in EP01 Muse prompts, exactly zg shots reference non-existent files on disk due to naming drift between prompt registry and 04_Assets/.z7Actual file on disk: vuong_ong_55yo_720p.png (11 shots)z5Actual file on disk: vuong_ba_50yo_720p.png (2 shots)z7Actual file on disk: vuong_quan_16yo_720p.png (8 shots)z/Actual file on disk: sai_nha_720p.png (6 shots))z!vuong_ong_patriarch_55yo_720p.pngz vuong_ba_matriarch_50yo_720p.pngzvuong_quan_young_14yo_720p.pngz)imperial_guards_brutal_officials_720p.png)Útotal_missing_shotsÚbreakdown_by_missing_fileÚmissing_files_mappingaP  Update muse_ai_video_prompts.json to align character_asset_ref with existing files: replace vuong_ong_patriarch_55yo_720p.png -> vuong_ong_55yo_720p.png, vuong_ba_matriarch_50yo_720p.png -> vuong_ba_50yo_720p.png, vuong_quan_young_14yo_720p.png -> vuong_quan_16yo_720p.png, imperial_guards_brutal_officials_720p.png -> sai_nha_720p.png.rá  rÇ  r   r   N)r=  r>  rs  r8   rK   rM   rx  ÚBASE_DIRr7   r^   r   ÚnamerG   rÈ  r+  )rN   r|  r{  Úmissing_refsrE  rF  ÚrefÚpathÚmissing_by_patternÚitemÚfilenamerí  s               r<   Ú>test_gap_02_broken_character_asset_references_filesystem_auditz_TestTier5AdversarialGapDiscovery.test_gap_02_broken_character_asset_references_filesystem_audit©  sò  € õ ”J�~×7Ò7ÀÐ7ÑIÔIÑJÔJˆ	Ø"ŸšÐ'7¸Ñ<Ô<ˆàˆØ"×(Ò(Ñ*Ô*ð 	Mð 	M‰DˆAˆqØ—<’< Ñ(Ô(Ð2¨(Ø—%’%Ð-Ñ.Ô.ˆCØð MÝ #‘~�Ø—{’{‘}”}ð MØ ×'Ò'°AÀsÐ(KÐ(KÑLÔLÐLøð  ÐØ ð 	Sð 	SˆDØ�~Ô&ˆCÝ˜C‘y”y”~ˆHØ+=×+AÒ+AÀ(ÈAÑ+NÔ+NÐQRÑ+RÐ˜xÑ(Ð(ð (Ø^ØØeðsÕ^aÐbnÑ^oÔ^oð sð sð sõ (+¨<Ñ'8Ô'8Ø-?à9rØ8oØ6oØArð	*ð *ð	ð 	ðQð)
ð 
ˆ	ð6 	Œ˜Ô×&Ò& yÑ1Ô1Ð1ð 	�Š•c˜,Ñ'Ô'¨!¨R¨Ñ1Ô1Ð1Ø�Š•cÐ,Ñ-Ô-°°1¨vÑ6Ô6Ð6Ð6Ð6r>   c           	      óÒ  — t           j                             dt          t          ¦  «        ¦  «         	 ddl}ddi}|                     d|¦  «        }|                      |du p t          |¦  «         	                    ¦   «         d¦  «         ddi}|                     d|¦  «        }|  
                    |d¦  «         |                      t          |¦  «         	                    ¦   «         d	¦  «         d
ddddt          |¦  «        t          |¦  «        dœddœ}| j        d                              |¦  «         dS # t          $ r#}|                      d|› �¦  «         Y d}~dS d}~ww xY w)z�
        GAP AUDIT 3: Verify that broken character_asset_ref breaks start-frame resolution
        when no previous tail frame exists.
        r   Nrð  zL04_Assets/characters/02_Vuong_Family_And_Fate/vuong_quan_young_14yo_720p.pngÚep01_scene99_shot01z,Resolved path must exist on disk if resolvedzF04_Assets/characters/02_Vuong_Family_And_Fate/vuong_quan_16yo_720p.pngz"Valid asset ref resolves correctlyz Resolved path must exist on diskzGAP-CREATIVE-03zFStart Frame Resolution Fallback Failure Due to Broken Asset ReferencesÚMEDIUMzG05_Production_Pipeline/production_orchestrator.py resolve_start_frame()a  When production_orchestrator.py resolves start frames for unrendered shots (e.g. shot01 or detached shots), it falls back to character_asset_ref. The broken asset paths cause resolve_start_frame() to return None, preventing automated headless rendering for those shots.)Úbroken_ref_resultÚvalid_ref_resultz]Correcting the 27 asset references immediately restores 100% start-frame fallback resolution.rá  rÇ  z*Could not import production_orchestrator: )Úsysrù  ÚinsertrŒ  ÚPIPELINE_DIRÚproduction_orchestratorÚresolve_start_framer5   r   r7   rî   rÈ  r^   ÚImportErrorrß   )rN   r  Úshot_data_brokenÚresolvedÚshot_data_validÚresolved_validrí  Úes           r<   ÚAtest_gap_03_orchestrator_start_frame_fallback_vulnerability_auditzbTestTier5AdversarialGapDiscovery.test_gap_03_orchestrator_start_frame_fallback_vulnerability_auditá  s­  € õ
 	Œ�Š˜�3�|Ñ,Ô,Ñ-Ô-Ð-ð$	HØ*Ð*Ð*Ð*à%Ð'uð Ðð /×BÒBÐCXÐZjÑkÔkˆHà�OŠO˜H¨Ð,ÐGµ°X±´×0EÒ0EÑ0GÔ0GÐIwÑxÔxÐxð &Ð'oðˆOð 5×HÒHÐI^Ð`oÑpÔpˆNØ× Ò  Ð1UÑVÔVÐVØ�OŠO�D Ñ0Ô0×7Ò7Ñ9Ô9Ð;]Ñ^Ô^Ð^ð ,ØaØ$Ø!jðOõ
 *-¨X©¬Ý(+¨NÑ(;Ô(;ðð ð  ðð ˆIð  ŒO˜FÔ#×*Ò*¨9Ñ5Ô5Ð5Ð5Ð5øÝð 	Hð 	Hð 	HØ�IŠIÐFÀ1ÐFÐFÑGÔGÐGÐGÐGÐGÐGÐGÐGøøøøð	Høøøs   ´DD9 Ä9
E&ÅE!Å!E&N)
r‡   rˆ   r‰   Ú__doc__rŠ   r=   rÐ  rî  rý  r  ri   r>   r<   rÃ  rÃ  ^  sŽ   € € € € € ðð ð
 ð
ð 
ñ „[ð
ð ðGð Gñ „[ðGð
5jð 5jð 5jðn67ð 67ð 67ðp*Hð *Hð *Hð *Hð *Hr>   rÃ  Ú__main__r   )Ú	verbosityr   )>r  Úbuiltinsr¡   Ú_pytest.assertion.rewriteÚ	assertionÚrewriterŸ   Úosr  rA   r=  ÚunittestÚpathlibr   ÚplatformÚstdoutÚreconfigureÚstderrÚ	ExceptionÚ__file__ÚresolveÚparentrõ  ÚFILMMAKER_DIRÚPROMPTS_DIRÚ	BIBLE_DIRÚ
ASSETS_DIRr  rË  r6   ré  r;  rs  r!  r%  r­  rL   rq   ÚvaluesrH   r  r  ÚTestCaser3   rŒ   rù   r  r9  rq  r£  rÃ  r‡   ÚTextTestRunnerÚrunnerÚdefaultTestLoaderÚloadTestsFromModuleÚmodulesÚsuiteÚrunÚresultÚexitÚwasSuccessfulri   r>   r<   ú<module>r1     s1  ððð ð0 € € € € € € € € € € € € €	€	€	€	Ø 
€
€
€
Ø 	€	€	€	Ø €€€Ø €€€Ø Ð Ð Ð Ð Ð ð „<�7ÒÐðØŒ
×Ò¨ÐÑ0Ô0Ð0ØŒ
×Ò¨ÐÑ0Ô0Ð0Ð0øØð ð ð Øˆðøøøð ˆ4�‰>Œ>×!Ò!Ñ#Ô#Ô*Ô1€Ø˜;Ñ&€Ø˜Ñ(€ØÐ)Ñ)€	Ø˜Ñ#€
ØÐ2Ñ2€Ø�wÑ€	ð ÐUÑU€
ØÐ=Ñ=€
ØÐ!=Ñ=Ð ØÐ;Ñ;€ØÐ2Ñ2€Ø"Ð%EÑEÐ ðJð ð 
ˆb�R˜B 2¨"°°q¸QØ
�˜˜r r¨qðð Ð ð �sÐ0×7Ò7Ñ9Ô9Ñ:Ô:Ð ðð ð €ðð ð Ð ðNNð NNð NNð NNð NN¨hÔ.?ñ NNô NNð NNðh`
ð `
ð `
ð `
ð `
 hÔ&7ñ `
ô `
ð `
ðLH]ð H]ð H]ð H]ð H]¨(Ô*;ñ H]ô H]ð H]ð\'jð 'jð 'jð 'jð 'j°hÔ6Gñ 'jô 'jð 'jðZ89ð 89ð 89ð 89ð 89¨XÔ->ñ 89ô 89ð 89ð|Fð Fð Fð Fð F°(Ô2Cñ Fô Fð FðX:>ð :>ð :>ð :>ð :>¨8Ô+<ñ :>ô :>ð :>ð@mHð mHð mHð mHð mH xÔ'8ñ mHô mHð mHð` ˆzÒÐØ$ˆXÔ$¨qÐ1Ñ1Ô1€FØÔ&×:Ò:¸3¼;ÀxÔ;PÑQÔQ€EØ�ZŠZ˜ÑÔ€FØ€C„H�&×&Ò&Ñ(Ô(Ð/ˆQˆQ¨aÑ0Ô0Ð0Ð0Ð0ð	 Ðs   ¶6A- Á-A5Á4A5