import json import subprocess import sys from pathlib import Path import pytest from pino.embeddings import OlfactoryEmbeddingEngine, RealOpenPOMUnavailableError ROOT = Path(__file__).resolve().parents[1] def test_real_pom_requirement_fails_closed(): with pytest.raises(RealOpenPOMUnavailableError, match="not configured"): OlfactoryEmbeddingEngine(use_fallback=False) def test_freeze_protocol_blocks_when_artifacts_missing(tmp_path): """The gate must FAIL (rc=2, DO_NOT_TRAIN) when readiness artifacts are absent. Runs the real gate logic against an empty directory (via a copied script) so the check is hermetic and independent of the repo's current READY state. """ scripts_dir = tmp_path / "scripts" scripts_dir.mkdir() (tmp_path / "artifacts").mkdir() (tmp_path / "data").mkdir() # Copy the real gate script so it re-anchors ROOT at tmp_path (parents[1]). src = (ROOT / "scripts" / "freeze_representation_validation.py").read_text() (scripts_dir / "freeze_representation_validation.py").write_text(src) result = subprocess.run( [sys.executable, "scripts/freeze_representation_validation.py", "--timestamp", "2026-07-16T00:00:00+00:00"], cwd=tmp_path, text=True, capture_output=True, ) assert result.returncode == 2 gate = json.loads((tmp_path / "artifacts" / "training_readiness.json").read_text()) assert gate["ready_for_training"] is False assert gate["decision"] == "DO_NOT_TRAIN" assert gate["blockers"], "expected at least one failing readiness check on empty artifacts" def test_current_repo_gate_is_ready_with_all_checks(): """The live repo gate should be READY with all five checks passing. Guards against regressions that silently flip the gate back to DO_NOT_TRAIN. """ gate = json.loads((ROOT / "artifacts" / "training_readiness.json").read_text()) assert gate["ready_for_training"] is True assert gate["decision"] == "READY_FOR_TRAINING" assert all(gate["checks"].values()), f"failing checks: {[k for k, v in gate['checks'].items() if not v]}"