feat(evidence): evaluate retrieval with a small fixture

This commit is contained in:
2026-08-25 01:44:12 +02:00
parent dcb5acc312
commit 619ac2e141
15 changed files with 782 additions and 6 deletions
+51 -1
View File
@@ -106,7 +106,7 @@ def item(name, fingerprint):
def pipeline(tmp_path, source, *, embedder=None, vectors=None, model="model-a", policy=None,
retain=3):
retain=3, candidate_evaluator=None):
return CorpusPipeline(
store=CorpusStore(tmp_path / "corpus"), sources=[source],
embedder=embedder or Embedder(), vector_store=vectors or Vectors(),
@@ -114,6 +114,7 @@ def pipeline(tmp_path, source, *, embedder=None, vectors=None, model="model-a",
chunk_policy=policy or ChunkPolicy(version="chunk-v1", max_chars=100),
pipeline_version="evidence-v1",
retain_published_generations=retain,
candidate_evaluator=candidate_evaluator,
)
@@ -853,6 +854,55 @@ def test_dimension_mismatch_fails_before_vector_write_and_publish(tmp_path):
assert candidate.store.active_generation() is None
def test_failed_candidate_evaluation_never_switches_the_active_generation(tmp_path):
from types import SimpleNamespace
vectors = Vectors()
active = pipeline(tmp_path, Source([(item("one", "a"), "old")]), vectors=vectors).run().generation
candidate = pipeline(
tmp_path,
Source([(item("one", "b"), "new")]),
vectors=vectors,
candidate_evaluator=lambda manifest: SimpleNamespace(passed=False),
)
with pytest.raises(PipelineError, match="candidate retrieval evaluation failed"):
candidate.run()
assert candidate.store.active_generation() == active
assert {record.record.metadata["vector_generation"] for record in vectors.records} == {active}
def test_job_failed_candidate_evaluation_never_switches_the_active_generation(tmp_path):
from types import SimpleNamespace
vectors = Vectors()
active = pipeline(tmp_path, Source([(item("one", "a"), "old")]), vectors=vectors).run_as_job(
workspace_id="demo",
workspace_root=tmp_path,
config_fingerprint="sha256:" + "1" * 64,
input_fingerprint="sha256:" + "2" * 64,
).generation
candidate = pipeline(
tmp_path,
Source([(item("one", "b"), "new")]),
vectors=vectors,
candidate_evaluator=lambda manifest: SimpleNamespace(passed=False),
)
result = candidate.run_as_job(
workspace_id="demo",
workspace_root=tmp_path,
config_fingerprint="sha256:" + "1" * 64,
input_fingerprint="sha256:" + "3" * 64,
)
assert result.status == "failed"
assert result.published is False
assert candidate.store.active_generation() == active
assert {record.record.metadata["vector_generation"] for record in vectors.records} == {active}
def test_pipeline_marks_each_evidence_fragment_for_server_side_italian_bm25(tmp_path):
vectors = Vectors()