# Handoff Report: Testing & Linting Infrastructure Investigation

- **Agent**: `explorer_survey_tests_1`
- **Working Directory**: `c:\Projects\FreeExile\.agents\teamwork\explorer_survey_tests_1`
- **Recipient**: `orchestrator_13` (Conversation ID: `0361e281-a64e-4264-a674-2b16c804009d`)
- **Date**: 2026-10-02

---

## 1. Observation

1. **Hardcoded Strings in Chat UI**:
   - `client/webapp/js/ui/chat_ui.js` contains 33 lines with hardcoded Vietnamese text:
     - Lines 7–14: Channel labels (`'Thế Giới'`, `'Khu Vực'`, `'Bang Hội'`, `'Đội Ngũ'`, `'Mật Thư'`, `'Hệ Thống'`, `'Chiêu Mộ'`, `'Góp Ý'`).
     - Line 18: Private isolated dictionary `CHANNEL_I18N`.
     - Lines 38–40: Rarity names (`'Phàm Phẩm'`, `'Linh Phẩm'`, `'Cực Phẩm'`, `'Thần Phẩm'`, `'Thái Cổ'`).
     - Line 42: Element names (`'Kim'`, `'Mộc'`, `'Thủy'`, `'Hỏa'`, `'Thổ'`).
     - Lines 124–128: Permission errors (`'Kênh Hệ Thống chỉ dành cho thông báo từ máy chủ.'`, `'Chưa gia nhập Bang Hội.'`, etc.).
     - Line 147: Input placeholder (`'Nhập tin nhắn [' + ch.label + ']...'`).
     - Lines 156, 163: Cooldown badges (`'Khóa'`, `'Chờ ' + sec + 's'`).
     - Lines 183–198: Item tooltip text (`'Vật Phẩm'`, `'Thiên Công'`, `'✓ HMAC Xác Thực'`, `'• Không có dữ liệu thuộc tính (Chưa xác thực)'`).
2. **DOM Element Localization Attributes**:
   - `client/webapp/index.html` lines 151–162 and `client/webapp/js/ui/templates/template_catalog_system.js` lines 438–455 define chat buttons (`.chat-channel-tab`, `#chat-send-btn`) and inputs (`#chat-input`) with static Vietnamese inner text and placeholders, lacking `data-i18n` and `data-i18n-placeholder` attributes.
3. **i18n Event Engine Capabilities**:
   - `client/webapp/js/data/i18n.js` lines 118–255 defines `FreeExileI18nEngine` with `setLocale(locale)`, `onLocaleChanged(callback)`, `updateDOM()`, and `window.dispatchEvent(new CustomEvent('freeexile:localeChanged', ...))`.
   - `client/webapp/js/ui/chat_ui.js` line 310 only attaches a listener to `#lang-select` (`change` event), failing to listen to `FreeExileI18n.onLocaleChanged` or the `window` custom event.
4. **Existing Linters in `tools/lint/`**:
   - `tools/lint/check_code_and_doc_hygiene.py` (373 lines) enforces code line caps ($\le 350$ soft, $\le 500$ hard) via Python AST and line scanning.
   - `tools/lint/verify_game_design_matrix.py` (128 lines) enforces database-to-doc synchronicity.
   - There is no linter currently checking for hardcoded Vietnamese strings or i18n key parity.
5. **Runtime Test Environment**:
   - Python 3.11.9, pytest 9.1.1, Node.js v24.14.0, npm 11.9.0.
   - Running `pytest tests/unit/test_challenger_chat_m2.py` passes 10/10 tests in 5.65s.
   - Running `pytest tests/unit/test_challenger_m2_chat_adversarial.py` passes 10/10 tests in 5.39s.
   - Running `pytest tests/e2e/test_ui_typography_i18n_wiki_streamlining_e2e.py` passes 60/60 tests in 0.26s.
   - Launching Playwright with `p.chromium.launch(channel='msedge', headless=True)` succeeded on Windows with exit code 0 (`MSEdge launch OK`).

