fix(intent): widen CORRECTION to catch fully-spoken `that is/was ...` forms
Follow-on to the word-boundary fix (commit 0dd30b8). After tightening
``\bno\b`` etc. with word boundaries, an audit surfaced a separate
pre-existing gap in the CORRECTION trigger: the contracted-only
``that'?s\s+(?:not|wrong)`` slot silently dropped every fully-spoken
copula form to UNKNOWN.
Concrete gap (every one previously UNKNOWN):
"That is not right." → UNKNOWN
"That is wrong." → UNKNOWN
"That was wrong." → UNKNOWN
"That is incorrect." → UNKNOWN
"That is false." → UNKNOWN
"That was not right." → UNKNOWN
"that is mistaken." → UNKNOWN
"That was incorrect." → UNKNOWN
Root cause: the slot ``that'?s\s+(?:not|wrong)`` matches only
that's / thats
— ``'?s`` makes the apostrophe optional but the literal ``s`` is
mandatory. ``that is`` (full word ``is``) and ``that was`` (full
word ``was``) had no path. And the predicate alternation only
accepted ``not`` or ``wrong``; ``incorrect``, ``false``, and
``mistaken`` were also missing.
Fix: widen both slots in one pattern revision.
Before:
that'?s\s+(?:not|wrong)
After:
that(?:'?s|\s+(?:is|was))\s+(?:not|wrong|incorrect|false|mistaken)
The full pattern now reads:
\b(?:no
|that(?:'?s|\s+(?:is|was))\s+(?:not|wrong|incorrect|false|mistaken)
|incorrect
|actually
|correction)\b
Boundary discipline holds: the outer ``\b...\b`` still prevents the
predicate alternation from eating into longer words. Verified:
"That is correct." → UNKNOWN (right NOT in predicate set)
"That is right." → UNKNOWN (right NOT in predicate set)
"That is true." → UNKNOWN (true NOT in predicate set)
"That works." → UNKNOWN
"That is interesting." → UNKNOWN
"That is falsifiable." → UNKNOWN (``false`` + ``i`` is word→word
so ``\b`` after ``false`` fails)
"That was wrongly accused." → UNKNOWN (same logic for ``wrong``+``ly``)
Tests extended:
* ``test_correction_canonical_forms_still_route`` — 8 new parametrize
cases for the fully-spoken copula forms
* ``test_correction_does_not_eat_no_prefixed_words`` — 9 new
parametrize cases for the affirmative ``That is/was ...`` shape
AND the boundary-trap cases ``falsifiable`` / ``wrongly accused``
Verified:
pytest tests/test_intent_subject_extraction.py 33/33 pass
full intent + register-diagnostic + proposition graph 77/77 pass
core test --suite smoke 67/67 pass
core test --suite runtime 19/19 pass
This commit is contained in:
parent
0dd30b86a7
commit
c945b9a045
2 changed files with 39 additions and 3 deletions
|
|
@ -216,7 +216,14 @@ _RULES: tuple[tuple[re.Pattern[str], IntentTag], ...] = (
|
|||
# ``"w remember light"``. The same hazard applies to ``incorrect``
|
||||
# (would eat ``incorrectly``), ``actually`` (would eat
|
||||
# ``actualization``), and ``correction`` (would eat ``corrections``).
|
||||
(re.compile(r"\b(?:no|that'?s\s+(?:not|wrong)|incorrect|actually|correction)\b", re.IGNORECASE), IntentTag.CORRECTION),
|
||||
#
|
||||
# The ``that(?:'?s|\s+(?:is|was))\s+(?:not|wrong|incorrect|false|
|
||||
# mistaken)`` slot covers both the contracted form (``"That's wrong"``,
|
||||
# ``"thats not"``) and the fully-spoken copula form (``"That is not
|
||||
# right"``, ``"That was wrong"``, ``"That is incorrect"``, ``"That is
|
||||
# false"``, ``"That was mistaken"``). The contracted-only predecessor
|
||||
# silently dropped these to UNKNOWN.
|
||||
(re.compile(r"\b(?:no|that(?:'?s|\s+(?:is|was))\s+(?:not|wrong|incorrect|false|mistaken)|incorrect|actually|correction)\b", re.IGNORECASE), IntentTag.CORRECTION),
|
||||
(re.compile(r"(?:remember|recall)\s+", re.IGNORECASE), IntentTag.RECALL),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -145,6 +145,7 @@ def test_recall_strips_articles(prompt: str, expected_subject: str) -> None:
|
|||
@pytest.mark.parametrize(
|
||||
"prompt",
|
||||
[
|
||||
# Pre-existing canonical forms (contracted ``that's``)
|
||||
"No, that's wrong.",
|
||||
"No.",
|
||||
"No way.",
|
||||
|
|
@ -153,11 +154,25 @@ def test_recall_strips_articles(prompt: str, expected_subject: str) -> None:
|
|||
"Actually, that's false.",
|
||||
"Correction: memory is not storage.",
|
||||
"That's wrong.",
|
||||
# Fully-spoken copula forms — added when the contracted-only
|
||||
# ``that'?s\s+(?:not|wrong)`` slot was widened to also accept
|
||||
# ``that\s+(?:is|was)`` and the predicate alternation grew
|
||||
# ``incorrect|false|mistaken``. Every one of these used to
|
||||
# silently fall through to UNKNOWN.
|
||||
"That is not right.",
|
||||
"That is wrong.",
|
||||
"That was wrong.",
|
||||
"That is incorrect.",
|
||||
"That is false.",
|
||||
"That was not right.",
|
||||
"that is mistaken.",
|
||||
"That was incorrect.",
|
||||
],
|
||||
)
|
||||
def test_correction_canonical_forms_still_route(prompt: str) -> None:
|
||||
"""Legitimate CORRECTION pragmas must still classify after the
|
||||
word-boundary fix narrowed the alternation."""
|
||||
"""Legitimate CORRECTION pragmas must classify after the
|
||||
word-boundary fix narrowed the alternation, AND the
|
||||
fully-spoken copula variants must route too (previously UNKNOWN)."""
|
||||
intent = classify_intent(prompt)
|
||||
assert intent.tag is IntentTag.CORRECTION
|
||||
|
||||
|
|
@ -178,6 +193,20 @@ def test_correction_canonical_forms_still_route(prompt: str) -> None:
|
|||
"Corrections department.",
|
||||
# ``Actually`` prefix — rarer but symmetric
|
||||
"Actualization of intent.",
|
||||
# Affirmatives that share the ``That is/was ...`` shape — the
|
||||
# predicate alternation (``not|wrong|incorrect|false|mistaken``)
|
||||
# must not over-match. ``That is correct/right/true`` are NOT
|
||||
# corrections; ``falsifiable`` / ``wrongly accused`` carry the
|
||||
# trigger root but extend past the boundary.
|
||||
"That is correct.",
|
||||
"That is right.",
|
||||
"That is true.",
|
||||
"That works.",
|
||||
"That is interesting.",
|
||||
"That is a fact.",
|
||||
"That was a good question.",
|
||||
"That is falsifiable.",
|
||||
"That was wrongly accused.",
|
||||
],
|
||||
)
|
||||
def test_correction_does_not_eat_no_prefixed_words(prompt: str) -> None:
|
||||
|
|
|
|||
Loading…
Reference in a new issue