fix(i18n): CI-enforced dictionary guard (FIX-I18N-DICT-GUARD) - #115
Merged
Conversation
PRD, 3 tickets and ADR for a CI-enforced i18n dictionary guard: block new MISSING keys unconditionally, block new empty non-EN stubs unless labeled skip-i18n, and fix translate_i18n.py's stub detection so the guard is actually satisfiable locally. Grilled with docs 2026-08-10.
Its stub-selection predicate only ever matched a non-EN value identical to the EN text. generate_i18n_dicts.ps1 -Apply writes a freshly-added non-EN entry as "" instead, so a new key was never selected for translation, with or without ANTHROPIC_API_KEY set. Extract the dict-file parser into a shared tools/build/i18n_dict_utils.py (also consumed by ticket 03's diff checker), extend the stub predicate to match "", and add tools/build/'s first test coverage. Wire `pytest tools/build/` into python-quality.yml so it runs in CI. Part of FIX-I18N-DICT-GUARD (ADR 0013).
New PR-only CI job i18n-guard, modeled on changelog-guard: covers tickets 01 and 03 of FIX-I18N-DICT-GUARD. Unconditional block on a ctld.tr or config-YAML key missing from any of the four dictionaries - reuses generate_i18n_dicts.ps1's existing dry-run; STALE stays non-blocking, unchanged. Diff-scoped block against the PR base on a newly-introduced empty non-EN entry, via the new tools/build/check_i18n_diff.py. Bypassable with the skip-i18n label for contributors without local ANTHROPIC_API_KEY access. Pre-existing debt already on develop, 91 KO plus 76 ES empty entries, is untouched by this diff-scoped check - a follow-up lot repays it. CHANGELOG updated. Closes FIX-I18N-DICT-GUARD, see ADR 0013.
Reviewer's GuideFixes i18n stub detection so newly-added empty non-EN entries are recognized, and introduces a CI i18n-guard job plus supporting scripts/tests to block PRs that add missing or newly-empty i18n dictionary entries, with design documented via ADR and backlog tickets. Sequence diagram for the new i18n-guard CI jobsequenceDiagram
actor Developer
participant GitHubCI
participant generate_i18n_dicts_ps1 as generate_i18n_dicts.ps1
participant check_i18n_diff_py as check_i18n_diff.py
Developer->>GitHubCI: Open/ update pull_request
GitHubCI->>GitHubCI: i18n-guard job starts
GitHubCI->>generate_i18n_dicts_ps1: run (dry-run)
generate_i18n_dicts_ps1-->>GitHubCI: output
GitHubCI->>GitHubCI: search output for MISSING
alt MISSING found
GitHubCI-->>Developer: fail PR (missing dict entries)
else no MISSING
GitHubCI->>GitHubCI: read skip-i18n label
alt HAS_SKIP == true
GitHubCI-->>Developer: pass (empty-stub check bypassed)
else HAS_SKIP == false
GitHubCI->>check_i18n_diff_py: python tools/build/check_i18n_diff.py BASE_SHA
check_i18n_diff_py-->>GitHubCI: exit code
alt exit code != 0
GitHubCI-->>Developer: fail PR (newly-empty non-EN entries)
else exit code == 0
GitHubCI-->>Developer: pass i18n-guard job
end
end
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Per the repo's default workflow, the README index line is set in the PR itself rather than as a separate post-merge commit.
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- In
check_i18n_diff.py,_git_showtreats any non-zerogit showexit status as “file absent”; consider distinguishing between “path does not exist at base” and genuine git errors so you don’t silently ignore repository/CI issues as if they were new files. - The new
pytest tools/build/step installspytestglobally withpipalongside the existing Poetry-managed environment; it may be more robust to either reuse Poetry’s venv (e.g.poetry run pytest tools/build/) or constrain the pip install to avoid version drift between the two runners.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `check_i18n_diff.py`, `_git_show` treats any non-zero `git show` exit status as “file absent”; consider distinguishing between “path does not exist at base” and genuine git errors so you don’t silently ignore repository/CI issues as if they were new files.
- The new `pytest tools/build/` step installs `pytest` globally with `pip` alongside the existing Poetry-managed environment; it may be more robust to either reuse Poetry’s venv (e.g. `poetry run pytest tools/build/`) or constrain the pip install to avoid version drift between the two runners.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
5 tasks
FullGas1
added a commit
that referenced
this pull request
Aug 10, 2026
…EPAYMENT) (#116) * fix(i18n): repay pre-existing KO/ES translation debt Follow-up to FIX-I18N-DICT-GUARD (PR #115), which explicitly deferred this work. 93 KO / 78 ES empty entries counted at merge; 23 / 8 turned out to be STALE dead keys in CTLD_i18n_en.lua (no longer referenced by src/), left untouched. The 70 live entries per language (same key set for both) are now translated. No ANTHROPIC_API_KEY was available, so translations were produced and written directly rather than via translate_i18n.py - the script itself is untouched, still the documented mechanism for next time. JTAC and %1 [%2] %3. (no translatable content) added to each dictionary's __keep_en block rather than left flagged as stubs forever. pytest tools/build/ 17/17 green; generate_i18n_dicts.ps1 dry-run reports 0 MISSING. Lot: .backlog/FIX-I18N-DEBT-REPAYMENT/. * chore(backlog): mark FIX-I18N-DEBT-REPAYMENT as merged (PR #116)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Test plan
Generated with Claude Code
Summary by Sourcery
Add a CI-enforced guard to prevent new untranslated i18n menu entries and fix local stub detection so newly added dictionary keys are correctly identified for translation.
New Features:
Bug Fixes:
Enhancements: