# Remediation Safeguards Final Specification (Milestone M1 Iteration 3)

**Author**: Explorer 3 (`explorer_m1_remediation_3`)  
**Date**: 2026-10-09  
**Target Milestone**: Milestone M1 Iteration 3 — Surgical Safeguards & Anchor Finalization  
**Scope**: `05_Production_Pipeline/production_orchestrator.py` & `tests/test_critic_gate.py`

---

## 1. Executive Summary

During Milestone M1 Iteration 2 Gate Verification, Reviewer 2 and Challenger 2 uncovered three specific edge-case vulnerabilities in `production_orchestrator.py`:
1. **Thúy Vân Safeguard Omission in Step C & Step D**: `is_thuy_van` was declared and applied in Step A, but omitted from Step C (L409–415) and Step D (L419–432), allowing Thúy Kiều asset references in `reference_start_frame` to leak into Thúy Vân shots.
2. **Compound Anchor Safeguard Neutralization**: In lines 344–348, the trailing `and "thuy_kieu" not in curr_anchor` disabled `is_kim_trong` whenever the anchor was joint (e.g., `ep01_scene10_shot07`: `"kim_trong + thuy_kieu_maiden"`), blinding Step A and Step D safeguards even when the shot title or motion prompt explicitly targeted Kim Trọng alone.
3. **Attendant Substring Shadowing**: In `resolve_character_portrait_from_anchor()`, `"kim_trong"` in clean string was evaluated before `"tieu_dong"`. Because the attendant anchor is `"tieu_dong_kim_trong"`, the substring `"kim_trong"` matched first, resolving attendant shots (`ep01_scene06_shot05`) to `kim_trong_18yo_720p.png` instead of `tieu_dong_kim_trong_720p.png`.

This document provides the exact code modifications, line-level drop-in replacements, and test hardening specifications to resolve all three issues cleanly and deterministically.

---

## 2. Target File Modifications

### File 1: `05_Production_Pipeline/production_orchestrator.py`

#### Patch 1.1: Heuristic Fallback in `get_character_anchor` (Lines 181–195)
**Problem**: `get_character_anchor()` had heuristic text fallbacks for Kim Trọng, Vương Quan, Vương Ông, and Thúy Kiều, but omitted Thúy Vân. When `shot_data` contained `"thúy vân"` in the title/prompt but had `character_anchor: "none"` or empty, `curr_anchor` evaluated to `""`, bypassing anchor resolution in Step B.

**Target Location**: Lines 181–195  
**Current Code**:
```python
    # Heuristic fallback dựa trên tiêu đề cảnh nếu anchor không tồn tại hoặc là none
    if shot_data:
        title = str(shot_data.get("scene_title", "")).lower()
        prompt = str(shot_data.get("motion_prompt", "")).lower()
        combined = f"{title} {prompt}"
        if "kim trọng" in combined and "thúy kiều" not in combined and "nàng kiều" not in combined:
            return "kim_trong"
        if "vương quan" in combined and "thúy kiều" not in combined:
            return "vuong_quan"
        if "vương ông" in combined and "thúy kiều" not in combined:
            return "vuong_ong"
        if ("thúy kiều" in combined or "nàng kiều" in combined) and "kim trọng" not in combined:
            return "thuy_kieu_maiden"
```

**Replacement Code**:
```python
    # Heuristic fallback dựa trên tiêu đề cảnh nếu anchor không tồn tại hoặc là none
    if shot_data:
        title = str(shot_data.get("scene_title", "")).lower()
        prompt = str(shot_data.get("motion_prompt", "")).lower()
        combined = f"{title} {prompt}"
        if "kim trọng" in combined and "thúy kiều" not in combined and "nàng kiều" not in combined:
            return "kim_trong"
        if "vương quan" in combined and "thúy kiều" not in combined:
            return "vuong_quan"
        if "vương ông" in combined and "thúy kiều" not in combined:
            return "vuong_ong"
        if "thúy vân" in combined and "thúy kiều" not in combined:
            return "thuy_van"
        if ("thúy kiều" in combined or "nàng kiều" in combined) and "kim trọng" not in combined:
            return "thuy_kieu_maiden"
```

---

