from __future__ import annotations import json import pytest from gap_pipeline.models import KernelCandidate from gap_pipeline.release import export_release from gap_pipeline.store import RunStore, sha256_payload from gap_pipeline.surface import SURFACE_FAMILIES def test_offline_release_export_verifies_and_assembles( tmp_path, item, candidate_dict, ) -> None: source_dir = tmp_path / "source" source_dir.mkdir() source_record = { "index": item.item_id, "question": item.problem, "solution": item.solution, "vars": item.variables, "params": [], "sci_consts": [], "problem_type": "proof", "variants": {}, } (source_dir / f"{item.item_id}.json").write_text( json.dumps(source_record), encoding="utf-8", ) surface_root = tmp_path / "surface-runs" surface_store = RunStore(surface_root, item.item_id) for family in SURFACE_FAMILIES: surface_store.write_stage( f"surface_{family}_variant", { "map": {"a": f"name{family.replace('_', '')}"}, "question": f"{family} question", "solution": f"{family} solution", }, request_id=None, ) kernel_root = tmp_path / "kernel-runs" kernel_store = RunStore(kernel_root, item.item_id) candidate = KernelCandidate.model_validate(candidate_dict) kernel_store.write_final( { "item_id": item.item_id, "status": "accepted", "accepted_candidate": candidate.model_dump(mode="json"), "accepted_candidate_sha256": sha256_payload(candidate), } ) output_root = tmp_path / "release" manifest = export_release( source_dataset=source_dir, surface_run_root=surface_root, kernel_run_root=kernel_root, output_root=output_root, ) assert manifest["status"] == "complete" assert manifest["exported_item_count"] == 1 output = json.loads( (output_root / "records" / f"{item.item_id}.json").read_text() ) assert set(output["variants"]) == {*SURFACE_FAMILIES, "kernel_variant"} assert output["variants"]["kernel_variant"]["question"] == candidate.problem with pytest.raises(FileExistsError): export_release( source_dataset=source_dir, surface_run_root=surface_root, kernel_run_root=kernel_root, output_root=output_root, )