# EMPIRICAL CHALLENGE HANDOFF REPORT: Milestone M1 Gate Verification

**Agent ID**: `challenger_m1_1`  
**Milestone**: M1 Gate Verification (2-Tier Quality Gate & Classifier)  
**Workspace**: `c:\Projects\KieuStory`  
**Timestamp**: 2026-10-09T04:14:00Z  
**Verdict**: **REQUEST_CHANGES** (2 High-Impact Vulnerabilities Discovered Empirically)

---

## 1. Observation

### 1.1 Baseline Test Runs & Execution Verbatim
1. **Baseline Critic Gate Test Suite**:
   - Command: `python -m pytest tests/test_critic_gate.py -v`
   - Result: 23 passed in 6.84s (all unit tests authored by worker passed).

2. **Adversarial Challenge Test Suite**:
   - Created: `tests/test_adversarial_critic_gate_m1.py` containing 29 adversarial test cases.
   - Command: `python -m pytest tests/test_adversarial_critic_gate_m1.py -v`
   - Result: 29 passed in 9.50s.

3. **Combined Test Execution**:
   - Command: `python -m pytest tests/test_critic_gate.py tests/test_adversarial_critic_gate_m1.py -v`
   - Result: 52 passed in 15.95s.

4. **Regression & Hygiene Verification**:
   - `python -m pytest tests/test_m2_hygiene.py -v`: 6 passed in 0.14s.
   - `python -m pytest tests/test_tier1_features.py -k "not test_render" -v`: 65 passed in 2.51s.

---

### 1.2 Empirical Failure Mode Observations (Reproducible Defects)

#### Observation 1: Frozen Still-Frames and Ultra-Short Videos Are Approved by Shot Gate
- **Location**: `05_Production_Pipeline/antigravity_critic_gate.py:388-396`
- **Verbatim Code**:
  ```python
  score = 1.0
  if not char_match:
      score -= 0.50
  if defects:
      score -= min(0.40, len(defects) * 0.15)
  if not audio_ok:
      score -= 0.15
  if squint_extra_limbs:
      score -= 0.20
  score = max(0.0, min(1.0, round(score, 3)))

  approved = score >= 0.8 and char_match and not squint_extra_limbs
  action = "APPROVE" if approved else "RETAKE_SHOT"
  ```
- **Direct Empirical Test**:
  Executing a 120-frame (5-second) completely frozen still-video render:
  ```powershell
  python -c "import sys, tempfile, cv2, numpy as np; sys.path.insert(0, '05_Production_Pipeline'); from antigravity_critic_gate import evaluate_shot_gate; f = tempfile.NamedTemporaryFile(suffix='.mp4', delete=False); out = cv2.VideoWriter(f.name, cv2.VideoWriter_fourcc(*'mp4v'), 24, (1280, 720)); [out.write(np.full((720, 1280, 3), 100, dtype=np.uint8)) for _ in range(120)]; out.release(); v = evaluate_shot_gate('shot1', f.name, force_engine='heuristic'); print('Frozen verdict:', v.overall_score, v.approved, v.suggested_action, v.shot_eval.visual_defects)"
  ```
- **Verbatim Output**:
  ```
  Frozen verdict: 0.85 True APPROVE ['Frozen video detected (virtually zero micro-motion across frames)']
  ```
- **Direct Empirical Test (Ultra-Short / 1-Frame Video)**:
  ```powershell
  python -c "import sys, tempfile, cv2, numpy as np; sys.path.insert(0, '05_Production_Pipeline'); from antigravity_critic_gate import evaluate_shot_gate; f = tempfile.NamedTemporaryFile(suffix='.mp4', delete=False); out = cv2.VideoWriter(f.name, cv2.VideoWriter_fourcc(*'mp4v'), 24, (1280, 720)); out.write(np.full((720, 1280, 3), 128, dtype=np.uint8)); out.release(); v = evaluate_shot_gate('shot1', f.name, force_engine='heuristic'); print('1-frame verdict:', v.overall_score, v.approved, v.suggested_action, v.shot_eval.visual_defects)"
  ```
- **Verbatim Output**:
  ```
  1-frame verdict: 0.85 True APPROVE ['Duration too short (0.0s, expected ~10s)']
  ```

---

