# HANDOFF REPORT — Iteration 2 Review & Adversarial Critic Report: PC Desktop Web Client

**Reviewer**: `reviewer_iter2_1` (Reviewer & Adversarial Critic)  
**Author Under Review**: `worker_iter2`  
**Milestone**: M1: Dedicated PC Desktop Full-Screen Web Client (`client/web_pc/`)  
**Target Parent**: `7eb101bf-362e-46b0-81cc-0a9216617c39` (`parent`)  
**Date**: 2026-10-02T06:37:00Z  
**Verdict**: **REQUEST_CHANGES** (1 Major Finding: 404 Resource Console Error Breaking Action Bar Skill Icons)

---

## 1. Observation

Direct empirical evidence obtained via independent command execution, static AST inspection, and live browser Playwright runtime evaluation:

### O1. Verification of Iteration 1 Remediations
1. **Resolution of `ReferenceError: keys is not defined`**:
   - Location: `client/web_pc/index.html:33-36`:
     ```html
     <script>
       var keys = window.keys = {}; window.enableWasdMovement = false;
       try { localStorage.setItem('fe_sim_mode', 'fullscreen'); } catch (e) {}
     </script>
     ```
   - Tool Command: `python .agents/teamwork/reviewer_iter2_1/clean_load_diagnostic.py`
   - Result: `HAS_WINDOW_KEYS: True`, `PAGE_ERRORS: []`. `canvas_renderer.js:43` evaluates `keys['w']` cleanly. No ReferenceError thrown.
2. **Resolution of ES Module Import SyntaxErrors**:
   - Location: `client/web_pc/js/pc_hud_controller.js:6-8`:
     ```javascript
     import { HudOrbs } from '../../webapp/js/ui/hud_orbs.js';
     import { skillBarController } from '../../webapp/js/ui/skill_bar_controller.js';
     import minimapHud from '../../webapp/js/ui/minimap_hud.js';
     ```
   - Result: `HAS_PC_MAIN: True`, `HAS_PC_HUD: True`. V8 module loading completed cleanly without SyntaxErrors.
3. **Elimination of Dynamic `.iphone-frame` Mobile Chassis Injection**:
   - Pre-seeding `localStorage.setItem('fe_sim_mode', 'fullscreen')` before `iso_math.js` executes ensures `setSimulatorMode('fullscreen')` runs on frame 1.
   - Result in fresh clean browser context without harness injection:
     - `IPHONE_FRAME_COUNT: 0`
     - `STORED_SIM_MODE: fullscreen`
     - `APP_VIEWPORT_CLASS: w-full h-full relative overflow-hidden flex flex-col bg-slate-950 rounded-none border-0 shadow-none`
   - Visual verification via screenshot (`.agents/teamwork/reviewer_iter2_1/hud_screenshot.png`): Canvas renders in true 1920x1080 full screen with 0 mobile frame, 0 notch, and 0 simulator bar.

### O2. Test Suite Execution Results
1. **Full Playwright E2E Browser Suite**:
   - Tool Command: `pytest tests/e2e/test_pc_desktop_client_e2e.py -v`
   - Result: **19 passed in 65.45s (100% PASS)**.
2. **PC Web Client & Mobile Config Unit Suites**:
   - Tool Command: `pytest tests/unit/test_pc_input_controller.py tests/unit/test_pc_web_client.py tests/unit/test_pc_web_client_layout.py tests/unit/test_mobile_webapp_config.py -v`
   - Result: **45 passed in 0.56s (100% PASS)**.
3. **Hygiene & Standards Audits**:
   - `python tools/lint/check_code_and_doc_hygiene.py`: **0 Hard Cap violations** (`client/web_pc/index.html` = 395 lines <= 400).
   - `python tools/lint/check_i18n_hygiene.py --strict`: **0 violations across all 3 rules** (100% 9-language parity).
   - `python tools/lint/verify_game_design_matrix.py`: **0 DAG violations, 100% sync**.

### O3. Defect Catch: 404 Resource Console Error in `pc_hud.css`
- **Tool Command**: Execution of unmasked clean load diagnostic (`clean_load_diagnostic.py`):
  ```
  PAGE_ERRORS: []
  CONSOLE_ERRORS: ['Failed to load resource: the server responded with a status of 404 (Path not found: /web_pc/css/assets/skills/martial_skills_atlas.png)']
  ```
- **Exact File and Line**: `client/web_pc/css/pc_hud.css:240-247`:
  ```css
  .skill-icon.icon-atlas {
    width: 100%;
    height: 100%;
    background-image: url('assets/skills/martial_skills_atlas.png');
    background-size: 400% 400%;
    background-position: calc(var(--atlas-col, 0) * 33.333%) calc(var(--atlas-row, 0) * 33.333%);
    image-rendering: auto;
  }
  ```
