Skip to content

Commit 433315f

Browse files
LastStepclaude
andcommitted
fix: smart trigger matching — normalize contractions + end-anchor patterns
Replace naive substring matching with regex-based trigger detection. Strips apostrophes before matching so "thats all" / "that's all" / "that is all" all work. Patterns are anchored to end-of-prompt to prevent false positives like "that's all I need to change". Tested against 28 positive and 10 negative cases — zero false positives. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent fe3ad0d commit 433315f

2 files changed

Lines changed: 40 additions & 12 deletions

File tree

catalog/sensors/context-guard/context-guard.sh.tmpl

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,28 @@ elif context_pct >= 30:
7474
7575
# ── Session-done trigger word detection ─────────────────────────────────────
7676
77-
trigger_words = [
78-
'session done', 'wrap up', 'wrapping up', 'end session',
79-
'session over', \"we're done\", \"i'm done\", 'finish up',
80-
\"let's wrap\", 'call it', \"that's all\",
77+
import re
78+
79+
# Normalize: strip apostrophes, lowercase
80+
normalized = re.sub(r\"'\", '', prompt).lower()
81+
82+
# Regex patterns — anchored to end-of-prompt to prevent false positives
83+
# e.g. \"thats all\" triggers, but \"thats all I need to change\" does not
84+
# Handles contractions (thats/that's/that is) via apostrophe stripping
85+
eol = r'[\\s.!?]*$'
86+
trigger_patterns = [
87+
r'\\b(thats|that is)\\s+all' + eol,
88+
r'\\b(were|we are)\\s+done' + eol,
89+
r'\\b(im|i am)\\s+done' + eol,
90+
r'\\b(lets|let us)\\s+(wrap|wrap up)' + eol,
91+
r'\\bsession\\s+(done|over)' + eol,
92+
r'\\bend\\s+session' + eol,
93+
r'\\b(wrap|wrapping)\\s+up' + eol,
94+
r'\\bfinish\\s+up' + eol,
95+
r'\\bcall\\s+it' + eol,
8196
]
8297
83-
prompt_lower = prompt.lower()
84-
triggered = any(tw in prompt_lower for tw in trigger_words)
98+
triggered = any(re.search(p, normalized) for p in trigger_patterns)
8599
86100
if triggered:
87101
checklist = (

station/agent/Sensors/context-guard.sh

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,28 @@ elif context_pct >= 30:
7171
7272
# ── Session-done trigger word detection ─────────────────────────────────────
7373
74-
trigger_words = [
75-
'session done', 'wrap up', 'wrapping up', 'end session',
76-
'session over', \"we're done\", \"i'm done\", 'finish up',
77-
\"let's wrap\", 'call it', \"that's all\",
74+
import re
75+
76+
# Normalize: strip apostrophes, lowercase
77+
normalized = re.sub(r\"'\", '', prompt).lower()
78+
79+
# Regex patterns — anchored to end-of-prompt to prevent false positives
80+
# e.g. \"thats all\" triggers, but \"thats all I need to change\" does not
81+
# Handles contractions (thats/that's/that is) via apostrophe stripping
82+
eol = r'[\\s.!?]*$'
83+
trigger_patterns = [
84+
r'\\b(thats|that is)\\s+all' + eol,
85+
r'\\b(were|we are)\\s+done' + eol,
86+
r'\\b(im|i am)\\s+done' + eol,
87+
r'\\b(lets|let us)\\s+(wrap|wrap up)' + eol,
88+
r'\\bsession\\s+(done|over)' + eol,
89+
r'\\bend\\s+session' + eol,
90+
r'\\b(wrap|wrapping)\\s+up' + eol,
91+
r'\\bfinish\\s+up' + eol,
92+
r'\\bcall\\s+it' + eol,
7893
]
7994
80-
prompt_lower = prompt.lower()
81-
triggered = any(tw in prompt_lower for tw in trigger_words)
95+
triggered = any(re.search(p, normalized) for p in trigger_patterns)
8296
8397
if triggered:
8498
wrapup = (

0 commit comments

Comments
 (0)