Skip to content

fix(i18n): stop matching STALE-commented lines as live, revive 56 wrongly-dead keys (FIX-I18N-STALE-COMMENT-PARSING) - #119

Merged
FullGas1 merged 3 commits into
developfrom
fix/i18n-stale-comment-parsing
Aug 10, 2026
Merged

fix(i18n): stop matching STALE-commented lines as live, revive 56 wrongly-dead keys (FIX-I18N-STALE-COMMENT-PARSING)#119
FullGas1 merged 3 commits into
developfrom
fix/i18n-stale-comment-parsing

Conversation

@FullGas1

@FullGas1 FullGas1 commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • The shared i18n dict parser (i18n_dict_utils.py), generate_i18n_dicts.ps1's Get-DictKeys, and translate_i18n.py's _apply_translations all matched a ctld.i18n[...] = "..." line regardless of a -- STALE: comment prefix, making a dead key indistinguishable from a live one. All three now skip any line starting with --.
  • Discovered while fixing it, much bigger than originally scoped: re-running the corrected generate_i18n_dicts.ps1 -Apply surfaced that 56 keys - every HAWK/BUK/KUB/NASAMS/Patriot/S-300 AA system label, several F10 menu labels, and 7 vehicle-category labels - were wrongly marked -- STALE: in all four dictionaries including English, almost certainly predating the script's config-YAML desc:/name: scan (these keys are referenced there, not via ctld.tr()). At runtime this meant ctld.i18n["en"]["HAWK Launcher"] and 55 others were nil - broken/missing F10 and AA-system text in every language, not a KO/ES-only cosmetic issue. This is a live production bug fix, not just a parsing correctness improvement.
  • -Apply revived all 56 keys (EN's text restored automatically, since EN's value always equals its key). The FR/ES/KO translations sitting inert in the old commented lines were hand-recovered into the freshly revived entries rather than lost or re-translated from scratch. Genuinely new stubs (7 category labels in KO/ES, 15 never-translated KO labels - all pre-existing debt unrelated to this bug) are left empty for a future translation pass.
  • No change to MISSING/STALE classification rules - only to how "present in a dictionary" is determined. check_i18n_diff.py needed no code change (inherits the fix via the shared parser).
  • Grilled with docs 2026-08-10. No ADR - a bug fix, not a design trade-off. Lot: .backlog/FIX-I18N-STALE-COMMENT-PARSING/ - PRD plus 1 ticket.

Test plan

  • pytest tools/build/ - 24/24 green (5 new tests: STALE-line exclusion in parse_dict/parse_keep_en, _apply_translations skipping a STALE-only line and writing a live one)
  • luac -p clean on all 4 modified dictionary files
  • generate_i18n_dicts.ps1 dry-run: 0 MISSING before the real-file fix reported the 56 revived keys as expected; final dry-run after -Apply + translation recovery reports OK on all four dictionaries
  • Manually verified the recovered FR/ES/KO translations landed in the correct freshly-revived lines (spot-checked via diff and grep)
  • CI green on this PR

Generated with Claude Code

Summary by Sourcery

Fix i18n tooling to ignore stale commented entries and revive wrongly-stale AA system and F10/menu labels across all languages.

Bug Fixes:

  • Correct i18n dictionary parsing and translation write paths to skip lines commented as stale, preventing dead keys from being treated as live.
  • Restore 56 AA system, crate, smoke, vehicle, and category labels that were incorrectly marked stale in all dictionaries, fixing missing F10 and AA-system text in every language.

Enhancements:

  • Add tests around i18n parsing and translation application to cover stale-comment handling and live-line writes.
  • Update roadmap and backlog documentation to reflect delivered lots and formalize the FIX-I18N-STALE-COMMENT-PARSING work, including its PRD and ticket.

Documentation:

  • Document the stale-comment parsing fix and 56-key revival in the unreleased changelog and backlog PRD/ticket.
  • Clean up roadmap entries to remove or annotate items that are already delivered, avoiding duplication and clarifying current status.

Tests:

  • Extend tools/build test suite for i18n_dict_utils and translate_i18n to validate skipping of commented stale entries and correct handling of live keys.

