fix(search): surface exact short profile names - #5480
Conversation
Short prefix searches can fill their bounded page with newer profile JSON lexemes before an exact one- or two-character display name is reached. Prioritize whole-lexeme matches only for short kind-0 prefix searches while preserving the existing result set, pagination, and authorization path. Add a Postgres regression with enough noisy profiles to saturate the first page and verify the exact name remains first. Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz> Signed-off-by: Wes <wesbillman@users.noreply.github.com>
wesbillman
left a comment
There was a problem hiding this comment.
Carl re-review on Wes’s behalf at exact head ff88761135d5045139aeb3da14d08cbfba203169: cleared / would approve. (GitHub will not accept an approval from the PR author’s account; the existing independent approval is pinned to this head.)
I traced the SQL construction and caller boundary. The new predicate is limited to Prefix queries whose kinds are exactly [0] and whose normalized input is at most two Unicode scalar values. It changes only ordering: community, deletion, channel, kind, author, time, pagination, canonical refetch, and authorization behavior remain on the existing path. The exact-lexeme check uses the same simple configuration as search_tsv, and deterministic rank/recency/id ordering remains behind it.
Tests changed because behavior intentionally changes: short_kind0_prefix_prioritizes_exact_lexeme_on_a_noisy_page adds a Postgres regression proving the old bounded-page failure and exact-first ordering.
Validation on this exact head:
cargo test -p buzz-search— 3 unit tests passed; 19 Postgres tests correctly ignored without DBcargo clippy -p buzz-search --tests -- -D warnings— passedgit diff --check— clean- GitHub CI, including the Postgres-backed/unit and integration lanes, is green
No blocking findings.
…gaps * origin/main: (35 commits) feat(desktop): time-based sweep for stale localStorage caches (#5453) ci(release): gate OSS desktop auto-update promotion (#5398) fix(release): pin desktop PR operations to block/buzz (#5212) fix(search): surface exact short profile names (#5480) Reduce repeated ACP session context (#5423) feat(desktop): NIP-AM agent-usage backend — P2 emission/transport/archive + P4a aggregation/D6 (#4000) fix(desktop): resolve overlapping member mentions (#5225) chore(deps): update react monorepo (#4441) ci(security): allow retired relay pool advisory (#5404) chore(deps): update dependency @tanstack/react-virtual to v3.14.9 (#4439) chore(deps): update all non-major dependencies (#3049) chore(deps): update rust crate anyhow to v1.0.104 (#4447) chore(deps): update rust crate arc-swap to v1.9.2 (#4448) chore(deps): update rust crate async-trait to v0.1.91 (#4458) chore(deps): update rust crate diffy to v0.5.1 (#4466) chore(deps): update rust crate async-compression to v0.4.43 (#4456) chore(deps): update rust crate clap to v4.6.6 (#4465) fix(desktop): preserve Welcome banner dismissal (#5406) fix(agent): retry LLM completion on malformed 2xx JSON body (#5351) fix(desktop): welcome banner overlap and missing dismiss control (#5330) ... # Conflicts: # crates/buzz-acp/src/config.rs
…gaps * origin/main: (35 commits) feat(desktop): time-based sweep for stale localStorage caches (#5453) ci(release): gate OSS desktop auto-update promotion (#5398) fix(release): pin desktop PR operations to block/buzz (#5212) fix(search): surface exact short profile names (#5480) Reduce repeated ACP session context (#5423) feat(desktop): NIP-AM agent-usage backend — P2 emission/transport/archive + P4a aggregation/D6 (#4000) fix(desktop): resolve overlapping member mentions (#5225) chore(deps): update react monorepo (#4441) ci(security): allow retired relay pool advisory (#5404) chore(deps): update dependency @tanstack/react-virtual to v3.14.9 (#4439) chore(deps): update all non-major dependencies (#3049) chore(deps): update rust crate anyhow to v1.0.104 (#4447) chore(deps): update rust crate arc-swap to v1.9.2 (#4448) chore(deps): update rust crate async-trait to v0.1.91 (#4458) chore(deps): update rust crate diffy to v0.5.1 (#4466) chore(deps): update rust crate async-compression to v0.4.43 (#4456) chore(deps): update rust crate clap to v4.6.6 (#4465) fix(desktop): preserve Welcome banner dismissal (#5406) fix(agent): retry LLM completion on malformed 2xx JSON body (#5351) fix(desktop): welcome banner overlap and missing dismiss control (#5330) ... # Conflicts: # crates/buzz-acp/src/config.rs Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Summary
jm…profiles saturate the bounded pageWhy
Desktop mention autocomplete starts searching after one character. The
jmprofile is indexed and matches bothjm:*prefix search and standard full-text search, but production prefix search returns a full 50-result page without it. Raw profile JSON supplies enough unrelatedjm…lexemes that newer equal-rank matches fill the bounded page before the exact short display name.Changing clients would leave deployed Desktop 0.5.8 installations broken. This shared search-layer compatibility fix changes ordering only for
Prefix + kinds:[0] + query length <= 2; message search, longer profile typeahead, and agent eligibility are untouched.Validation
At commit
ff88761135d5045139aeb3da14d08cbfba203169with a clean worktree:BUZZ_TEST_DATABASE_URL=postgres://buzz:buzz_dev@localhost:5432/buzz cargo test -p buzz-search --tests -- --include-ignored— 22 passed (3 unit + 19 Postgres integration)cargo clippy -p buzz-search --tests -- -D warningscargo fmt --all -- --checkshort_kind0_prefix_prioritizes_exact_lexeme_on_a_noisy_pagefailRisk
Low. The extra ordering predicate applies only to one- or two-character prefix searches restricted exactly to kind 0. It does not add candidates, bypass filters, or alter access control. Exact matches move ahead of broader prefix matches; all remaining ordering stays relevance, recency, then event ID.