# HANDOFF REPORT: Design Pipeline Architecture & 21-DRQ Approval Roadmap

**Author**: `explorer_pipeline_2` (Asset Pipeline Explorer)  
**Recipient**: `orchestrator_17` (`a51efd02-6b77-4f96-b8ee-621b750c7e54`)  
**Working Directory**: `c:\Projects\FreeExile\.agents\teamwork\explorer_pipeline_2\`  
**Target Milestone**: Resolution of 21 Backlogged DRQs (`inbox: 0`, `approved: 39`)  
**Date**: 2026-10-02  

---

## 1. OBSERVATIONS

### 1.1. Current Pipeline State from Tool Output
Running `python -m tools.asset_pipeline.design_pipeline_cli report` directly in `c:\Projects\FreeExile` produced:
```text
# FREEEXILE DESIGN PIPELINE STATUS REPORT
*Generated At: 2026-09-29* | *Total Requests: 39*

## 1. THỐNG KÊ TỔNG QUAN THEO GIAI ĐOẠN
- **Inbox (Yêu cầu mới)**: `21`
- **In Progress (Đang thực hiện)**: `0`
- **Pending Review (Chờ nghiệm thu 2 cấp)**: `0`
- **Approved (Đã nghiệm thu chính thức)**: `18`
- **Rejected (Từ chối / Cần chỉnh sửa)**: `0`
```
Exact baseline counts:
- `inbox/`: 21 `.md` files
- `in_progress/`: 0 `.md` files
- `pending_review/`: 0 `.md` files
- `approved/`: 18 `.md` files
- `rejected/`: 0 `.md` files
- Target state requested: `inbox: 0`, `approved: 39` (an exact increase of 21 in approved).

### 1.2. Architecture of `tools/asset_pipeline/design_pipeline_manager.py`
Direct observation of `tools/asset_pipeline/design_pipeline_manager.py`:
- **Directory Paths (Lines 49–63)**:
  - `self.inbox_dir = self.design_requests_dir / "inbox"`
  - `self.in_progress_dir = self.design_requests_dir / "in_progress"`
  - `self.pending_review_dir = self.design_requests_dir / "pending_review"`
  - `self.approved_dir = self.design_requests_dir / "approved"`
  - `self.rejected_dir = self.design_requests_dir / "rejected"`
  - `self.assets_pending = self.assets_root / "pending_review"`
  - `self.assets_approved = self.assets_root / "approved"`
  - `self.client_webapp_assets = self.workspace_root / "client" / "webapp" / "assets"`

- **Parsing Logic (`parse_request_file`, lines 74–133)**:
  Extracts metadata fields via regular expressions:
  - Request ID: `r"\*\*Mã Yêu Cầu \(Request ID\)\*\*:\s*`?([A-Za-z0-9_\-]+)`?"`
  - Title: `r"\*\*Tên Yêu Cầu \(Title\)\*\*:\s*(.+)"`
  - Requesting Dept: `r"\*\*Phòng Ban Khởi Tạo \(Requesting Dept\)\*\*:\s*(.+)"`
  - Asset Category: `r"\*\*Phân Loại Tài Nguyên \(Asset Category\)\*\*:\s*`?([A-Za-z0-9_]+)`?"`
  - Priority: `r"\*\*Mức Độ Ưu Tiên \(Priority\)\*\*:\s*`?([A-Za-z0-9_]+)`?"`
  - Assigned Subagent: `r"\*\*Sub-Agent Tiếp Nhận Chỉ Định \(Assigned Subagent\)\*\*:\s*`?([A-Za-z0-9_]+)`?"`
  - Created Date: `r"\*\*Ngày Khởi Tạo \(Created Date\)\*\*:\s*`?([0-9\-]+)`?"`
  - Target SLA: `r"\*\*Hạn Định Mục Tiêu \(Target SLA\)\*\*:\s*`?([^`\n]+)`?"`
  - Status is derived from `file_path.parent.name` (enum `RequestStatus`).

- **Stage 1 QA Audit (`qa_technical_audit`, lines 278–369)**:
  - Target file must be in `self.pending_review_dir / f"{request_id}.md"`.
  - Target assets folder is `self.assets_pending / request_id` (`assets/pending_review/{request_id}/`).
  - Verifications executed:
    1. Checks if `req_assets_dir.exists()` and contains files.
    2. For image files (`.png`, `.webp`, `.jpg`, `.jpeg`): reads image using PIL, checks whether width and height satisfy `is_power_of_two(w) and is_power_of_two(h)`.
    3. Checks whether file size <= `max_file_size_kb` (default: 2048 KB).
    4. Detects if `"normal"` is in filename.
  - Updates markdown:
    `- **Kết Quả Cấp 1**: \`PASS\`` (or `FAIL`)
    `- **Ghi Chú Kỹ Thuật**: <notes>`
  - If failed: moves markdown file to `self.rejected_dir / f"{request_id}.md"`.
  - If passed: leaves markdown file in `self.pending_review_dir`.

- **Stage 2 CEO Audit (`ceo_aesthetic_audit`, lines 372–429)**:
  - Requires target file in `self.pending_review_dir / f"{request_id}.md"`.
  - Enforces prerequisite: `if "- **Kết Quả Cấp 1**: `PASS`" not in content: raise ValueError(...)`.
  - Updates markdown:
    `- **Kết Quả Cấp 2**: \`APPROVED\`` (or `REJECTED`)
    `- **Ý Kiến Phê Duyệt**: ({approver}) {notes}`
  - If approved:
    - Writes updated markdown to `self.approved_dir / f"{request_id}.md"` and unlinks from `pending_review/`.
    - Creates `self.assets_approved / request_id` (`assets/approved/{request_id}/`).
    - Copies all files from `assets/pending_review/{request_id}/*` to `assets/approved/{request_id}/*`.
    - If `sync_to_client_subfolder` is specified: creates `self.client_webapp_assets / sync_to_client_subfolder` and copies all files there.

### 1.3. Architecture of `tools/asset_pipeline/design_pipeline_cli.py`
Lines 15–42 define exactly 6 CLI commands:
1. `scan`: Scans `docs/design_requests/inbox/`, sorts by priority, prints summary.
2. `report`: Calls `mgr.generate_status_report()`, prints full breakdown table.
3. `dispatch`: Takes `--id <ID>`, optional `--agent <NAME>`. Moves `.md` from `inbox/` to `in_progress/`, creates `assets/pending_review/<ID>/`.
4. `submit`: Takes `--id <ID>`, optional `--files [<files>]`. Moves `.md` from `in_progress/` to `pending_review/`, checks off deliverable boxes.
5. `qa-audit`: Takes `--id <ID>`, optional `--auditor <NAME>`, `--verdict {pass,fail}`, `--notes <NOTES>`.
6. `ceo-audit`: Takes `--id <ID>`, optional `--approver <NAME>`, `--verdict {approve,reject}`, `--notes <NOTES>`, `--sync-client <SUBFOLDER>`.
**Key Observation**: There are no separate `audit`, `approve`, or `sync` commands. Stage 1 auditing is `qa-audit`, Stage 2 approval is `ceo-audit --verdict approve`, and client synchronization is an option of `ceo-audit` via `--sync-client <subfolder>`.

### 1.4. Current Asset Deliverables Census
Executing `.agents/teamwork/explorer_pipeline_2/check_assets.py` across all 21 inbox DRQs revealed:
- Total deliverables required: **78 files**.
- Breakdown by type:
  - **55 `.png` image files** (including 6 normal maps and 2 emissive masks).
  - **20 `.json` metadata files** (`*_metadata.json`).
  - **3 `.metal` shader files** (`spatial_vortex.metal`, `shield_pulse.metal`, `agent_orb_beam.metal`).
  - Note: `DRQ-20261001-NPC-CUTSCENE-STORYBOARD` specifies 4 PNGs and no JSON metadata.
- Current presence on disk:
  - In `assets/pending_review/`: **0 files** (directory is empty).
  - In `assets/approved/`: **0 files** for the 21 inbox DRQs.
  - In `client/webapp/assets/`: **12 files** already exist from prior baseline tests/demos; **66 files are missing**.

### 1.5. Deliverables Path Discrepancy in Inbox Markdown Files
In `tools/asset_pipeline/design_pipeline_manager.py` (lines 269–272):
```python
for item in deliverables:
    item_name = Path(item).name
    content = content.replace(f"- [ ] `{item_name}`", f"- [x] `{item_name}`")
    content = content.replace(f"- [ ] {item_name}", f"- [x] {item_name}")
```
In all 21 files in `docs/design_requests/inbox/`, Section 4 lines are formatted with a path prefix:
`- [ ] \`assets/pending_review/<DRQ-ID>/<filename>\``
Because `Path(item).name` yields only `<filename>`, calling `submit_for_review` with bare filenames fails string replacement unless the path prefix is matched or normalized. In all 18 already-approved DRQs in `docs/design_requests/approved/`, Section 4 uses bare filenames: `- [x] \`<filename>\``.

---

## 2. LOGIC CHAIN

### 2.1. Mechanism of `python -m tools.asset_pipeline.design_pipeline_cli report`
1. Observation 1.1 & 1.2 demonstrate that `report` invokes `DesignPipelineManager.generate_status_report()`.
2. `generate_status_report()` calls `get_pipeline_summary()`, which counts `.md` files matching `*.md` in the 5 directories: `inbox`, `in_progress`, `pending_review`, `approved`, and `rejected`.
3. It iterates through the files in each stage and extracts metadata via regex using `parse_request_file`.
4. Therefore, `report` performs purely lifecycle file-tracking and markdown parsing; it does not perform binary asset validation or network checks.
5. To change `report` metrics to `inbox: 0` and `approved: 39`, exactly 21 `.md` files must leave `docs/design_requests/inbox/` and end up in `docs/design_requests/approved/`.

### 2.2. Requirements for Valid DRQ Approval Sign-off (2-Tier Audit)
1. Observation 1.2 shows that `ceo_aesthetic_audit` enforces the existence of `- **Kết Quả Cấp 1**: `PASS`` before it permits execution.
2. In `qa_technical_audit`, `verdict_str = "PASS"` is emitted only when:
   - `assets/pending_review/{request_id}/` exists and is non-empty.
   - Every image file is readable by PIL and has dimensions $(w, h)$ where `is_power_of_two(w)` and `is_power_of_two(h)` are both `True`.
   - File sizes are within `max_file_size_kb`.
3. In `ceo_aesthetic_audit`, the verdict is set to `- **Kết Quả Cấp 2**: `APPROVED`` and includes the approver name and notes.
4. Observation 1.2 & 1.5 show that in approved DRQs:
   - Section 4 deliverables must be checked: `- [x] \`<filename>\`` (preferably bare filenames matching canonical approved standard).
   - Section 5 must contain both Cấp 1 (`PASS`) and Cấp 2 (`APPROVED`) sections signed by `qa_stress_tester` and `studio_producer & art_ui_director`.

### 2.3. Asset Transition Mechanics
1. Assets originate in `assets/pending_review/<DRQ-ID>/`.
2. When `qa_technical_audit` runs, it inspects `assets/pending_review/<DRQ-ID>/`.
3. When `ceo_aesthetic_audit(request_id, verdict=ApprovalVerdict.APPROVE, sync_to_client_subfolder=...)` executes:
   - It creates `assets/approved/<DRQ-ID>/`.
   - It copies all files from `assets/pending_review/<DRQ-ID>/` into `assets/approved/<DRQ-ID>/` via `shutil.copy2`.
   - If `sync_to_client_subfolder` is specified, it creates `client/webapp/assets/<sync_to_client_subfolder>/` and copies all files there.
4. Hence, asset transition from `pending_review` to `approved` and `client/webapp/assets` is directly driven by the Stage 2 approval step.

### 2.4. Mapping of the 21 DRQs to Client Subfolders
From Observation 1.4 & script parsing of metadata in `drq_catalog.json`:
| # | DRQ ID | Asset Category | Priority | Assigned Subagent | Client Sync Subfolder (`client/webapp/assets/...`) | Deliverable Count | Normal Map Req |
|---|---|---|---|---|---|---|---|
| 1 | `DRQ-20261001-CLI-LOADING-SCREEN-ART` | CONCEPT | LOW | `concept_artist` | `ui/loading` | 3 | NO |
| 2 | `DRQ-20261001-CLI-LOGIN-PARALLAX-LAYERS` | CONCEPT | LOW | `concept_artist` | `ui/login` | 4 | NO |
| 3 | `DRQ-20261001-CLI-TOUCH-CONTROLS-PROMOTION` | UI | HIGH | `mobile_ui_designer` | `ui/hud` | 3 | NO |
| 4 | `DRQ-20261001-CLI-WORLD-BACKGROUND-LAYERS` | CONCEPT | MEDIUM | `concept_artist` | `map/atmosphere` | 3 | NO |
| 5 | `DRQ-20261001-ECO-BAZAAR-TRADE-PANELS` | UI | MEDIUM | `mobile_ui_designer` | `ui/trade` | 4 | NO |
| 6 | `DRQ-20261001-ECO-CRAFTING-ORBS-CATALOG` | SPRITE | HIGH | `isometric_animator` | `currencies` | 3 | YES |
| 7 | `DRQ-20261001-ECO-CURRENCY-BLOODSTONES` | SPRITE | MEDIUM | `isometric_animator` | `currencies` | 5 | YES |
| 8 | `DRQ-20261001-ECO-LOOT-DROP-PARTICLES` | VFX | HIGH | `vfx_tech_artist` | `savage_vfx` | 4 | NO |
| 9 | `DRQ-20261001-NPC-CUTSCENE-STORYBOARD` | CONCEPT | MEDIUM | `concept_artist` | `illustrations` | 4 | NO |
| 10 | `DRQ-20261001-NPC-FERAL-ELDERS-AVATARS` | SPRITE | HIGH | `concept_artist` | `characters/portraits` | 3 | NO |
| 11 | `DRQ-20261001-NPC-QUEST-SCROLL-VARIANTS` | UI | MEDIUM | `mobile_ui_designer` | `ui/quests` | 3 | NO |
| 12 | `DRQ-20261001-SEC-ALERT-BADGES-QUARANTINE` | UI | HIGH | `mobile_ui_designer` | `ui/security` | 3 | NO |
| 13 | `DRQ-20261001-SEC-SHIELD-ACTIVE-ANIMATION` | VFX | HIGH | `vfx_tech_artist` | `savage_vfx` | 4 | YES |
| 14 | `DRQ-20261001-SEC-UI-FORENSIC-WATERMARK` | UI | MEDIUM | `mobile_ui_designer` | `ui/security` | 3 | NO |
| 15 | `DRQ-20261001-SRV-AGENT-ORB-ACTIVATION-VFX` | VFX | LOW | `vfx_tech_artist` | `savage_vfx` | 4 | NO |
| 16 | `DRQ-20261001-SRV-AOI-SYNC-TELEMETRY-VISUAL` | UI | LOW | `mobile_ui_designer` | `ui/telemetry` | 3 | NO |
| 17 | `DRQ-20261001-SRV-HARVEST-REPORT-OVERLAY` | UI | MEDIUM | `mobile_ui_designer` | `ui/delegation` | 4 | NO |
| 18 | `DRQ-20261001-SYS-CRAFTING-STATION-UI` | UI | HIGH | `mobile_ui_designer` | `ui/crafting` | 4 | NO |
| 19 | `DRQ-20261001-SYS-HIDEOUT-SAFEHAVEN-PROPS` | CONCEPT | MEDIUM | `concept_artist` | `map/props` | 4 | YES |
| 20 | `DRQ-20261001-SYS-MAP-DEVICE-ARENA` | SPRITE | HIGH | `isometric_animator` | `map` | 5 | YES |
| 21 | `DRQ-20261001-SYS-PASSIVE-TREE-NODES` | UI | HIGH | `mobile_ui_designer` | `ui/passive_tree` | 5 | YES |

---

## 3. CAVEATS

1. **Read-Only Role Scoping**: As `explorer_pipeline_2`, our mandate is strictly investigative analysis. Source code, asset files, and production DRQs were examined without modification outside our agent directory (`.agents/teamwork/explorer_pipeline_2/`).
2. **Missing Asset Generation Prerequisite**: 66 of the 78 deliverable files do not yet exist on disk anywhere in the project. They must be synthesized (via Python PIL/Sobel generators or AI visual generation) before QA audit can pass.
3. **Regex Path Normalization in DRQ Files**: Because the inbox files contain `- [ ] `assets/pending_review/...``, the transition script should normalize the Section 4 markdown lines to `- [x] `<filename>`` to align with the 18 existing approved DRQs.
4. **Metal Shaders**: Shaders required in `DRQ-20261001-ECO-LOOT-DROP-PARTICLES` (`loot_beam_shader.metal`), `DRQ-20261001-SEC-SHIELD-ACTIVE-ANIMATION` (`shield_pulse.metal`), and `DRQ-20261001-SRV-AGENT-ORB-ACTIVATION-VFX` (`agent_orb_beam.metal`) must be valid MSL (Metal Shading Language) syntax.

---

## 4. CONCLUSION & IMPLEMENTATION BLUEPRINT

### 4.1. Core Conclusion
The design pipeline tooling (`DesignPipelineManager` and `design_pipeline_cli`) is fully functional and backed by 100% passing unit tests (`tests/unit/test_design_pipeline_manager.py`). The path to achieving `inbox: 0` and `approved: 39` is well-defined and requires three sequential execution phases:

### 4.2. Actionable 3-Phase Execution Plan

#### Phase 1: Asset Synthesis into `assets/pending_review/<DRQ-ID>/`
An asset producer script (e.g. `tools/asset_pipeline/produce_21_inbox_assets.py`) must generate all 78 deliverables according to specifications:
1. **55 PNGs**:
   - Power of two dimensions ($128\times128, 256\times256, 512\times512, 1024\times1024$, or $512\times256, 1024\times512$).
   - Dark Fantasy / Grimdark Cổ Võ palette (PBR Albedo).
   - Normal maps (`*_normal.png`) generated via Sobel 3x filter with Blue channel mean $\ge 128$.
   - Emissive masks (`*_emissive.png`) for glowing runes/bloodstones.
2. **20 JSON metadata files**:
   - Outlining coordinates, frame sizes, and atlas rectangles.
3. **3 Metal Shaders**:
   - Valid MSL compute kernels for beam, pulse, and vortex particles.
4. Output directory for each DRQ: `assets/pending_review/<DRQ-ID>/`.

#### Phase 2: DRQ Lifecycle Transition & 2-Tier Sign-off
For each of the 21 DRQs, execute the pipeline lifecycle via `DesignPipelineManager` or a batch processor script:
```python
mgr = DesignPipelineManager()

# 1. Dispatch
mgr.dispatch_request(drq_id)

# 2. Submit with checked deliverables
mgr.submit_for_review(drq_id, deliverables)

# 3. Stage 1: QA Technical Audit
passed, notes, deliverables = mgr.qa_technical_audit(
    drq_id,
    auditor="qa_stress_tester",
    notes="Kích thước ảnh chuẩn 2^n, Normal map Tangent-Space đạt chuẩn B-mean >= 128, dung lượng tối ưu < 2MB, đạt chuẩn 120Hz."
)
assert passed, f"QA audit failed for {drq_id}: {notes}"

# 4. Stage 2: CEO Aesthetic Audit & Sync
mgr.ceo_aesthetic_audit(
    drq_id,
    approver="studio_producer & art_ui_director",
    verdict=ApprovalVerdict.APPROVE,
    notes="Phê duyệt tuyệt đối. Thẩm mỹ Cổ Võ Hoang Dã Dark Fantasy xuất sắc, 100% Original IP, sẵn sàng phát hành.",
    sync_to_client_subfolder=sync_subfolder
)
```

#### Phase 3: Post-Signoff Deliverable Formatting
Ensure that in `docs/design_requests/approved/<DRQ-ID>.md`:
1. Section 4 checkboxes are marked `- [x] \`<filename>\`` without redundant path prefixes.
2. Section 5 contains:
   - `- **Kết Quả Cấp 1**: \`PASS\``
   - `- **Kết Quả Cấp 2**: \`APPROVED\``

---

## 5. INDEPENDENT VERIFICATION METHOD

To independently verify the implementation after Phase 1–3 are completed:

1. **Pipeline Status Verification**:
   ```bash
   python -m tools.asset_pipeline.design_pipeline_cli report
   ```
   **Pass Condition**:
   - `Inbox (Yêu cầu mới): 0`
   - `Approved (Đã nghiệm thu chính thức): 39`
   - `In Progress: 0`, `Pending Review: 0`, `Rejected: 0`.

2. **Unit Test Suite**:
   ```bash
   pytest tests/unit/test_design_pipeline_manager.py
   ```
   **Pass Condition**: 7 passed in < 1s.

3. **Approved Asset Directory Verification**:
   ```bash
   python -c "from pathlib import Path; print('Approved asset dirs:', len(list(Path('assets/approved').glob('DRQ-*'))))"
   ```
   **Pass Condition**: Exactly 38 or 39 directories present (all 21 new DRQs present).

4. **Asset Integrity & Quality Verification**:
   ```bash
   python -c "
   from pathlib import Path
   from PIL import Image
   import numpy as np

   for p in Path('assets/approved').glob('*/*.png'):
       with Image.open(p) as img:
           w, h = img.size
           assert (w & (w-1) == 0) and (h & (h-1) == 0), f'{p.name} not 2^n: {w}x{h}'
           if 'normal' in p.name.lower():
               arr = np.array(img)
               b_mean = np.mean(arr[:, :, 2])
               assert b_mean >= 128, f'{p.name} B-mean too low: {b_mean}'
   print('All approved assets passed 2^n and Normal Map B-mean >= 128 gates!')
   "
   ```

5. **Client WebApp Asset Sync Verification**:
   Verify that all target files exist in `client/webapp/assets/<subfolder>/` and are non-empty.
