The REST server does not reuse the persistent vector index created by the CLI.
repowise init stores embeddings in the repository-local .repowise/lancedb directory. However, repowise serve always initializes a new, empty
InMemoryVectorStore, so semantic searches made through the REST API cannot see the existing embeddings.
This also affects workspace indexing jobs because the job executor always passes the global primary vector store to every repository pipeline.
Exact failure path
1. CLI persists embeddings to LanceDB
The CLI’s vector-store factory prefers a repository-local LanceDB store:
- packages/cli/src/repowise/cli/providers/vector_store.py:9
- LanceDB path: /.repowise/lancedb
- It only falls back to InMemoryVectorStore when LanceDB is unavailable.
During repowise init, that store is passed to the generation pipeline and populated with page and decision embeddings.
2. REST startup discards that persisted index
When the REST server starts, it builds the configured embedder but unconditionally creates a new in-memory store:
- packages/server/src/repowise/server/app.py:193
- packages/server/src/repowise/server/app.py:195
embedder = _build_embedder()
vector_store = InMemoryVectorStore(embedder=embedder)
There is no code here that checks for .repowise/lancedb or opens a configured pgvector backend.
The comment claiming that LanceDB or pgvector can be configured through the environment does not match the implementation; no corresponding
server configuration path exists.
3. Single-repository search queries the empty store
In single-repository mode, workspace_config is None, so semantic search immediately queries the primary in-memory store:
- packages/server/src/repowise/server/routers/search.py:149
- packages/server/src/repowise/server/routers/search.py:153
- packages/server/src/repowise/server/routers/search.py:156
Because this store was created during server startup and contains no vectors, InMemoryVectorStore.search() returns an empty list.
The existing workspace-only LanceDB resolver is never called in this path.
4. Workspace jobs use the wrong vector store
The job executor resolves the correct repository database through session_factory_override, but still takes the vector store from the global
application state:
- packages/server/src/repowise/server/job_executor.py:317
- packages/server/src/repowise/server/job_executor.py:319
- packages/server/src/repowise/server/job_executor.py:395
vector_store = app_state.vector_store
That same store is used for generation, decision embeddings, and deletion of swept page vectors.
Consequences in workspace mode include:
- New embeddings being written to the primary repository’s store or a shared in-memory store.
- Existing per-repository LanceDB indexes remaining stale.
- Embeddings disappearing after a server restart.
- Repository-scoped searches potentially falling back to a shared store containing vectors from another repository.
- Swept page IDs being deleted from the wrong vector store.
Reproduction
- Run repowise init inside a repository with LanceDB installed.
- Confirm that .repowise/lancedb exists and contains the wiki_pages table.
- Stop the CLI process.
- Run repowise serve from the same repository.
- Call:
GET /api/search?query=authentication&search_type=semantic
- Observe that semantic search returns no results even though the persisted LanceDB index contains matching pages.
- Run the equivalent CLI semantic search and observe that it can use the persisted index.
Expected behavior
- Single-repository REST startup should open the repository’s existing .repowise/lancedb store.
- Semantic search should work immediately after repowise init, without requiring a server-side reindex.
- Workspace jobs should use the vector store belonging to the job’s repository.
- Vector writes, deletes, and searches should remain isolated by repository.
- InMemoryVectorStore should remain an explicit fallback when persistent storage is unavailable.
Proposed implementation direction
Introduce a shared, repository-aware vector-store resolver that can be used by:
- REST application startup for the primary repository.
- Workspace semantic-search routing.
- The background job executor.
- API-managed repositories registered after startup.
For a repository with a .repowise/lancedb directory, the resolver should open LanceDBVectorStore with the configured embedder and cache it by
repository ID. The job executor should resolve the store only after it has loaded the job’s repository metadata.
All cached stores should be closed during application shutdown.
Test gap
The current REST semantic-search test manually inserts vectors into the server’s in-memory store:
- tests/unit/server/test_search.py:21
- tests/unit/server/test_search.py:41
This proves that the endpoint works when its transient store is manually populated, but it does not test the actual repowise init → repowise
serve lifecycle.
The REST server does not reuse the persistent vector index created by the CLI.
repowise init stores embeddings in the repository-local .repowise/lancedb directory. However, repowise serve always initializes a new, empty
InMemoryVectorStore, so semantic searches made through the REST API cannot see the existing embeddings.
This also affects workspace indexing jobs because the job executor always passes the global primary vector store to every repository pipeline.
Exact failure path
1. CLI persists embeddings to LanceDB
The CLI’s vector-store factory prefers a repository-local LanceDB store:
During repowise init, that store is passed to the generation pipeline and populated with page and decision embeddings.
2. REST startup discards that persisted index
When the REST server starts, it builds the configured embedder but unconditionally creates a new in-memory store:
embedder = _build_embedder()
vector_store = InMemoryVectorStore(embedder=embedder)
There is no code here that checks for .repowise/lancedb or opens a configured pgvector backend.
The comment claiming that LanceDB or pgvector can be configured through the environment does not match the implementation; no corresponding
server configuration path exists.
3. Single-repository search queries the empty store
In single-repository mode, workspace_config is None, so semantic search immediately queries the primary in-memory store:
Because this store was created during server startup and contains no vectors, InMemoryVectorStore.search() returns an empty list.
The existing workspace-only LanceDB resolver is never called in this path.
4. Workspace jobs use the wrong vector store
The job executor resolves the correct repository database through session_factory_override, but still takes the vector store from the global
application state:
vector_store = app_state.vector_store
That same store is used for generation, decision embeddings, and deletion of swept page vectors.
Consequences in workspace mode include:
Reproduction
GET /api/search?query=authentication&search_type=semantic
Expected behavior
Proposed implementation direction
Introduce a shared, repository-aware vector-store resolver that can be used by:
For a repository with a .repowise/lancedb directory, the resolver should open LanceDBVectorStore with the configured embedder and cache it by
repository ID. The job executor should resolve the store only after it has loaded the job’s repository metadata.
All cached stores should be closed during application shutdown.
Test gap
The current REST semantic-search test manually inserts vectors into the server’s in-memory store:
This proves that the endpoint works when its transient store is manually populated, but it does not test the actual repowise init → repowise
serve lifecycle.