4.8 KiB
4.8 KiB
Task 5 Report — Implement the Qdrant VectorStore adapter
Status
Implemented on 2026-08-08 in /Users/mp/projects/ThothII/.worktrees/git-workspace-registry.
RED evidence
Command:
cd harness
./.venv/bin/pytest tests/test_qdrant_vector_store.py tests/test_vector_port_contract.py -q
Observed before implementation:
- exit code
2 - collection failed during import because the adapter did not exist yet
Representative failures:
ModuleNotFoundError: No module named 'tht.adapters.vector.qdrant'
GREEN evidence
Focused behavior suite:
cd harness
./.venv/bin/pytest tests/test_qdrant_vector_store.py tests/test_vector_port_contract.py -q
- exit code
0 31 passed, 1 warning
Touched-file lint:
cd harness
./.venv/bin/ruff check tht/adapters/vector/qdrant.py tht/adapters/vector/__init__.py \
tht/ports/vector.py tht/vectorstore/records.py tht/vectorstore/store.py \
tests/test_qdrant_vector_store.py tests/test_vector_port_contract.py
- exit code
0 All checks passed!
Patch hygiene:
git diff --check
- exit code
0
What changed
- added
QdrantVectorStorewith directrequests-based REST calls for:GET /collections/{collection}PUT /collections/{collection}PUT /collections/{collection}/indexPUT /collections/{collection}/points?wait=truePOST /collections/{collection}/points/queryPOST /collections/{collection}/points/scrollPOST /collections/{collection}/points/delete?wait=true
- implemented idempotent collection provisioning for
1024dimensions andCosinedistance - created deterministic UUIDv5 point IDs from workspace, semantic kind, and canonical record key
- preserved canonical record identity and only upserted/deleted points matching the exact workspace and generation filters
- added Qdrant payload helpers so stored payloads carry:
workspace_id- grouped semantic
kind(schema,evidence,memory) - original
record_kind - canonical
record_key content_hash- existing Thoth metadata fields
- mapped Qdrant payloads back into existing
VectorHitobjects without losing the original Thoth kind - exported the new adapter from the public vector adapter package and added focused contract tests
- sanitized timeout and malformed-response failures so CLI-facing callers do not leak raw endpoint details
Self-review
- confirmed collection mismatch fails without any delete/recreate path
- confirmed every query/scroll/delete operation includes a workspace filter
- confirmed the adapter never deletes or rewrites unrelated Qdrant points
- added keyword payload indexes for all filter-critical fields used here, including
document_idfor exact Evidence filtering
Concerns
- the requested
adversarial-reviewskill could not run its full external reviewer flow in this environment because the skill’s referencedbrain/files are missing at/Users/mp/.agents/skills/adversarial-review; I performed a manual adversarial self-review instead - the focused suite still emits one pre-existing warning from
testcontainers.postgres
Fix round 1 — 2026-08-08
Findings addressed
- IMPORTANT: metadata collisions could override canonical Qdrant payload identity fields and break workspace isolation
- IMPORTANT: scroll-based operations only read the first page and did not follow
next_page_offset, makingexisting_hashes,list_evidence_generations, and delete counts inexact beyond one page
RED evidence
Command:
cd harness
./.venv/bin/pytest tests/test_qdrant_vector_store.py tests/test_vector_port_contract.py -q
Observed before the fix:
- exit code
1 2 failed, 31 passed, 1 warning
Representative failures:
assert payload["workspace_id"] == "demo"failed because collidingrecord.metadataoverwrote canonical payload fields- paginated scroll test missed later pages, so
existing_hashesand generation cleanup counts were incomplete
GREEN evidence
Command:
cd harness
./.venv/bin/pytest tests/test_qdrant_vector_store.py tests/test_vector_port_contract.py -q
Observed after the fix:
- exit code
0 33 passed, 1 warning
Touched-file lint:
cd harness
./.venv/bin/ruff check tht/adapters/vector/qdrant.py tht/vectorstore/records.py \
tests/test_qdrant_vector_store.py tests/test_vector_port_contract.py
- exit code
0 All checks passed!
Patch hygiene:
git diff --check
- exit code
0
Minimal fix
- made
qdrant_payloadapply canonical fields afterrecord.metadataso workspace ID, semantic kind, original record kind, canonical record key, and content hash cannot be overridden by metadata collisions - paginated
_scrolluntilnext_page_offsetis absent, sent the returnedoffsetback on the next request, and reject repeated offsets as malformed to avoid infinite loops