| Metadata | Value |
|---|---|
| Status | Completed |
| Version | 2.2.0 |
| Last Updated | 2026-09-08 |
| Author | Antigravity AI (for Seshadri) |
| Priority | P2 — first new user-facing capability after foundation is sound |
Implementation & Optimization Completed (2026-09-08): Implemented using Gemini Embedding 2 (
models/gemini-embedding-2) with 768-D Matryoshka Representation Learning (MRL) and PostgreSQL 18pgvectorHNSW index. Features hybrid search with Reciprocal Rank Fusion (RRF), section/overview context chunking, backfill CLI, 23-query musicological evaluation benchmark (Recall@5: 91.3%, MRR: 0.773), musical forms taxonomy (R__seed_08_update_musical_forms.sql), iterative HNSW scanning, overview boosting, and React 19 Admin UI hybrid search mode with dynamic relevance scoring. See Implementation Summary and Validation Report.
Deliver the long-parked “semantic search beyond keyword matching” capability (uplift finding F6; opportunity #5 in 09-ai/integration-opportunities.md) as a shippable v1 — “find similar krithis / search by meaning” over the catalogue — without standing up a separate ML stack or vector database. Embeddings live beside the relational data in the existing PostgreSQL 18 instance via pgvector.
The blocker for this feature used to be infrastructure (an embeddings model + a vector store). Both are now cheap:
gemini-embedding-001 is generally available: multilingual across 100+ languages (covers the Dravidian + Sanskrit corpus), with Matryoshka Representation Learning — emit 3072-dim vectors and truncate to 1536 or 768 with minimal quality loss.pgvector keeps vectors in Postgres 18 — no new datastore, no new operational surface, consistent with the project’s open-source / minimise-integration-debt posture.This is a new feature, not maintenance — it gets its own track and its own rollout, and it is explicitly not gated on any just-announced model (e.g. Gemini Embedding 2); build on the GA 001 model today.
flowchart TB
LYR[Krithi sections / lyrics]
EMB[Gemini Embedding 2<br/>768-d MRL]
TBL[(pgvector HNSW)]
Q[Query text]
ANN[ANN + RRF hybrid]
EP["POST /v1/search/*"]
UI[Curator Console]
LYR --> EMB --> TBL
Q --> EMB
TBL --> ANN --> EP --> UI
Design choices:
model_version and dims per row so re-embeds (model upgrades) are detectable and reversible — reconciliation as a first-class concern.pgvector extension via a Flyway migration (database/migrations/V58__semantic_search_pgvector.sql, ADR-013).document_embeddings, search_documents, embedding_profiles with 768-D MRL vectors; HNSW index with cosine ops.pgvector/pgvector:pg18 in Docker Compose and Testcontainers.embed_content path in extraction worker with google-genai SDK and Gemini Embedding 2 (src/embeddings/gemini_embedder.py).scripts/embed_catalogue.py).src/embeddings/context_formatter.py).POST /v1/search/semantic and POST /v1/search/hybrid Ktor routes (SemanticSearchRoutes.kt → HybridSearchService.kt → KrithiSearchRepository.kt).SemanticSearchRoutesTest.kt passing against Testcontainers.KrithiList.tsx with relevance scores and passage previews.evals/retrieval_benchmarks.json & scripts/evaluate_retrieval.py).pgvector enabled via a Flyway migration; krithi_embedding populated for the full catalogue.model_version recorded for every vector.model_version column + reconciliation job; never mix versions silently in one index.embed_content).1AND SQL syntax error on authenticated search, configured hnsw.iterative_scan = 'strict_order' and ef_search = 100, added overview preference boosting, updated Flyway musical forms taxonomy (R__seed_08_update_musical_forms.sql) classifying Syama Sastri’s Swarajathi Ratnatrayam, embedded musical form metadata, refined Admin UI with default hybrid discovery and dynamic score badges, expanded frozen benchmark to 23 queries achieving 91.3% Recall@5 and 0.773 MRR, and resolved documentation link checks.src/embeddings/catalogue_index.py: dimension guard (vector(768)), inactive replacement profiles with atomic --activate-profile, read-only dry-run profile lookup, obsolete-document retirement, and write_audit. Both embed scripts commit per composition, roll back on failure, persist failed ids and exit 1; upserts refresh original_content; update_search_headers.py audits each document. Backend binds each request to one resolved profile (activeEmbeddingProfile) and returns 503 on model/dimension mismatch; hybrid degrades to lexical-only when nothing is indexed. Remediation table in the Validation Report.Deferred from the validation remediation by decision on 2026-09-08. Finding 5 of the validation report remains open and is to be planned as its own Intent → Spec → Plan:
POST /v1/search/{semantic,hybrid} routes (including the publication predicate) and a lexical baseline, not only the evaluator’s private SQL.Ref: application_documentation/10-implementations/track-108-validation-2026-09-08.md