david / evidence /test_retrieve.py
SNAPKITTYWEST's picture
October 2026 main drop: mirror from GitHub
f109bf8 verified
Raw History Blame Contribute Delete
5.75 kB
"""Tests for in-memory hybrid evidence retrieval."""
from __future__ import annotations
import unittest
from evidence.retrieve import (
COBOL_BALANCE_QUERY,
COBOL_BALANCE_QUERY_VEC,
EvidenceIndex,
empty_bundle,
lexical_score,
retrieve,
seed_cobol_corpus,
)
class RetrieveTests(unittest.TestCase):
def setUp(self):
self.index = EvidenceIndex(seed_cobol_corpus())
self.query = COBOL_BALANCE_QUERY
self.qvec = COBOL_BALANCE_QUERY_VEC
def test_cobol_balance_prefers_legacy_not_quant(self):
bundle = retrieve(
self.query,
query_embedding=self.qvec,
index=self.index,
min_authority=0.5,
require_parent_evidence=True,
top_k=5,
)
ids = [s["evidence_id"] for s in bundle["sources"]]
self.assertTrue(ids, "expected non-empty sources")
# Top hit must not be the quant pricing chunk
self.assertNotEqual(ids[0], "ev_quant_pricing_01")
# COBOL / copybook / schema evidence should appear
self.assertTrue(
any(
i in ids
for i in ("ev_copybook_01", "ev_cobol_src_01", "ev_db2_schema_01")
),
f"expected legacy evidence in {ids}",
)
# Quant must not be the top hit; preferably absent from top-3 when
# authority + dense favor legacy chunks
top3 = ids[:3]
self.assertNotIn("ev_quant_pricing_01", top3)
def test_provenance_authority_drops_junk(self):
# Without filter, junk may score on lexical overlap
open_bundle = retrieve(
self.query,
query_embedding=self.qvec,
index=self.index,
min_authority=0.0,
require_parent_evidence=False,
top_k=10,
)
open_ids = {s["evidence_id"] for s in open_bundle["sources"]}
self.assertIn("ev_junk_lowauth_01", open_ids)
filtered = retrieve(
self.query,
query_embedding=self.qvec,
index=self.index,
min_authority=0.5,
require_parent_evidence=True,
top_k=10,
)
filt_ids = {s["evidence_id"] for s in filtered["sources"]}
self.assertNotIn("ev_junk_lowauth_01", filt_ids)
# Every returned source has provenance fields
for src in filtered["sources"]:
self.assertIn("content_hash", src)
self.assertIn("source_authority", src)
self.assertIn("parent_evidence", src)
self.assertTrue(src["parent_evidence"])
def test_hybrid_lexical_can_lift_weak_dense(self):
"""Rule: score = dense + lexical + authority - penalties (no dense floor).
ev_lexical_lift_01 has weak cosine vs the COBOL query vector but strong
token overlap on cobol/payment/balance, so it can appear in results.
"""
# Dense-only ranking of lexical_lift should be poor
from evidence.retrieve import cosine_similarity
lift = self.index._by_id["ev_lexical_lift_01"]
dense_lift = cosine_similarity(self.qvec, lift.embedding)
dense_copy = cosine_similarity(
self.qvec, self.index._by_id["ev_copybook_01"].embedding
)
self.assertLess(dense_lift, dense_copy)
self.assertLess(dense_lift, 0.55) # weak dense
lex = lexical_score(self.query, lift.content)
self.assertGreaterEqual(lex, 0.5) # strong lexical
bundle = retrieve(
self.query,
query_embedding=self.qvec,
index=self.index,
min_authority=0.5,
require_parent_evidence=True,
top_k=10,
)
ids = [s["evidence_id"] for s in bundle["sources"]]
self.assertIn(
"ev_lexical_lift_01",
ids,
"lexical-strong / dense-weak chunk should appear under hybrid score",
)
# Confirm retrieval_metadata records both components
meta = {
m["evidence_id"]: m for m in bundle["retrieval_metadata"]
}
self.assertIn("ev_lexical_lift_01", meta)
self.assertGreaterEqual(meta["ev_lexical_lift_01"]["lexical"], 0.5)
self.assertLess(meta["ev_lexical_lift_01"]["dense"], 0.55)
def test_empty_query_returns_empty_bundle(self):
bundle = retrieve("", query_embedding=self.qvec, index=self.index)
self.assertEqual(bundle, empty_bundle())
self.assertEqual(bundle["sources"], [])
self.assertEqual(bundle["facts"], [])
def test_no_match_returns_empty_bundle(self):
# Metadata filter that matches nothing
bundle = retrieve(
self.query,
query_embedding=self.qvec,
index=self.index,
source_types=["nonexistent_type"],
top_k=5,
)
self.assertEqual(bundle["sources"], [])
self.assertEqual(bundle["facts"], [])
self.assertEqual(bundle["provenance"], [])
self.assertEqual(bundle["retrieval_metadata"], [])
def test_bundle_shape_has_provenance(self):
bundle = retrieve(
self.query,
query_embedding=self.qvec,
index=self.index,
min_authority=0.5,
top_k=3,
)
for key in ("facts", "sources", "provenance", "retrieval_metadata"):
self.assertIn(key, bundle)
self.assertEqual(len(bundle["sources"]), len(bundle["provenance"]))
# No bare text: each source carries provenance fields
for src in bundle["sources"]:
self.assertTrue(src.get("content_hash"))
self.assertIsNotNone(src.get("source_authority"))
if __name__ == "__main__":
unittest.main()