Grilled with docs, 2026-08-10. Also cleans up dev/roadmap.md: removes
the FEAT-MOVING-ZONE entry (duplicate of already-merged PR #49),
marks ctld-tools modTypes validation as done (FIX-VALIDATE-MODTYPES,
PR #87), and marks the unit:/group: schema metadata entry as
apparently already delivered (no dedicated lot found).

No ADR - fixing a comment-blind regex across three call sites is a
bug fix, not a design trade-off with alternatives to record.
The shared dict parser (i18n_dict_utils.py), generate_i18n_dicts.ps1's
Get-DictKeys, and translate_i18n.py's _apply_translations all matched
a "ctld.i18n[...] = ..." line regardless of a "-- STALE: " comment
prefix, making a dead key indistinguishable from a live one. All three
now skip any line starting with "--".

Re-running the corrected generate_i18n_dicts.ps1 -Apply surfaced a
production bug far bigger than the originally-scoped KO/ES cosmetic
drift: 56 keys - every HAWK/BUK/KUB/NASAMS/Patriot/S-300 AA system
label, several F10 menu labels, and 7 vehicle-category labels - were
wrongly marked -- STALE: in all four dictionaries including English,
almost certainly predating generate_i18n_dicts.ps1's config-YAML
desc/name scan (these keys are referenced there, not via ctld.tr()).
At runtime this meant ctld.i18n["en"]["HAWK Launcher"] and 55 others
were nil - broken/missing F10 and AA-system text in every language.

-Apply revives all 56 (EN's text restored automatically since EN's
value always equals its key). The FR/ES/KO translations sitting inert
in the old commented lines were hand-recovered into the freshly
revived entries rather than lost or re-translated from scratch.
Genuinely new stubs (7 category labels in KO/ES, 15 never-translated
KO labels) are left empty for a future translation pass.

pytest tools/build/ 24/24 green (5 new tests). luac -p clean on all 4
dictionaries. Final dry-run: OK on all four. See
.backlog/FIX-I18N-STALE-COMMENT-PARSING/.
@FullGas1
FullGas1 requested a review from davidp57 as a code owner August 10, 2026 12:22
@sourcery-ai

sourcery-ai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Reviewer's Guide

Fixes i18n tooling so -- STALE:-commented lines are treated as dead, and revives 56 AA-system and menu-label keys that were wrongly marked stale across all dictionaries, plus updates roadmap/backlog/docs and tests accordingly.

Sequence diagram for i18n translation applying with STALE-line exclusion

sequenceDiagram
    participant Dev
    participant translate_i18n_py as translate_i18n_py
    participant i18n_dict_utils as i18n_dict_utils_py
    participant CTLD_i18n as CTLD_i18n_xx_lua

    Dev->>translate_i18n_py: run translate_i18n.py
    translate_i18n_py->>CTLD_i18n: read dict file text
    translate_i18n_py->>i18n_dict_utils: parse_dict(text)
    i18n_dict_utils-->>translate_i18n_py: {key: value} (STALE lines skipped)
    translate_i18n_py->>translate_i18n_py: _collect_stubs(en_dict)
    translate_i18n_py->>translate_i18n_py: _apply_translations(path, translations, lang)
    alt line starts with --
        translate_i18n_py->>translate_i18n_py: [pattern does not match]
        translate_i18n_py-->>Dev: count unchanged for STALE key
    else live entry line
        translate_i18n_py->>translate_i18n_py: pattern.subn(replacement, text)
        translate_i18n_py->>CTLD_i18n: write updated dict file
        translate_i18n_py-->>Dev: count incremented for live key
    end
Loading

File-Level Changes

Change Details Files
Make i18n dictionary parsing consistently ignore commented -- STALE: lines so dead keys are not treated as live.
  • Update parse_dict to process line-by-line, skipping any line whose stripped text starts with --, before applying the entry regex.
  • Update parse_keep_en to skip commented lines inside the __keep_en block so commented keep-en entries are ignored.
  • Add unit tests verifying parse_dict and parse_keep_en ignore -- STALE: and other commented entries while still parsing neighboring live lines.
tools/build/i18n_dict_utils.py
tools/build/test_i18n_dict_utils.py
Align PowerShell i18n key-scanning and Python translation writer with the new comment-aware behavior so STALE keys aren’t counted or overwritten.
  • Change Get-DictKeys to iterate file lines, skip any starting with --, and only match keys on uncommented lines.
  • Modify _apply_translations to use a compiled, line-anchored MULTILINE regex so only lines starting with ctld.i18n[...] are rewritten, never commented -- STALE: lines.
  • Add tests for _apply_translations to assert it does not modify a stale-commented line and does update a live line as expected.
tools/build/generate_i18n_dicts.ps1
tools/build/translate_i18n.py
tools/build/test_translate_i18n.py
Revive 56 wrongly-stale AA system, crate/menu, and category-label keys across all four i18n dictionaries and bump translation version.
  • Re-run generate_i18n_dicts.ps1 -Apply with the fixed parser and add back 56 keys as live entries in the English, French, Spanish, and Korean dictionaries.
  • Restore FR/ES/KO translations for revived keys by copying values from prior commented lines into the new live entries instead of re-translating.
  • Leave genuinely new or never-translated KO/ES stubs empty for future translation, and bump translation_version from 1.17 to 1.18 in all four dicts.
src/CTLD_i18n_en.lua
src/CTLD_i18n_fr.lua
src/CTLD_i18n_es.lua
src/CTLD_i18n_ko.lua
Document the bug and fix in changelog, roadmap, and backlog, replacing an inline roadmap item with a formal lot PRD and ticket.
  • Add an [Unreleased] changelog entry describing the stale-comment parsing bug, its runtime impact on AA system labels, and the 56-key revival.
  • Update dev/roadmap.md to mark related roadmap items as delivered or removed, and to reference the new FIX-I18N-STALE-COMMENT-PARSING lot instead of an inline tooling note.
  • Create backlog PRD and ticket files for FIX-I18N-STALE-COMMENT-PARSING, capturing problem statement, solution, testing/acceptance criteria, and linking to the implementation branch.
  • Register the lot in .backlog/README.md with a short description and branch name.
CHANGELOG.md
dev/roadmap.md
.backlog/README.md
.backlog/FIX-I18N-STALE-COMMENT-PARSING/PRD.md
.backlog/FIX-I18N-STALE-COMMENT-PARSING/tickets/01-skip-commented-lines-and-cleanup-drift.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • Consider applying translations in a deterministic order (e.g., iterating over sorted(translations) in _apply_translations) so dictionary diffs stay stable and easier to review across runs.
  • The key-matching regex and comment-skipping logic are now duplicated between parse_dict and Get-DictKeys; it may be worth centralizing or clearly documenting a single canonical pattern to reduce the risk of future divergence.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider applying translations in a deterministic order (e.g., iterating over `sorted(translations)` in `_apply_translations`) so dictionary diffs stay stable and easier to review across runs.
- The key-matching regex and comment-skipping logic are now duplicated between `parse_dict` and `Get-DictKeys`; it may be worth centralizing or clearly documenting a single canonical pattern to reduce the risk of future divergence.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@FullGas1
FullGas1 merged commit cbd7b93 into develop Aug 10, 2026
9 checks passed
@FullGas1
FullGas1 deleted the fix/i18n-stale-comment-parsing branch August 10, 2026 12:25
FullGas1 added a commit that referenced this pull request Aug 10, 2026
…T-REPAYMENT-2) (#120)

* fix(i18n): repay KO/ES debt from the revived stale keys (FIX-I18N-DEBT-REPAYMENT-2)

Follow-up to FIX-I18N-STALE-COMMENT-PARSING (PR #119), which revived
56 keys wrongly marked -- STALE: in all four dictionaries. 22 KO + 7
ES entries among them were genuine debt - never translated even
before that bug. EN/FR were already complete.

Same method as FIX-I18N-DEBT-REPAYMENT: direct translation, no
ANTHROPIC_API_KEY available and the Claude Code CLI fallback can't be
invoked from a nested Claude Code session. FARP / FOB added to
__keep_en for both languages (acronym, no translatable content).

pytest tools/build/ 24/24 unchanged; generate_i18n_dicts.ps1 dry-run
reports OK on all four dictionaries. Lot:
.backlog/FIX-I18N-DEBT-REPAYMENT-2/.

* chore(backlog): mark FIX-I18N-DEBT-REPAYMENT-2 as merged (PR #120)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant