from __future__ import annotations import importlib.util import json from pathlib import Path import sys ROOT = Path(__file__).resolve().parents[2] def load_split_report_builder(): script_path = ROOT / "scripts" / "build_background_corpus_split_report.py" assert script_path.exists() spec = importlib.util.spec_from_file_location("background_split_report_builder", script_path) assert spec is not None assert spec.loader is not None module = importlib.util.module_from_spec(spec) sys.modules[spec.name] = module spec.loader.exec_module(module) return module def write_summary(path: Path, *, category: str, detections: list[int]) -> None: items = [ { "sample_slug": f"{category}_{index}", "background_category": category, "model_asset_id": "candidate-model", "tile_size": 512, "tile_overlap": 64, "threshold": 0.35, "tile_count": 4, "detection_count": detection_count, "false_positive_pressure": detection_count / 4, } for index, detection_count in enumerate(detections, start=1) ] path.write_text( json.dumps( { "generated_at": "2026-07-10T00:00:00+00:00", "sample_count": len(items), "run_count": len(items), "background_category_counts": {category: len(items)}, "best_by_lowest_pressure": min(items, key=lambda item: item["false_positive_pressure"]), "items": items, } ), encoding="utf-8", ) def test_split_report_builder_creates_strict_gate_and_context_review(tmp_path: Path) -> None: module = load_split_report_builder() pure_summary = tmp_path / "pure_empty.json" sparse_summary = tmp_path / "sparse_context.json" output_dir = tmp_path / "split-report" write_summary(pure_summary, category="pure_empty_negative", detections=[0, 2]) write_summary(sparse_summary, category="sparse_building_context", detections=[1, 5]) report = module.build_split_report( pure_empty_summary_path=pure_summary, sparse_context_summary_path=sparse_summary, output_dir=output_dir, ) assert report["strict_default_gate"]["category"] == "pure_empty_negative" assert report["strict_default_gate"]["passes_zero_detection_gate"] is False assert report["strict_default_gate"]["max_detection_count"] == 2 assert report["context_review"]["category"] == "sparse_building_context" assert report["context_review"]["review_only"] is True assert report["context_review"]["max_detection_count"] == 5 assert report["recommended_next_step"] == "retrain_or_recalibrate_after_review" assert (output_dir / "background_corpus_split_summary.json").exists() markdown = (output_dir / "background_corpus_split_summary.md").read_text(encoding="utf-8") assert "Strict default gate" in markdown assert "Sparse-context review" in markdown def test_split_report_builder_rejects_wrong_summary_category(tmp_path: Path) -> None: module = load_split_report_builder() wrong_summary = tmp_path / "wrong.json" sparse_summary = tmp_path / "sparse.json" write_summary(wrong_summary, category="sparse_building_context", detections=[0]) write_summary(sparse_summary, category="sparse_building_context", detections=[0]) try: module.build_split_report( pure_empty_summary_path=wrong_summary, sparse_context_summary_path=sparse_summary, output_dir=tmp_path / "out", ) except SystemExit as exc: assert "pure_empty_negative" in str(exc) else: # pragma: no cover - defensive assertion for the contract. raise AssertionError("wrong category summary should fail") def test_split_matrix_runner_invokes_both_background_categories() -> None: runner = ROOT / "scripts" / "run_background_corpus_split_matrix.sh" assert runner.exists() source = runner.read_text(encoding="utf-8") assert "run_operator_hard_negative_detection_matrix.sh" in source assert "OPERATOR_BACKGROUND_CATEGORIES=\"pure_empty_negative\"" in source assert "OPERATOR_BACKGROUND_CATEGORIES=\"sparse_building_context\"" in source assert "build_background_corpus_split_report.py" in source assert "background_corpus_split_summary.json" in source assert "/qa/reference" not in source assert "fixture_mode" not in source def test_readiness_covers_split_matrix_runner() -> None: readiness = (ROOT / "scripts" / "run_readiness_check.sh").read_text(encoding="utf-8") assert "py_compile scripts/build_background_corpus_split_report.py" in readiness assert "bash -n scripts/run_background_corpus_split_matrix.sh" in readiness