Skip to content

fix: prune orphaned service data on rename/removal (#75)#89

Merged
GoodbyePlanet merged 3 commits into
mainfrom
fix/prune-orphaned-services
Jul 8, 2026
Merged

fix: prune orphaned service data on rename/removal (#75)#89
GoodbyePlanet merged 3 commits into
mainfrom
fix/prune-orphaned-services

Conversation

@GoodbyePlanet

@GoodbyePlanet GoodbyePlanet commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes #75 — when a service is renamed or removed from config.yaml, its old points remain orphaned in both the code symbols and git commits Qdrant collections, showing up in unfiltered searches.

Changes

  • New: server/indexer/cleanup.py — Defines a PrunableStore protocol and a shared prune_orphaned_services() function that compares indexed service names against the configured set and deletes orphaned data.
  • server/store/commit_store.py — Added get_indexed_services() (scrolls commits, collects distinct service names) and delete_by_service() (deletes all commit points for a service).
  • server/store/qdrant.py — Added get_indexed_services() (delegates to existing get_service_stats(), filtering out the internal "unknown" placeholder so it can never be treated as an orphaned service name).
  • server/indexer/pipeline.py — Calls ensure_collection() then prune_orphaned_services() at the start of IndexPipeline.index_all().
  • server/indexer/git_history.py — Calls ensure_collection() then prune_orphaned_services() at the start of GitHistoryPipeline.index_all().

Safety fix (post-review)

Code review flagged that an empty configured-services set (e.g. config.yaml with services: [], or the key missing) would previously cause prune_orphaned_services() to treat every indexed service as orphaned and wipe the entire store. Fixed: the function now refuses to prune and logs a warning when the configured set is empty, since that's far more likely to be a config error than an intentional wipe-everything request.

Behavior

Call Prunes orphans?
POST /reindex (no service) Yes
POST /reindex-history (no service) Yes
POST /reindex with "service": "foo" No — single-service reindex
reindex() MCP tool (no service arg) Yes
reindex(service="foo") MCP tool No
config.yaml has no configured services (empty/missing) No — prune is skipped to avoid wiping the store

Testing

  • All 264 tests pass (uv run pytest), including 10 new tests added in this update:
    • tests/test_cleanup.py (new) — orphan deletion, configured-service protection, empty-config guard, no-op on empty store, sorted multi-orphan output
    • tests/test_pipeline.py / tests/test_git_history.pyindex_all() prunes orphans before indexing, and skips pruning when no services are configured
    • tests/test_store.pyQdrantStore.get_indexed_services() excludes the "unknown" placeholder
  • ruff check and ruff format --check pass clean

GoodbyePlanet and others added 3 commits July 7, 2026 09:03
…ml (#75)

When a service is renamed or removed from config.yaml, the old service
name's points remain in both the code symbols and git commits Qdrant
collections, showing up in unfiltered searches.

Add a shared prune_orphaned_services() utility (via PrunableStore
protocol) that compares indexed service names against the configured
set and deletes orphaned data. Wire it into both IndexPipeline.index_all
and GitHistoryPipeline.index_all so it runs automatically on every
full reindex (POST /reindex and POST /reindex-history).
…erage

An empty configured-services set (e.g. config.yaml with services: []) would
previously cause every indexed service to be treated as orphaned and deleted.
Also ensures the collection exists before pruning, filters the "unknown"
service placeholder out of get_indexed_services, and adds tests for the new
pruning behavior across cleanup.py, pipeline.py, git_history.py, and qdrant.py.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@GoodbyePlanet GoodbyePlanet merged commit 2202d96 into main Jul 8, 2026
2 checks passed
@GoodbyePlanet GoodbyePlanet deleted the fix/prune-orphaned-services branch July 8, 2026 06:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Renamed service in config.yaml orphans its old points

1 participant