diff --git a/docs/plans/2026-08-05-ia-improvements-design.md b/docs/plans/2026-08-05-ia-improvements-design.md index 6b167e3..17937a2 100644 --- a/docs/plans/2026-08-05-ia-improvements-design.md +++ b/docs/plans/2026-08-05-ia-improvements-design.md @@ -143,11 +143,17 @@ no function that could do otherwise. | failure | behaviour | | --- | --- | | empty content | retry once at a higher token ceiling, then apologise | -| reply contains CJK or other foreign script | discard, retry once | +| reply contains a non-Latin script (CJK, Cyrillic, Arabic, …) | discard, retry once | | wiki 403 / timeout / no hit | answer without the article, and say the wiki was not consulted | | MiniMax non-zero `base_resp` | log and apologise; HTTP 200 does not mean success | | tool call absent despite forcing | fall back to answering ungrounded | +Known gap: the foreign-script check works by alphabet, so it only catches +non-Latin scripts. Latin-script leakage — the observed French `contiennent` in +an otherwise Portuguese answer — passes straight through, and this design does +not close that. Catching it would need dictionary or language-identification +work that is out of scope here. + ## Features - **Privacy per question.** `/ia` public, `/iap` visible only to the asker. diff --git a/pom.xml b/pom.xml index 380c5af..97bf42c 100644 --- a/pom.xml +++ b/pom.xml @@ -71,8 +71,9 @@ + misplaced or misnamed, which ends the same way: a green build that + ran nothing. Failing on an empty suite closes that gap. A disabled + class is still reported as skipped, so it is not covered here. --> true diff --git a/src/main/java/dev/marcospaulo/canalhandia/AiText.java b/src/main/java/dev/marcospaulo/canalhandia/AiText.java index d6c53bb..f9ce84a 100644 --- a/src/main/java/dev/marcospaulo/canalhandia/AiText.java +++ b/src/main/java/dev/marcospaulo/canalhandia/AiText.java @@ -11,8 +11,8 @@ import java.util.regex.Pattern; final class AiText { /** - * Scripts that should never appear in a Portuguese answer. The model has - * been observed dropping single Chinese words mid-sentence. + * Non-Latin scripts that should never appear in a Portuguese answer. The + * model has been observed dropping single Chinese words mid-sentence. */ private static final Pattern FOREIGN = Pattern.compile( "[\\p{IsHan}\\p{IsHiragana}\\p{IsKatakana}\\p{IsHangul}\\p{IsCyrillic}\\p{IsArabic}]"); @@ -20,6 +20,15 @@ final class AiText { private AiText() { } + /** + * True if the text contains a character from a non-Latin script. + * + *

This detects leakage by alphabet, so it catches only what a different + * alphabet makes visible. A foreign word written in Latin script is + * not caught: the French {@code contiennent}, observed in an + * otherwise Portuguese reply, passes this check. Catching that would need + * dictionary or language-identification work this method does not do. + */ static boolean hasForeignScript(String text) { return text != null && FOREIGN.matcher(text).find(); }