From 3d2150d2a6cdeb6eba6be4a16626eb6c1bd0f3ce Mon Sep 17 00:00:00 2001 From: marcos Date: Wed, 5 Aug 2026 15:09:37 +0000 Subject: [PATCH] docs: scope the foreign-script and surefire claims to what the code does hasForeignScript detects by alphabet, so Latin-script leakage such as the observed French "contiennent" is not caught. Say so in the javadoc and admit the gap in the design doc rather than implying coverage. failIfNoTests catches a misplaced or misnamed test class, not a disabled one: an @Disabled class still reports as skipped and the build stays green. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01F3jSvSTrG4qsniLSr6TpC6 --- docs/plans/2026-08-05-ia-improvements-design.md | 8 +++++++- pom.xml | 5 +++-- .../java/dev/marcospaulo/canalhandia/AiText.java | 13 +++++++++++-- 3 files changed, 21 insertions(+), 5 deletions(-) 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(); }