Assistant: claude-code Assistant-Model: opus Assistant-Process: 2583210@bnt-lap001 Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
13 KiB
| id | type | title | domain | repo | status | owner | topic_slug | created | updated | depends_on_workplans | state_hub_workstream_id | ||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| RISK-WP-0005 | workplan | Close the gaps between what INTENT claims and what the register can actually do | infotech | risk-nexus | finished | the-custodian | risk-nexus | 2026-08-21 | 2026-08-21 |
|
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_trackingis 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
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
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:
- 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 toRISK-POL-0005— breach notification runs on a 72-hour clock that nothing currently starts. - External report. There is no address an outsider could use and no
security.txtanywhere in the estate. Where that address lives is not this repo's call — route the question tothe-custodianandpolicy-nexus, since it is a published surface. - 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
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
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
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
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 checksays 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
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-0003stands as a note. A register that grows probes becomes a second engineering team, whichINTENT.mdnames. - 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.