Skip to content

rebuild_index writes embeddings to a dead table, breaking semantic search after every reindex #172

Description

@seekmistar01

Summary

rebuild_index writes regenerated embeddings to the wrong table, so semantic search silently returns nothing after every reindex/import until artifacts are individually re-written.

Where

  • src/vouch/health.py:205 (_rebuild_embeddings) calls index_db.index_embedding(...), which writes the legacy embeddings table (index_db.py:123, INSERT OR REPLACE INTO embeddings).
  • The reader path context._retrieveindex_db.search_semanticsearch_embedding queries a different table, embedding_index (index_db.py:379).
  • rebuild_index first calls index_db.reset(), which deletes embedding_index (index_db.py:113) but not embeddings.
  • The live write hook KBStore._embed_and_store (storage.py) correctly populates embedding_index via index_db.put_embedding.

Root cause

reset() clears the table search reads (embedding_index); _rebuild_embeddings then refills only the legacy embeddings table, which no reader queries (search_embeddings plural is dead code — no call sites in src/). So after vouch index, vouch reindex, or import-apply (which all call rebuild_index), embedding/semantic search returns zero hits and retrieval silently degrades to the FTS5/substring fallback.

Why it's a real bug (not intended)

reset()'s own docstring says the embedding write hook should backfill embedding_index on reindex. No test calls rebuild_index and then asserts the embedding backend returns hits — test_search.py accepts any of embedding/fts5/substring (the fallback masks it), and the one embedding-specific integration test never calls rebuild_index. So the current behavior is unintended and untested.

Fix

Write to embedding_index via index_db.put_embedding with the same content_hash + model/version/dim metadata the live hook uses. Regression test rebuilds and asserts each artifact's embedding is readable from embedding_index. PR attached.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions