Repository navigation
fix(runtime): preserve unicode while stripping markers - #6917
Conversation
Rename the session-repair unicode fragment to include the PR number per changelog.d/README.md, and add the missing (#6917) reference next to the author handle.
There was a problem hiding this comment.
Commit a1d91314 ("chore(changelog): name fragment after PR and add PR reference") has its author identity set to Claude <noreply@anthropic.com> (git log --format='%an <%ae>' 13a30adc5..HEAD).
This is exactly the case scripts/hooks/commit-msg is designed to reject even when the commit message text itself is clean, per CLAUDE.md's "No AI / Claude attribution" rule.
Fixing this requires rewriting the commit (amend/rebase) and force-pushing, which is outside the scope of an automated hardening pass — please re-author that commit and force-push before merge.
The actual fix looks correct: the old code lowercased the whole string with to_lowercase() and then reused byte offsets found in that lowercased copy to slice the original string — Unicode case expansion (e.g. Turkish İ U+0130 → i̇, 2 bytes → 3 bytes) desyncs those offsets from the original string's byte layout, risking a non-char-boundary slice panic or corrupted output.
The rewrite builds a single case-insensitive regex::Regex over the escaped marker list and calls replace_all directly on the original string, so there's no separate lowercased copy and no manual byte-offset bookkeeping — match ranges the regex crate returns are always char-boundary-aligned.
test_strip_injection_marker_after_expanding_unicode_lowercase (İ before a marker) exercises exactly the case-expansion class of bug.
Verified locally: cargo test -p librefang-runtime --lib -- session_repair:: (53 passed, including the new test) and cargo clippy -p librefang-runtime --all-targets -- -D warnings (clean).
Generated by Claude Code
houko
left a comment
There was a problem hiding this comment.
Automated review pass. The unicode/byte-boundary fix and its regression test are correct (regex-based case-insensitive replace on the original string instead of lowercase-copy + reused byte offsets; new test exercises the real strip_tool_result_details end-to-end path). Changelog fragment is present and correctly formatted under changelog.d/fixed/.
One blocking item confirmed independently: the HEAD commit's author identity is Claude <noreply@anthropic.com>, which violates CLAUDE.md's no-AI-attribution rule (enforced server-side by scripts/hooks/commit-msg on author identity, not just message text) and needs to be re-authored and force-pushed by a human before merge — outside the scope of what this pass will do.
Generated by Claude Code
There was a problem hiding this comment.
Confirmed independently at head sha a1d913147f7c8610639713cb458a5a9e9ec2429d: the commit that added/renamed this fragment ("chore(changelog): name fragment after PR and add PR reference") has its author identity set to Claude <noreply@anthropic.com>.
That's exactly the case scripts/hooks/commit-msg rejects even when the message text is clean, per CLAUDE.md's no-AI-attribution rule — the check runs on git var GIT_AUTHOR_IDENT, not just the message body.
This blocks a clean merge on the letter of the policy and needs the commit re-authored and the branch force-pushed, which is outside what this automated pass can do (no force-push allowed here) — flagging for the maintainer to fix before merge.
Separately, the substantive code change looks correct: switching from lowercase-copy + byte-offset reuse to a single case-insensitive regex::Regex over the original string avoids the Unicode case-expansion byte-boundary desync (e.g. Turkish İ), and the new test_strip_injection_marker_after_expanding_unicode_lowercase regression exercises the real end-to-end path (strip_tool_result_details → strip_injection_markers), not just the inner helper.
The changelog fragment itself is correctly placed under changelog.d/fixed/ with the right filename convention and trailing (#6917) (@houko).
Generated by Claude Code
houko
left a comment
There was a problem hiding this comment.
Automated review pass: code fix looks correct and well-tested (regex-based rewrite correctly resolves the byte-boundary bug from mixing to_lowercase() offsets with original-string slicing). One process finding flagged inline: a commit on this branch carries Claude/Anthropic author+committer identity, in violation of this repo's own CLAUDE.md no-AI-attribution policy. No code changes pushed — nothing else needed a fix.
Generated by Claude Code
There was a problem hiding this comment.
Commit a1d9131 ("chore(changelog): name fragment after PR and add PR reference") on this branch has both author identity and committer identity set to Claude <noreply@anthropic.com>.
This is a direct violation of the repo's own CLAUDE.md policy ("No Claude / Anthropic / AI attribution ... The commit-msg git hook rejects matching strings ... and separately rejects a commit whose author identity ... resolves to Claude / Anthropic"). The commit message text itself is clean, so this slipped past message-content scanning, but git var GIT_AUTHOR_IDENT on this commit resolves to Claude, which is exactly the case the commit-msg hook's author-identity check is meant to catch — it likely landed because core.hooksPath was not pointed at scripts/hooks in the environment that made this commit (see CLAUDE.md's "Enable once per clone" just setup step).
Not fixing via history rewrite/force-push per policy — flagging so a maintainer can decide whether to squash-merge (which drops the individual commit identities) or ask for a rebase with corrected identity before merge.
Content-wise, the actual fix (crates/librefang-runtime/src/session_repair.rs) looks correct: replacing the old manual lowercase-then-byte-offset search (which mixed byte offsets from to_lowercase()'d text with slicing on the original string — broken whenever a character's lowercase form has a different UTF-8 byte length, e.g. İ → i̇) with a single case-insensitive regex over the original string fixes the byte-boundary corruption bug directly, and the added regression test (test_strip_injection_marker_after_expanding_unicode_lowercase) exercises exactly that case. rustfmt --check is clean on both changed files, and the changelog fragment is correctly named/formatted per changelog.d/README.md.
Generated by Claude Code
Summary
LazyLockVerification
cargo test -p librefang-runtime --lib session_repair::tests(53 passed)cargo clippy -p librefang-runtime --lib -- -D warningscargo fmt --checkgit diff --checkReport:
confirmed/crates/librefang-runtime/src/session_repair.rs.md