#### Patch 1.2: Order of Precedence in `resolve_character_portrait_from_anchor` (Lines 236–287)
**Problem**: Attendant anchors such as `"tieu_dong_kim_trong"` contain the substring `"kim_trong"`. Because `"kim_trong"` was checked at line 238 while `"tieu_dong"` was checked at line 283, attendant shots resolved to Kim Trọng. Additionally, line 268 lacked `and "kim_trong" not in clean`, asymmetrically favoring Thúy Kiều on joint anchors.

**Target Location**: Lines 236–287  
**Current Code**:
```python
    clean = anchor.lower().strip()

    if "kim_trong" in clean and "thuy_kieu" not in clean:
        cand = CHARACTERS_DIR / "01_Main_Protagonists" / "kim_trong_18yo_720p.png"
        if cand.exists():
            return cand

    if "vuong_ong" in clean and "sai_nha" not in clean:
        cand = CHARACTERS_DIR / "02_Vuong_Family_And_Fate" / "vuong_ong_55yo_720p.png"
        if cand.exists():
            return cand

    if "vuong_ba" in clean and "sai_nha" not in clean:
        cand = CHARACTERS_DIR / "02_Vuong_Family_And_Fate" / "vuong_ba_50yo_720p.png"
        if cand.exists():
            return cand

    if "vuong_quan" in clean and "sai_nha" not in clean and "thuy_kieu" not in clean:
        cand = CHARACTERS_DIR / "02_Vuong_Family_And_Fate" / "vuong_quan_16yo_720p.png"
        if cand.exists():
            return cand

    if "dam_tien" in clean:
        cand = CHARACTERS_DIR / "02_Vuong_Family_And_Fate" / "dam_tien_720p.png"
        if cand.exists():
            return cand

    if "thuy_van" in clean and "thuy_kieu" not in clean:
        cand = CHARACTERS_DIR / "01_Main_Protagonists" / "thuy_van_maiden_16yo_720p.png"
        if cand.exists():
            return cand

    if "thuy_kieu" in clean:
        cand = CHARACTERS_DIR / "01_Main_Protagonists" / "thuy_kieu_maiden_16yo_720p.png"
        if cand.exists():
            return cand

    if "sai_nha" in clean:
        cand = CHARACTERS_DIR / "05_Imperial_Court_And_Officials" / "sai_nha_720p.png"
        if cand.exists():
            return cand

    if "thang_ban_to" in clean:
        cand = CHARACTERS_DIR / "05_Imperial_Court_And_Officials" / "thang_ban_to_720p.png"
        if cand.exists():
            return cand

    if "tieu_dong" in clean:
        cand = CHARACTERS_DIR / "02_Vuong_Family_And_Fate" / "tieu_dong_kim_trong_720p.png"
        if cand.exists():
            return cand
```

**Replacement Code**:
```python
    clean = anchor.lower().strip()

    # 1. Attendants và tiểu đồng kiểm tra TRƯỚC Kim Trọng để tránh bị nuốt chuỗi con (substring shadowing)
    if "tieu_dong" in clean:
        cand = CHARACTERS_DIR / "02_Vuong_Family_And_Fate" / "tieu_dong_kim_trong_720p.png"
        if cand.exists():
            return cand

    if "quan_gia_kim_trong" in clean:
        cand = CHARACTERS_DIR / "02_Vuong_Family_And_Fate" / "quan_gia_kim_trong_720p.png"
        if cand.exists():
            return cand

    # 2. Nhân vật chính
    if "kim_trong" in clean and "thuy_kieu" not in clean and "tieu_dong" not in clean and "quan_gia" not in clean:
        cand = CHARACTERS_DIR / "01_Main_Protagonists" / "kim_trong_18yo_720p.png"
        if cand.exists():
            return cand

    if "vuong_ong" in clean and "sai_nha" not in clean:
        cand = CHARACTERS_DIR / "02_Vuong_Family_And_Fate" / "vuong_ong_55yo_720p.png"
        if cand.exists():
            return cand

    if "vuong_ba" in clean and "sai_nha" not in clean:
        cand = CHARACTERS_DIR / "02_Vuong_Family_And_Fate" / "vuong_ba_50yo_720p.png"
        if cand.exists():
            return cand

    if "vuong_quan" in clean and "sai_nha" not in clean and "thuy_kieu" not in clean:
        cand = CHARACTERS_DIR / "02_Vuong_Family_And_Fate" / "vuong_quan_16yo_720p.png"
        if cand.exists():
            return cand

    if "dam_tien" in clean:
        cand = CHARACTERS_DIR / "02_Vuong_Family_And_Fate" / "dam_tien_720p.png"
        if cand.exists():
            return cand

    if "thuy_van" in clean and "thuy_kieu" not in clean:
        cand = CHARACTERS_DIR / "01_Main_Protagonists" / "thuy_van_maiden_16yo_720p.png"
        if cand.exists():
            return cand

    if "thuy_kieu" in clean and "kim_trong" not in clean:
        cand = CHARACTERS_DIR / "01_Main_Protagonists" / "thuy_kieu_maiden_16yo_720p.png"
        if cand.exists():
            return cand

    if "sai_nha" in clean:
        cand = CHARACTERS_DIR / "05_Imperial_Court_And_Officials" / "sai_nha_720p.png"
        if cand.exists():
            return cand

    if "thang_ban_to" in clean:
        cand = CHARACTERS_DIR / "05_Imperial_Court_And_Officials" / "thang_ban_to_720p.png"
        if cand.exists():
            return cand
```

---

#### Patch 1.3: Character Flags & Precedence in `resolve_start_frame` (Lines 344–348)
**Problem**: Compound anchors like `"kim_trong + thuy_kieu_maiden"` deactivated `is_kim_trong` because of `and "thuy_kieu" not in curr_anchor`, even when the title/prompt clearly indicated Kim Trọng alone.

**Target Location**: Lines 344–348  
**Current Code**:
```python
    is_kim_trong = ("kim_trong" in curr_anchor or ("kim trọng" in combined and "thúy kiều" not in combined and "nàng kiều" not in combined)) and "thuy_kieu" not in curr_anchor
    is_thuy_kieu = ("thuy_kieu" in curr_anchor or (("thúy kiều" in combined or "nàng kiều" in combined) and "kim trọng" not in combined)) and "kim_trong" not in curr_anchor
    is_vuong_quan = ("vuong_quan" in curr_anchor or ("vương quan" in combined and "thúy kiều" not in combined)) and "thuy_kieu" not in curr_anchor
    is_vuong_ong = ("vuong_ong" in curr_anchor or ("vương ông" in combined and "thúy kiều" not in combined)) and "thuy_kieu" not in curr_anchor
    is_thuy_van = ("thuy_van" in curr_anchor or ("thúy vân" in combined and "thúy kiều" not in combined)) and "thuy_kieu" not in curr_anchor
```

**Replacement Code**:
```python
    title_kt_only = ("kim trọng" in combined and "thúy kiều" not in combined and "nàng kiều" not in combined)
    title_tk_only = (("thúy kiều" in combined or "nàng kiều" in combined) and "kim trọng" not in combined)
    title_vq_only = ("vương quan" in combined and "thúy kiều" not in combined)
    title_vo_only = ("vương ông" in combined and "thúy kiều" not in combined)
    title_tv_only = ("thúy vân" in combined and "thúy kiều" not in combined)

    is_kim_trong = ("kim_trong" in curr_anchor and "thuy_kieu" not in curr_anchor and "tieu_dong" not in curr_anchor and "quan_gia" not in curr_anchor) or title_kt_only
    is_thuy_kieu = ("thuy_kieu" in curr_anchor and "kim_trong" not in curr_anchor) or title_tk_only
    is_vuong_quan = ("vuong_quan" in curr_anchor and "thuy_kieu" not in curr_anchor and "sai_nha" not in curr_anchor) or title_vq_only
    is_vuong_ong = ("vuong_ong" in curr_anchor and "thuy_kieu" not in curr_anchor and "sai_nha" not in curr_anchor) or title_vo_only
    is_thuy_van = ("thuy_van" in curr_anchor and "thuy_kieu" not in curr_anchor) or title_tv_only
```

---

#### Patch 1.4: Step C Violation Guard (Lines 409–415)
**Problem**: `is_thuy_van` was missing from Step C's `violation` check, allowing Thúy Kiều start frames to be resolved directly from `reference_start_frame`.

**Target Location**: Lines 409–415  
**Current Code**:
```python
                violation = (
                    (is_kim_trong and "thuy_kieu" in ref_name) or
                    (is_thuy_kieu and "kim_trong" in ref_name) or
                    (is_vuong_quan and "thuy_kieu" in ref_name) or
                    (is_vuong_ong and "thuy_kieu" in ref_name)
                )
                if not violation:
                    resolved_path = str(ref_path.resolve())
```

**Replacement Code**:
```python
                violation = (
                    (is_kim_trong and "thuy_kieu" in ref_name) or
                    (is_thuy_kieu and "kim_trong" in ref_name) or
                    (is_vuong_quan and "thuy_kieu" in ref_name) or
                    (is_vuong_ong and "thuy_kieu" in ref_name) or
                    (is_thuy_van and "thuy_kieu" in ref_name)
                )
                if not violation:
                    resolved_path = str(ref_path.resolve())
```

---

#### Patch 1.5: Step D Override & Fallback (Lines 419–433)
**Problem**: `is_thuy_van` was missing from Step D's override branches. Furthermore, if `resolved_path` was blocked by Step C's violation check and was not already set, `resolved_path` remained `None` rather than falling back to the canonical portrait of the character designated by the title/prompt.

**Target Location**: Lines 419–433  
**Current Code**:
```python
    # D. Final Bilateral & Multi-character Safeguards: Ghi đè tuyệt đối nếu có vi phạm
    if resolved_path:
        res_lower = resolved_path.lower()
        if is_kim_trong and "thuy_kieu" in res_lower:
            kt_portrait = CHARACTERS_DIR / "01_Main_Protagonists" / "kim_trong_18yo_720p.png"
            resolved_path = str(kt_portrait.resolve()) if kt_portrait.exists() else None
        elif is_thuy_kieu and "kim_trong" in res_lower:
            tk_portrait = CHARACTERS_DIR / "01_Main_Protagonists" / "thuy_kieu_maiden_16yo_720p.png"
            resolved_path = str(tk_portrait.resolve()) if tk_portrait.exists() else None
        elif is_vuong_quan and "thuy_kieu" in res_lower:
            vq_portrait = CHARACTERS_DIR / "02_Vuong_Family_And_Fate" / "vuong_quan_16yo_720p.png"
            resolved_path = str(vq_portrait.resolve()) if vq_portrait.exists() else None
        elif is_vuong_ong and "thuy_kieu" in res_lower:
            vo_portrait = CHARACTERS_DIR / "02_Vuong_Family_And_Fate" / "vuong_ong_55yo_720p.png"
            resolved_path = str(vo_portrait.resolve()) if vo_portrait.exists() else None
```

**Replacement Code**:
```python
    # D. Final Bilateral & Multi-character Safeguards: Ghi đè tuyệt đối nếu có vi phạm
    if resolved_path:
        res_lower = resolved_path.lower()
        if is_kim_trong and "thuy_kieu" in res_lower:
            kt_portrait = CHARACTERS_DIR / "01_Main_Protagonists" / "kim_trong_18yo_720p.png"
            resolved_path = str(kt_portrait.resolve()) if kt_portrait.exists() else None
        elif is_thuy_kieu and "kim_trong" in res_lower:
            tk_portrait = CHARACTERS_DIR / "01_Main_Protagonists" / "thuy_kieu_maiden_16yo_720p.png"
            resolved_path = str(tk_portrait.resolve()) if tk_portrait.exists() else None
        elif is_vuong_quan and "thuy_kieu" in res_lower:
            vq_portrait = CHARACTERS_DIR / "02_Vuong_Family_And_Fate" / "vuong_quan_16yo_720p.png"
            resolved_path = str(vq_portrait.resolve()) if vq_portrait.exists() else None
        elif is_vuong_ong and "thuy_kieu" in res_lower:
            vo_portrait = CHARACTERS_DIR / "02_Vuong_Family_And_Fate" / "vuong_ong_55yo_720p.png"
            resolved_path = str(vo_portrait.resolve()) if vo_portrait.exists() else None
        elif is_thuy_van and "thuy_kieu" in res_lower:
            tv_portrait = CHARACTERS_DIR / "01_Main_Protagonists" / "thuy_van_maiden_16yo_720p.png"
            resolved_path = str(tv_portrait.resolve()) if tv_portrait.exists() else None

    # Step D Fallback: Nếu vi phạm tại Step C khiến resolved_path là None, nạp chân dung chuẩn của nhân vật đích
    if not resolved_path:
        if is_kim_trong:
            p = CHARACTERS_DIR / "01_Main_Protagonists" / "kim_trong_18yo_720p.png"
            if p.exists(): resolved_path = str(p.resolve())
        elif is_thuy_kieu:
            p = CHARACTERS_DIR / "01_Main_Protagonists" / "thuy_kieu_maiden_16yo_720p.png"
            if p.exists(): resolved_path = str(p.resolve())
        elif is_vuong_quan:
            p = CHARACTERS_DIR / "02_Vuong_Family_And_Fate" / "vuong_quan_16yo_720p.png"
            if p.exists(): resolved_path = str(p.resolve())
        elif is_vuong_ong:
            p = CHARACTERS_DIR / "02_Vuong_Family_And_Fate" / "vuong_ong_55yo_720p.png"
            if p.exists(): resolved_path = str(p.resolve())
        elif is_thuy_van:
            p = CHARACTERS_DIR / "01_Main_Protagonists" / "thuy_van_maiden_16yo_720p.png"
            if p.exists(): resolved_path = str(p.resolve())
```

