fix(evidence): bind corpus to workspace identity
This commit is contained in:
@@ -329,6 +329,66 @@ def test_pipeline_result_dump_does_not_deepcopy_frozen_metadata():
|
||||
assert payload["manifest"]["metadata"] == {"nested": {"value": ["safe"]}}
|
||||
|
||||
|
||||
def test_reused_corpus_root_rejects_workspace_rename_before_any_mutation(tmp_path):
|
||||
vectors = Vectors()
|
||||
first = pipeline(tmp_path, Source([(item("one", "a"), "stable")]), vectors=vectors)
|
||||
first.run_as_job(
|
||||
workspace_id="workspace-a", workspace_root=tmp_path,
|
||||
config_fingerprint="sha256:" + "1" * 64,
|
||||
input_fingerprint="sha256:" + "2" * 64,
|
||||
)
|
||||
active = first.store.active_generation()
|
||||
records = list(vectors.records)
|
||||
renamed_source = Source([(item("one", "a"), "stable")])
|
||||
renamed = pipeline(tmp_path, renamed_source, vectors=vectors)
|
||||
with pytest.raises(PipelineError, match="different workspace"):
|
||||
renamed.run_as_job(
|
||||
workspace_id="workspace-b", workspace_root=tmp_path,
|
||||
config_fingerprint="sha256:" + "1" * 64,
|
||||
input_fingerprint="sha256:" + "2" * 64,
|
||||
)
|
||||
assert renamed_source.acquire_calls == []
|
||||
assert renamed.store.active_generation() == active
|
||||
assert vectors.records == records
|
||||
|
||||
|
||||
def test_gc_rejects_workspace_mismatch_without_deleting(tmp_path):
|
||||
vectors = Vectors()
|
||||
owner = pipeline(tmp_path, Source([(item("one", "a"), "stable")]), vectors=vectors)
|
||||
owner.run_as_job(
|
||||
workspace_id="workspace-a", workspace_root=tmp_path,
|
||||
config_fingerprint="sha256:" + "1" * 64,
|
||||
input_fingerprint="sha256:" + "2" * 64,
|
||||
)
|
||||
generations = owner.store.list_generations()
|
||||
wrong = pipeline(tmp_path, Source([]), vectors=vectors)
|
||||
wrong.workspace_id = "workspace-b"
|
||||
with pytest.raises(PipelineError, match="different workspace"):
|
||||
wrong.gc(workspace_root=tmp_path)
|
||||
assert wrong.store.list_generations() == generations
|
||||
|
||||
|
||||
def test_active_search_rejects_workspace_mismatch_before_delegate(tmp_path):
|
||||
from tht.search.evidence import ActiveEvidenceSearcher, CorpusWorkspaceMismatchError
|
||||
|
||||
vectors = Vectors()
|
||||
owner = pipeline(tmp_path, Source([(item("one", "a"), "stable")]), vectors=vectors)
|
||||
owner.run_as_job(
|
||||
workspace_id="workspace-a", workspace_root=tmp_path,
|
||||
config_fingerprint="sha256:" + "1" * 64,
|
||||
input_fingerprint="sha256:" + "2" * 64,
|
||||
)
|
||||
|
||||
class Delegate:
|
||||
def search(self, *args, **kwargs):
|
||||
raise AssertionError("workspace mismatch reached vector delegate")
|
||||
|
||||
with pytest.raises(CorpusWorkspaceMismatchError, match="different workspace"):
|
||||
ActiveEvidenceSearcher(
|
||||
owner.store, Delegate(), expected_workspace_id="workspace-b",
|
||||
).search([1.0], kinds=["evidence"])
|
||||
|
||||
|
||||
def test_unchanged_documents_skip_acquire_normalize_chunk_and_embed(tmp_path):
|
||||
one = item("one", "a")
|
||||
first_source = Source([(one, "hello")])
|
||||
|
||||
Reference in New Issue
Block a user