feat: Support never_translate phrases - #233
Conversation
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.
Tip: disable this comment in your organization's Code Review settings.
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit e9f1a3b. Configure here.
| return ""; | ||
| } | ||
| return `\n\n${renderSection({ tag: "never_translate", content: terms.join("\n") })}`; | ||
| } |
There was a problem hiding this comment.
Escaped terms break verbatim checks
Medium Severity
buildNeverTranslateSection runs terms through renderSection, so &, <, and > become XML entities in the prompt while the system prompt demands those listings be copied verbatim and verifyNeverTranslateTerms counts the original unescaped strings. Common brand terms like AT&T therefore instruct the model with a different spelling than compliance checks for, so preservation and reporting diverge.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit e9f1a3b. Configure here.
| if (!seen.has(trimmed)) { | ||
| seen.add(trimmed); | ||
| validated.push(trimmed); | ||
| } |
There was a problem hiding this comment.
Case variants inflate expected counts
Medium Severity
validateNeverTranslateTerms keeps case-only duplicates such as Mux and MUX, while verifyNeverTranslateTerms computes each term’s expectedCount with a shared case-insensitive scan of the source. The same source hits are therefore demanded verbatim for every casing variant at once, so mixed case lists cannot all pass and clean translations are reported as violations.
| } | |
| if (!seen.has(trimmed.toLowerCase())) { | |
| seen.add(trimmed.toLowerCase()); | |
| validated.push(trimmed); | |
| } |
Additional Locations (2)
Reviewed by Cursor Bugbot for commit e9f1a3b. Configure here.


Note
Medium Risk
Expands partly trusted input into the translation prompt; mitigated by term caps and XML escaping, but still reaches the model as content.
Overview
Adds a
neverTranslateoption totranslateCaptionsso brand names and proper nouns can be kept verbatim in translated captions.Terms are validated (max 100, 100 chars each), XML-escaped into a
<never_translate>prompt section, and checked after translation. Shortfalls are reported onresult.neverTranslate.violations— the library never rewrites the output to fix them.Docs, unit tests, and a
never-translate-complianceeval scorer cover the new option and its security boundary.Reviewed by Cursor Bugbot for commit 12993f9. Bugbot is set up for automated code reviews on this repo. Configure here.