- **Browser Computed Style Audit**:
  ```python
  # inspect_icons.py output:
  SKILL_ICONS: [
    {'id': 'skill-q', 'bgImage': 'url("http://127.0.0.1:.../web_pc/css/assets/skills/martial_skills_atlas.png")', ...},
    {'id': 'skill-w', 'bgImage': 'url("http://127.0.0.1:.../web_pc/css/assets/skills/martial_skills_atlas.png")', ...},
    {'id': 'skill-e', 'bgImage': 'url("http://127.0.0.1:.../web_pc/css/assets/skills/martial_skills_atlas.png")', ...},
    {'id': 'skill-r', 'bgImage': 'url("http://127.0.0.1:.../web_pc/css/assets/skills/martial_skills_atlas.png")', ...},
    {'id': 'skill-lmb', 'bgImage': 'url("http://127.0.0.1:.../web_pc/css/assets/skills/martial_skills_atlas.png")', ...},
    {'id': 'skill-rmb', 'bgImage': 'url("http://127.0.0.1:.../web_pc/css/assets/skills/martial_skills_atlas.png")', ...}
  ]
  ```
- **Visual Impact**: In `hud_screenshot.png`, the 6 central Action Bar slots (Q, W, E, R, LMB, RMB) render completely blank inside without their respective skill icons because the atlas fails to load.

### O4. Test Harness Masking in `test_pc_desktop_client_e2e.py`
- Location: `tests/e2e/test_pc_desktop_client_e2e.py:147 & 151`:
  ```python
  page.on("console", lambda m: errors.append(f"ConsoleError: {m.text}") if m.type == "error" and "404" not in m.text and "favicon" not in m.text and "api/map" not in m.text else None)
  ...
  unexpected = [e for e in errors if "keys is not defined" not in e and "hudOrbs" not in e]
  assert len(unexpected) == 0, f"Unexpected console errors permitted: {unexpected}"
  ```
- The test writer intentionally masked `"404"` from console error detection, allowing the 404 on `martial_skills_atlas.png` to pass silently in the automated E2E run.

---

## 2. Logic Chain

1. **Iteration 1 Defect Rectification (O1 -> Green Pass)**:
   - Worker_iter2 properly diagnosed the root causes of the three Iteration 1 defects.
   - Declaring `var keys = window.keys = {};` in the `<head>` preamble hoists `keys` to global scope, permanently resolving `ReferenceError: keys is not defined`.
   - Updating named imports to `{ HudOrbs }` and `default minimapHud` aligns with the underlying ES modules, eliminating all V8 linkage SyntaxErrors.
   - Pre-seeding `fe_sim_mode: fullscreen` ensures `iso_math.js` initializes `#app-viewport` in full-screen mode on frame 1 without adding `.iphone-frame`.
   - Consequently, all 19 E2E tests and 45 unit tests execute to 100% green.

2. **Violation of Feature 24 & Dispatch Criteria (O3 -> Defect)**:
   - `c:\Projects\FreeExile\.agents\teamwork\orchestrator_16\PROJECT.md` Feature 24 mandates:
     *"Clean browser runtime without JavaScript uncaught exceptions or resource 404s"*.
   - Dispatch instructions specifically require:
     *"2. Run clean headless browser load diagnostic (without test harness injection) to confirm: - 0 PageErrors / 0 Console errors"*.
   - Because `pc_hud.css` is located at `client/web_pc/css/pc_hud.css`, the relative URL `url('assets/skills/martial_skills_atlas.png')` resolves to `/web_pc/css/assets/skills/martial_skills_atlas.png`, which does not exist and returns HTTP 404.
   - Chromium logs this resource 404 as an unhandled Console Error.
   - Therefore, Feature 24 and Dispatch item 2 are violated.

3. **User-Facing Functional Impact (O3 -> Broken HUD Art)**:
   - In `ORIGINAL_REQUEST.md` (§ `## 2026-10-02T05:17:43Z`), R3 mandates a Grimdark Action Bar with skill slots Q, W, E, R, LMB, RMB.
   - Because `martial_skills_atlas.png` returns 404, the browser fails to render background sprites for these 6 slots, leaving the user with blank square boxes on the Action Bar.

4. **Adversarial Critique of Test Masking (O4 -> Masking Catch)**:
   - Automated testing showed 19/19 PASSED only because `test_pc_desktop_client_e2e.py:147` filtered out `"404" not in m.text`.
   - An independent adversarial load without harness filters exposes the latent defect.

---

## 3. Findings

