The char index and rom id index sidecars are cached under a key that
encodes only user/order/grouping. is_unscoped previously excluded only
scope and search, so metadata/tag/status filters and the bool flags
applied to the query bypassed the gate: a filtered all-games request
stored a narrowed id list under the shared "all" key and later
unfiltered (or differently-filtered) requests read it back, showing the
wrong set and count of games.
Treat any narrowing parameter as scoped so those sets compute live.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Give all three tools the same header shape: shebang, summary docstring, a
short detail paragraph, and a "Run from the backend directory:" command
block. Adds docstrings to generate_supported_platforms.py and
xml_diagnostics.py, which previously had none.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Relocate generate_test_data.py (from backend/scripts) and
generate_supported_platforms.py (from backend/utils) into backend/tools,
alongside the existing xml_diagnostics.py. Update their run-command
references and document backend/tools in CLAUDE.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>