risk-nexus/workplans/RISK-WP-0005-close-the-intent-gaps.md
tegwick a05ca6822b RISK-WP-0005 finished: the seven gaps closed
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>
2026-08-21 08:34:30 +02:00

264 lines
13 KiB
Markdown

---
id: RISK-WP-0005
type: workplan
title: "Close the gaps between what INTENT claims and what the register can actually do"
domain: infotech
repo: risk-nexus
status: finished
owner: the-custodian
topic_slug: risk-nexus
created: "2026-08-21"
updated: "2026-08-21"
depends_on_workplans:
- RISK-WP-0001
- RISK-WP-0004
---
# RISK-WP-0005 — close the INTENT gaps
## Goal
`history/2026-08-21-intent-gap-analysis.md` compared what `INTENT.md` claims
against what four days of building actually produced. Five of six ownership
claims hold. Seven gaps do not.
Done means: the register no longer reports anything it cannot see, no longer
claims a surface it does not have, and the two intake paths `INTENT.md` names
but has never had — incident and external report — exist.
## The honest framing
Every task here exists because the register failed one of its own tests, not
because someone imagined an improvement. Two are uncomfortable enough to state
plainly at the top:
- **`fix_tracking` is a string nobody reads.** The register claims to track
remediation and does not. An owner who goes quiet and a fix that goes quiet
are currently indistinguishable.
- **A regulation that applies was found *after* it was needed**, by about
nineteen months. The policy catalogue fixes the next one; nothing fixes that
one.
## Tasks
### T01 — Make remediation tracking track
```task
id: RISK-WP-0005-T01
status: done
priority: high
```
Gap 2, and first because it is the only place the register currently reports
something it cannot see.
`fix_tracking` holds ids like `FLEX-WP-0015-T02`. The hub knows whether those
moved. Read them: resolve each `fix_tracking` against the hub, record the
status and the date it last changed, and surface it in `make check`.
Then separate the two silences that currently look alike:
- **The register has not checked** — the cadence rung already says this.
- **The fix has not moved** — its own timer, independent of whether anyone
checked, escalating on trigger 5 without needing a human to notice.
**Acceptance:** `make check` reports, per open finding, when its fix record
last changed. A finding whose fix has not moved in its stall window is listed
whether or not the register has been checking.
Where `fix_tracking` is `unset` (`RISK-F-0004`, `RISK-F-0006`, `RISK-F-0009`),
that absence is itself the report.
Completed 2026-08-21. `tools/fix_tracker.py`, behind `make fixes` and inside `make check`. Resolves `fix_tracking` against the owning repo's workplan **file** — task-level ids do not exist in the hub, and the file is the ADR-001 source of truth anyway — and uses the file's last commit date as the honest answer to "has this moved", independent of whether the register looked. Archived workplans are searched too, so a finished-and-filed fix does not read as missing.
**The first run found two things the register should have known.** `RISK-F-0005`: `AUDIT-WP-0008-T04` had read `done` since 2026-08-18 — the fix landed and this repo spent three days not knowing. Now `mitigated`, embargo lifted, `public`. `RISK-F-0002`: both tracked records were closed *before the finding was filed*`WARDEN-WP-0007` archived 2026-07-08, `FLEX-WP-0007` finished 2026-06-29, against a finding of 2026-08-18 naming `FLEX-WP-0007` as its blocker. Routed as a question to both owners rather than a conclusion.
Four findings carry no fix tracking at all, which the report now says out loud instead of leaving an empty field.
### T02 — An intake path for incidents and external reports
```task
id: RISK-WP-0005-T02
status: done
priority: high
```
Gap 1. `INTENT.md` claims intake "from any source: research, review, incident,
external report". Two of those four have no path at all.
Three pieces, and only the first is this repo's alone:
1. **Incident intake.** A finding that describes something happening *now*
rather than a latent defect. Needs: an entry shape, a tempo (the ladder
already starts at `instant`, which is most of it), and a link from an
incident to `RISK-POL-0005` — breach notification runs on a 72-hour clock
that nothing currently starts.
2. **External report.** There is no address an outsider could use and no
`security.txt` anywhere in the estate. Where that address lives is not this
repo's call — route the question to `the-custodian` and `policy-nexus`,
since it is a published surface.
3. **Severity for a live incident.** The scale assumes a defect nobody is
exercising. Say what changes when someone is.
**Non-goal:** a bug bounty, a disclosure programme, or any commitment to
outside parties. The ask is a route, not a promise.
Completed 2026-08-21. `docs/method/intake.md`. Incident intake: file first and grade within the hour, `first_observed` because obligations run from it rather than from the grade, `instant` cadence until it is over, and **escalation immediately rather than batched** — the batching rule protects the operator's attention and a 72-hour notification clock outranks that. `RISK-POL-0005` is wired to `first_observed`, which is what starts the clock. Severity gained a live-incident section: `L4` is what that band was always for.
External report: **no address exists anywhere in the estate** and creating one is not this repo's call. Routed to `the-custodian` and `policy-nexus` with a concrete proposal — RFC 9116 `security.txt` on the published surface, reports routed here, `reported_by: external` — and an explicit non-goal: a route in, not a bounty, a timeline or safe harbour.
### T03 — Define the production transition
```task
id: RISK-WP-0005-T03
status: done
priority: high
```
Gap 4, and cheap. Five findings owe a re-score at "the production transition"
and `RISK-F-0007`'s acceptance **expires** there.
Nobody has defined the event, nobody has been named to declare it, and nothing
outside this repo knows the obligation exists. An acceptance that expires on an
undefined event expires on nobody's calendar.
Settle: what counts as the transition (first real user? first real tenant data?
a declaration?), who declares it, and how this register hears about it. Then
tell the repos that carry re-score obligations.
Custodian decision on the definition; the plumbing is ours.
Completed 2026-08-21 as a proposal; the definition is the custodian's. `docs/method/production-transition.md` defines it by **what is held rather than what was announced**: the first moment any system holds, processes or decides about real external data. Which means it can happen by accident — one real signup, one migrated contact list — and cannot be reversed by deleting the data afterwards.
Declared by the custodian, never by this register: a risk register that unilaterally declares the estate to be in production has appointed itself. What the register does is notice and ask. Five re-scores, two acceptances ending and six dormant policies activating are listed as what fires on the day.
### T04 — Stop claiming a surface we do not have
```task
id: RISK-WP-0005-T04
status: done
priority: medium
```
Gap 5. `README.md` and `INTENT.md` both say this repo serves
`risk.coulomb.social`. It serves nothing.
Correct the README to say what is true — that publication runs through
`policy-nexus` and two documents are pending an address. `INTENT.md` is the
repo's constitutional document and its amendment is the custodian's; propose
the wording rather than editing it.
Small, and exactly the class of claim this register grades other repos down
for: a stated control that is not there.
Completed 2026-08-21. `README.md` now says the repo serves nothing yet and that publication runs through `policy-nexus`, with three documents waiting for an address. `INTENT.md` is the constitutional document and its amendment is the custodian's — the wording is proposed to them rather than edited here.
### T05 — Give escalation a delivery guarantee
```task
id: RISK-WP-0005-T05
status: done
priority: medium
```
Gap 6. An escalation goes to an inbox and is said aloud in whatever session is
running. If nobody reads it, it is indistinguishable from one never sent —
which is the failure this register committed on 2026-08-19 and fixed **for
itself** with `hourly-register-inbox-watch`, without applying the same fix to
the path that matters more.
Needs: an acknowledgement state on the escalation (sent → seen → answered), and
a re-raise once, per the adopted rule's "raised again once" clause. Not a
weekly nag; the rule is explicit that repetition until someone answers is how
the operator becomes the queue.
Completed 2026-08-21. Escalation carries a delivery state — `sent → seen → answered` — with `escalation_sent` beside it, and `make check` reports how long each has gone unacknowledged. At seven days it says so and the escalation is raised **once** more, per the adopted rule, after which the default applies and is recorded. This is the fix the register applied to its own inbox on 2026-08-19 and had not applied to the path that matters more.
### T06 — Make a lie about stability impossible to miss
```task
id: RISK-WP-0005-T06
status: done
priority: medium
```
Gap 7. If nothing performs checks, every finding still climbs nowhere and sits
at `instant` — but the reverse case is the dangerous one: a `1q` rung means
"stable for a quarter" and "nobody looked for a quarter" and those read
identically.
Two cheap defences:
- **Attribution.** Record who or what performed each check. A rung earned by
nobody should be visible as such.
- **A register heartbeat.** If no check has been recorded anywhere in the
register for longer than the shortest rung by some margin, `make check` says
so first, before anything else.
Completed 2026-08-21. Two defences against the rung lying: `checked_by` recorded on every check (`RISK_CHECKED_BY`, so an agent names itself rather than inheriting a unix login), and a **heartbeat** that prints before anything else in `make check` when nothing anywhere in the register has been checked for two days. A `1q` rung means "stable for a quarter" and "nobody looked for a quarter", and the heartbeat is what separates them.
### T07 — A coverage model
```task
id: RISK-WP-0005-T07
status: done
priority: low
```
Gap 3: the largest, the most expensive, and the one that decides whether
"nobody is surprised" is a claim this repo can ever make.
The register knows what was reported. It has no view of what was never looked
at, so a system with zero findings is indistinguishable from a system nobody
assessed — while `RISK-N-0003` records that every repo which *has* examined its
own boundary this month found a defect.
Start minimal: a list of systems from the hub, a last-assessed date per system,
and the count of systems that have never been. Not an assessment programme, not
a maturity model, and not this repo assessing anyone.
**If this task grows past a page it becomes its own workplan.** Coverage is a
different problem from triage and should not quietly absorb this one.
Completed 2026-08-21, minimal and within its escape clause. `tools/coverage.py`, behind `make coverage`, counts what the register has heard from. First run: **7 of 117 registered repos have ever appeared in a finding; 110 never have.**
That is not 110 clean repos and the report says so — it is 110 repos the register knows nothing about, against an estate whose own evidence is that looking tends to find something. Recorded as an update to `RISK-N-0003` rather than promoted: there is still no owner for estate-wide detection and still no defect to route. What changed is that the gap has a size, which is the difference between an argument and a measurement.
## Non-goals
- **No monitoring.** `RISK-N-0003` stands as a note. A register that grows
probes becomes a second engineering team, which `INTENT.md` names.
- **No blocking.** Build mode: a finding is information.
- **No commitment to outside parties.** T02 builds a route in, not a promise
out.
- **No new instruments.** The four exist and have survived use. This workplan
makes them honest, not larger.
## Sequencing
T01 first — it is the only gap where the register misreports. T02 and T03 next
and in parallel; both are cheap and T03 is mostly a decision. T04 any time.
T05 and T06 after T01, since both touch the same reporting surface. T07 last,
and possibly not here at all.
## Risks
**The register spends another workplan on itself.** Seven tasks, none of which
fix a defect in the estate. Mitigation: T01, T02 and T03 all close claims
`INTENT.md` already makes, which is repayment rather than expansion — and the
same test as last time applies: if the next round produces no such items, this
kind of workplan should stop.
**T07 swallows the workplan.** Mitigation: it is last, explicitly minimal, and
carries its own escape clause.
**Incident intake invites a promise.** Mitigation: T02's non-goal is stated in
the task, not only here.
## Residuals
- The nineteen-month-late obligations are not recoverable and are recorded in
the history note rather than converted into a task.
- Whether findings should be reported to the estate by anything other than
their owners — monitoring, coverage sweeps — stays a note until evidence
makes it a finding.