fix(check_framework_version): decode git diff output as UTF-8 (#511)

* fix(check_framework_version): decode git diff output as UTF-8

run_git() passed subprocess.run(text=True) with no explicit encoding,
so it fell back to the host locale's default codec - cp1252 on
Windows - instead of UTF-8. Any non-ASCII byte in a modified
framework file's diff (e.g. an em dash in a profile edit) then raised
UnicodeDecodeError before the gate could evaluate the change, instead
of a pass/fail verdict. Reproduced on a real Windows checkout.

Pin encoding="utf-8" on the subprocess.run() call. Added a regression
test that patches subprocess.run and asserts run_git() always passes
encoding="utf-8" - confirmed it fails against the pre-fix code and
passes against the fix.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix(check_framework_version): address review on UTF-8 decode fix

Per MadsLorentzen's review on PR #511:
- Add errors="replace" alongside encoding="utf-8" on the subprocess.run()
  call, matching the convention used elsewhere in this repo (robots_check.py).
- Correct the docstring: an em dash does not crash the un-pinned decode
  (cp1252 maps it fine); the actual trigger is a byte cp1252 leaves
  undefined, e.g. Cyrillic Ё/ё, much CJK, or Á-class Latin.
- Correct "profile file" to "framework file" - the tool only diffs the
  framework's own directories, not arbitrary profile files.
- Add a CHANGELOG entry under [Unreleased] / Fixed naming the tool and test.

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Timofei ErokhinandClaude Sonnet 5 authored and GitHub committed 2026-10-02 20:03:35 +02:00
1 parent f9ef82f169
commit 27a9b4a91d
3 files changed
+58 -1

No files matched your search

+11
View File
@@ -15,6 +15,17 @@ per-file diff commands.
### Fixed
- **`check_framework_version.py`'s git diff read no longer crashes on non-ASCII framework-file
content** (`tools/check_framework_version.py`) - `run_git()` called
`subprocess.run(text=True)` without an explicit `encoding`, so output decoded via the host
locale's default codec instead of UTF-8. On a real Windows checkout (cp1252 default) this
raised `UnicodeDecodeError` on any byte cp1252 leaves undefined - Cyrillic Ё/ё, much CJK,
Á-class Latin - appearing in a framework file's diff, crashing the version gate before it
ever evaluated the change. `run_git()` now passes `encoding="utf-8"` and `errors="replace"`
(matching the convention already used elsewhere in this repo, e.g. `robots_check.py`),
decoding deterministically regardless of host locale. Pinned by `RunGitEncodingTests` in
`tests/test_check_framework_version.py`, which fails against the original un-pinned call.
- **`/rank` still sweeps deadlines when there is nothing new to score** (`.claude/commands/rank.md`
Step 1, `tests/test_rank_command.py`) - when `rank_state.py candidates` reported no eligible
jobs, Step 1 said "Nothing new to rank" and stopped before Step 3's rule 6 expiry sweep ever