feat(fb-38): score semantics — score_kind on search_hit.v1 + RRF formula docs #131

Merged
altair823 merged 9 commits from feat/fb-38-score-semantics into main 2026-05-10 09:38:27 +00:00
Owner

Summary

  • search_hit.v1 에 optional score_kind: string 필드 추가 — "rrf" (hybrid) / "bm25" (lexical) / "cosine" (vector). additive minor wire (no schema bump).
  • LexicalRetriever → Bm25, VectorRetriever → Cosine, HybridRetriever fuse → Rrf override.
  • HybridRetriever search_with_trace mode=Lexical/Vector → underlying retriever 의 score_kind 그대로 보존.
  • README + design §2.2 + SKILL — RRF 수식 전체 (2/(k+rank) per-chunk, 2/(k+1) ceiling, normalize 과정) + ranking-vs-confidence 안내. agent 용 trust threshold 는 retrieval.lexical_score (BM25 raw) / retrieval.vector_score (cosine raw).

Design: docs/superpowers/specs/2026-05-10-p9-fb-38-score-semantics-design.md
Plan: docs/superpowers/plans/2026-05-10-p9-fb-38-score-semantics.md

Test plan

  • cargo test --workspace --no-fail-fast -j 1 green
  • cargo clippy --workspace --all-targets -- -D warnings clean
  • kebab-core: 3 unit tests (serde roundtrip, default Rrf, backwards-compat deserialize)
  • kebab-search: 2 hybrid unit tests + lexical integration test
  • kebab-cli: wire_search_score_kind 2 integration tests
  • Manual smoke: kebab search Q --mode lexical --json | jq .hits[0].score_kind returns "bm25"

🤖 Generated with Claude Code

## Summary - `search_hit.v1` 에 optional `score_kind: string` 필드 추가 — `"rrf"` (hybrid) / `"bm25"` (lexical) / `"cosine"` (vector). additive minor wire (no schema bump). - LexicalRetriever → Bm25, VectorRetriever → Cosine, HybridRetriever fuse → Rrf override. - HybridRetriever `search_with_trace` mode=Lexical/Vector → underlying retriever 의 score_kind 그대로 보존. - README + design §2.2 + SKILL — RRF 수식 전체 (`2/(k+rank)` per-chunk, `2/(k+1)` ceiling, normalize 과정) + ranking-vs-confidence 안내. agent 용 trust threshold 는 `retrieval.lexical_score` (BM25 raw) / `retrieval.vector_score` (cosine raw). Design: `docs/superpowers/specs/2026-05-10-p9-fb-38-score-semantics-design.md` Plan: `docs/superpowers/plans/2026-05-10-p9-fb-38-score-semantics.md` ## Test plan - [x] `cargo test --workspace --no-fail-fast -j 1` green - [x] `cargo clippy --workspace --all-targets -- -D warnings` clean - [x] kebab-core: 3 unit tests (serde roundtrip, default Rrf, backwards-compat deserialize) - [x] kebab-search: 2 hybrid unit tests + lexical integration test - [x] kebab-cli: wire_search_score_kind 2 integration tests - [ ] Manual smoke: `kebab search Q --mode lexical --json | jq .hits[0].score_kind` returns `"bm25"` 🤖 Generated with [Claude Code](https://claude.com/claude-code)
altair823 added 9 commits 2026-05-10 09:30:23 +00:00
- search_hit.v1 에 optional score_kind 필드 (rrf | bm25 | cosine)
- LexicalRetriever → Bm25, VectorRetriever → Cosine, HybridRetriever → Rrf
- fb-37 search_with_trace 의 mode-dispatch hits 는 underlying retriever 의
  score_kind 그대로 보존
- README + design §4 + SKILL 에 RRF 수식 전체 + "ranking signal, NOT confidence"
  안내, agent 용 trust threshold 는 nested retrieval.{lexical,vector}_score
- additive minor wire — schema bump 없음

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7 tasks: kebab-core ScoreKind enum + SearchHit field, lexical Bm25
labeling, vector Cosine, hybrid Rrf + search_with_trace pass-through,
cross-crate SearchHit literal cleanup, CLI integration test, docs
(wire schema + README + design + SKILL + INDEX).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add ScoreKind::Bm25 to LexicalRetriever::build_hit SearchHit construction
- Import ScoreKind from kebab_core in lexical.rs
- Add integration test lexical_retriever_hits_carry_bm25_score_kind to verify all
  hits from LexicalRetriever carry score_kind == ScoreKind::Bm25
- Update lexical snapshot test baseline to include new score_kind field

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit unblocks Tasks 3 and 4 of fb-38:
- VectorRetriever::build_hit now labels hits with ScoreKind::Cosine
- Hybrid retriever test helpers (mk_hit functions) label synthetic hits with ScoreKind::Rrf
- Updated lexical snapshot fixture to reflect new score_kind field in output

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add missing score_kind field to SearchHit constructors in:
- kebab-tui/tests/search.rs::make_hit()
- kebab-eval/tests/metrics_and_compare.rs::hit()
- kebab-eval/src/metrics.rs::hit()

All test fixtures default to Rrf (hybrid mode), matching the field's
Default impl and the test semantics.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
altair823 merged commit 945319ae93 into main 2026-05-10 09:38:27 +00:00
altair823 deleted branch feat/fb-38-score-semantics 2026-05-10 09:38:28 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: altair823-org/kebab#131