diff --git a/.claude/rules/finding-routing.md b/.claude/rules/finding-routing.md new file mode 100644 index 0000000..06a6ae0 --- /dev/null +++ b/.claude/rules/finding-routing.md @@ -0,0 +1,94 @@ +# Finding routing (risk-nexus) and policy publication (policy-nexus) + +Two estate repos exist that did not when most of ops-warden's practices were +written. Both are owned by `the-custodian` and both are **downstream by +construction** — the same rule ops-warden's own catalog lives under. + +| Repo | Owns | ops-warden's relationship | +| --- | --- | --- | +| `risk-nexus` | Findings, severity, disclosure timing, escalation, regulatory intake. Serves `risk.coulomb.social` | **Route findings to it.** It does not fix; ops-warden fixes what ops-warden owns | +| `policy-nexus` | Publication of canon and ADRs at permanent addresses. Serves `policy.coulomb.social` | Source repo. It publishes; it never writes back | + +## When a session discovers or receives a defect, route it + +**A design question is not a finding. A defect is.** The distinction matters +because ops-warden receives both through the same channel — the State Hub inbox. + +This was gotten wrong on 2026-08-17. `flex-auth` reported directly to ops-warden +that `/v1/check` authenticates no caller — a live authorization bypass in the +service ops-warden's own pre-sign gate consults. ops-warden answered the design +question well and wrote the recommendation into +`wiki/NetKingdomSecurityMap.md`. It did not route the finding. `rapp-postgres` +filed it as `RISK-F-0001`, which is why that record reads +`reported_via: rapp-postgres` and not `ops-warden`, despite ops-warden being a +first-hand recipient and the affected PEP. + +The failure mode is exactly the one `risk-nexus/INTENT.md` names: *"findings +landed in whichever document was open."* A wiki section answers the question; it +does not carry a severity, an owner, a date, or a review that fires when nobody +looks. + +**So: when an inbound message or a session turns up a defect — in any repo — +answer it *and* route it.** They are not alternatives. + +### How to route + +Write the finding file into `~/risk-nexus/findings/` following +`RISK-F-0001`/`RISK-F-0002`, and commit it there. This is the established +pattern: a repo routes a finding by writing the record. + +Leave `severity`, `disclosure`, and `escalation` **unset**. They are +`risk-nexus`'s to set, not the reporter's. The reporter says what is true; that +repo says how bad it is and who hears about it. State exposure only as far as +you can support it — do not infer a mitigating control (a NetworkPolicy, a +deployment flag) on a system you do not own; say it should be verified. + +### What does not go there + +`risk-nexus/INTENT.md` is explicit that a register nobody can read is worse than +none: *"if a finding would not change anyone's decision, it is a note, not a +risk."* + +The **delegation register is not a findings feed.** `warden route gaps` lists +interim lanes with an intended owner, a blocker and a review date — that is +already tracked, already legible, and already ops-warden's. Do not bulk-file it. +What goes to `risk-nexus` from ops-warden is a defect or an exposure, not a +known gap that is being worked under a workplan. + +Also re-read a *blocker* before trusting it. A blocker is a claim about the +world at a date; `RISK-F-0001` invalidated one of ops-warden's in a day and +nothing would have re-checked it. + +## Escalation: ops-warden already solved this shape + +`risk-nexus` carries an unwritten escalation duty — deciding what reaches the +operator personally rather than sitting in a register — and says the rule +*"must be written down rather than exercised by instinct"*. + +ops-warden shipped that classifier for the credential domain in WP-0029. +`warden plan ""` returns `autonomous` / `founder_required` / `unroutable`, +and when it escalates it returns a **typed act** (`approve`, `login`, +`provision`) plus the `reasons` that produced the verdict, with `warden desk` as +the surface that actually executes the act. The transferable design properties: + +- escalation is decided by **properties of the thing** (lane type, status, + request signals), not by the assessor's judgement in the moment +- every verdict carries its `reasons`, so the rule is auditable after the fact +- there is a typed act, so "needs the operator" says *what the operator does* +- there is a real surface for the act, so escalation is not just a flag + +Offer this rather than let a second, incompatible escalation vocabulary grow. +Do not implement it for them — routing work is theirs to own. + +## ADR gap (open, not yet resolved) + +`policy-nexus` publishes canon and ADRs — roughly 68 ADRs across 18 repos. +**ops-warden has none**, and it carries binding rules that govern other repos' +behaviour: the no-double-source catalog rule (CI-enforced), conduit-not-broker, +interim-by-default with a named owner, the agent read-boundary on `risk: high` +lanes. These live in wiki prose and workplan files, so they are unaddressable +and unpublishable — a reader outside ops-warden cannot cite them or tell whether +they are current. + +Do not create an ADR corpus unilaterally; it is a structural decision for the +operator. Raise it when ops-warden next records a rule of that kind. diff --git a/CLAUDE.md b/CLAUDE.md index 243f076..a812bb4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -9,4 +9,5 @@ @.claude/rules/architecture.md @.claude/rules/repo-boundary.md @.claude/rules/credential-routing.md +@.claude/rules/finding-routing.md @.claude/rules/agents.md