risk-nexus/docs/method/review.md
tegwick d5a3953f2e RISK-WP-0001 T01-T06,T08: the four instruments, the index, and the first grading
Severity (impact x likelihood, fidelity modifier for controls that lie,
headline-vs-constraint, build-mode double grade, the floor), disclosure
(publish/embargoed/restricted, and the build-mode deferral re-taken and
narrowed with RISK-F-0001 in hand), escalation (the five INTENT triggers
settled plus an ordering-hazard trigger the RISK-F-0002 case forced;
proposed, awaiting the custodian), review (intervals, what a review is,
what missing one produces, the production re-score).

Then applied: RISK-F-0001 critical/embargoed/escalated, RISK-F-0002
medium with a high constraint on RISK-F-0001's remediation, filed as a
peer and escalated only on the ordering, RISK-F-0003 high/embargoed/no
escalation. No unset field remains.

REGISTER.md is generated; make check reports overdue, stalled, ungraded
and unanswered escalations without changing anything.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 23:29:39 +02:00

109 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
id: RISK-METHOD-REVIEW
type: method
title: "Review and expiry: what happens when nobody looks"
status: adopted
owner: risk-nexus
adopted: "2026-08-19"
workplan: RISK-WP-0001-T04
review_interval: 180d
---
# Review and expiry
`INTENT.md`: a finding that has sat untouched past its review date is itself a
finding. Silence is not resolution. This document makes that operable.
## Intervals
Set from the headline severity at grading time, and reset at each review.
| Severity | Interval | Stale (2×, escalation trigger 5) |
| --- | --- | --- |
| `critical` | 7 days | 14 days |
| `high` | 30 days | 60 days |
| `medium` | 90 days | 180 days |
| `low` | 180 days | — (ages out through review) |
A finding graded `critical` is being looked at weekly or it is not being
managed. If weekly is unbearable, the honest response is to re-grade it, not
to let the date slide.
## What a review is
Four questions, answered in writing on the finding. It takes minutes; it is not
an investigation.
1. **Is the grade still right?** Re-read impact and likelihood against what has
changed. New facts move the grade in both directions.
2. **Is the blocker still true?** This is the one `RISK-F-0002` bought with
evidence: *a blocker is a claim about the world at a date*. Its own stated
blocker — "`flex-auth` is not deployed yet" — was invalidated within a day
by `RISK-F-0001`, and nothing would have re-checked it. Every review
re-checks every stated blocker.
3. **Has the fix moved?** Read the owner's tracking record, not our memory of
it. Confirm the record still exists and still refers to this defect.
4. **Is the disclosure state still right?** An embargo whose condition has
been met is published; an embargo whose condition has not moved in two
reviews is a stall.
The finding gets a dated line under `## Reviews`, `last_reviewed` is updated,
and `review_by` is pushed by one interval. A review that changes nothing still
writes the line — "checked, nothing moved" is the evidence that the silence was
observed rather than accidental.
## When a review is missed
Overdue is not a status change on the finding. It is a fact about *this repo*,
and it surfaces in three places:
- `make check` reports it (`tools/register_check.py`), always, unconditionally.
- `REGISTER.md` shows the finding as overdue with the day count.
- At **twice** the interval, escalation trigger 5 fires for `critical`,
`high` and `medium`. That is the point at which the register's own silence
reaches the operator.
The register does not auto-escalate severity for lateness, and it does not
auto-close anything. Both would be the register lying about its own state to
make a number look better.
## The production re-score
Every finding carries `severity_at_production` alongside `severity`
(`docs/method/severity.md`). Where the two differ, the finding is flagged
`production_rescore: true`.
On the day any part of the estate declares production readiness, every flagged
finding is re-scored before that declaration completes. This is not a review
date — it is an event, and it fires regardless of where the review dates
happen to sit.
Until then, `make check` lists the flagged findings so the size of that
obligation is visible rather than discovered on the day.
## Front-matter this adds
```yaml
last_reviewed: "2026-08-19"
review_by: "2026-08-26"
production_rescore: true
```
`review_by` is what the nag reads. It is a date, never a duration, so that
nothing has to recompute an interval to know whether a finding is late.
## Closing a finding
A finding leaves `open` for exactly one of:
- `fixed` — the owner's record shows the defect gone, and this repo has read
something concrete rather than been told. Publication follows if the
disclosure state was `embargoed`.
- `accepted` — the estate is deliberately carrying it. Requires who accepted
it, why, and a re-review date. `accepted` is not `closed`; it keeps a review
interval forever.
- `withdrawn` — the finding was wrong, or the defect never existed. Say which.
There is no `stale`, no `wontfix` and no silent expiry. A finding that nobody
will fix and nobody will accept stays `open` and keeps arriving in the nag,
because that is the true state.