---

### File 2: `tests/test_critic_gate.py`

#### Patch 2.1: Test Hardening in `test_adversarial_bilateral_safeguards_override`
**Target Location**: Lines 560–572  
**Current Code**:
```python
        # 4. Cố tình gán Thúy Kiều vào cú máy Vương Ông đạo mạo -> Phải tự sửa thành Vương Ông
        adv_vo = {
            "character_asset_ref": "04_Assets/characters/01_Main_Protagonists/thuy_kieu_maiden_16yo_720p.png",
            "scene_title": "Vương Ông đĩnh đạc gia phong"
        }
        res_vo = po.resolve_start_frame("ep01_scene02_shot04", adv_vo)
        assert res_vo is not None
        assert "vuong_ong" in res_vo.lower()
        assert "thuy_kieu" not in res_vo.lower()
```

**Replacement Code**:
```python
        # 4. Cố tình gán Thúy Kiều vào cú máy Vương Ông đạo mạo -> Phải tự sửa thành Vương Ông
        adv_vo = {
            "character_asset_ref": "04_Assets/characters/01_Main_Protagonists/thuy_kieu_maiden_16yo_720p.png",
            "scene_title": "Vương Ông đĩnh đạc gia phong"
        }
        res_vo = po.resolve_start_frame("ep01_scene02_shot04", adv_vo)
        assert res_vo is not None
        assert "vuong_ong" in res_vo.lower()
        assert "thuy_kieu" not in res_vo.lower()

        # 5a. Cố tình gán Thúy Kiều qua character_asset_ref vào cú máy Thúy Vân -> Phải tự sửa thành Thúy Vân
        adv_tv_asset = {
            "character_asset_ref": "04_Assets/characters/01_Main_Protagonists/thuy_kieu_maiden_16yo_720p.png",
            "scene_title": "Thúy Vân trang trọng đoan trang",
            "motion_prompt": "Thúy Vân mỉm cười ung dung"
        }
        res_tv_asset = po.resolve_start_frame("ep01_scene01_shot05", adv_tv_asset)
        assert res_tv_asset is not None
        assert "thuy_van" in res_tv_asset.lower()
        assert "thuy_kieu" not in res_tv_asset.lower()

        # 5b. Cố tình gán Thúy Kiều qua reference_start_frame vào cú máy Thúy Vân -> Step C & D phải chặn và sửa thành Thúy Vân
        adv_tv_ref = {
            "reference_start_frame": "04_Assets/characters/01_Main_Protagonists/thuy_kieu_maiden_16yo_720p.png",
            "scene_title": "Thúy Vân trang trọng đoan trang",
            "motion_prompt": "Thúy Vân mỉm cười ung dung"
        }
        res_tv_ref = po.resolve_start_frame("ep01_scene01_shot05", adv_tv_ref)
        assert res_tv_ref is not None
        assert "thuy_van" in res_tv_ref.lower()
        assert "thuy_kieu" not in res_tv_ref.lower()

        # 6a. Cố tình gán Thúy Kiều vào cú máy compound anchor (ep01_scene10_shot07: kim_trong + thuy_kieu_maiden)
        # khi scene_title/motion_prompt chỉ rõ Kim Trọng -> Safeguard không bị vô hiệu hóa bởi anchor chung
        adv_kt_compound_asset = {
            "character_asset_ref": "04_Assets/characters/01_Main_Protagonists/thuy_kieu_maiden_16yo_720p.png",
            "scene_title": "Kim Trọng viết lời thề nguyền",
            "motion_prompt": "Kim Trọng cầm bút lông viết chữ"
        }
        res_kt_compound_asset = po.resolve_start_frame("ep01_scene10_shot07", adv_kt_compound_asset)
        assert res_kt_compound_asset is not None
        assert "kim_trong" in res_kt_compound_asset.lower()
        assert "thuy_kieu" not in res_kt_compound_asset.lower()

        # 6b. Cố tình gán Thúy Kiều qua reference_start_frame vào compound anchor shot ep01_scene10_shot07
        adv_kt_compound_ref = {
            "reference_start_frame": "04_Assets/characters/01_Main_Protagonists/thuy_kieu_maiden_16yo_720p.png",
            "scene_title": "Kim Trọng viết lời thề nguyền",
            "motion_prompt": "Kim Trọng cầm bút lông viết chữ"
        }
        res_kt_compound_ref = po.resolve_start_frame("ep01_scene10_shot07", adv_kt_compound_ref)
        assert res_kt_compound_ref is not None
        assert "kim_trong" in res_kt_compound_ref.lower()
        assert "thuy_kieu" not in res_kt_compound_ref.lower()

        # 7. Cú máy attendant tiểu đồng theo hầu (ep01_scene06_shot05: tieu_dong_kim_trong)
        # không bị nuốt chuỗi thành Kim Trọng mà phải ra đúng tiểu đồng
        res_td = po.resolve_start_frame("ep01_scene06_shot05", {})
        assert res_td is not None
        assert "tieu_dong" in res_td.lower()
        assert "01_main_protagonists" not in res_td.lower()
```

