RISK-F-0007 moved to accepted and dropped out of the production-rescore list, which contradicts what the finding itself says: an acceptance that expires at the production transition has to be visible at that transition. accepted is carried, not closed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
98 lines
3.3 KiB
Python
98 lines
3.3 KiB
Python
#!/usr/bin/env python3
|
|
"""Report what the register is not saying out loud.
|
|
|
|
RISK-WP-0001-T08. Report only: it writes nothing, changes no field,
|
|
escalates nothing on its own, and blocks nothing. A human or the custodian
|
|
acts on the output. Exit code is 0 unless a finding cannot be read.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import datetime as dt
|
|
|
|
import register_lib as lib
|
|
|
|
TODAY = dt.date.today()
|
|
|
|
|
|
def date(value):
|
|
if isinstance(value, dt.date):
|
|
return value
|
|
if isinstance(value, str) and value not in ("", "unset"):
|
|
return dt.date.fromisoformat(value)
|
|
return None
|
|
|
|
|
|
def main() -> int:
|
|
# "accepted" is deliberately carried, not closed: it keeps its review
|
|
# interval and its production re-score, so the nag must keep watching it.
|
|
fs = [f for f in lib.findings() if f.get("status") in ("open", "accepted")]
|
|
lines: list[str] = []
|
|
|
|
def section(title: str, rows: list[str], quiet: str) -> None:
|
|
lines.append(f"{title}:")
|
|
if rows:
|
|
lines.extend(f" {r}" for r in rows)
|
|
else:
|
|
lines.append(f" {quiet}")
|
|
lines.append("")
|
|
|
|
ungraded = [
|
|
f"{f['id']} — {', '.join(k for k in lib.GRADED_FIELDS if str(f.get(k, 'unset')) == 'unset')}"
|
|
for f in fs
|
|
if any(str(f.get(k, "unset")) == "unset" for k in lib.GRADED_FIELDS)
|
|
]
|
|
section("Ungraded", ungraded, "none — every open finding carries a grade")
|
|
|
|
overdue = []
|
|
for f in fs:
|
|
due = date(f.get("review_by"))
|
|
if due and TODAY > due:
|
|
overdue.append(f"{f['id']} — review was due {due} ({(TODAY - due).days}d ago)")
|
|
section("Overdue review", overdue, "none")
|
|
|
|
stale = []
|
|
for f in fs:
|
|
seen = date(f.get("last_reviewed"))
|
|
interval = lib.REVIEW_INTERVAL_DAYS.get(f.get("severity"))
|
|
if not seen or not interval or f.get("severity") == "low":
|
|
continue
|
|
limit = seen + dt.timedelta(days=interval * lib.STALE_MULTIPLIER)
|
|
if TODAY > limit:
|
|
stale.append(
|
|
f"{f['id']} ({f.get('severity')}) — untouched since {seen}; "
|
|
f"escalation trigger 5 fires (limit was {limit})"
|
|
)
|
|
section("Stalled — escalation trigger 5", stale, "none")
|
|
|
|
embargo = []
|
|
for f in fs:
|
|
if f.get("disclosure") != "embargoed":
|
|
continue
|
|
due = date(f.get("embargo_review"))
|
|
if due and TODAY > due:
|
|
embargo.append(
|
|
f"{f['id']} — embargo not re-decided since {due}; lifts when: {f.get('embargo_condition')}"
|
|
)
|
|
section("Embargo overdue for re-decision", embargo, "none")
|
|
|
|
esc = [
|
|
f"{f['id']} — trigger {f.get('escalation_trigger')}, {f.get('escalation_status')}"
|
|
for f in fs
|
|
if f.get("escalation") == "required" and f.get("escalation_status") != "answered"
|
|
]
|
|
section("Escalations awaiting the operator", esc, "none")
|
|
|
|
rescore = [
|
|
f"{f['id']} — {f.get('severity')} now, {f.get('severity_at_production')} at production"
|
|
for f in fs
|
|
if f.get("production_rescore")
|
|
]
|
|
section("Owed at the production transition", rescore, "none — no finding is graded lower for build mode")
|
|
|
|
print(f"Register check — {TODAY}\n{len(fs)} open or accepted finding(s)\n")
|
|
print("\n".join(lines).rstrip())
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|