Skip to content

fix(rank): match whole words, fold plurals, drop query stopwords - #47

Merged
stormer78 merged 1 commit into
mainfrom
fix/rank-whole-words
Nov 11, 2026
Merged

stormer78 merged 1 commit into
mainfrom
fix/rank-whole-words

Conversation

@stormer78

Copy link
Copy Markdown
Contributor

Fixes the two ranking defects the evaluation harness (#46) found, and makes their probes hard checks.

Changes

  • Whole-word matching instead of substring containment — "run" no longer matches "Test runner", nor "test" "latest".
  • Plurals folded to singular by rule, on both sides ("tests"→"test", "policies"→"policy", "pushes"→"push"; "status", "analysis", "bus" untouched). Plurals only — "-ing"/"-ed" stripping guesses wrong in ways nobody can predict.
  • Query stopwords (short English list) dropped. Negations ("not", "never", "no") are kept — they change meaning. A query of only stopwords returns nothing, not the whole context.
  • Words split on any script, not ASCII only — "café" / "Straße" now match.

Evaluation, before → after

before after
minimisation precision 29% 67%
precision (dimension) 81% 93%
overall precision 74% 82%
MRR 0.97 1.00
checks 24/27 + 3 known gaps 29/29, no known gaps

minimisation-stopwords and precision-word-boundaries are now hard. One adjustment to the latter: its "runner" memory's description no longer contains the word "run" itself, because with whole-word matching that memory legitimately matches both query words and the probe was testing two things at once. As adjusted, the probe fails under the old substring ranking (the name "runner" scored) and passes under this one.

Unit tests cover word boundaries, plural folding both ways, non-plural -s words, stopword-only queries, and non-Latin words.

Plugin and crate → 0.6.1.

The evaluation (#35) found two ranking defects. Both are fixed here, and
the soft probes that recorded them are now hard checks:

- Query terms matched as substrings, so "run" matched "Test runner"
  and "test" matched "latest", and a memory that merely contained the
  letters could outrank the one that answered.
- There was no stopword list, so "what is the for" matched every memory
  containing "the" or "for".

Fields and queries are now split into words (any script, not just
ASCII), lowercased, and folded from plural to singular by rule
("tests" → "test", "policies" → "policy"); terms match whole words. A
short English stopword list is dropped from the query — negations stay,
since they change meaning. A query of nothing but stopwords has no terms
and, being non-empty, returns nothing rather than the whole context.

Evaluation, before → after: minimisation precision 29% → 67%, overall
precision 74% → 82%, MRR 0.97 → 1.00; all 29 checks pass, no known gaps.

Bumps the plugin to 0.6.1.

Signed-off-by: Glenn Gore <glenn.g@affinidi.com>
@stormer78
stormer78 merged commit 44d46e2 into main Nov 11, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant