# DISPATCH — Worker 3 (Milestone M3 Iteration 3 Remediation)

## Mission
Remediate the latent face-leakage vulnerability in `classify_shot_take`, align `character_anchor` in `gemini_banana_prompts.json` and `banana_prompts.json`, tighten `batch_render_scene` gate abort, and add comprehensive transition tests in `tests/test_m3_challenger1_probe.py`.

## Mandatory Reading
- `c:\Projects\KieuStory\.agents\teamwork\ORIGINAL_REQUEST.md` (read completely first)
- `c:\Projects\KieuStory\.agents\teamwork\orchestrator_1\PROJECT.md`
- Reviewer 1 Report: `c:\Projects\KieuStory\.agents\teamwork\reviewer_m3_iter2_1\handoff.md`
- Challenger 1 Report: `c:\Projects\KieuStory\.agents\teamwork\challenger_m3_iter2_1\handoff.md`

## Mandatory Anti-Cheating Warning
DO NOT CHEAT. All implementations must be genuine. DO NOT hardcode test results, create dummy/facade implementations, or circumvent the intended task. A teamwork_preview_auditor will independently verify your work. Integrity violations WILL be detected and your work WILL be rejected.

## Exclusive Write Ownership
- `c:\Projects\KieuStory\05_Production_Pipeline\production_orchestrator.py`
- `c:\Projects\KieuStory\02_AI_Prompts\gemini_banana_prompts.json`
- `c:\Projects\KieuStory\episodes\ep01\prompts\banana_prompts.json`
- `c:\Projects\KieuStory\tests\test_m3_challenger1_probe.py`
- READ-ONLY: `04_Assets/characters/` (DO NOT MODIFY OR DELETE)
- PRESERVE: `04_Assets/archive/ep01_legacy_v1/` (DO NOT MODIFY OR DELETE)

## Tasks to Execute in Exact Order:

1. **Update `02_AI_Prompts/gemini_banana_prompts.json` & `episodes/ep01/prompts/banana_prompts.json`**:
   - For `ep01_scene03_shot03` (both buckets: `ep01_start_frames` around line 550 and top-level around line 1679):
     Set `"character_anchor": "thuy_van"`.
     Update prompt text to reflect Thúy Vân ("Khuôn trăng đầy đặn nét ngài nở nang... Thúy Vân maiden...").
   - For `ep01_scene03_shot05` (both buckets):
     Set `"character_anchor": "thuy_van"`.
   - For `ep01_scene02_shot10` (both buckets):
     Set `"character_anchor": "vuong_ong"`.
   - For `ep01_scene08_shot08` (both buckets):
     Set `"character_anchor": "thuy_kieu_maiden"`.
   - Apply identical updates to `episodes/ep01/prompts/banana_prompts.json`.

2. **Harden `classify_shot_take` in `05_Production_Pipeline/production_orchestrator.py`**:
   - In `classify_shot_take(shot_id, prev_shot_id=None, shot_data=None)`:
     * If not `prev_shot_id`: determine `prev_shot_id = f"{scene_prefix}_shot{shot_num - 1:02d}"`.
     * Retrieve `all_ep01_shots = get_all_shots("ep01")`.
     * Retrieve `prev_data = all_ep01_shots.get(prev_shot_id, {})`.
     * Retrieve `curr_data = shot_data if shot_data is not None else all_ep01_shots.get(shot_id, {})`.
     * Check character asset reference change (Hard Gate):
       ```python
       prev_ref = prev_data.get("character_asset_ref", "")
       curr_ref = curr_data.get("character_asset_ref", "")
       if prev_ref and curr_ref:
           def _char_group(name: str) -> str:
               n = Path(name).stem.lower()
               for k in ["thuy_van", "thuy_kieu", "kim_trong", "vuong_ong", "vuong_ba", "vuong_quan", "dam_tien", "tieu_dong", "quan_gia"]:
                   if k in n:
                       return k
               return n
           if _char_group(prev_ref) != _char_group(curr_ref):
               return "CINEMATIC_CUT"
       ```
     * Pass `prev_data` when calling `get_character_anchor`:
       `prev_anchor = get_character_anchor(prev_shot_id, prev_data)`
     * If `curr_anchor != prev_anchor`:
       return `"CINEMATIC_CUT"`
     * In addition, check actor-switch keywords between previous and current shot titles/prompts.

3. **Defense-in-Depth in `resolve_start_frame`**:
   - In Step 1 of `resolve_start_frame`: if `take_type == "CONTINUOUS_TAKE"`, verify that if `prev_tail` exists, bilateral character safeguards are not violated before returning `prev_tail`. If violated, fall through to Step A/Step D.

4. **Defensive Gate in `batch_render_scene`**:
   - In `production_orchestrator.py:batch_render_scene` (around line 889):
     Change `if not scene_verdict.approved and scene_verdict.suggested_action == "RETAKE_SHOT": return False`
     to `if not scene_verdict.approved: return False`.

5. **Harden `tests/test_m3_challenger1_probe.py`**:
   - Add `test_classify_shot_take_actor_switches_are_cinematic_cuts()`:
     Verify `po.classify_shot_take("ep01_scene03_shot06") == "CINEMATIC_CUT"`.
     Verify `po.classify_shot_take("ep01_scene02_shot11") == "CINEMATIC_CUT"`.
     Verify `po.classify_shot_take("ep01_scene08_shot08") == "CINEMATIC_CUT"`.
     Verify 0 actor-switch mismatches across all 140 shots.
   - Add `test_simulated_tail_frame_actor_switch_prevents_face_leak()`:
     Simulate `clean_frame_239.jpg` in `04_Assets/keyframes/ep01_scene03_shot05/`.
     Call `po.resolve_start_frame_v2("ep01_scene03_shot06", shots["ep01_scene03_shot06"])`.
     Assert resolved path is Thúy Kiều portrait and does NOT leak Thúy Vân's tail frame.
     Clean up simulated tail frame cleanly.

6. **Run Full Verification Suites**:
   - `python -m pytest tests/test_m3_challenger1_probe.py -v`
   - `python -m pytest tests/test_production_pipeline_m3.py -v`
   - `python -m pytest tests/test_critic_gate.py -v`
   - `python -m pytest tests/test_m2_hygiene.py -v`
   - `python -m pytest tests/test_m1_challenger2_probe.py -v`
   - `pytest tests/test_tier1_features.py -k "not test_render" -v`
   Confirm 100% tests PASS across all suites without regressions.

7. **Deliver Handoff Report**:
   Write `c:\Projects\KieuStory\.agents\teamwork\worker_m3_remediation_3\handoff.md` and send message to parent orchestrator.
