Record unique hard-negative YOLO candidate gate
GeoIntel CI / docs-smoke (push) Has been cancelled
GeoIntel CI / contract-smoke (push) Has been cancelled

This commit is contained in:
Codex
2026-07-09 03:54:48 +02:00
parent afd2cba7c8
commit 4e9fe6ccb1
6 changed files with 202 additions and 7 deletions
@@ -167,3 +167,88 @@ def test_detection_model_promotion_report_combines_positive_and_background_gates
assert "candidate-clean" in markdown
assert "candidate-leaky" in markdown
assert "background_false_positive_pressure" in markdown
def test_detection_model_promotion_report_uses_portfolio_and_tile_defaults(
tmp_path: Path,
) -> None:
script_path = ROOT / "scripts" / "build_detection_model_promotion_report.py"
positive_path = tmp_path / "positive_portfolio.json"
positive_path.write_text(
json.dumps(
{
"portfolio_name": "Positive AOI portfolio",
"model_asset_id": "candidate-from-portfolio",
"samples": [
{
"sample_slug": "geel",
"runs": [
{
"model_asset_id": None,
"tile_size": None,
"tile_overlap": None,
"threshold": 0.25,
"precision": 0.7,
"recall": 0.42,
"f1_score": 0.525,
}
],
}
],
}
),
encoding="utf-8",
)
background_path = tmp_path / "hard_negative_matrix_summary.json"
background_path.write_text(
json.dumps(
{
"items": [
{
"sample_slug": "postel_bos",
"model_asset_id": "candidate-from-portfolio",
"tile_size": 640,
"tile_overlap": 64,
"threshold": 0.25,
"detection_count": 0,
}
]
}
),
encoding="utf-8",
)
output_dir = tmp_path / "promotion-report"
subprocess.run(
[
"python",
str(script_path),
"--positive-portfolio",
str(positive_path),
"--hard-negative-summary",
str(background_path),
"--output-dir",
str(output_dir),
"--min-positive-samples",
"1",
"--min-background-samples",
"1",
"--min-mean-f1",
"0.35",
"--max-background-detections-per-sample",
"0",
"--default-positive-tile-size",
"640",
"--default-positive-tile-overlap",
"64",
],
cwd=ROOT,
check=True,
text=True,
capture_output=True,
)
report = json.loads((output_dir / "detection_model_promotion_report.json").read_text(encoding="utf-8"))
assert report["recommended_candidate"]["candidate_key"] == "candidate-from-portfolio|640|64|0.25"