#### Observation 2: Scene Gate False Positive Approval (Score 0.95) on Missing or Corrupt Files
- **Location**: `05_Production_Pipeline/antigravity_critic_gate.py:423-440` and `516-541`
- **Verbatim Code**:
  ```python
  # Line 423: Chỉ kiểm tra nếu list rỗng
  if not shot_video_paths or len(shot_video_paths) < 1:
      ... return 0.0 ...
  
  # Lines 451-455: Bỏ qua file không tồn tại hoặc không mở được
  for p_str in shot_video_paths:
      p = Path(p_str)
      if not p.exists():
          continue
      cap = cv2.VideoCapture(str(p))
      if not cap.isOpened():
          continue
      ...
  
  # Lines 516-522: Nếu không trích xuất được frame nào, pair_count <= 0, junction_scores = []
  avg_junction = float(np.mean(junction_scores)) if junction_scores else 0.95
  avg_color = float(np.mean(color_diffs)) if color_diffs else 0.95
  ...
  score = (avg_junction * 0.5 + avg_color * 0.5)  # -> 0.95
  score = max(0.0, min(1.0, round(score, 3)))
  approved = score >= 0.8                         # -> True
  action = "APPROVE"                              # -> APPROVE
  ```
- **Direct Empirical Test (Non-existent files)**:
  ```powershell
  python -c "import sys; sys.path.insert(0, '05_Production_Pipeline'); from antigravity_critic_gate import evaluate_scene_gate; v = evaluate_scene_gate('test_scene', ['nonexistent_1.mp4', 'nonexistent_2.mp4'], force_engine='heuristic'); print('Verdict:', v.overall_score, v.approved, v.suggested_action)"
  ```
- **Verbatim Output**:
  ```
  Verdict: 0.95 True APPROVE
  ```
- **Direct Empirical Test (Corrupted unreadable files)**:
  ```powershell
  python -c "import sys, tempfile; sys.path.insert(0, '05_Production_Pipeline'); from antigravity_critic_gate import evaluate_scene_gate; f1 = tempfile.NamedTemporaryFile(suffix='.mp4', delete=False); f1.write(b'CORRUPT1'); f1.close(); f2 = tempfile.NamedTemporaryFile(suffix='.mp4', delete=False); f2.write(b'CORRUPT2'); f2.close(); v = evaluate_scene_gate('test_scene', [f1.name, f2.name], force_engine='heuristic'); print('Verdict:', v.overall_score, v.approved, v.suggested_action)"
  ```
- **Verbatim Output**:
  ```
  Verdict: 0.95 True APPROVE
  ```

---

## 2. Logic Chain

1. **Pydantic Validation & Classifier Soundness (Ref: Observation 1.1)**:
   - Round-trip JSON serialization works seamlessly (`TestPydanticAdversarialSchema::test_roundtrip_complete_hierarchy`).
   - Boundary condition at 0.8000 is strictly adhered to: 0.7999 produces `approved=False`, 0.8000 produces `approved=True`.
   - Out-of-bounds numbers (-0.001, 1.001), NaNs, and Infs are strictly rejected by Pydantic v2.
   - Action override operates correctly: `suggested_action == "RETAKE_SHOT"` forces `approved=False` regardless of numeric score.
   - Classifier correctly separates `CINEMATIC_CUT` (start frame resolved independently) vs `CONTINUOUS_TAKE` (tail frame chained), with Kim Trọng safeguards active.

