Skip to content

docs(embedding): record issue #35 relevance-floor investigation (negative result) - #36

Merged
Platonenkov merged 2 commits into
mainfrom
claude/relevance-floor-524a4
Aug 5, 2026
Merged

docs(embedding): record issue #35 relevance-floor investigation (negative result)#36
Platonenkov merged 2 commits into
mainfrom
claude/relevance-floor-524a4

Conversation

@Platonenkov

Copy link
Copy Markdown
Collaborator

Summary

Investigates #35 (semantic search misses Platforms/Windows/App.xaml.cs for auto-lock queries on the wallet corpus). Reproduced both reported phrasings and measured the chunk's actual cosine similarity directly against Ollama, bypassing MinCosineSimilarity entirely.

Finding: this is not a threshold-calibration bug.

  • what fires when the auto-lock timeout elapses -> the relevant chunk (OnAppWindowChanged) scores 0.4184 -- 0.13 below the 0.55 floor, squarely inside the noise band (0.3321-0.5402) the floor was measured against, not a borderline miss.
  • how does the app lock on resume -> the same chunk scores 0.5880 for the same file/chunk, comfortably above the floor. (This phrasing's ranking/crowding was already fixed by fix(search): cap per-file hits so a small limit spans more files #34.)

The method body (OnAppWindowChanged) never mentions "lock", "auto", or "timeout" -- it only calls GetAuthStateProvider()?.OnAppSleep()/OnAppResume() on window minimize/restore. RoslynChunker.BuildEmbedText already prepends the file's path as a lexical signal (File: {path}), but that doesn't help here: the path (Platforms/Windows/App.xaml.cs) has no lock/timeout vocabulary either. This is a genuine, phrasing-sensitive content gap in one chunk's embedding, not a systemic miscalibration -- lowering the floor far enough to admit 0.4184 would re-admit several of the genuinely off-topic queries the 0.55 default was measured against (noise tops out at 0.5402).

Decision

Left MinCosineSimilarity (0.55) unchanged. No relative-floor or below-floor-backfill redesign was implemented either: both would need their own measurement against the golden suite to justify, and neither is evidenced to help this specific case (the gap to the top hit for this query is also large, not a near-miss). Recorded the full measurement and reasoning as a <remarks> addendum on EmbeddingOptions.MinCosineSimilarity, matching how the constant's original derivation is already documented there, so the data point survives for whoever revisits this threshold next.

What this costs: the miss described in #35 remains -- a query phrased exactly as "what fires when the auto-lock timeout elapses" still won't surface this one Windows-only wiring file. The underlying auto-lock feature is still found via more central chunks (AuthService.SetAutoLockDate, IAuthService docs), and the cross-platform-completeness framing ("how does the app lock on resume") already clears the floor and (post-#34) ranks reasonably. Any fix for the narrower miss belongs on the indexing/chunking side (e.g. enriching platform-glue chunks with cross-referenced call-target context) -- a larger, separate change, not attempted here for lack of measurement.

Test plan

Measured the wallet corpus's Windows-only auto-lock wiring chunk
(Platforms/Windows/App.xaml.cs's OnAppWindowChanged) directly against
Ollama for both reported phrasings, bypassing the floor entirely:

- "what fires when the auto-lock timeout elapses" -> cosine 0.4184,
  0.13 below MinCosineSimilarity and squarely inside the measured
  noise band (0.3321-0.5402), not a borderline miss.
- "how does the app lock on resume" -> cosine 0.5880 for the exact
  same chunk, comfortably above the floor.

The method body never mentions "lock", "auto", or "timeout", and the
file-path lexical signal RoslynChunker already embeds does not help
here because the path itself carries no lock/timeout vocabulary
either. This is a phrasing-sensitive content gap in one chunk's
embedding, not a systemic threshold miscalibration -- lowering the
floor far enough to admit 0.4184 would re-admit several of the
genuinely off-topic queries the constant was measured against.

No production behavior changes; the 0.55 default is left as-is. This
records the measurement and reasoning on MinCosineSimilarity itself,
matching how the constant's original derivation is already documented
there.
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4bca1534-1456-4da5-b405-b2009db7e833

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

The #35 investigation is recorded on MinCosineSimilarity, where a maintainer
deciding whether to move that constant will find it. The finding generalises
past that constant, though, and the generalisation belongs where a user
deciding which tool to reach for will see it.

Similarity is computed against a chunk's own text, so code that takes part in
a feature without naming it has nothing to match on. Grep reaches it in two
hops -- find the symbol, then find its callers -- and embedding similarity has
no equivalent second hop. That is a capability boundary rather than a tuning
problem, and it is the concrete mechanism behind the coverage gap the
benchmark measured (82% vs 88% of required facts), since platform-guarded
variants and parallel code paths are precisely the shapes that participate
without naming.

Ends with the actionable form: for completeness questions, use Grep, or use
code_search to find the symbol and Grep to find its callers.
@Platonenkov

Copy link
Copy Markdown
Collaborator Author

Добавил обобщение в README, в раздел «Known limitations» — ваш разбор его вполне заслуживает, а комментарий к константе видит мейнтейнер, решающий двигать ли 0.55, но не пользователь, решающий каким инструментом искать.

Формулировка такая: код, участвующий в фиче только тем, что вызывает её, здесь почти невидим. Похожесть считается по собственному тексту чанка, поэтому методу, который делает своё дело не называя его, не на чем совпасть. Grep берёт это в два шага — найти символ, потом найти вызывающих — а у эмбеддинга второго шага нет. Это граница возможностей, а не настройка.

И это же объясняет разрыв покрытия из бенчмарка (82% против 88%): платформенные ветки, альтернативные реализации и параллельные пути — ровно те формы, которые участвуют не называя.

Отдельно ценю два решения в вашей работе. Первое — вы отказались вводить относительный порог и добор подпороговых с пометкой, потому что для обоснования именно этого случая данных не хватало; предложить непроверенное было бы легче, чем сказать «недостаточно измерений». Второе — вы поймали ошибку в моём тексте issue: я написал path_filter с обратными слэшами, а сравнение идёт по путям с прямыми, так что буквальный вариант не совпал бы ни с чем. Вывод от этого не изменился, но заметить стоило.

@Platonenkov
Platonenkov merged commit 6757736 into main Aug 5, 2026
4 checks passed
@Platonenkov
Platonenkov deleted the claude/relevance-floor-524a4 branch August 5, 2026 15:30
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