mirror of
https://github.com/elder-plinius/OBLITERATUS.git
synced 2026-08-17 16:37:30 +02:00
fix: bound conditional evidence waivers
This commit is contained in:
@@ -6,6 +6,7 @@ from __future__ import annotations
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
from datetime import date, timedelta
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@@ -19,7 +20,10 @@ SOFTWARE_ONLY_GATES = (
|
||||
"operator-ui",
|
||||
)
|
||||
SHA = re.compile(r"^[0-9a-f]{40}$")
|
||||
ISSUE_URL = "https://github.com/elder-plinius/OBLITERATUS/issues/"
|
||||
ISSUE_URL = re.compile(
|
||||
r"^https://github\.com/elder-plinius/OBLITERATUS/issues/[1-9][0-9]*$",
|
||||
)
|
||||
MAX_STALE_EXCEPTION_DAYS = 30
|
||||
|
||||
|
||||
def validate(policy_path: Path, quality_path: Path, workflow_path: Path) -> list[str]:
|
||||
@@ -88,13 +92,24 @@ def _load_json_object(path: Path, label: str, errors: list[str]) -> dict:
|
||||
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 _valid_stale_exception(
|
||||
reason: str | None,
|
||||
issue: str | None,
|
||||
expires: str | None,
|
||||
*,
|
||||
today: date,
|
||||
) -> bool:
|
||||
if not isinstance(reason, str) or not reason.strip():
|
||||
return False
|
||||
if not isinstance(issue, str) or ISSUE_URL.fullmatch(issue) is None:
|
||||
return False
|
||||
if not isinstance(expires, str):
|
||||
return False
|
||||
try:
|
||||
expiry = date.fromisoformat(expires)
|
||||
except ValueError:
|
||||
return False
|
||||
return today <= expiry <= today + timedelta(days=MAX_STALE_EXCEPTION_DAYS)
|
||||
|
||||
|
||||
def validate_evidence(
|
||||
@@ -105,6 +120,8 @@ def validate_evidence(
|
||||
required_gates: list[str] | None = None,
|
||||
stale_exception_reason: str | None = None,
|
||||
stale_exception_issue: str | None = None,
|
||||
stale_exception_expires: str | None = None,
|
||||
today: date | None = None,
|
||||
) -> list[str]:
|
||||
"""Validate selected software-only conditional evidence against a candidate SHA."""
|
||||
|
||||
@@ -129,10 +146,21 @@ def validate_evidence(
|
||||
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:
|
||||
today = today or date.today()
|
||||
exception = _valid_stale_exception(
|
||||
stale_exception_reason,
|
||||
stale_exception_issue,
|
||||
stale_exception_expires,
|
||||
today=today,
|
||||
)
|
||||
if (
|
||||
stale_exception_reason
|
||||
or stale_exception_issue
|
||||
or stale_exception_expires
|
||||
) and not exception:
|
||||
errors.append(
|
||||
"stale evidence exception requires a non-empty reason and an OBLITERATUS issue URL",
|
||||
"stale evidence exception requires a reason, a canonical OBLITERATUS issue URL, "
|
||||
"and an ISO expiry no more than 30 days away",
|
||||
)
|
||||
|
||||
for gate_id in requested:
|
||||
@@ -188,6 +216,11 @@ def main() -> int:
|
||||
default="",
|
||||
help="OBLITERATUS issue URL approving older software conditional evidence",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--stale-evidence-expires",
|
||||
default="",
|
||||
help="ISO expiry date for a stale-evidence waiver (maximum 30 days)",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
errors = validate(args.policy, args.quality, args.workflow)
|
||||
if args.evidence_dir is not None:
|
||||
@@ -202,6 +235,7 @@ def main() -> int:
|
||||
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,
|
||||
stale_exception_expires=args.stale_evidence_expires or None,
|
||||
),
|
||||
)
|
||||
if errors:
|
||||
|
||||
Reference in New Issue
Block a user