Exception registry: repository-owned, expiring waivers for rule violations.
Every entry MUST carry owner, rationale, expiry, and review date (LAY-ADR SS7
rule 6). An expired entry is itself a violation that cannot be suppressed, so
exceptions rot loudly, never silently.
Bases: ValueError
The exception registry is missing required fields or malformed.
apply_exceptions(violations: list[Violation], entries: tuple[ExceptionEntry, ...], today: date | None = None) -> tuple[list[Violation], list[tuple[Violation, str]]]
Split violations into (active, suppressed-with-entry-id).
Expired entries never suppress anything.
Source code in src/symfonic/devtools/archcheck/registry.py
| def apply_exceptions(
violations: list[Violation],
entries: tuple[ExceptionEntry, ...],
today: dt.date | None = None,
) -> tuple[list[Violation], list[tuple[Violation, str]]]:
"""Split violations into (active, suppressed-with-entry-id).
Expired entries never suppress anything.
"""
today = today or dt.date.today()
live = [entry for entry in entries if entry.expiry >= today]
active: list[Violation] = []
suppressed: list[tuple[Violation, str]] = []
for violation in violations:
entry = next((e for e in live if e.matches(violation)), None)
if entry is None:
active.append(violation)
else:
suppressed.append((violation, entry.id))
return active, suppressed
|
expired_entries(entries: tuple[ExceptionEntry, ...], today: date | None = None) -> list[Violation]
An expired exception fails CI (LAY-ADR SS7 rule 6).
Source code in src/symfonic/devtools/archcheck/registry.py
| def expired_entries(
entries: tuple[ExceptionEntry, ...], today: dt.date | None = None
) -> list[Violation]:
"""An expired exception fails CI (LAY-ADR SS7 rule 6)."""
today = today or dt.date.today()
return [
Violation(
rule="expired-exception",
message=(
f"exception {entry.id} (owner {entry.owner}, rule {entry.rule}) "
f"expired {entry.expiry.isoformat()}; renew or fix the underlying debt"
),
modules=(entry.id,),
)
for entry in entries
if entry.expiry < today
]
|