diff --git a/src/openamp_foundry/evidence/scientific_review_readiness_gate.py b/src/openamp_foundry/evidence/scientific_review_readiness_gate.py new file mode 100644 index 00000000..421c8263 --- /dev/null +++ b/src/openamp_foundry/evidence/scientific_review_readiness_gate.py @@ -0,0 +1,220 @@ +from __future__ import annotations +from dataclasses import dataclass, field +from typing import List, Optional + + +REQUIRED_SRG_ARTIFACT_TYPES = frozenset({ + "CFC", # candidate family clustering + "FNR", # family novelty report + "ATR", # audit trail report + "PQG", # Phase Q completeness gate +}) + +VALID_READINESS_VERDICTS = frozenset({ + "ready_for_external_review", # all gates passed; safe for external scientific review + "not_ready", # one or more gates failed + "conditionally_ready", # minor issues noted; external reviewer must be informed + "review_blocked_by_safety", # safety flag unresolved; must not proceed +}) + +VALID_SAFETY_FLAG_TYPES = frozenset({ + "unresolved_hemolysis", + "unresolved_toxicity", + "dual_use_concern", + "off_target_risk", + "contamination_suspected", + "no_flags", +}) + +VALID_REVIEW_SCOPE_TYPES = frozenset({ + "internal_only", + "trusted_partner", + "open_preprint", + "peer_review_submission", +}) + + +@dataclass +class ScientificReviewReadinessGate: + srg_id: str + candidate_family_id: str + cfc_id: str + fnr_id: str + atr_id: str + pqg_id: str + readiness_verdict: str + safety_flags: List[str] + failed_gates: List[str] + review_scope: str + n_confirmed_hits: int + n_total_candidates: int + dry_lab_only: bool + limitations: str + notes: str = "" + + +@dataclass +class SRGValidationResult: + passed: bool + violations: List[str] = field(default_factory=list) + + +def validate_scientific_review_readiness_gate(gate: ScientificReviewReadinessGate) -> SRGValidationResult: + violations = [] + + if not gate.srg_id.startswith("SRG-"): + violations.append("srg_id must start with 'SRG-'") + + if not gate.candidate_family_id: + violations.append("candidate_family_id is required") + + if gate.candidate_family_id.startswith("TOY-"): + violations.append("TOY- candidate_family_id is not allowed in real SRG- records") + + if not gate.cfc_id.startswith("CFC-"): + violations.append("cfc_id must start with 'CFC-'") + + if not gate.fnr_id.startswith("FNR-"): + violations.append("fnr_id must start with 'FNR-'") + + if not gate.atr_id.startswith("ATR-"): + violations.append("atr_id must start with 'ATR-'") + + if not gate.pqg_id.startswith("PQG-"): + violations.append("pqg_id must start with 'PQG-'") + + if gate.readiness_verdict not in VALID_READINESS_VERDICTS: + violations.append( + f"readiness_verdict '{gate.readiness_verdict}' must be one of {sorted(VALID_READINESS_VERDICTS)}" + ) + + for sf in gate.safety_flags: + if sf not in VALID_SAFETY_FLAG_TYPES: + violations.append( + f"safety_flag '{sf}' must be one of {sorted(VALID_SAFETY_FLAG_TYPES)}" + ) + + if gate.review_scope not in VALID_REVIEW_SCOPE_TYPES: + violations.append( + f"review_scope '{gate.review_scope}' must be one of {sorted(VALID_REVIEW_SCOPE_TYPES)}" + ) + + if gate.n_confirmed_hits < 0: + violations.append("n_confirmed_hits must be >= 0") + + if gate.n_total_candidates < 1: + violations.append("n_total_candidates must be >= 1") + + if gate.n_confirmed_hits > gate.n_total_candidates: + violations.append( + f"n_confirmed_hits ({gate.n_confirmed_hits}) cannot exceed n_total_candidates ({gate.n_total_candidates})" + ) + + # review_blocked_by_safety requires a real safety flag + if gate.readiness_verdict == "review_blocked_by_safety": + blocking_flags = VALID_SAFETY_FLAG_TYPES - {"no_flags"} + if not any(sf in blocking_flags for sf in gate.safety_flags): + violations.append( + "readiness_verdict='review_blocked_by_safety' requires at least one real safety flag " + "(not 'no_flags')" + ) + + # ready_for_external_review must not have unresolved safety flags + if gate.readiness_verdict == "ready_for_external_review": + blocking_flags = VALID_SAFETY_FLAG_TYPES - {"no_flags"} + if any(sf in blocking_flags for sf in gate.safety_flags): + violations.append( + "readiness_verdict='ready_for_external_review' cannot have unresolved safety flags" + ) + if gate.failed_gates: + violations.append( + "readiness_verdict='ready_for_external_review' requires empty failed_gates" + ) + if gate.n_confirmed_hits < 1: + violations.append( + "readiness_verdict='ready_for_external_review' requires n_confirmed_hits >= 1" + ) + + # no_flags and real flags cannot coexist + if "no_flags" in gate.safety_flags and len(gate.safety_flags) > 1: + violations.append("safety_flag 'no_flags' cannot coexist with other flags") + + # open_preprint requires ready_for_external_review or conditionally_ready + if gate.review_scope in ("open_preprint", "peer_review_submission"): + if gate.readiness_verdict == "review_blocked_by_safety": + violations.append( + f"review_scope='{gate.review_scope}' is not allowed with readiness_verdict='review_blocked_by_safety'" + ) + if gate.readiness_verdict == "not_ready": + violations.append( + f"review_scope='{gate.review_scope}' is not allowed with readiness_verdict='not_ready'" + ) + + if not gate.dry_lab_only: + violations.append( + "dry_lab_only must be True for SRG- records (readiness gate is a documentation artifact)" + ) + + if not gate.limitations or len(gate.limitations.strip()) < 10: + violations.append("limitations must be a non-empty string (at least 10 characters)") + + return SRGValidationResult(passed=len(violations) == 0, violations=violations) + + +def build_scientific_review_readiness_gate( + srg_id: str, + candidate_family_id: str, + cfc_id: str, + fnr_id: str, + atr_id: str, + pqg_id: str, + readiness_verdict: str, + safety_flags: List[str], + failed_gates: List[str], + review_scope: str, + n_confirmed_hits: int, + n_total_candidates: int, + limitations: str, + notes: str = "", +) -> ScientificReviewReadinessGate: + gate = ScientificReviewReadinessGate( + srg_id=srg_id, + candidate_family_id=candidate_family_id, + cfc_id=cfc_id, + fnr_id=fnr_id, + atr_id=atr_id, + pqg_id=pqg_id, + readiness_verdict=readiness_verdict, + safety_flags=safety_flags, + failed_gates=failed_gates, + review_scope=review_scope, + n_confirmed_hits=n_confirmed_hits, + n_total_candidates=n_total_candidates, + dry_lab_only=True, + limitations=limitations, + notes=notes, + ) + result = validate_scientific_review_readiness_gate(gate) + if not result.passed: + raise ValueError(f"Invalid SRG: {result.violations}") + return gate + + +def format_scientific_review_readiness_gate(gate: ScientificReviewReadinessGate) -> str: + lines = [ + f"Scientific Review Readiness Gate — {gate.srg_id}", + f"Candidate Family: {gate.candidate_family_id}", + f"Readiness Verdict: {gate.readiness_verdict}", + f"Review Scope: {gate.review_scope}", + f"Confirmed Hits: {gate.n_confirmed_hits}/{gate.n_total_candidates}", + f"CFC: {gate.cfc_id} | FNR: {gate.fnr_id}", + f"ATR: {gate.atr_id} | PQG: {gate.pqg_id}", + f"Safety Flags: {', '.join(gate.safety_flags) if gate.safety_flags else 'none'}", + ] + if gate.failed_gates: + lines.append(f"Failed Gates: {', '.join(gate.failed_gates)}") + lines.append(f"Limitations: {gate.limitations}") + if gate.notes: + lines.append(f"Notes: {gate.notes}") + lines.append("dry_lab_only: True (readiness gate is a documentation artifact)") + return "\n".join(lines) diff --git a/tests/evidence/test_scientific_review_readiness_gate.py b/tests/evidence/test_scientific_review_readiness_gate.py new file mode 100644 index 00000000..58601e0f --- /dev/null +++ b/tests/evidence/test_scientific_review_readiness_gate.py @@ -0,0 +1,483 @@ +import pytest +from src.openamp_foundry.evidence.scientific_review_readiness_gate import ( + REQUIRED_SRG_ARTIFACT_TYPES, + VALID_READINESS_VERDICTS, + VALID_SAFETY_FLAG_TYPES, + VALID_REVIEW_SCOPE_TYPES, + ScientificReviewReadinessGate, + SRGValidationResult, + validate_scientific_review_readiness_gate, + build_scientific_review_readiness_gate, + format_scientific_review_readiness_gate, +) + + +def _valid_gate(**kwargs): + defaults = dict( + srg_id="SRG-0001", + candidate_family_id="AMPF-FAM-001", + cfc_id="CFC-0001", + fnr_id="FNR-0001", + atr_id="ATR-0001", + pqg_id="PQG-0001", + readiness_verdict="ready_for_external_review", + safety_flags=["no_flags"], + failed_gates=[], + review_scope="trusted_partner", + n_confirmed_hits=2, + n_total_candidates=10, + dry_lab_only=True, + limitations="Single candidate family; multi-family review not performed.", + notes="", + ) + defaults.update(kwargs) + return ScientificReviewReadinessGate(**defaults) + + +# ── Constants ────────────────────────────────────────────────────────────────── + +class TestConstants: + def test_required_artifact_types_is_frozenset(self): + assert isinstance(REQUIRED_SRG_ARTIFACT_TYPES, frozenset) + + def test_required_artifact_types_count(self): + assert len(REQUIRED_SRG_ARTIFACT_TYPES) == 4 + + def test_cfc_in_required_types(self): + assert "CFC" in REQUIRED_SRG_ARTIFACT_TYPES + + def test_fnr_in_required_types(self): + assert "FNR" in REQUIRED_SRG_ARTIFACT_TYPES + + def test_atr_in_required_types(self): + assert "ATR" in REQUIRED_SRG_ARTIFACT_TYPES + + def test_pqg_in_required_types(self): + assert "PQG" in REQUIRED_SRG_ARTIFACT_TYPES + + def test_readiness_verdicts_is_frozenset(self): + assert isinstance(VALID_READINESS_VERDICTS, frozenset) + + def test_readiness_verdicts_count(self): + assert len(VALID_READINESS_VERDICTS) == 4 + + def test_ready_for_external_review_in_verdicts(self): + assert "ready_for_external_review" in VALID_READINESS_VERDICTS + + def test_review_blocked_by_safety_in_verdicts(self): + assert "review_blocked_by_safety" in VALID_READINESS_VERDICTS + + def test_safety_flag_types_is_frozenset(self): + assert isinstance(VALID_SAFETY_FLAG_TYPES, frozenset) + + def test_no_flags_in_safety_types(self): + assert "no_flags" in VALID_SAFETY_FLAG_TYPES + + def test_dual_use_concern_in_safety_types(self): + assert "dual_use_concern" in VALID_SAFETY_FLAG_TYPES + + def test_review_scope_types_is_frozenset(self): + assert isinstance(VALID_REVIEW_SCOPE_TYPES, frozenset) + + def test_open_preprint_in_scope_types(self): + assert "open_preprint" in VALID_REVIEW_SCOPE_TYPES + + +# ── Dataclass ────────────────────────────────────────────────────────────────── + +class TestScientificReviewReadinessGateDataclass: + def test_instantiation(self): + g = _valid_gate() + assert g.srg_id == "SRG-0001" + + def test_dry_lab_only_true(self): + g = _valid_gate() + assert g.dry_lab_only is True + + def test_safety_flags_list(self): + g = _valid_gate() + assert "no_flags" in g.safety_flags + + def test_failed_gates_empty(self): + g = _valid_gate() + assert g.failed_gates == [] + + def test_notes_default_empty(self): + g = _valid_gate(notes="") + assert g.notes == "" + + +# ── Validation ───────────────────────────────────────────────────────────────── + +class TestValidateScientificReviewReadinessGate: + def test_valid_gate_passes(self): + g = _valid_gate() + result = validate_scientific_review_readiness_gate(g) + assert result.passed + + def test_invalid_srg_id_prefix(self): + g = _valid_gate(srg_id="BAD-0001") + result = validate_scientific_review_readiness_gate(g) + assert not result.passed + assert any("srg_id" in v for v in result.violations) + + def test_empty_candidate_family_id_blocked(self): + g = _valid_gate(candidate_family_id="") + result = validate_scientific_review_readiness_gate(g) + assert not result.passed + + def test_toy_candidate_family_id_blocked(self): + g = _valid_gate(candidate_family_id="TOY-FAM-001") + result = validate_scientific_review_readiness_gate(g) + assert not result.passed + assert any("TOY-" in v for v in result.violations) + + def test_invalid_cfc_id_prefix(self): + g = _valid_gate(cfc_id="BAD-0001") + result = validate_scientific_review_readiness_gate(g) + assert not result.passed + + def test_invalid_fnr_id_prefix(self): + g = _valid_gate(fnr_id="BAD-0001") + result = validate_scientific_review_readiness_gate(g) + assert not result.passed + + def test_invalid_atr_id_prefix(self): + g = _valid_gate(atr_id="BAD-0001") + result = validate_scientific_review_readiness_gate(g) + assert not result.passed + + def test_invalid_pqg_id_prefix(self): + g = _valid_gate(pqg_id="BAD-0001") + result = validate_scientific_review_readiness_gate(g) + assert not result.passed + + def test_invalid_readiness_verdict_blocked(self): + g = _valid_gate(readiness_verdict="probably_ready") + result = validate_scientific_review_readiness_gate(g) + assert not result.passed + + def test_invalid_safety_flag_blocked(self): + g = _valid_gate(safety_flags=["unknown_flag"]) + result = validate_scientific_review_readiness_gate(g) + assert not result.passed + + def test_invalid_review_scope_blocked(self): + g = _valid_gate(review_scope="social_media") + result = validate_scientific_review_readiness_gate(g) + assert not result.passed + + def test_n_confirmed_hits_negative_blocked(self): + g = _valid_gate(n_confirmed_hits=-1) + result = validate_scientific_review_readiness_gate(g) + assert not result.passed + + def test_n_total_candidates_zero_blocked(self): + g = _valid_gate(n_total_candidates=0) + result = validate_scientific_review_readiness_gate(g) + assert not result.passed + + def test_n_confirmed_hits_exceeds_total_blocked(self): + g = _valid_gate(n_confirmed_hits=11, n_total_candidates=10) + result = validate_scientific_review_readiness_gate(g) + assert not result.passed + + def test_review_blocked_requires_real_safety_flag(self): + g = _valid_gate(readiness_verdict="review_blocked_by_safety", safety_flags=["no_flags"]) + result = validate_scientific_review_readiness_gate(g) + assert not result.passed + assert any("real safety flag" in v for v in result.violations) + + def test_ready_for_review_blocks_safety_flags(self): + g = _valid_gate(readiness_verdict="ready_for_external_review", safety_flags=["dual_use_concern"]) + result = validate_scientific_review_readiness_gate(g) + assert not result.passed + assert any("safety flags" in v for v in result.violations) + + def test_ready_for_review_blocks_failed_gates(self): + g = _valid_gate(readiness_verdict="ready_for_external_review", failed_gates=["ATR incomplete"]) + result = validate_scientific_review_readiness_gate(g) + assert not result.passed + + def test_ready_for_review_requires_n_confirmed_hits_ge_1(self): + g = _valid_gate(readiness_verdict="ready_for_external_review", n_confirmed_hits=0) + result = validate_scientific_review_readiness_gate(g) + assert not result.passed + assert any("n_confirmed_hits" in v for v in result.violations) + + def test_no_flags_cannot_coexist_with_other_flags(self): + g = _valid_gate(safety_flags=["no_flags", "dual_use_concern"]) + result = validate_scientific_review_readiness_gate(g) + assert not result.passed + assert any("no_flags" in v for v in result.violations) + + def test_open_preprint_blocked_with_review_blocked(self): + g = _valid_gate( + readiness_verdict="review_blocked_by_safety", + safety_flags=["dual_use_concern"], + review_scope="open_preprint", + ) + result = validate_scientific_review_readiness_gate(g) + assert not result.passed + + def test_peer_review_blocked_with_not_ready(self): + g = _valid_gate( + readiness_verdict="not_ready", + safety_flags=["no_flags"], + failed_gates=["FNR incomplete"], + review_scope="peer_review_submission", + ) + result = validate_scientific_review_readiness_gate(g) + assert not result.passed + + def test_dry_lab_only_false_blocked(self): + g = _valid_gate(dry_lab_only=False) + result = validate_scientific_review_readiness_gate(g) + assert not result.passed + + def test_empty_limitations_blocked(self): + g = _valid_gate(limitations="") + result = validate_scientific_review_readiness_gate(g) + assert not result.passed + + def test_not_ready_verdict_valid(self): + g = _valid_gate( + readiness_verdict="not_ready", + safety_flags=["no_flags"], + failed_gates=["ATR grade D"], + review_scope="internal_only", + ) + result = validate_scientific_review_readiness_gate(g) + assert result.passed + + def test_conditionally_ready_verdict_valid(self): + g = _valid_gate( + readiness_verdict="conditionally_ready", + safety_flags=["no_flags"], + review_scope="trusted_partner", + ) + result = validate_scientific_review_readiness_gate(g) + assert result.passed + + def test_review_blocked_with_real_flag_valid(self): + g = _valid_gate( + readiness_verdict="review_blocked_by_safety", + safety_flags=["unresolved_hemolysis"], + review_scope="internal_only", + ) + result = validate_scientific_review_readiness_gate(g) + assert result.passed + + def test_open_preprint_with_ready_valid(self): + g = _valid_gate( + readiness_verdict="ready_for_external_review", + safety_flags=["no_flags"], + review_scope="open_preprint", + n_confirmed_hits=3, + ) + result = validate_scientific_review_readiness_gate(g) + assert result.passed + + def test_peer_review_with_conditionally_ready_valid(self): + g = _valid_gate( + readiness_verdict="conditionally_ready", + safety_flags=["no_flags"], + review_scope="peer_review_submission", + ) + result = validate_scientific_review_readiness_gate(g) + assert result.passed + + +# ── Build ────────────────────────────────────────────────────────────────────── + +class TestBuildScientificReviewReadinessGate: + def test_build_valid(self): + g = build_scientific_review_readiness_gate( + srg_id="SRG-0001", + candidate_family_id="AMPF-FAM-001", + cfc_id="CFC-0001", + fnr_id="FNR-0001", + atr_id="ATR-0001", + pqg_id="PQG-0001", + readiness_verdict="ready_for_external_review", + safety_flags=["no_flags"], + failed_gates=[], + review_scope="trusted_partner", + n_confirmed_hits=2, + n_total_candidates=10, + limitations="Single candidate family; multi-family review not performed.", + ) + assert g.srg_id == "SRG-0001" + assert g.dry_lab_only is True + + def test_build_enforces_dry_lab_only_true(self): + g = build_scientific_review_readiness_gate( + srg_id="SRG-0002", + candidate_family_id="AMPF-FAM-002", + cfc_id="CFC-0002", + fnr_id="FNR-0002", + atr_id="ATR-0002", + pqg_id="PQG-0002", + readiness_verdict="conditionally_ready", + safety_flags=["no_flags"], + failed_gates=[], + review_scope="internal_only", + n_confirmed_hits=1, + n_total_candidates=5, + limitations="Conditional readiness due to limited replicate count.", + ) + assert g.dry_lab_only is True + + def test_build_raises_on_toy_family(self): + with pytest.raises(ValueError): + build_scientific_review_readiness_gate( + srg_id="SRG-0003", + candidate_family_id="TOY-FAM-001", + cfc_id="CFC-0003", + fnr_id="FNR-0003", + atr_id="ATR-0003", + pqg_id="PQG-0003", + readiness_verdict="ready_for_external_review", + safety_flags=["no_flags"], + failed_gates=[], + review_scope="trusted_partner", + n_confirmed_hits=1, + n_total_candidates=5, + limitations="TOY- family should fail.", + ) + + def test_build_raises_on_open_preprint_with_not_ready(self): + with pytest.raises(ValueError): + build_scientific_review_readiness_gate( + srg_id="SRG-0004", + candidate_family_id="AMPF-FAM-004", + cfc_id="CFC-0004", + fnr_id="FNR-0004", + atr_id="ATR-0004", + pqg_id="PQG-0004", + readiness_verdict="not_ready", + safety_flags=["no_flags"], + failed_gates=["ATR incomplete"], + review_scope="open_preprint", + n_confirmed_hits=0, + n_total_candidates=5, + limitations="Not ready but open preprint scope — should fail.", + ) + + def test_build_not_ready_verdict(self): + g = build_scientific_review_readiness_gate( + srg_id="SRG-0005", + candidate_family_id="AMPF-FAM-005", + cfc_id="CFC-0005", + fnr_id="FNR-0005", + atr_id="ATR-0005", + pqg_id="PQG-0005", + readiness_verdict="not_ready", + safety_flags=["no_flags"], + failed_gates=["FNR grade weak"], + review_scope="internal_only", + n_confirmed_hits=0, + n_total_candidates=8, + limitations="FNR novelty grade too weak for external review.", + ) + assert g.readiness_verdict == "not_ready" + + def test_build_review_blocked_by_safety(self): + g = build_scientific_review_readiness_gate( + srg_id="SRG-0006", + candidate_family_id="AMPF-FAM-006", + cfc_id="CFC-0006", + fnr_id="FNR-0006", + atr_id="ATR-0006", + pqg_id="PQG-0006", + readiness_verdict="review_blocked_by_safety", + safety_flags=["dual_use_concern"], + failed_gates=[], + review_scope="internal_only", + n_confirmed_hits=1, + n_total_candidates=5, + limitations="Dual-use concern must be resolved before any review.", + ) + assert g.readiness_verdict == "review_blocked_by_safety" + + +# ── Format ───────────────────────────────────────────────────────────────────── + +class TestFormatScientificReviewReadinessGate: + def _build(self, **kwargs): + defaults = dict( + srg_id="SRG-0001", + candidate_family_id="AMPF-FAM-001", + cfc_id="CFC-0001", + fnr_id="FNR-0001", + atr_id="ATR-0001", + pqg_id="PQG-0001", + readiness_verdict="ready_for_external_review", + safety_flags=["no_flags"], + failed_gates=[], + review_scope="trusted_partner", + n_confirmed_hits=2, + n_total_candidates=10, + limitations="Single candidate family; multi-family review not performed.", + ) + defaults.update(kwargs) + return build_scientific_review_readiness_gate(**defaults) + + def test_format_returns_string(self): + g = self._build() + assert isinstance(format_scientific_review_readiness_gate(g), str) + + def test_format_contains_srg_id(self): + g = self._build() + assert "SRG-0001" in format_scientific_review_readiness_gate(g) + + def test_format_contains_family_id(self): + g = self._build() + assert "AMPF-FAM-001" in format_scientific_review_readiness_gate(g) + + def test_format_contains_readiness_verdict(self): + g = self._build() + assert "ready_for_external_review" in format_scientific_review_readiness_gate(g) + + def test_format_contains_review_scope(self): + g = self._build() + assert "trusted_partner" in format_scientific_review_readiness_gate(g) + + def test_format_contains_artifact_ids(self): + g = self._build() + out = format_scientific_review_readiness_gate(g) + assert "CFC-0001" in out + assert "FNR-0001" in out + assert "ATR-0001" in out + assert "PQG-0001" in out + + def test_format_contains_confirmed_hits(self): + g = self._build() + assert "2/10" in format_scientific_review_readiness_gate(g) + + def test_format_contains_dry_lab_only_true(self): + g = self._build() + assert "dry_lab_only: True" in format_scientific_review_readiness_gate(g) + + def test_format_contains_limitations(self): + g = self._build() + assert "Single candidate family" in format_scientific_review_readiness_gate(g) + + def test_format_contains_failed_gates_when_present(self): + g = self._build( + readiness_verdict="not_ready", + safety_flags=["no_flags"], + failed_gates=["FNR grade weak"], + review_scope="internal_only", + n_confirmed_hits=0, + ) + assert "Failed Gates" in format_scientific_review_readiness_gate(g) + + def test_format_omits_failed_gates_when_empty(self): + g = self._build() + assert "Failed Gates" not in format_scientific_review_readiness_gate(g) + + def test_format_multiline(self): + g = self._build() + lines = format_scientific_review_readiness_gate(g).split("\n") + assert len(lines) >= 9 diff --git a/tests/test_test_count_regression.py b/tests/test_test_count_regression.py index 3a120b6a..6f17e1e1 100644 --- a/tests/test_test_count_regression.py +++ b/tests/test_test_count_regression.py @@ -3,7 +3,7 @@ import subprocess import math -BASELINE = 9089 +BASELINE = 9152 def test_test_count_regression():