fix(intent): widen RECALL trigger to accept `recall alongside remember`

The articulation breadth benchmark surfaced a RECALL intent gap:

  Before (bench output):
    RECALL    UNKNOWN    pack    Pack-resident tokens — pack-grounded
                                 (en_core_cognition_v1): recall ...

The probe prompt ``"Recall truth."`` classified as UNKNOWN and fell
through to the ADR-0086 pack-resident-token surface — a graceful
degradation, not a hard failure, but a real classifier gap.

Root cause: ``generate/intent.py`` ``_RULES`` line 213 only matched
the imperative ``remember``:

    (re.compile(r"remember\s+", re.IGNORECASE), IntentTag.RECALL)

The verb ``recall`` — every bit as natural an imperative — was
missing from the trigger pattern.  ``"Remember truth."`` correctly
routed to RECALL; ``"Recall truth."`` did not.

Fix: widen the alternation to ``(?:remember|recall)\s+``.  One-word
change; ``re.match`` anchoring at the start of the prompt means the
fix only catches the canonical imperative form, leaving downstream
contexts untouched:

  * ``Does memory require recall?``      → VERIFICATION (unchanged;
    earlier rule on the aux-verb pattern fires first)
  * ``What is recall?``                  → DEFINITION   (unchanged;
    ``what\s+is\s+`` fires first)
  * ``Why does recall exist?``           → CAUSE        (unchanged;
    ``why\s+`` fires first)
  * ``I recall.``                        → UNKNOWN      (unchanged;
    no trailing word after ``recall``, ``\s+`` doesn't match)
  * ``Please recall the truth.``         → UNKNOWN      (unchanged
    — symmetric with ``Please remember the truth.`` since rules use
    ``pattern.match`` not ``pattern.search``)

After (bench output):
    RECALL    RECALL    pack    Truth is what is true. pack-grounded
                                (en_core_cognition_v1).

The articulation bench probe now routes correctly and produces a
pack-grounded definition surface — the canonical RECALL output on
a pack-resident lemma.

Tests extended: ``tests/test_intent_subject_extraction.py::
test_recall_strips_articles`` is parametrized with four new
``Recall ...`` cases parallel to the existing ``Remember ...``
cases.  A regression that re-narrows the trigger pattern fails the
gate immediately.

Verified:
  * pytest tests/test_intent_subject_extraction.py            7/7 pass
  * pytest tests/test_register_firing_diagnostic.py           3/3 pass
  * core test --suite smoke                                  67/67 pass
  * core test --suite runtime                                19/19 pass
  * core bench --suite articulation  → RECALL ✓ pack-grounded
This commit is contained in:
Shay 2026-05-21 08:26:01 -07:00
parent cc3beede53
commit 7ef4ef4546
2 changed files with 11 additions and 1 deletions

View file

@ -210,7 +210,7 @@ _RULES: tuple[tuple[re.Pattern[str], IntentTag], ...] = (
(re.compile(r"how\s+(?:do|can|should|would)\s+(?:I|we|you)\s+", re.IGNORECASE), IntentTag.PROCEDURE),
(re.compile(r"(?:is|are|does|do|can|could|would|should|was|were|has|have|will)\s+.+\??\s*$", re.IGNORECASE), IntentTag.VERIFICATION),
(re.compile(r"(?:no|that'?s\s+(?:not|wrong)|incorrect|actually|correction)", re.IGNORECASE), IntentTag.CORRECTION),
(re.compile(r"remember\s+", re.IGNORECASE), IntentTag.RECALL),
(re.compile(r"(?:remember|recall)\s+", re.IGNORECASE), IntentTag.RECALL),
)

View file

@ -108,6 +108,16 @@ def test_verification_extracts_head_noun(prompt: str, expected_subject: str) ->
("Remember light", "light"),
("Remember the truth", "truth"),
("Remember a procedure", "procedure"),
# ``recall`` is a synonym imperative of ``remember`` and must
# route identically. The articulation breadth benchmark probe
# ``"Recall truth."`` was misclassified as UNKNOWN until the
# trigger pattern in ``_RULES`` was widened to ``(?:remember|
# recall)\s+`` — without this case the regression silently
# returns.
("Recall light", "light"),
("Recall the truth", "truth"),
("Recall a procedure", "procedure"),
("Recall truth.", "truth"),
],
)
def test_recall_strips_articles(prompt: str, expected_subject: str) -> None: