work-record-types_v0.1 pins workplan ids to ^[A-Z]+-WP-[0-9]{4}$ and tasks
to that plus -TNN; a hyphenated RISK-NEXUS prefix trips the sidetrack
detector. RISK-WP also matches the register's existing RISK-F finding
prefix. Renamed before the workplan was indexed anywhere.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
331 lines
13 KiB
Markdown
331 lines
13 KiB
Markdown
---
|
||
id: RISK-WP-0001
|
||
type: workplan
|
||
title: "Make the register decidable: severity, disclosure, escalation, expiry"
|
||
domain: infotech
|
||
repo: risk-nexus
|
||
status: active
|
||
owner: the-custodian
|
||
topic_slug: risk-nexus
|
||
created: "2026-08-19"
|
||
updated: "2026-08-19"
|
||
---
|
||
|
||
# RISK-WP-0001 — make the register decidable
|
||
|
||
## Goal
|
||
|
||
Give this repo the four instruments it needs to answer a finding, and then
|
||
answer the three findings already sitting here.
|
||
|
||
Done means: every open finding carries a severity from a written scale, a
|
||
disclosure state from a written set, an escalation ruling from a written rule,
|
||
and a review date that something checks; the register has an index a person can
|
||
read in one sitting; and `RISK-F-0001`, `RISK-F-0002` and `RISK-F-0003` have
|
||
none of those fields at `unset`.
|
||
|
||
## The forcing case
|
||
|
||
Three findings are open. All three were filed correctly by their reporting
|
||
repos, and all three carry the same block:
|
||
|
||
```yaml
|
||
# risk-nexus's to set, not the reporter's (INTENT, "What it does not own").
|
||
severity: unset
|
||
disclosure: unset
|
||
escalation: unset
|
||
```
|
||
|
||
`RISK-F-0002` states the ask outright — it names severity, filing shape and
|
||
escalation as three decisions it is waiting on, and it declines to make them
|
||
itself. That is the boundary working exactly as `INTENT.md` describes it. It is
|
||
also a queue: the reporters have done their half, this repo has not built the
|
||
half that answers.
|
||
|
||
This is the failure `INTENT.md` says the repo must avoid, arriving early and in
|
||
its mildest form. Findings recorded, nothing decided, converts "we did not
|
||
know" into "we knew and did nothing" while changing no behaviour. Three
|
||
findings is the cheapest possible moment to fix it.
|
||
|
||
## What this workplan produces
|
||
|
||
Four instruments, one index, and one graded register.
|
||
|
||
| Instrument | Answers | Output |
|
||
| --- | --- | --- |
|
||
| Severity scale | how bad, how likely, and what is not a risk at all | `docs/method/severity.md` |
|
||
| Disclosure states | publish now, hold, or restrict — and the record that a hold was deliberate | `docs/method/disclosure.md` |
|
||
| Escalation rule | what reaches the operator personally | `docs/method/escalation.md` |
|
||
| Review and expiry | when a finding must be looked at again, and what happens when it is not | `docs/method/review.md` |
|
||
| Register index | the whole register, readable at once | `REGISTER.md` |
|
||
|
||
Each instrument is a governing document of this repo. It is written to be
|
||
publishable through `policy-nexus` later; this workplan does not publish it.
|
||
|
||
## Authority
|
||
|
||
- **This repo** sets severity, disclosure and escalation. Reporters do not, and
|
||
the current findings correctly leave them unset.
|
||
- **Owning repos** keep their own account of the defect and its fix. A finding
|
||
here points at that account; it does not replace it or edit it.
|
||
- **the-custodian** owns the escalation duty. This workplan writes the rule
|
||
down; adopting it is the custodian's call, and T04 asks for it explicitly.
|
||
- **Canon** is `the-custodian`'s and NetKingdom's. A severity scale is a
|
||
judgement instrument, not a standard, and must not be written as one.
|
||
|
||
## Non-goals
|
||
|
||
- **No remediation.** Not one line of another repo's fix. Findings route.
|
||
- **No publication.** `policy-nexus` is the surface; this workplan produces
|
||
documents that could be published, and publishes nothing.
|
||
- **No blocking gate.** In build mode a finding is information. If that ever
|
||
changes it is a recorded decision, not a side effect of this workplan.
|
||
- **No tool before the judgement.** The scale and the rule are written first
|
||
and applied by hand to three findings. Automation is T06 and is deliberately
|
||
the smallest thing that can nag.
|
||
- **No back-filling the estate.** Only findings already filed here, plus the
|
||
named waiting items in T07. Sweeping every repo for undiscovered risk is not
|
||
this workplan.
|
||
|
||
## Tasks
|
||
|
||
### T01 — Severity scale
|
||
|
||
```task
|
||
id: RISK-WP-0001-T01
|
||
status: todo
|
||
priority: high
|
||
```
|
||
|
||
Write the scale: impact bands, likelihood bands, how they combine, and the
|
||
threshold below which something is a note rather than a register entry.
|
||
|
||
Constraints it has to satisfy, taken from the findings already here:
|
||
|
||
- It must be able to score *the absence of a control* and *a control that lies*
|
||
differently. `RISK-F-0002` argues the second is worse than the first and asks
|
||
the register to say which it scored. A scale that cannot express that is not
|
||
finished.
|
||
- It must score against **build mode** honestly. "No real tenant data yet" is a
|
||
genuine likelihood input, not an excuse, and the scale must make the
|
||
production re-score automatic rather than optional.
|
||
- It must have a floor. `INTENT.md`: if a finding would not change anyone's
|
||
decision, it is a note. Say where that line is.
|
||
|
||
**Output:** `docs/method/severity.md`.
|
||
|
||
### T02 — Disclosure states
|
||
|
||
```task
|
||
id: RISK-WP-0001-T02
|
||
status: todo
|
||
priority: high
|
||
```
|
||
|
||
Define the disclosure states — at minimum publish-now, embargoed-until-fixed,
|
||
restricted — with the entry condition for each and what is recorded when a
|
||
finding is held.
|
||
|
||
Then revisit the standing deferral. `INTENT.md` records controlled disclosure
|
||
as deferred to production, on the reasoning that build mode has no users to
|
||
expose, and then records that `RISK-F-0001` tested that reasoning with a live
|
||
authorization bypass in the service every other service trusts. The deferral may
|
||
still be right. It must be re-taken with that case in hand and the reasoning
|
||
written down, because "publish or hold with nothing in between" is the state
|
||
`RISK-F-0001` is currently sitting in.
|
||
|
||
Whichever way it goes is a recorded decision, not a habit.
|
||
|
||
**Output:** `docs/method/disclosure.md`, including the re-taken deferral.
|
||
|
||
### T03 — The escalation rule
|
||
|
||
```task
|
||
id: RISK-WP-0001-T03
|
||
status: todo
|
||
priority: high
|
||
```
|
||
|
||
Write the rule `INTENT.md` says is not yet written. Settle the five candidate
|
||
triggers it lists rather than restating them:
|
||
|
||
1. anything exposing real tenant data;
|
||
2. anything creating a legal or regulatory obligation;
|
||
3. anything requiring spend;
|
||
4. anything where two repos disagree about who owns the fix;
|
||
5. any finding whose remediation has stalled past a stated interval.
|
||
|
||
For each: adopt, drop, or bound it with a number. A trigger with no threshold
|
||
is not a rule. Say also what escalation *is* — a message, a conversation, a
|
||
flagged item — and what the operator is expected to do with one.
|
||
|
||
Test the draft against the three open findings before calling it done.
|
||
`RISK-F-0002` states its own view (it does not think it needs the operator);
|
||
the rule must reach an answer there on its own terms, and if it disagrees with
|
||
the reporter, that disagreement is the useful output.
|
||
|
||
The custodian adopts the rule. Ask, do not assume.
|
||
|
||
**Output:** `docs/method/escalation.md`.
|
||
|
||
### T04 — Review dates and expiry
|
||
|
||
```task
|
||
id: RISK-WP-0001-T04
|
||
status: todo
|
||
priority: medium
|
||
```
|
||
|
||
Every finding gets a review date on entry, set from its severity. Define the
|
||
intervals, what a review is (re-score, re-check the blocker, re-read the fix
|
||
owner's account), and what happens when one is missed.
|
||
|
||
`INTENT.md` is explicit that a finding sitting untouched past its review date is
|
||
itself a finding, and `RISK-F-0002` supplies the mechanism: a blocker is a claim
|
||
about the world at a date, its own blocker was invalidated in a day, and nothing
|
||
would have re-checked it. Overdue review therefore has to produce something —
|
||
an escalation, a severity bump, a register entry of its own — and this task
|
||
picks which.
|
||
|
||
**Output:** `docs/method/review.md`; the finding front-matter contract extended
|
||
with `review_by` and `last_reviewed`.
|
||
|
||
### T05 — Register index
|
||
|
||
```task
|
||
id: RISK-WP-0001-T05
|
||
status: todo
|
||
priority: medium
|
||
```
|
||
|
||
One `REGISTER.md`: id, title, system, severity, disclosure, escalation, fix
|
||
owner, status, review date — one row per finding, newest first.
|
||
|
||
Generate it from the finding front-matter rather than maintaining it by hand;
|
||
a hand-maintained index drifts and then lies. Keep the generator small and in
|
||
this repo (`tools/`), and keep the output legible: if the table stops being
|
||
readable in one sitting, that is the "register too large to read" failure
|
||
arriving, and it is worth a note in the residuals rather than a wider table.
|
||
|
||
**Output:** `REGISTER.md`, its generator, and the front-matter contract the
|
||
generator relies on written down where a reporter will see it.
|
||
|
||
### T06 — Grade the three open findings
|
||
|
||
```task
|
||
id: RISK-WP-0001-T06
|
||
status: todo
|
||
priority: high
|
||
```
|
||
|
||
Apply T01–T04 to `RISK-F-0001`, `RISK-F-0002` and `RISK-F-0003`. For each:
|
||
severity with its reasoning, disclosure state, escalation ruling, review date,
|
||
and confirmation that the fix owner recorded in the file is still the right
|
||
one.
|
||
|
||
Two specific questions are already on the table and must be answered here, not
|
||
deferred:
|
||
|
||
- **`RISK-F-0002`: peer or consequence?** It is filed as a peer of
|
||
`RISK-F-0001` because the fix owner differs, and it offers to be carried as a
|
||
dependency instead. Rule on it; `ops-warden` has said it will not re-file
|
||
either way.
|
||
- **The sequencing constraint.** `RISK-F-0002` states that `policy.enabled`
|
||
must not flip anywhere while `flex-auth`'s `/v1/check` answers unauthenticated
|
||
callers. That is a cross-repo ordering constraint between two open findings,
|
||
and the register is where it stays visible. Record it as such.
|
||
|
||
Where grading changes what an owning repo should do, that goes back as a
|
||
message to that repo, not as an edit in it.
|
||
|
||
**Acceptance:** no `unset` field remains in `findings/`.
|
||
|
||
### T07 — Rule on what is waiting outside the register
|
||
|
||
```task
|
||
id: RISK-WP-0001-T07
|
||
status: todo
|
||
priority: medium
|
||
```
|
||
|
||
`INTENT.md` names things visible but unfiled, held back pending the precedent
|
||
this workplan sets. Now that the floor from T01 exists, rule on each:
|
||
|
||
- the three further defects surfaced in the same round as `RISK-F-0001` and
|
||
recorded inside it as visible-but-unfiled;
|
||
- the unverified tenant boundary — no consumer's tenant boundary is verified
|
||
anywhere, Broken Object Level Authorization, currently open question 3 in an
|
||
unratified draft;
|
||
- the absent noisy-neighbour characterisation;
|
||
- the erasure-versus-audit tension.
|
||
|
||
Each becomes a finding with a full grade, or a recorded note with the reason it
|
||
is below the floor. "Still waiting on the precedent" stops being available as an
|
||
answer once T01 lands.
|
||
|
||
The last three live in NetKingdom's *Tenancy Posture*, a draft, and filing them
|
||
here does not amend it. A finding may say a standard is wrong; it cannot change
|
||
one.
|
||
|
||
### T08 — Nag
|
||
|
||
```task
|
||
id: RISK-WP-0001-T08
|
||
status: todo
|
||
priority: low
|
||
```
|
||
|
||
The smallest mechanism that makes silence visible: a check over the register
|
||
that reports findings past `review_by`, findings whose fix has not moved in the
|
||
interval T03 set, and any finding still carrying an `unset` field.
|
||
|
||
Report only. It writes nothing, escalates nothing on its own, and blocks
|
||
nothing. A human or the custodian acts on the output.
|
||
|
||
Runs from a `Makefile` target in this repo, in the same shape as the sibling
|
||
`policy-nexus` `make check`.
|
||
|
||
## Sequencing
|
||
|
||
T01 first — the floor it sets is what T02, T04, T05 and T07 lean on.
|
||
T02 and T03 can run in parallel after it; T03 wants a custodian answer and
|
||
should be raised early so the wait is not on the critical path.
|
||
T04 after T01. T05 after T04, since the index needs the review fields.
|
||
T06 after T01–T04. T07 after T01 and T06's precedent. T08 last, after T05.
|
||
|
||
Do not hold T06 for T07. Grading what is already filed is the point; deciding
|
||
what else to file is the follow-on.
|
||
|
||
## Risks
|
||
|
||
**The instruments become a standard.** A severity scale that reads like canon
|
||
invites arguments about the scale instead of about the risk. Mitigation: each
|
||
document states it is this repo's judgement instrument, revisable by this repo,
|
||
and cites the finding that forced it.
|
||
|
||
**Grading becomes re-investigation.** The three findings are well-evidenced by
|
||
their reporters. Mitigation: T06 scores what is in the file and asks the owner
|
||
where the file is silent; it does not re-derive the defect.
|
||
|
||
**The escalation rule is written and never adopted.** Mitigation: T03 is not
|
||
done until the custodian has ruled on it. An unadopted rule is worse than an
|
||
unwritten one, because it looks like coverage.
|
||
|
||
**Automation arrives before judgement and freezes a bad scale.** Mitigation:
|
||
T08 is last, is report-only, and has no authority to change a field.
|
||
|
||
**The register grows past readability while nobody notices.** Mitigation: T05
|
||
treats index length as a signal, and T07's floor is the instrument that keeps
|
||
notes out.
|
||
|
||
## Residuals
|
||
|
||
- Publication of these instruments through `policy-nexus` is a later workplan,
|
||
and only if T02 concludes anything here should be public.
|
||
- Regulatory intake — the second half of this repo's remit — is untouched here.
|
||
It needs its own workplan and its own retention rule; `INTENT.md` records that
|
||
regulation was previously "consulted and discarded", which is a different
|
||
failure from the one this workplan addresses.
|
||
- Routing mechanics between this register and owning repos are done by hand at
|
||
three findings. If the register reaches a size where hand-routing slips, that
|
||
is the trigger for a routing workplan, not for widening T08.
|