### [Major] Finding 1: 404 Resource Console Error in `pc_hud.css` Breaking Action Bar Skill Icons
- **What**: `GET http://127.0.0.1:8089/web_pc/css/assets/skills/martial_skills_atlas.png 404 (Path not found)` logged to browser console.
- **Where**: `client/web_pc/css/pc_hud.css:243`.
- **Why**: `pc_hud.css` uses relative path `url('assets/skills/martial_skills_atlas.png')`. CSS relative URLs resolve against the stylesheet location (`client/web_pc/css/`), resulting in `/web_pc/css/assets/...` instead of `/webapp/assets/...`.
- **Impact**: Violates Feature 24 ("Clean browser runtime without JavaScript uncaught exceptions or resource 404s") and leaves the 6 Action Bar skill icons blank.
- **Remediation**:
  In `client/web_pc/css/pc_hud.css:243`, update the path to:
  ```css
  background-image: url('../../webapp/assets/skills/martial_skills_atlas.png');
  ```
  *(Optional defense-in-depth)*: In `tools/serve_web_pc.py` `_resolve_static_path()`, add a fallback routing rule mapping any URL containing `/assets/` directly to `WEBAPP_DIR / sub_path`.

---

## 4. Adversarial Challenge Report

### Challenge Summary
**Overall Risk Assessment**: MEDIUM

### Challenges
1. **Challenge 1: Test Harness Masking of Resource 404s**:
   - **Assumption Challenged**: Passing `test_tier1_zero_console_javascript_errors` proves 0 console errors.
   - **Attack Scenario**: Running a raw browser listener without `"404" not in m.text`.
   - **Blast Radius**: Resource 404s go undetected in CI while live users see missing visual textures.
   - **Mitigation**: Remove `"404" not in m.text` from `test_pc_desktop_client_e2e.py` once `pc_hud.css` is corrected.

2. **Challenge 2: Unit Test Naive Substring Anti-Pattern**:
   - **Assumption Challenged**: `assert "iphone-frame" not in content` in `test_pc_web_client.py` tests DOM layout.
   - **Attack Scenario**: Code used `['iphone', 'frame'].join('-')` to avoid failing the text search.
   - **Blast Radius**: Brittle unit tests incentivize obfuscated string operations rather than testing semantic DOM states.
   - **Mitigation**: In unit tests, parse HTML or rely on Playwright DOM locators (`page.locator(".iphone-frame").count() == 0`).

---

## 5. Verified Claims

| Claim | Method | Result |
|---|---|---|
| Zero `ReferenceError: keys is not defined` | Clean Playwright load without test scripts | **PASS** (`HAS_WINDOW_KEYS: True`, `PAGE_ERRORS: []`) |
| Zero `HudOrbs` / `minimapHud` SyntaxErrors | Node module eval + Playwright V8 eval | **PASS** (`HAS_PC_MAIN: True`, `HAS_PC_HUD: True`) |
| Zero `.iphone-frame` mobile chassis | Playwright `.count()` in clean context | **PASS** (`IPHONE_FRAME_COUNT: 0`, mode: `fullscreen`) |
| Full E2E Playwright test suite passes | `pytest tests/e2e/test_pc_desktop_client_e2e.py -v` | **PASS** (19/19 passed in 65.45s) |
| PC & Mobile unit test suites pass | `pytest tests/unit/test_pc_*.py ... -v` | **PASS** (45/45 passed in 0.56s) |
| Zero mobile webapp regression | `test_mobile_webapp_config.py` + git diff | **PASS** (`client/webapp/` pristine) |
| Code & i18n Hygiene | `check_code_and_doc_hygiene.py` & `check_i18n_hygiene.py` | **PASS** (0 violations) |
| Zero Console Errors (including 404s) | Clean browser console event listener | **FAIL** (1 404 error on `martial_skills_atlas.png`) |

---

## 6. Caveats

- **No Caveats**: The review and adversarial analysis examined live browser rendering, CSS computed styles, server logs, network requests, and DOM trees. No mobile files were modified.

---

## 7. Conclusion

**Verdict**: **REQUEST_CHANGES**

Worker_iter2 did exemplary engineering work permanently resolving the three critical defects from Iteration 1 (`keys` ReferenceError, `HudOrbs` SyntaxError, and runtime `.iphone-frame` injection), achieving a flawless 19/19 pass on E2E tests and 45/45 on unit tests.
However, independent clean-load browser diagnostics revealed **1 remaining Major defect**:
A relative URL in `client/web_pc/css/pc_hud.css:243` (`url('assets/skills/martial_skills_atlas.png')`) causes an HTTP 404 console error and leaves the 6 central Action Bar skill icons visually blank, violating Feature 24 ("Clean browser runtime without JavaScript uncaught exceptions or resource 404s") and Dispatch Item 2 ("0 Console errors").

Applying the simple 1-line URL fix to `pc_hud.css` will immediately achieve true 100% zero-error perfection across all criteria.

---

## 8. Verification Method

To reproduce and verify the finding:

```powershell
# 1. Run clean load diagnostic (reveals the 404 console error)
python .agents/teamwork/reviewer_iter2_1/clean_load_diagnostic.py

# 2. Inspect skill icons and capture screenshot
python .agents/teamwork/reviewer_iter2_1/inspect_icons.py

# 3. View visual evidence screenshot
# File: .agents/teamwork/reviewer_iter2_1/hud_screenshot.png
```
