## 2026-10-02T01:51:10Z
You are worker_m1_1.
Working directory: c:\Projects\FreeExile\.agents\teamwork\worker_m1_1
Authoritative request: c:\Projects\FreeExile\.agents\teamwork\ORIGINAL_REQUEST.md (specifically section ## 2026-10-02T01:42:06Z). You MUST read this file first.
Project scope: c:\Projects\FreeExile\.agents\teamwork\orchestrator_13\PROJECT.md
Survey reports to study:
- c:\Projects\FreeExile\.agents\teamwork\explorer_survey_chat_1\survey_report.md
- c:\Projects\FreeExile\.agents\teamwork\explorer_survey_i18n_1\survey_report.md
- c:\Projects\FreeExile\.agents\teamwork\explorer_survey_tests_1\survey_report.md

MANDATORY INTEGRITY WARNING:
DO NOT CHEAT. All implementations must be genuine. DO NOT hardcode test results, create dummy/facade implementations, or circumvent the intended task. An auditor will independently verify your work. Integrity violations WILL be detected and your work WILL be rejected.

Your exclusive write ownership files:
- client/webapp/js/data/i18n.js
- client/webapp/js/data/i18n_catalog.js (or client/webapp/js/data/chat_i18n_catalog.js)
- client/webapp/js/ui/chat_ui.js
- client/webapp/index.html (only chat dock / tooltip elements)
- client/webapp/js/ui/templates/template_catalog_system.js (only chat dock / tooltip templates)

Mission: Implement Milestone 1 — Reactive i18n Event Bus & Chat UI Full Localization.

Tasks:
1. Core i18n Event Bus:
   - Enhance FreeExileI18nEngine in client/webapp/js/data/i18n.js:
     - Add subscribe(callback) returning an unsubscribe function.
     - Ensure setLocale(locale) updates this.currentLocale, persists to localStorage['freeexile_locale'], syncs #lang-select if present, calls updateDOM(document), triggers all subscribers, and dispatches window.dispatchEvent(new CustomEvent('freeexile:localeChanged', { detail: { locale, prevLocale, dict } })).
     - Add listener for freeexile:templateMounted and freeexile:templatesMounted to call updateDOM(e.detail.element || document).
     - Add cross-window storage event listener for freeexile_locale.
     - Maintain i18n.js <= 350 lines (soft cap).

2. Master 9-Language Chat Dictionaries:
   - Register all needed chat keys in i18n_catalog.js (or via chat_i18n_catalog.js imported into catalog) across all 9 languages (vi, en, zh, ja, ko, th, de, ru, es):
     - Channels: channel_world, channel_zone, channel_guild, channel_party, channel_whisper, channel_system, channel_recruit, channel_feedback.
     - Permissions: chat_perm_system_only, chat_perm_guild_required, chat_perm_party_required, chat_perm_level_world, chat_perm_level_recruit, chat_perm_muted.
     - Microcopy: chat_input_placeholder, chat_input_placeholder_default, chat_badge_locked, chat_badge_wait, chat_btn_send, chat_ticker_default, chat_sender_fallback, chat_system_sender, chat_system_alert_prefix.
     - Rarities & Elements: rarity_1 to rarity_5, element_metal, element_wood, element_water, element_fire, element_earth.
     - Tooltip & Badges: chat_item_fallback_name, chat_item_element_suffix, chat_item_level, chat_item_level_unknown, chat_item_crafter_default, chat_item_crafter_unknown, chat_item_unverified_affixes, chat_item_no_affixes, chat_item_badge_verified, chat_item_badge_unverified, chat_item_crafter_label.
   - Enforce 100% key parity across all 9 languages.

3. Chat UI Complete Overhaul (client/webapp/js/ui/chat_ui.js):
   - Replace isolated #lang-select DOM listener with subscription to freeexile:localeChanged and window.FreeExileI18n.onLocaleChanged.
   - Remove inline CHANNEL_I18N data silo; replace with lookup to window.FreeExileI18n.t(...) (maintain export const CHANNEL_I18N as a proxy/alias for backwards-compatibility with tests).
   - In initChatUI(): read stored locale on boot (window.FreeExileI18n.getLocale()), call updateLanguage(currentLocale), and guard against duplicate listeners.
   - In updateLanguage(lang):
     - Update all channel tab labels (.chat-channel-tab).
     - Update CHANNELS[id].label with translated channel names.
     - Update ticker channel badge and default ticker placeholder if not showing an active message.
     - Update input placeholder dynamically via updateInputPlaceholder().
     - Update cooldown badge via updateCooldownUI().
     - Update send button (#chat-send-btn).
     - Re-render active chat log messages (renderChatLog()) in-place so channel tags and timestamps reflect current locale.
     - If item tooltip modal is open, re-render it with localized rarity, element, crafter, and verification status.
   - Zero hardcoded Vietnamese strings remaining in chat_ui.js.
   - CRITICAL CONSTRAINT: chat_ui.js MUST remain <= 350 lines (Soft Cap in GEMINI.md).

4. HTML & Template synchronization:
   - Add data-i18n attributes to chat dock tabs, ticker, input placeholder, send button in client/webapp/index.html and client/webapp/js/ui/templates/template_catalog_system.js.

5. Verification & Testing:
   - Run existing tests: pytest tests/unit/test_webapp_chat_ui.py (all 18 tests MUST pass).
   - Run pytest tests/unit/test_challenger_chat_m2.py and pytest tests/unit/test_challenger_m2_chat_adversarial.py.
   - Run python tools/lint/check_code_and_doc_hygiene.py --strict to verify line caps.

6. Reporting:
   - Write implementation report to c:\Projects\FreeExile\.agents\teamwork\worker_m1_1\implementation_report.md.
   - Write standard 5-component handoff.md in your working directory.
   - Send completion message back to orchestrator_13.
