fix: bound conditional evidence waivers

This commit is contained in:
Joseph Magly
2026-08-15 02:00:50 -04:00
parent ba749c68b9
commit fa99d5a424
3 changed files with 77 additions and 12 deletions
+8
View File
@@ -43,6 +43,10 @@ on:
description: OBLITERATUS issue URL approving older software conditional evidence
type: string
default: ""
stale_evidence_expires:
description: ISO date when the stale-evidence waiver expires (maximum 30 days)
type: string
default: ""
schedule:
- cron: "17 6 * * 0"
release:
@@ -57,6 +61,7 @@ concurrency:
env:
CONDITIONAL_CANDIDATE_SHA: ${{ github.event.inputs.candidate_sha || github.sha }}
CONDITIONAL_STALE_EVIDENCE_EXPIRES: ${{ github.event.inputs.stale_evidence_expires || '' }}
CONDITIONAL_STALE_EVIDENCE_ISSUE: ${{ github.event.inputs.stale_evidence_issue || '' }}
CONDITIONAL_STALE_EVIDENCE_REASON: ${{ github.event.inputs.stale_evidence_reason || '' }}
PIP_DISABLE_PIP_VERSION_CHECK: "1"
@@ -119,6 +124,7 @@ jobs:
--require-gate external-evaluation
--stale-evidence-reason "$CONDITIONAL_STALE_EVIDENCE_REASON"
--stale-evidence-issue "$CONDITIONAL_STALE_EVIDENCE_ISSUE"
--stale-evidence-expires "$CONDITIONAL_STALE_EVIDENCE_EXPIRES"
- name: Upload model-runtime evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
@@ -160,6 +166,7 @@ jobs:
--require-gate network-services
--stale-evidence-reason "$CONDITIONAL_STALE_EVIDENCE_REASON"
--stale-evidence-issue "$CONDITIONAL_STALE_EVIDENCE_ISSUE"
--stale-evidence-expires "$CONDITIONAL_STALE_EVIDENCE_EXPIRES"
- name: Upload network evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
@@ -201,6 +208,7 @@ jobs:
--require-gate operator-ui
--stale-evidence-reason "$CONDITIONAL_STALE_EVIDENCE_REASON"
--stale-evidence-issue "$CONDITIONAL_STALE_EVIDENCE_ISSUE"
--stale-evidence-expires "$CONDITIONAL_STALE_EVIDENCE_EXPIRES"
- name: Upload UI evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+45 -11
View File
@@ -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:
+24 -1
View File
@@ -3,6 +3,7 @@
from __future__ import annotations
import json
from datetime import date
from pathlib import Path
from scripts import check_conditional_policy
@@ -11,6 +12,7 @@ from scripts import check_conditional_policy
ROOT = Path(__file__).parents[1]
SHA = "0123456789abcdef0123456789abcdef01234567"
OLD_SHA = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
TODAY = date(2026, 8, 15)
def _write_evidence(path: Path, gate: str, *, git_sha: str = SHA, status: str = "passed") -> None:
@@ -65,6 +67,8 @@ def test_maintainer_exception_only_allows_sha_mismatch(tmp_path):
required_gates=["external-evaluation"],
stale_exception_reason="Gate reviewed against equivalent conditional surface.",
stale_exception_issue="https://github.com/elder-plinius/OBLITERATUS/issues/123",
stale_exception_expires="2026-08-30",
today=TODAY,
) == []
@@ -80,7 +84,8 @@ def test_exception_requires_reason_and_issue_url(tmp_path):
)
assert (
"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"
) in errors
assert (
"conditional evidence external-evaluation git_sha "
@@ -97,3 +102,21 @@ def test_evidence_freshness_does_not_make_hardware_lanes_mandatory(tmp_path):
candidate_sha=SHA,
required_gates=["cuda-runtime"],
) == ["hardware or credential gate is not software-only: cuda-runtime"]
def test_exception_rejects_noncanonical_issue_and_unbounded_expiry(tmp_path):
_write_evidence(tmp_path / "network-services.json", "network-services", git_sha=OLD_SHA)
errors = check_conditional_policy.validate_evidence(
ROOT / "ci" / "conditional-test-policy.json",
tmp_path,
candidate_sha=SHA,
required_gates=["network-services"],
stale_exception_reason="reviewed",
stale_exception_issue="https://github.com/elder-plinius/OBLITERATUS/issues/not-a-number",
stale_exception_expires="2027-01-01",
today=TODAY,
)
assert errors[0].startswith("stale evidence exception requires a reason")
assert "does not match candidate" in errors[1]