fix: close semantic isolation review gaps

This commit is contained in:
2026-08-08 23:53:37 +02:00
parent 2c4534d968
commit fa151c5ea5
5 changed files with 158 additions and 4 deletions
+80
View File
@@ -289,11 +289,30 @@ def test_search_filters_by_workspace_and_allowed_record_kinds():
assert query_call[2]["filter"] == {
"must": [
{"key": "workspace_id", "match": {"value": "demo"}},
{"key": "kind", "match": {"any": ["memory"]}},
{"key": "record_kind", "match": {"any": ["memory"]}},
]
}
def test_search_excludes_inconsistent_semantic_kind_in_bound_workspace():
fake = FakeQdrantHttp()
store = _store(fake)
store.upsert("memory", [_write_record("memory:1", "memory")])
contaminated = next(iter(fake.points.values())).copy()
contaminated["id"] = point_id("demo", "evidence", "memory:contaminated")
contaminated["payload"] = {
**contaminated["payload"],
"kind": "evidence",
"record_key": "memory:contaminated",
}
fake.points[contaminated["id"]] = contaminated
hits = store.search(["memory"], [0.2] * 1024, limit=5, kinds=["memory"])
assert [hit.id for hit in hits] == ["memory:1"]
def test_existing_hashes_health_and_exact_generation_inventory_and_delete():
fake = FakeQdrantHttp()
store = _store(fake)
@@ -328,6 +347,46 @@ def test_existing_hashes_health_and_exact_generation_inventory_and_delete():
assert health.dimension_compatible is True
def test_evidence_inventory_and_delete_ignore_inconsistent_semantic_kind():
fake = FakeQdrantHttp()
store = _store(fake)
generation = "gen:" + "1" * 32
contaminated_generation = "gen:" + "2" * 32
store.upsert("evidence", [
_write_record(
f"demo:{generation}:chunk:1",
"evidence",
metadata={
"workspace_id": "demo",
"vector_generation": generation,
"document_id": "doc:1",
},
),
])
contaminated_delete = next(iter(fake.points.values())).copy()
contaminated_delete["id"] = point_id("demo", "memory", "evidence:contaminated-delete")
contaminated_delete["payload"] = {
**contaminated_delete["payload"],
"kind": "memory",
"record_key": "evidence:contaminated-delete",
}
fake.points[contaminated_delete["id"]] = contaminated_delete
contaminated_list = next(iter(fake.points.values())).copy()
contaminated_list["id"] = point_id("demo", "memory", "evidence:contaminated-list")
contaminated_list["payload"] = {
**contaminated_list["payload"],
"kind": "memory",
"record_key": "evidence:contaminated-list",
"vector_generation": contaminated_generation,
}
fake.points[contaminated_list["id"]] = contaminated_list
assert store.list_evidence_generations("evidence", "demo") == [generation]
assert store.delete_generation("evidence", generation, "demo") == 1
assert contaminated_delete["id"] in fake.points
assert contaminated_list["id"] in fake.points
def test_metadata_search_rejects_a_workspace_id_different_from_the_bound_adapter():
fake = FakeQdrantHttp()
store = _store(fake)
@@ -444,6 +503,7 @@ def test_delete_kinds_is_workspace_scoped_and_preserves_other_semantic_kinds():
assert delete_call[2]["filter"] == {
"must": [
{"key": "workspace_id", "match": {"value": "demo"}},
{"key": "kind", "match": {"any": ["memory"]}},
{"key": "record_kind", "match": {"any": ["memory"]}},
]
}
@@ -457,6 +517,26 @@ def test_delete_kinds_is_workspace_scoped_and_preserves_other_semantic_kinds():
}
def test_existing_hashes_and_delete_kinds_ignore_inconsistent_semantic_kind():
fake = FakeQdrantHttp()
store = _store(fake)
store.upsert("memory", [_write_record("memory:1", "memory")])
contaminated = next(iter(fake.points.values())).copy()
contaminated["id"] = point_id("demo", "evidence", "memory:contaminated")
contaminated["payload"] = {
**contaminated["payload"],
"kind": "evidence",
"record_key": "memory:contaminated",
}
fake.points[contaminated["id"]] = contaminated
assert store.existing_hashes("memory", ["memory"]) == {
"memory:1": "sha256:" + "a" * 64,
}
assert store.delete_kinds("memory", ["memory"]) == 1
assert contaminated["id"] in fake.points
def test_sanitizes_timeout_and_malformed_responses():
fake = FakeQdrantHttp()
store = _store(fake)