From 13741f205b32282de13178d9900d6992a8c5cd8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20=C3=96zel?= Date: Thu, 2 Jul 2026 12:18:44 +0300 Subject: [PATCH] fix(heuristics): add word boundaries to live-debug keywords _JOINED_LIVE_DEBUG joined LIVE_DEBUG_KEYWORDS without word boundaries, so patterns like "logs?" substring-matched unrelated words ("login", "blog", "catalog", "dialog"). This made detect_live_debug return True for benign prompts, cascading through detect_troubleshooting_intent and the Content/LiveDebug handlers into PolicyHandler, which then escalated policy to risk_level=medium / human_approval_required via debug_request. Wrap each keyword with \b (mirroring the existing _TEACHING_RE fix) instead of re.escape, since the keywords intentionally contain regex like "logs?". Add regression tests covering the false positives and the genuine log/debug cues that must still match. Co-Authored-By: Claude Opus 4.8 --- app/heuristics/__init__.py | 6 +++++- tests/test_detect_live_debug.py | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/app/heuristics/__init__.py b/app/heuristics/__init__.py index 7532b397..6504ac81 100644 --- a/app/heuristics/__init__.py +++ b/app/heuristics/__init__.py @@ -704,7 +704,11 @@ def detect_coding_context(text: str) -> bool: r"istisna", ] -_JOINED_LIVE_DEBUG = re.compile("|".join(LIVE_DEBUG_KEYWORDS)) +# Word boundaries prevent substring false positives: "logs?" must not match +# inside "login"/"blog"/"catalog", "mre" inside unrelated tokens, etc. The +# keywords intentionally contain regex (e.g. "logs?"), so we wrap with \b rather +# than re.escape. Mirrors the fix already applied to _TEACHING_RE above. +_JOINED_LIVE_DEBUG = re.compile("|".join(rf"\b{keyword}\b" for keyword in LIVE_DEBUG_KEYWORDS)) def detect_live_debug(text: str) -> bool: diff --git a/tests/test_detect_live_debug.py b/tests/test_detect_live_debug.py index 0dce4b15..8a5ce9a1 100644 --- a/tests/test_detect_live_debug.py +++ b/tests/test_detect_live_debug.py @@ -11,3 +11,20 @@ def test_detect_live_debug_false_cases(): assert detect_live_debug("How do I write a Python function?") is False assert detect_live_debug("Explain quantum physics") is False assert detect_live_debug("") is False + + +def test_detect_live_debug_ignores_substring_false_positives(): + # Keywords like "logs?" must not substring-match unrelated words such as + # "login", "blog", "catalog", or "dialog" (regression for the missing + # word boundaries in _JOINED_LIVE_DEBUG). + assert detect_live_debug("Implement secure login sessions") is False + assert detect_live_debug("write a blog post") is False + assert detect_live_debug("browse the catalog") is False + assert detect_live_debug("open the dialog box") is False + + +def test_detect_live_debug_matches_log_and_debug_keywords(): + # Genuine log/debug cues must still be detected once word boundaries are added. + assert detect_live_debug("check the error log") is True + assert detect_live_debug("attach the logs") is True + assert detect_live_debug("help me debug this stack trace") is True