test: enforce gate 2 coverage and vertical contracts

This commit is contained in:
Joseph Magly
2026-08-15 02:00:50 -04:00
parent dadd42648a
commit ba749c68b9
17 changed files with 2134 additions and 40 deletions
+128
View File
@@ -5,12 +5,21 @@ from __future__ import annotations
import argparse
import json
import re
from pathlib import Path
REQUIRED_GATE_FIELDS = {
"id", "job", "marker", "runner", "prerequisites", "expected_cost", "coverage_paths"
}
SOFTWARE_ONLY_GATES = (
"model-download-runtime",
"external-evaluation",
"network-services",
"operator-ui",
)
SHA = re.compile(r"^[0-9a-f]{40}$")
ISSUE_URL = "https://github.com/elder-plinius/OBLITERATUS/issues/"
def validate(policy_path: Path, quality_path: Path, workflow_path: Path) -> list[str]:
@@ -67,6 +76,86 @@ def validate(policy_path: Path, quality_path: Path, workflow_path: Path) -> list
return errors
def _load_json_object(path: Path, label: str, errors: list[str]) -> dict:
try:
value = json.loads(path.read_text(encoding="utf-8"))
except (OSError, json.JSONDecodeError) as exc:
errors.append(f"cannot read {label}: {exc}")
return {}
if not isinstance(value, dict):
errors.append(f"{label} root must be an object")
return {}
return value
def _valid_stale_exception(reason: str | None, issue: str | None) -> bool:
return (
isinstance(reason, str)
and bool(reason.strip())
and isinstance(issue, str)
and issue.startswith(ISSUE_URL)
)
def validate_evidence(
policy_path: Path,
evidence_dir: Path,
*,
candidate_sha: str,
required_gates: list[str] | None = None,
stale_exception_reason: str | None = None,
stale_exception_issue: str | None = None,
) -> list[str]:
"""Validate selected software-only conditional evidence against a candidate SHA."""
errors: list[str] = []
policy = _load_json_object(policy_path, "conditional policy", errors)
if errors:
return errors
if SHA.fullmatch(candidate_sha) is None:
errors.append("candidate SHA must be a 40-character lowercase hex commit")
gates = policy.get("gates")
policy_gate_ids = {
gate.get("id")
for gate in gates
if isinstance(gates, list) and isinstance(gate, dict)
} if isinstance(gates, list) else set()
requested = required_gates or list(SOFTWARE_ONLY_GATES)
for gate_id in requested:
if gate_id not in SOFTWARE_ONLY_GATES:
errors.append(f"hardware or credential gate is not software-only: {gate_id}")
if gate_id not in policy_gate_ids:
errors.append(f"conditional policy does not define gate {gate_id}")
exception = _valid_stale_exception(stale_exception_reason, stale_exception_issue)
if (stale_exception_reason or stale_exception_issue) and not exception:
errors.append(
"stale evidence exception requires a non-empty reason and an OBLITERATUS issue URL",
)
for gate_id in requested:
evidence = _load_json_object(
evidence_dir / f"{gate_id}.json",
f"conditional evidence {gate_id}",
errors,
)
if not evidence:
continue
if evidence.get("gate") != gate_id:
errors.append(f"conditional evidence {gate_id} records gate {evidence.get('gate')!r}")
if evidence.get("status") != "passed":
errors.append(f"conditional evidence {gate_id} did not pass: {evidence.get('status')!r}")
evidence_sha = evidence.get("git_sha")
if evidence_sha != candidate_sha and not exception:
errors.append(
f"conditional evidence {gate_id} git_sha {evidence_sha!r} "
f"does not match candidate {candidate_sha}",
)
return errors
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--policy", type=Path, default=Path("ci/conditional-test-policy.json"))
@@ -74,8 +163,47 @@ def main() -> int:
parser.add_argument(
"--workflow", type=Path, default=Path(".github/workflows/conditional-tests.yml")
)
parser.add_argument(
"--evidence-dir",
type=Path,
help="validate software-only conditional evidence files in this directory",
)
parser.add_argument(
"--candidate-sha",
help="40-character candidate commit SHA required for evidence freshness validation",
)
parser.add_argument(
"--require-gate",
action="append",
default=[],
help="software-only gate that must have current passed evidence (repeatable)",
)
parser.add_argument(
"--stale-evidence-reason",
default="",
help="maintainer reason for accepting older software conditional evidence",
)
parser.add_argument(
"--stale-evidence-issue",
default="",
help="OBLITERATUS issue URL approving older software conditional evidence",
)
args = parser.parse_args()
errors = validate(args.policy, args.quality, args.workflow)
if args.evidence_dir is not None:
if not args.candidate_sha:
errors.append("evidence freshness validation requires --candidate-sha")
else:
errors.extend(
validate_evidence(
args.policy,
args.evidence_dir,
candidate_sha=args.candidate_sha,
required_gates=args.require_gate or None,
stale_exception_reason=args.stale_evidence_reason or None,
stale_exception_issue=args.stale_evidence_issue or None,
),
)
if errors:
for error in errors:
print(f"ERROR: {error}")
+4 -4
View File
@@ -13,11 +13,11 @@ from typing import Any
BASELINE_FLOORS = {
"repository_statement": 70.0,
"repository_branch": 55.0,
"repository_statement": 75.0,
"repository_branch": 60.0,
"changed_line": 90.0,
"mature_cpu_statement": 90.0,
"mature_cpu_branch": 78.0,
"mature_cpu_statement": 92.0,
"mature_cpu_branch": 80.0,
"mutation_score": 75.0,
"warning_budget": 0.0,
}
+8
View File
@@ -15,18 +15,26 @@ from xml.etree import ElementTree
DEFAULT_TESTS = (
"tests/test_bayesian_optimizer_contracts.py",
"tests/test_config.py",
"tests/test_config_properties.py",
"tests/test_conditional_evidence_freshness.py",
"tests/test_coverage_thresholds.py",
"tests/test_evaluation_reporting_contracts.py",
"tests/test_lm_eval_reporting_contracts.py",
"tests/test_informed_pipeline_contracts.py",
"tests/test_model_profile_contracts.py",
"tests/test_numerical_contracts.py",
"tests/test_package_export_contracts.py",
"tests/test_persistence_contracts.py",
"tests/test_property_contracts.py",
"tests/test_advanced_metrics.py",
"tests/test_metrics.py",
"tests/test_remote_contracts.py",
"tests/test_remaining_cpu_contracts.py",
"tests/test_runtime_contracts.py",
"tests/test_strategy_navigation_contracts.py",
"tests/test_sweep_contracts.py",
"tests/test_telemetry_failure_contracts.py",
)
HASH_SEEDS = ("0", "1", "8675309")