Review: Hybrid search -- RRF blending + semantic search

review-1570-2026-06-22 Review

review needs-refinement

Verdict: NEEDS_REFINEMENT

Template Completeness

  • [x] Type -- Feature
  • [x] Lineage -- Decomposed from paldocs#52, depends on #52 and #59
  • [x] Repo -- ldraney/paldocs
  • [x] User Story -- As the MCP layer...
  • [x] Context -- clear motivation and relationship to consolidation
  • [x] File Targets -- modify and do-not-touch lists present
  • [x] Feature Flag -- "none", appropriate for stub replacement
  • [x] Acceptance Criteria -- 3 criteria present
  • [x] Test Expectations -- unit + integration tests with run command
  • [x] Constraints -- RRF formula, neighbor gem, tsvector dependencies
  • [x] Checklist -- present
  • [x] Related -- project, story, arch, upstream/downstream links
All required sections for Feature template are present and populated. Template is complete.

Traceability

  • [x] story:consolidation label -- story-paldocs-consolidation
  • [x] story note verified -- found in project-paldocs user-stories section
  • [x] arch:rails-api label -- rails-api component
  • [ ] arch note MISSING -- [SCOPE] Create architecture note arch-rails-api. No matching note found in pal-e-docs. Multiple board items reference this arch label (#1567, #1569, #1570) so the note is needed.
  • [x] Forgejo issue -- https://forgejo.tail5b443a.ts.net/ldraney/paldocs/issues/61, open

File Targets

  • [x] app/services/hybrid_search.rb -- to be created. No app/services/ directory exists yet, but creation is standard Rails convention. OK.
  • [ ] app/controllers/api/search_controller.rb -- ISSUE: This file does not exist yet. It depends on paldocs#59 creating the API namespace and search controller stub first. No app/controllers/api/ directory exists in the current repo. This is correctly documented as a dependency but the agent implementing this ticket must verify #59 is merged before starting.
  • [x] Do-not-touch list is well-defined (block.rb, jobs, migrations)

Repo Placement

OK. Issue filed on ldraney/paldocs, work targets ldraney/paldocs. Single-repo scope.

Dependencies

  • paldocs#52 (Embedding pipeline) -- in todo column, state open. This ticket requires embeddings to exist in blocks.embedding column. BLOCKED until #52 is complete.
  • paldocs#59 (Search controller stub) -- in todo column, state open. This ticket replaces the semantic search stub created by #59. BLOCKED until #59 is complete.
  • neighbor gem -- not yet in Gemfile. Will be added by #52. Dependency is implicit but not explicitly stated in the Constraints section.
  • paldocs#54 (MCP server) -- downstream consumer, in todo column. Not a blocker but should be aware.
Dependencies are documented in the Lineage section. The blocking relationship is clear. Wave ordering should ensure #52 and #59 complete before this ticket moves to in_progress.

Acceptance Criteria

  • [x] AC1 (semantic search returns cosine-ranked results) -- testable via integration test
  • [x] AC2 (hybrid search returns RRF-blended results) -- testable via unit + integration test
  • [ ] AC3 ("compare search results to pal-e-docs semantic search, top-5 overlap") -- ISSUE: this is subjective and hard to verify automatically. "Known queries" are not defined. An agent cannot verify "overlap" without a reference dataset. [BODY] Recommend replacing with a concrete assertion, e.g., "When I search for 'keycloak auth' against test fixtures, then the top result contains the keycloak architecture note."

Blast Radius

Low. This ticket adds a new service and modifies a controller stub that does not yet exist (created by #59). No existing functionality is changed. The neighbor gem (from #52) and tsvector are database-level concerns already handled by PostgreSQL. No sibling services affected.

Decomposition Assessment

2 file targets in 1 repo. 3 acceptance criteria. Estimated agent work under 5 minutes. No decomposition needed.

Recommendation

  • [SCOPE] Create architecture note arch-rails-api for the rails-api component. Multiple board items reference this arch label (#1567, #1569, #1570).
  • [BODY] AC3 is not agent-verifiable as written. Replace "top-5 results overlap for known queries" with a concrete assertion against test fixtures.
  • [BODY] Add explicit note in Constraints that the neighbor gem must be available (added by #52) before this ticket can proceed.