risk-nexus/docs/method/review.md

200 lines
8.5 KiB
Markdown
Raw Permalink Normal View History

---
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: 6m
disclosure: public
revision: "adopted-1"
last_reviewed: "2026-08-20"
---
# 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.
## The cadence ladder
Operator ruling, 2026-08-20. **Intervals are not set by severity. They are
earned by outcomes.**
A finding is checked, and the check comes back clean or it does not. Clean
climbs one rung. Anything wrong drops straight back to the bottom.
| Rung | Wait before the next check |
| --- | --- |
| `instant` | now, and again immediately until a check comes back clean |
| `1h` | one hour |
| `8h` | eight hours |
| `24h` | one day |
| `48h` | two days |
| `96h` | four days |
| `7d` | one week |
| `14d` | two weeks |
| `1mo` | one month |
| `1q` | one quarter — **the ceiling; nothing is ever checked less often than this** |
Two rules and one escape:
- **Climb on clean.** One rung per clean check, never two.
- **Reset on anything wrong.** Not a slide down one rung — straight to
`instant`. A matter that has just moved has no track record, whatever it had
before.
- **The operator may defer.** An `instant` finding can be deferred to a stated
future date by explicit operator decision, recorded as `deferred_to`. That is
the only way out of the bottom rung other than a clean check, and it is a
decision with a name on it rather than a check quietly not happening.
### Who checked, and when anyone last did
`RISK-WP-0005-T06`. Two defences against the rung telling a lie:
- **`checked_by` on every check.** `record_check.py` writes it. A rung earned
by nobody in particular is visible as such.
- **A heartbeat.** If nothing anywhere in the register has been checked for two
days, `make check` says so **before anything else**. A `1q` rung means
"stable for a quarter" and "nobody looked for a quarter", and those read
identically from the outside — the heartbeat is what separates them.
### The rung is the signal
This is the point of the design, not a side effect. **The cadence a finding
sits on is a statement about how stable the estate has been on that matter.**
`RISK-F-0002` at `1q (9)` says the signing gate has been examined ten times
over three months and nothing has moved. `RISK-F-0002` at `instant (0)` says
something changed within the day. The number carries information that no
severity does — severity says how bad it would be, the rung says how settled
it is — and the two are independent. A `low` finding that keeps resetting is
telling you something a `critical` one at the ceiling is not.
It is also self-correcting in the direction that matters. Anything volatile
gets attention often, automatically, without anyone deciding it deserves it;
anything genuinely quiet stops consuming attention, without anyone deciding to
stop looking. Neither of those judgements has to be made by a person who might
be wrong or busy.
### What "clean" means
A check is **clean** when nothing about the assessment moved: the grade still
holds, every stated blocker is still true, the fix state is unchanged, the
disclosure state is still right, and no new fact has arrived.
A check is **not clean** when any of those moved — including when they moved in
a good direction. `RISK-F-0001` being fixed is not a clean check; it is a large
change, and the next check comes immediately. Good news resets the ladder
exactly like bad news, because the ladder measures stillness, not health.
### Starting position
Every finding starts at `instant`. A register with no check history has no
grounds to wait, and the first clean check is what buys the first hour.
The whole register sat at `instant (0)` on 2026-08-20, which is correct and
temporary: everything in it had been graded, re-graded or ruled on within the
preceding day.
## What a review is
Five questions, answered in writing on the finding. It takes minutes; it is not
an investigation.
0. **Has the inbox said anything?** Read the messages addressed to this repo
before anything else. This is question zero because on 2026-08-19 the
register graded `RISK-F-0001` `critical` while two messages sat unread in
its own inbox — one narrowing the exposure, one reporting the fix. Both
changed the grade. A register that does not read its own inbox is guessing
with a straight face.
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 check 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` lists it under "Checks due", with how late it is and which rung
it is on.
- `REGISTER.md` shows the next check as **due**.
- A finding sitting at the bottom rung for more than fourteen days with no
movement fires escalation trigger 5. Bottom rung means it keeps failing or
keeps being skipped; fourteen days of that is a stall whichever it is.
The register does not auto-escalate severity for lateness and 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_checked: "2026-08-20T05:40:00Z"
next_check: "2026-08-20T06:40:00Z"
cadence: 1h
clean_streak: 1
production_rescore: true
deferred_to: "" # only by explicit operator decision
```
`next_check` is what the nag reads, and it is an absolute moment rather than a
duration, so nothing has to recompute an interval to know whether a check is
late. The rungs run in hours as well as days, so it carries a time.
## 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 what ends the acceptance. `accepted` is not closed: it stays on
the ladder forever, and it climbs like anything else.
- `mitigated` — the live gap is closed but the finding is not. `RISK-F-0003` is
the case: the boundary now fires, and the omission that let it not fire is
still there. Stays watched.
- `withdrawn` — the finding was wrong, or the defect never existed. Say which.
**Any status the tooling does not recognise keeps the finding watched, and the
unrecognised word is reported.** `RISK-F-0003` arrived as `mitigated` on
2026-08-20, before that word existed here, and dropped silently out of
`make check` — a finding vanishing from the nag because someone used an
unfamiliar word is precisely the failure this register exists to prevent. The
tooling now fails loud instead of quiet.
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.