---

## 3. Verification Commands

The modifications can be independently verified using the following execution sequence:

```powershell
# 1. Verify Thúy Vân safeguard resilience (Step C & D)
python -c "
import sys
sys.path.insert(0, '05_Production_Pipeline')
import production_orchestrator as po

adv_tv = {
    'reference_start_frame': '04_Assets/characters/01_Main_Protagonists/thuy_kieu_maiden_16yo_720p.png',
    'scene_title': 'Thúy Vân trang trọng đoan trang',
    'motion_prompt': 'Thúy Vân mỉm cười ung dung'
}
res = po.resolve_start_frame('ep01_scene01_shot05', adv_tv)
print('Resolved Thúy Vân:', res)
assert 'thuy_van' in res.lower() and 'thuy_kieu' not in res.lower()
print('PASS: Thúy Vân protected against Thúy Kiều leakage!')
"

# 2. Verify Compound Anchor safeguard precedence on ep01_scene10_shot07
python -c "
import sys
sys.path.insert(0, '05_Production_Pipeline')
import production_orchestrator as po

adv_kt = {
    'character_asset_ref': '04_Assets/characters/01_Main_Protagonists/thuy_kieu_maiden_16yo_720p.png',
    'scene_title': 'Kim Trọng viết lời thề nguyền',
    'motion_prompt': 'Kim Trọng cầm bút lông viết chữ'
}
res = po.resolve_start_frame('ep01_scene10_shot07', adv_kt)
print('Resolved Compound Anchor:', res)
assert 'kim_trong' in res.lower() and 'thuy_kieu' not in res.lower()
print('PASS: Kim Trọng compound anchor protected against Thúy Kiều leakage!')
"

# 3. Verify Attendant substring resolution on ep01_scene06_shot05
python -c "
import sys
sys.path.insert(0, '05_Production_Pipeline')
import production_orchestrator as po

res = po.resolve_start_frame('ep01_scene06_shot05', {})
print('Resolved Attendant:', res)
assert 'tieu_dong' in res.lower() and '01_main_protagonists' not in res.lower()
print('PASS: Tiểu đồng resolved authentically without Kim Trọng shadowing!')
"

# 4. Run full quality gate test suites
python -m pytest tests/test_critic_gate.py -v
python -m pytest tests/test_m1_challenger2_probe.py -v
python -m pytest tests/test_adversarial_deep_probe.py -v
pytest tests/test_tier1_features.py -k "not test_render" -v
```
