# Bug Backlog (from user report, 2026-08-11) Status legend: [x] fixed+tested, [~] partially addressed, [ ] open/needs input - [x] Allies and enemies seem to share indices. Investigated: `Board.add_target`/`add_ally` already use fully separate id namespaces by design (see `models.py`'s `Ally`/`Target` docstrings), confirmed with a new regression test (`test_ally_and_target_ids_are_independent_namespaces`). What was probably actually seen: an ally and a hostile target of the same type display with the *same name* ("Tank#1") on the map with no visual "ally" cue beyond icon/side color — related to the next item, which fixes one concrete instance of that (TargetType.ENEMY's "Enemy" label on an Ally). If the symptom persists after that, it's a display/ legibility issue, not an id collision — happy to take a screenshot of what's confusing. - [x] Ally type 'ally' is called Enemy on map title. `icons._target_type_label` (now public `icons.target_type_label`) already special-cased this for the type picker, but the map's right-click popover heading, "Change type (...)" button, and toast all printed `obj.type.value` directly instead, so an Ally with the ad-hoc TargetType.ENEMY still showed "Enemy" everywhere except the picker itself. Fixed in `app.py` (`_display_name`, and the three spots using it). - [x] Reordering firing commands lags UI hard. `FiringPanel._reorder()` was calling `self.on_change()` — app.py's full-app refresh (re-solve every target's clue graph, dedupe, redraw the map, THEN rebuild the panel) — on every single drag-drop, even though reordering touches no location/clue/coord state at all. Now calls a local `self.refresh()` instead. - [x] "Always show geo" doesn't reliably work / blast radius should stay shown too. `GridCanvas._draw_geo_overlays()`'s candidate list was `reference_points + targets` only — Allies have a `show_geo_desc` pin in the UI and can carry OCR'd clues too, but were never drawn. Added. `_draw_blast_radius()` only ever looked at `self.selected`, ignoring `show_geo_desc` entirely, so pinning it and then selecting/ deselecting something else made it vanish; now iterates every selected-or-pinned target. - [x] Clearing the board doesn't clear allies. `Board.clear()` cleared everything except `self.allies`. Fixed, plus the "clear board?" confirm-dialog's early-return guard (which skipped the whole action if only allies were on the board) now checks allies too. - [x] Allow right-click on Clear button: clear all enemies/units/flights, keep spotters/RPs/nest. New `Board.clear_units()` + a right-click popover on the header's Clear button wired to it. - [x] On map-reading error: save a screenshot locally to adapt the algo. New `debug_capture.py` — `save_map_read_failure()` writes the PNG + the solver's rejection reason under `$XDG_DATA_HOME/fenigma/debug_captures/failures/`, wired into `app.py`'s `_start_map_import`. - [x] When the user corrects the grid, store screenshot + ground truth too. `debug_capture.save_grid_correction()`, wired into `_accept_grid`: fires only when the accepted `GridSolution` isn't the one auto-solve produced (the user actually dragged a handle in GridFixDialog), saves both solutions under `.../debug_captures/corrections/`. - [x] Many map screenshots seem to get read as text; if nothing relevant is found, also store the image to check whether it was actually a map. `debug_capture.save_maybe_map()`, wired into `_ocr_png`: fires when a screenshot (not a plain-text paste) fell through to the OCR/text path and `_merge_all` found nothing at all. Saved under `.../debug_captures/maybe_map/`. - [x] Unable to parse 3 given chat messages (Infantry "taking fire" fire- support requests). A different grammar from the existing Marine Garrison fire-support request: reversed shell word order ("Requesting X Shell" vs "X Shells requested"), a bare "before/by