Follow-up from PR #791 review (fixes #778). Not a regression from that PR; a pre-existing asymmetry the short-token frequency fallback narrows but does not close.
Problem
symbol_frequency's short-token fallback (exact_leaf_name_count, for tokens with no >=3-char segment) measures leaf equality: how many definition nodes are named exactly the token at their kind:Qualified.leaf signature. Three different notions of "this token matches this node" are now in play, and leaf equality is the odd one out:
exact_leaf_name_count (the short-token fallback) measures leaf equality.
- the
nodes_words_vocab path it falls back from measures segment membership.
ident::contains_token, which actually decides whether a node enters anchor_pool in travsr-mcp/src/seed.rs, measures a contiguous segment run.
So whenever a short token appears as a sub-segment of a compound member name rather than as the whole leaf, the frequency measure sees one node while the anchor path admits all of them, and grounding vs abstaining is decided by token length on identically shaped corpora.
Repro
Two identically shaped corpora, compound member names this time (300 method:Widget{i}.user_id plus one class:Id, and 300 method:Widget{i}.user_key plus one class:Key):
freq("id") 2ch = Some(1) # the leaf of `user_id` is `user_id`, not `id`
freq("key") 3ch = Some(301) # vocab counts `key` as a segment of `user_key`
contains_token("id", "method:Widget0.user_id") = true
contains_token("key", "method:Widget0.user_key") = true
All 300 compound members enter anchor_pool for id, while the frequency measure sees one node. End to end through build_seed_set:
query="id" freq=1 idf=0.900 anchors=3 confidence=Weak
query="key" freq=301 idf=0.173 anchors=3 confidence=None
build_ui, open_db, parse_id are common enough shapes for this to bite in practice.
Blast radius
Materially smaller than the original #778 defect: the emitted anchors here are the compound members, so g1 does not escalate and the verdict is Weak rather than Exact. It is grounding-vs-abstaining, not the strongest-trust-signal inversion the PR #791 review blocked on. Worth an issue, not a reason to have held that PR.
Proposed fix
Index 2-char segments in nodes_words_vocab so the segment-membership path can measure short tokens directly. That removes the second scale entirely, is O(1), and subsumes both this fallback and the deferred leaf-name index (see the perf note on PR #791). It is a schema migration either way, so it fits the same follow-up already scoped for the leaf-name index.
Context
Follow-up from PR #791 review (fixes #778). Not a regression from that PR; a pre-existing asymmetry the short-token frequency fallback narrows but does not close.
Problem
symbol_frequency's short-token fallback (exact_leaf_name_count, for tokens with no >=3-char segment) measures leaf equality: how many definition nodes are named exactly the token at theirkind:Qualified.leafsignature. Three different notions of "this token matches this node" are now in play, and leaf equality is the odd one out:exact_leaf_name_count(the short-token fallback) measures leaf equality.nodes_words_vocabpath it falls back from measures segment membership.ident::contains_token, which actually decides whether a node entersanchor_poolintravsr-mcp/src/seed.rs, measures a contiguous segment run.So whenever a short token appears as a sub-segment of a compound member name rather than as the whole leaf, the frequency measure sees one node while the anchor path admits all of them, and grounding vs abstaining is decided by token length on identically shaped corpora.
Repro
Two identically shaped corpora, compound member names this time (300
method:Widget{i}.user_idplus oneclass:Id, and 300method:Widget{i}.user_keyplus oneclass:Key):All 300 compound members enter
anchor_poolforid, while the frequency measure sees one node. End to end throughbuild_seed_set:build_ui,open_db,parse_idare common enough shapes for this to bite in practice.Blast radius
Materially smaller than the original #778 defect: the emitted anchors here are the compound members, so g1 does not escalate and the verdict is
Weakrather thanExact. It is grounding-vs-abstaining, not the strongest-trust-signal inversion the PR #791 review blocked on. Worth an issue, not a reason to have held that PR.Proposed fix
Index 2-char segments in
nodes_words_vocabso the segment-membership path can measure short tokens directly. That removes the second scale entirely, is O(1), and subsumes both this fallback and the deferred leaf-name index (see the perf note on PR #791). It is a schema migration either way, so it fits the same follow-up already scoped for the leaf-name index.Context
exact_leaf_name_count)