---

## 2. Logic Chain

1. From Observation 1 and 3, `chat_ui.js` does not subscribe to the global i18n event bus and maintains hardcoded strings in its internal logic. Consequently, when a user changes language outside the `#lang-select` dropdown (e.g. settings modal or API), `chat_ui.js` receives zero updates.
2. From Observation 1, 2, and 4, without an automated static linter scanning for non-ASCII/Vietnamese text, future development will inevitably re-introduce hardcoded strings into UI modules. Implementing `tools/lint/check_i18n_hygiene.py` with diacritic regex detection and dictionary parity validation provides an authoritative automated gate.
3. From Observation 5, Node.js ES module evaluation under Python `unittest` is established in the repo and executes in < 6 seconds. Constructing `tests/unit/test_i18n_event_bus.py` following this exact pattern ensures high test speed and zero dependency overhead.
4. From Observation 5, Microsoft Edge is pre-installed on the host environment and launches headlessly via Playwright (`channel='msedge'`). This enables building a real browser E2E test `tests/e2e/test_i18n_reactive_switching_e2e.py` that confirms dynamic DOM updates without page reload (`page.reload()`).

---

## 3. Caveats

1. The static linter regex `[\u00C0-\u1EF9]` specifically targets Vietnamese accented characters; general ASCII text (e.g. English) cannot be classified as localized vs unlocalized by regex alone, so Rule 3 (verifying that all `data-i18n` references exist in `i18n_catalog.js`) is required as a complementary check.
2. Production code modifications are out of scope for this investigation agent; the concrete implementations for M1 (`chat_ui.js` refactoring and event bus attachment) and M2 (linter and test script creation) must be carried out by implementer subagents.

---

## 4. Conclusion

The testing and linting strategy for multi-tiered anti-regression is fully formulated and validated:
- **Linter**: `tools/lint/check_i18n_hygiene.py` will enforce zero hardcoded Vietnamese text in UI scripts and 100% dictionary parity across all 9 languages.
- **Unit Tests**: `tests/unit/test_i18n_event_bus.py` (23 test cases) will validate event bus registration, unsubscription, exception isolation, fallback chaining (`current -> en -> vi -> key`), and Chat UI reactive DOM rendering.
- **E2E Tests**: `tests/e2e/test_i18n_reactive_switching_e2e.py` using Playwright (`channel='msedge'`) will verify live reactive DOM updates upon language switching without reloading the page.
- **Milestone Gates**: Milestone 2 and Milestone 4 verification checklists are established to guarantee zero regression and 100% compliance.

---

## 5. Verification Method

To independently verify the facts and findings established in this investigation:

1. **Verify Hardcoded Strings in `chat_ui.js`**:
   ```bash
   python -c "import sys, re; sys.stdout.reconfigure(encoding='utf-8'); lines = open('client/webapp/js/ui/chat_ui.js', encoding='utf-8').readlines(); [print(f'Line {i}: {l.strip()}') for i, l in enumerate(lines, 1) if re.search(r'[\u00C0-\u1EF9]', l.split('//')[0])]"
   ```
   *Expected Result*: 33 matching lines printed.

2. **Verify Existing Unit Test Compatibility**:
   ```bash
   pytest tests/unit/test_challenger_chat_m2.py
   pytest tests/unit/test_challenger_m2_chat_adversarial.py
   ```
   *Expected Result*: 10 passed, 10 passed.

3. **Verify Playwright Edge Launch**:
   ```bash
   python -c "from playwright.sync_api import sync_playwright; p = sync_playwright().start(); b = p.chromium.launch(channel='msedge', headless=True); print('MSEdge OK'); b.close(); p.stop()"
   ```
   *Expected Result*: Prints `MSEdge OK`.

4. **Inspect Generated Report**:
   Inspect `file:///c:/Projects/FreeExile/.agents/teamwork/explorer_survey_tests_1/survey_report.md`.
