# DISPATCH: Milestone M4 Iteration 2 Remediation Worker (worker_m4_fix_1)

## Agent Identity
- Name: worker_m4_fix_1
- Archetype: teamwork_preview_worker
- Working Directory: c:\Projects\FreeExile\.agents\teamwork\worker_m4_fix_1
- Parent Conversation ID: 1cc48fc5-ce57-4f48-8964-24cab4bfcacc

## Authoritative User Request
MANDATORY: Read the authoritative user request at:
c:\Projects\FreeExile\.agents\teamwork\ORIGINAL_REQUEST.md (specifically section ## 2026-10-01T19:19:13Z - R4).
Also read c:\Projects\FreeExile\GEMINI.md and c:\Projects\FreeExile\AGENTS.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. A teamwork_preview_auditor will independently verify your work. Integrity violations WILL be detected and your work WILL be rejected.

## Iteration 1 Failure Context
In Milestone M4 Iteration 1, Reviewer `reviewer_m4_2` rejected the work with REQUEST_CHANGES due to:
1. Anti-Maphack Combat Target Leak in `client/webapp/js/engine/monster_system.js`:
   `getBestCombatTarget` (lines 102–116) falls back to `window.monster` without checking fog state or range (`return best || (window.monster && window.monster.hp > 0 ? window.monster : null);`). When `window.monster` is located in unexplored fog or across the map, player combat skills in `combat_skills.js` snap facing angle and fire slashes towards the hidden coordinates.
2. Self-Certifying / Facade Test Suite in `tests/unit/test_fog_and_minimap.py`:
   `TestDynamicIndicatorsAndThrottling` and `TestEntitySuppressionWiring` tested Python boolean tautologies (`assert (0 > 0) is False`, `assert ("#10b981" if True else "#ef4444") == "#10b981"`) and static string checks (`"WarFog.getFogState" in content`), masking the combat targeting leak.
3. Fog Persistence Robustness & Save Flush in `client/webapp/js/ui/war_fog.js`:
   - `initFog(width, height)` accepts negative/zero dimensions, corrupting bitpack headers.
   - `debouncedSave` lacks a `beforeunload` listener to flush pending saves on page exit/reload.
   - Line count is at 299/300 lines (only 1 line headroom below cap).

Consult the full failure report at:
`c:\Projects\FreeExile\.agents\teamwork\reviewer_m4_2\handoff.md`

## Required Remediation Actions
1. Fix `client/webapp/js/engine/monster_system.js`:
   In `getBestCombatTarget(originWx, originWy, maxRange = 7.5)`:
   - Ensure the fallback to `window.monster` strictly checks:
     - `window.monster.hp > 0`
     - Euclidean distance `Math.hypot(window.monster.wx - originWx, window.monster.wy - originWy) <= maxRange`
     - Fog state is VISIBLE: `(!window.WarFog?.getFogState) || window.WarFog.getFogState(Math.floor(window.monster.wx), Math.floor(window.monster.wy)) === 2`
   - If not visible or out of range, return `null`.
   - Keep `monster_system.js` strictly <= 490 lines (Hard cap 500 lines).

2. Fix `client/webapp/js/ui/war_fog.js`:
   - Sanitize input dimensions: `mapW = (typeof width === 'number' && width > 0) ? Math.floor(width) : 60;` and same for `mapH`.
   - Register `beforeunload` listener: `if (typeof window !== 'undefined' && typeof window.addEventListener === 'function') window.addEventListener('beforeunload', () => saveFog());`.
   - Compact minor helpers to gain safety headroom, keeping `war_fog.js` at <= 285 lines (Cap <= 300 lines).

3. Fix `tests/unit/test_fog_and_minimap.py`:
   - Eliminate all Python boolean tautologies (`assert (0 > 0) is False`, etc.).
   - Implement genuine runtime subprocess execution via Node.js:
     - Test that `getBestCombatTarget` returns `null` when a monster is in fog (`fogState = 0` or `1`).
     - Test that `getBestCombatTarget` returns the monster when it is in visible light (`fogState = 2`) and within range.
     - Test that `getBestCombatTarget` returns `null` when `window.monster` is out of range (> 7.5 tiles) even if visible.
     - Test `MinimapHUD` battery throttling and pause freezing via direct Node.js execution.
   - Keep `tests/unit/test_fog_and_minimap.py` strictly <= 300 lines.

## Verification Requirements
Run and verify all test suites:
- `pytest tests/unit/test_fog_and_minimap.py -v` (Must PASS all tests)
- `pytest tests/unit/test_tile_collision.py -v` (11/11 PASS)
- `pytest tests/unit/test_mobile_webapp_config.py -v` (15/15 PASS)
- `pytest tests/e2e/test_poe2_map_system_e2e.py -v` (81/81 PASS)
- `node tools/perf/map_render_benchmark.js` (Must PASS with 0 stationary re-bakes)
- `pytest tests/unit/ -q` (all unit tests must PASS with zero regressions)
- `python tools/lint/check_code_and_doc_hygiene.py --strict` (0 violations)

Write handoff.md in your working directory and notify parent when complete.
