Problem
search(query="SuccessFactors") returns total: 41. search(query="SuccessFactors AI Talent"), a more specific, narrower-sounding query with two additional terms, returns total: 1103 — 27x more results than the single-term search.
Adding terms to a search query should narrow the result set (implicit AND, or ideally phrase-awareness), not expand it by more than an order of magnitude. The only mechanism that produces this pattern is the query being treated as an OR across all terms ("SuccessFactors" OR "AI" OR "Talent"), where "AI" and "Talent" are each independently common enough across the HR-tech corpus to explode the match count on their own.
Root cause
src/reed/graph.py:873:
prefix = (
f"CALL QUERY_FTS_INDEX('Item', 'item_fts', $q) "
f"WITH node AS i, score{feed_clause}{tag_clause}{where}"
)
Kuzu's QUERY_FTS_INDEX defaults to disjunctive (OR/BM25-across-any-term) matching unless called with an explicit conjunctive := true argument. That default is never overridden here, so every multi-word query silently becomes an OR query.
Impact
Defeats the actual use case for a multi-word query — using more specific language to get a smaller, more relevant result set. As implemented, adding qualifying terms makes results worse (broader and less relevant), the opposite of what a user typing a longer, more specific query expects. Surfaced via the search MCP tool (src/reed/mcp_server.py:316) and the underlying src/reed/api/search.py:45 endpoint, both of which call search_items with no way to control this.
Recommended fix
- Default multi-term queries to
conjunctive := true (implicit AND across terms) in the QUERY_FTS_INDEX call at src/reed/graph.py:873.
- Consider supporting explicit phrase matching (quoted strings) and a documented, deliberate OR mode for when that's genuinely wanted, rather than only a global AND/OR switch.
- Whichever default is chosen, state it explicitly in the
search tool's own docstring/description (src/reed/mcp_server.py) so a caller isn't left guessing which behaviour to expect — the same gap that made this bug easy to miss until directly comparing two related queries.
Problem
search(query="SuccessFactors")returnstotal: 41.search(query="SuccessFactors AI Talent"), a more specific, narrower-sounding query with two additional terms, returnstotal: 1103— 27x more results than the single-term search.Adding terms to a search query should narrow the result set (implicit AND, or ideally phrase-awareness), not expand it by more than an order of magnitude. The only mechanism that produces this pattern is the query being treated as an OR across all terms (
"SuccessFactors" OR "AI" OR "Talent"), where "AI" and "Talent" are each independently common enough across the HR-tech corpus to explode the match count on their own.Root cause
src/reed/graph.py:873:Kuzu's
QUERY_FTS_INDEXdefaults to disjunctive (OR/BM25-across-any-term) matching unless called with an explicitconjunctive := trueargument. That default is never overridden here, so every multi-word query silently becomes an OR query.Impact
Defeats the actual use case for a multi-word query — using more specific language to get a smaller, more relevant result set. As implemented, adding qualifying terms makes results worse (broader and less relevant), the opposite of what a user typing a longer, more specific query expects. Surfaced via the
searchMCP tool (src/reed/mcp_server.py:316) and the underlyingsrc/reed/api/search.py:45endpoint, both of which callsearch_itemswith no way to control this.Recommended fix
conjunctive := true(implicit AND across terms) in theQUERY_FTS_INDEXcall atsrc/reed/graph.py:873.searchtool's own docstring/description (src/reed/mcp_server.py) so a caller isn't left guessing which behaviour to expect — the same gap that made this bug easy to miss until directly comparing two related queries.