feat(perception): publish immutable lab session instances
This commit is contained in:
@@ -777,6 +777,78 @@ def test_delete_session_removes_only_the_exact_evidence_tree_and_catalog_row(
|
||||
assert store.get_session(retained.name).summary.session_id == retained.name
|
||||
|
||||
|
||||
def test_lab_instance_is_independent_and_never_deletes_source_evidence(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
repository = tmp_path / "repo"
|
||||
sessions = repository / "sessions"
|
||||
source = make_legacy_session(sessions, "20260716T205632Z_viewer_live")
|
||||
store = SessionStore(repository, data_dir=tmp_path / "data")
|
||||
archive = xgrids_k1_archive_source(sessions)
|
||||
store.reconcile_archive(archive)
|
||||
source_command = store.prepare_replay(source.name)
|
||||
|
||||
binding = store.publish_lab_instance(
|
||||
session_id="lab-e21-d0201712",
|
||||
source_session_id=source.name,
|
||||
display_name="LAB E21 · RT 1× · d0201712",
|
||||
lab_id="LAB E21",
|
||||
result_kind="e10-integrated-perception",
|
||||
result_id="e10-integrated-perception-" + "a" * 64,
|
||||
source_result_id="e21-realtime-envelope-" + "b" * 64,
|
||||
config_sha256="c" * 64,
|
||||
run_created_at_utc="2026-07-23T15:51:25.000Z",
|
||||
provenance={"storage_mode": "hard-linked-immutable-payloads"},
|
||||
)
|
||||
|
||||
detail = store.get_session(binding.session_id)
|
||||
lab_command = store.prepare_replay(binding.session_id)
|
||||
assert detail.summary.lab == binding
|
||||
assert detail.summary.display_name == "LAB E21 · RT 1× · d0201712"
|
||||
assert lab_command.primary_artifact.path == source_command.primary_artifact.path
|
||||
assert lab_command.session_id == binding.session_id
|
||||
assert source.is_dir()
|
||||
|
||||
with pytest.raises(SessionIntegrityError, match="has LAB instances"):
|
||||
store.delete_session(source.name)
|
||||
assert source.is_dir()
|
||||
|
||||
store.delete_session(binding.session_id)
|
||||
assert source.is_dir()
|
||||
assert store.get_session(source.name).summary.lab is None
|
||||
with pytest.raises(SessionNotFoundError):
|
||||
store.get_session(binding.session_id)
|
||||
|
||||
|
||||
def test_lab_instance_publication_is_idempotent_but_provenance_is_immutable(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
repository = tmp_path / "repo"
|
||||
sessions = repository / "sessions"
|
||||
source = make_legacy_session(sessions, "20260716T205632Z_viewer_live")
|
||||
store = SessionStore(repository, data_dir=tmp_path / "data")
|
||||
store.reconcile_archive(xgrids_k1_archive_source(sessions))
|
||||
parameters = {
|
||||
"session_id": "lab-e19-36964643",
|
||||
"source_session_id": source.name,
|
||||
"display_name": "LAB E19 · Ground-aware 3D",
|
||||
"lab_id": "LAB E19",
|
||||
"result_kind": "e10-integrated-perception",
|
||||
"result_id": "e10-integrated-perception-" + "d" * 64,
|
||||
"source_result_id": "e10-integrated-perception-" + "e" * 64,
|
||||
"config_sha256": "f" * 64,
|
||||
"run_created_at_utc": "2026-07-23T05:19:43.138Z",
|
||||
"provenance": {"source": "accepted"},
|
||||
}
|
||||
|
||||
first = store.publish_lab_instance(**parameters)
|
||||
second = store.publish_lab_instance(**parameters)
|
||||
assert second == first
|
||||
|
||||
with pytest.raises(SessionIntegrityError, match="different provenance"):
|
||||
store.publish_lab_instance(**{**parameters, "config_sha256": "0" * 64})
|
||||
|
||||
|
||||
def test_delete_session_rejects_a_catalog_target_outside_its_allowed_root(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
|
||||
Reference in New Issue
Block a user