Assistant: claude-code Assistant-Model: opus Assistant-Process: 2583210@bnt-lap001 Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
272 lines
13 KiB
Markdown
272 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
|
|
state_hub_workstream_id: "bdcf890a-c870-502c-9ca8-dbb782faa3da"
|
|
---
|
|
|
|
# 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
|
|
state_hub_task_id: "6e8bd46e-fe49-5df2-878d-6e656ce2cd28"
|
|
```
|
|
|
|
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
|
|
state_hub_task_id: "a3152d63-5364-5c2f-a5da-31b39834c5a1"
|
|
```
|
|
|
|
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
|
|
state_hub_task_id: "9f308660-a5bd-5f2b-9865-62d9b5a316ad"
|
|
```
|
|
|
|
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
|
|
state_hub_task_id: "e8997412-13de-5cb7-a819-06ec234fdfc9"
|
|
```
|
|
|
|
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
|
|
state_hub_task_id: "30dbcabd-7217-5997-9386-a5c39a9ccd60"
|
|
```
|
|
|
|
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
|
|
state_hub_task_id: "a2319f77-3cbc-56dd-ab75-f1792c2ea9f9"
|
|
```
|
|
|
|
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
|
|
state_hub_task_id: "b0798b6c-96d4-539f-9edc-fb1fd72fe9fb"
|
|
```
|
|
|
|
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.
|