2. **Root Cause Analysis of Bug 1 — Shot Gate Leaks Frozen / Ultra-Short Videos (Ref: Observation 1.2 #1)**:
   - `antigravity_critic_gate.py` assigns penalty for generic visual defects via `score -= min(0.40, len(defects) * 0.15)`.
   - When a video render suffers a common AI motion-stall failure (generating a frozen still image for 5-10s), exactly 1 defect is reported: `"Frozen video detected (virtually zero micro-motion across frames)"`.
   - `len(defects) == 1`, deducting only `0.15`.
   - Final score: `1.0 - 0.15 = 0.85`.
   - Since `0.85 >= 0.8`, the gate approves the shot and emits `suggested_action = "APPROVE"`.
   - In production batching, this means frozen still frames generated by Muse.ai will pass without triggering an automated re-take, destroying cinematic motion and corrupting subsequent takes.

3. **Root Cause Analysis of Bug 2 — Scene Gate Approves Missing / Corrupt Files (Ref: Observation 1.2 #2)**:
   - `evaluate_scene_gate` only checks if `shot_video_paths` list is empty (`len < 1`).
   - When filenames are passed but files do not exist or are corrupt, OpenCV fails to open any frames.
   - `head_frames` and `tail_frames` are empty (`len == 0`).
   - Consequently, `pair_count <= 0`, no pairwise junction calculation occurs, and lines 516-517 fall back to default: `avg_junction = 0.95`, `avg_color = 0.95`.
   - Final score is computed as `0.95`, resulting in `approved = True` and `suggested_action = "APPROVE"`.
   - The scene gate greenlights missing or broken video files as pristine cinematic masters.

---

## 3. Caveats

- **Offline Heuristic Scope**: Tests were executed in the offline environment using the OpenCV/FFprobe Heuristic Engine (`force_engine="heuristic"`), which is the primary deterministic fallback gate and the foundation of local automated testing.
- **Pre-existing Workspace Files**: Untouched non-M1 files across `FilmMaker/` and `04_Assets/characters/` were left unmodified.
- No other caveats.

---

## 4. Conclusion & Verdict

**Verdict**: **REQUEST_CHANGES**

While the foundational architecture (Pydantic models, cut/take classifier, asset reference repairs, Kim Trọng safeguard) is well-constructed, the two empirical bugs identified will directly undermine automated production in Milestone M3:
1. Muse.ai frozen still-frame renders will pass the Shot Gate with score 0.85.
2. Missing or failed renders will pass the Scene Gate with score 0.95.

### Required Changes for Worker (`worker_m1_critic_1`):
1. **Fix Shot Gate Frozen / Duration Penalties** in `05_Production_Pipeline/antigravity_critic_gate.py`:
   - Treat frozen video and ultra-short duration (< 2.0s) as disqualifying defects:
     ```python
     # In evaluate_shot:
     if any("Frozen" in d or "Duration too short" in d for d in defects):
         score -= 0.25  # Ensures score drops to <= 0.75
     ```
     or set `score = min(score, 0.70)` when a frozen frame is detected.
2. **Fix Scene Gate Missing / Unreadable Frame Fallback** in `05_Production_Pipeline/antigravity_critic_gate.py`:
   - After decoding frames in `evaluate_scene`:
     ```python
     if len(head_frames) < 1 or len(tail_frames) < 1:
         return VideoCriticVerdict(
             overall_score=0.0,
             approved=False,
             scene_eval=SceneEvaluation(
                 junction_smoothness=0.0,
                 axis_180_ok=False,
                 eyeline_ok=False,
                 color_continuity=0.0,
                 score=0.0
             ),
             suggested_action="RETAKE_SHOT",
             critique_notes="Lỗi: Không tìm thấy hoặc không thể giải mã khung hình hợp lệ từ danh sách video."
         )
     ```

---

## 5. Verification Method

To independently verify these findings and reproduce the bugs:

```powershell
# 1. Reproduce Bug 1 (Frozen video receives 0.85 APPROVE):
python -c "import sys, tempfile, cv2, numpy as np; sys.path.insert(0, '05_Production_Pipeline'); from antigravity_critic_gate import evaluate_shot_gate; f = tempfile.NamedTemporaryFile(suffix='.mp4', delete=False); out = cv2.VideoWriter(f.name, cv2.VideoWriter_fourcc(*'mp4v'), 24, (1280, 720)); [out.write(np.full((720, 1280, 3), 100, dtype=np.uint8)) for _ in range(120)]; out.release(); v = evaluate_shot_gate('shot1', f.name, force_engine='heuristic'); print('Frozen verdict: score =', v.overall_score, '| approved =', v.approved, '| action =', v.suggested_action)"

# 2. Reproduce Bug 2 (Missing files in scene gate receive 0.95 APPROVE):
python -c "import sys; sys.path.insert(0, '05_Production_Pipeline'); from antigravity_critic_gate import evaluate_scene_gate; v = evaluate_scene_gate('test_scene', ['nonexistent_1.mp4', 'nonexistent_2.mp4'], force_engine='heuristic'); print('Missing files verdict: score =', v.overall_score, '| approved =', v.approved, '| action =', v.suggested_action)"

# 3. Verify All 52 Test Cases (23 existing + 29 adversarial):
python -m pytest tests/test_critic_gate.py tests/test_adversarial_critic_gate_m1.py -v
```

**Invalidation Conditions**:
- If Bug 1 is fixed such that frozen videos yield `overall_score < 0.80`, `approved == False`, and `suggested_action == "RETAKE_SHOT"`.
- If Bug 2 is fixed such that non-existent/corrupted file lists yield `overall_score == 0.0`, `approved == False`, and `suggested_action == "RETAKE_SHOT"`.
