T01 fix tracking now reads the owner's workplan file and found two findings the register should have known about. T02 incident and external report intake, the latter routed since the address is not ours to create. T03 the production transition defined by what is held rather than what was announced. T04 the README stops claiming a surface. T05 escalation carries a delivery state and is raised once when unacknowledged. T06 checked_by and a heartbeat, so a 1q rung cannot silently mean nobody looked. T07 coverage: 7 of 117 repos have ever appeared in a finding. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
216 lines
9.6 KiB
Markdown
216 lines
9.6 KiB
Markdown
---
|
|
id: RISK-METHOD-ESCALATION
|
|
type: method
|
|
title: "Escalation: what reaches the operator personally"
|
|
status: adopted
|
|
owner: the-custodian
|
|
drafted_by: risk-nexus
|
|
drafted: "2026-08-19"
|
|
adopted: "2026-08-20"
|
|
adopted_by: the-custodian
|
|
workplan: RISK-WP-0001-T03
|
|
review_interval: 3m
|
|
disclosure: restricted
|
|
restricted_reason: "names the operator's spend thresholds and describes when the operator personally is interrupted"
|
|
---
|
|
|
|
# Escalation
|
|
|
|
`INTENT.md` gives `the-custodian` the duty of deciding what must reach the
|
|
operator personally rather than sitting in a register, and says the rule is not
|
|
yet written. This is the rule, drafted by `risk-nexus`.
|
|
|
|
**Status: `adopted`, 2026-08-20, as written.** The thresholds in trigger 3 —
|
|
€50/month recurring, €500 one-off — were this repo's proposal and are now the
|
|
operator's numbers. They bound nothing yet: the one spend decision taken so far
|
|
(`RISK-F-0006`) was approved without a figure being named.
|
|
|
|
The rule governed four escalations before it was adopted, which is the state
|
|
`RISK-WP-0001-T03` refused to leave open — a draft that quietly governs is
|
|
worse than either an adopted rule or no rule, because it looks like coverage
|
|
while nobody has agreed to it.
|
|
|
|
Getting this wrong in either direction is a failure: escalating everything
|
|
makes the operator the queue, escalating nothing makes the register a place
|
|
where serious things go quiet.
|
|
|
|
## What escalation is
|
|
|
|
A message to the operator personally — inbox message to `the-custodian`, and
|
|
said out loud in whatever session is running — containing exactly four things:
|
|
|
|
1. the finding id and one sentence of what is true;
|
|
2. the decision being asked for;
|
|
3. what happens if no answer comes;
|
|
4. by when.
|
|
|
|
Point 2 is a **typed act**, not a topic: `approve` (spend, a target, a plan),
|
|
`rule` (a question only they can settle), `assign` (name an owner), or
|
|
`accept` (record that the estate knowingly carries it, and for how long).
|
|
Naming the act is what stops an escalation from becoming a notification —
|
|
`INTENT.md`'s candidate triggers are conditions, and a condition without an act
|
|
tells the operator something is wrong without telling them what they are being
|
|
asked to do.
|
|
|
|
The typed-act shape is `ops-warden`'s, offered on 2026-08-18 from their
|
|
`warden plan` classifier (`WARDEN-WP-0029`), which returns `autonomous |
|
|
founder_required | unroutable` plus the reasons that produced the verdict and
|
|
the act to perform. Two of its properties are adopted here: escalation is
|
|
decided by properties of the thing rather than the assessor's mood, and every
|
|
verdict carries its reasons so a misfire is visible afterwards. The vocabulary
|
|
is theirs; the design is deliberately not re-invented.
|
|
|
|
It is **not** a copy of the finding, not a status report, and not a request for
|
|
the operator to do the work. If the operator's answer would not change
|
|
anything, it was not an escalation.
|
|
|
|
The operator is expected to rule, or to defer explicitly with a date. Silence
|
|
is not resolution: an unanswered escalation past its date goes back into the
|
|
register as an open item on this repo, visible in `REGISTER.md`, and is raised
|
|
again once. It is never quietly dropped, and it is never repeated weekly until
|
|
someone answers to make it stop.
|
|
|
|
## The triggers
|
|
|
|
Each of the five candidates from `INTENT.md` is adopted, dropped, or bounded.
|
|
A trigger without a threshold is not a rule.
|
|
|
|
### 1. Real tenant data — adopted, bounded
|
|
|
|
Escalate when a finding exposes real data belonging to a real counterparty, or
|
|
**the decision that governs access to it**, while live and unfixed.
|
|
|
|
The bound matters: `INTENT.md` asks whether governing the access counts as
|
|
exposing the data. It does. An authorization oracle that can be forged is not
|
|
one step removed from the data; it is the step. Test data and empty tenants do
|
|
not trigger it — the word is *real*.
|
|
|
|
### 2. Legal or regulatory obligation — adopted, unbounded
|
|
|
|
Escalate when a finding creates or reveals an obligation with an outside
|
|
counterparty: a notification duty, a retention or erasure requirement, a
|
|
contractual commitment, an in-scope determination under a regime.
|
|
|
|
No threshold. The estate cannot decide unilaterally that an obligation is
|
|
small, and this repo is explicitly not the place where legal advice is given.
|
|
|
|
### 3. Spend — adopted, bounded
|
|
|
|
Escalate when remediation needs money that is not already committed:
|
|
**recurring above €50/month, or one-off above €500.**
|
|
|
|
Below those, the owning repo decides and records it. The numbers are a
|
|
starting proposal from this repo; the operator owns them and should overwrite
|
|
them on adoption if they are wrong.
|
|
|
|
### 4. Ownership disagreement — adopted, bounded by one exchange
|
|
|
|
Escalate when two repos disagree about who owns a fix **and one routing
|
|
exchange has already failed to settle it.**
|
|
|
|
Disagreement itself is normal and is the register's job to route. What needs
|
|
the operator is a *stuck* disagreement, because only the operator can assign
|
|
work across repos that will not take it. One exchange, then escalate — not
|
|
three, and not zero.
|
|
|
|
### 5. Stalled remediation — adopted, bounded by the bottom rung
|
|
|
|
Escalate when a finding has sat at the **`instant` rung of the cadence ladder
|
|
for more than fourteen days** (`docs/method/review.md`).
|
|
|
|
The bottom rung means one of two things: every check keeps finding something
|
|
wrong, or no check is happening. Fourteen days of either is a stall, and the
|
|
escalation does not have to know which — the operator will.
|
|
|
|
This replaces the original severity-keyed interval. It is strictly better: a
|
|
`medium` finding that keeps resetting is stalling visibly, and the old rule
|
|
would have waited 180 days to say so.
|
|
|
|
`low` findings are not exempt. Under the ladder, severity does not set cadence
|
|
at all, so there is no rung a `low` finding sits on that a `critical` one does
|
|
not.
|
|
|
|
## What does not escalate
|
|
|
|
Stated so the rule bites in both directions.
|
|
|
|
- **Known, owned, and moving.** However bad. A `critical` finding with an
|
|
active fix and a responsive owner is register work.
|
|
- **Severity alone.** There is deliberately no "escalate everything
|
|
`critical`" trigger. Severity drives review cadence, not the operator's
|
|
attention. `RISK-F-0002` argued its own case for not escalating and was
|
|
right on triggers 1-5; it reaches the operator only through trigger 6, and
|
|
only once.
|
|
- **The reporter asking for it.** A repo can flag that it thinks something
|
|
needs the operator. That is input, not a decision. This repo rules.
|
|
- **Anything this repo can decide itself.** Severity, disclosure, filing
|
|
shape, review dates. Asking the operator to confirm a judgement that is this
|
|
repo's to make is how the operator becomes the queue.
|
|
|
|
## Testing the rule against the register
|
|
|
|
The draft was tested against the first three findings before it was proposed
|
|
(`docs/rulings/2026-08-19-first-grading.md`) and then against the four filed
|
|
out of the backlog the same day
|
|
(`docs/rulings/2026-08-19-second-grading.md`).
|
|
|
|
| Finding | Escalates | Trigger |
|
|
| --- | --- | --- |
|
|
| `RISK-F-0001` flex-auth oracle | yes | 1 — governs access to tenant data |
|
|
| `RISK-F-0002` signing gate off | yes, once | 6 — ordering hazard, jointly with `RISK-F-0001` |
|
|
| `RISK-F-0003` ungraded lanes | no | known, owned, tracked, moving |
|
|
| `RISK-F-0004` tenant-engine reads | no | no real tenant data yet |
|
|
| `RISK-F-0005` audit-core reads | no | known, owned, tracked, moving |
|
|
| `RISK-F-0006` apps-pg no backup | yes | 3 — recurring spend nobody can self-authorise |
|
|
| `RISK-F-0007` unverified boundary | yes | 4 — estate-wide and unowned |
|
|
|
|
`RISK-F-0002` is the case worth reading: `ops-warden` judged it did not need
|
|
the operator, the register agrees on triggers 1-5, and it escalates anyway on
|
|
6. That disagreement is the reason the rule was worth writing down.
|
|
|
|
## The ratio, and what it would mean
|
|
|
|
Four of seven escalate. That is more than this rule should produce in steady
|
|
state, and it is not evidence the rule is loose — it is what a **first sweep**
|
|
looks like. Three of the four are the backlog: items that sat outside the
|
|
register precisely because nobody had decided them, and undecided items are
|
|
exactly the population that needs the person who can decide.
|
|
|
|
The test therefore applies to intake, not to sweeps:
|
|
|
|
> If more than one in three **newly reported** findings escalates over any
|
|
> rolling ninety days, the rule is wrong, not the register.
|
|
|
|
If that trips, the first suspects are triggers 3 and 4 — spend thresholds set
|
|
too low, and "unowned" being read where "not yet routed" is meant.
|
|
|
|
## Delivery is a state, not an act
|
|
|
|
`RISK-WP-0005-T05`. An escalation that nobody acknowledged is indistinguishable
|
|
from one never sent — which is precisely the failure this register committed
|
|
on 2026-08-19 and then fixed for its **own** inbox with an hourly watch, while
|
|
leaving the path that matters more unguarded.
|
|
|
|
So an escalation carries a state:
|
|
|
|
```yaml
|
|
escalation_status: pending-operator # sent | seen | answered | withdrawn
|
|
escalation_sent: "2026-08-19"
|
|
```
|
|
|
|
`make check` reports how long each has been unacknowledged. At seven days it
|
|
says so and the escalation is **raised once more** — once, per the rule above.
|
|
After that the default applies and is recorded. Repetition until someone
|
|
answers is how the operator becomes the queue, and silence that is recorded is
|
|
not the same as silence that is ignored.
|
|
|
|
## Escalations are batched
|
|
|
|
Four escalations are one conversation, not four interruptions. Open items go
|
|
to the operator together, in register order, each with its own decision and
|
|
its own default-if-no-answer. Escalating is not the same as escalating
|
|
separately, and a rule that produces four messages in an afternoon has made the
|
|
operator the queue by a different route.
|
|
|
|
`make check` lists everything awaiting an answer, so the batch is a report and
|
|
not somebody's recollection.
|