risk-nexus/docs/method/disclosure.md
tegwick f0db7c83ca RISK-WP-0002: findings publish whole; method docs public except escalation
Operator ruled both. Findings publish as the file a reader gets —
including RISK-F-0001's record that this register graded it critical
while its fix notice sat unread. A summary would be a second document per
finding kept in sync by hand, and drift is the failure this repo most
distrusts; and a published register containing only other repos' defects
reads as an accusation, while one containing its own reads as a record.

Method docs public except escalation, which is restricted because it
names spend thresholds and describes when the operator personally is
interrupted — a map of where attention is scarce, needed by nobody
judging a finding.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 22:43:48 +02:00

144 lines
6.6 KiB
Markdown

---
id: RISK-METHOD-DISCLOSURE
type: method
title: "Disclosure: publish now, hold, or restrict"
status: adopted
owner: risk-nexus
adopted: "2026-08-19"
workplan: RISK-WP-0001-T02
review_interval: 6m
disclosure: public
revision: "adopted-1"
last_reviewed: "2026-08-20"
---
# Disclosure
Whether and when a finding is published. `policy-nexus` is the surface; this
document decides what it is handed.
## What disclosure is not
**A finding file in this repo is not a publication.** This repo is a private
checkout on a private forge. Holding a finding means not routing it to
`policy-nexus`; it does not mean hiding it from the estate, from the owning
repo, or from the operator. Every state below is fully visible internally.
## The states
| State | Meaning | Entry condition |
| --- | --- | --- |
| `public` | Published through `policy-nexus` now. | The finding is fixed, or reading it gives no one an advantage they do not already have. |
| `embargoed` | Held, with a stated condition that lifts it. | Live, unfixed, and the text would help someone reach the defect faster than they could without it. |
| `restricted` | Held with no expected lift. | Publication would remain harmful after the fix — third-party material, a named person, or a credential-shaped detail that survives remediation. |
There is no fourth state and no `unset` after grading. A finding whose
disclosure has not been decided is an ungraded finding.
## Embargo is a record, not a silence
`INTENT.md` requires the record that a delay was deliberate rather than a
document quietly going missing. An `embargoed` finding therefore carries:
```yaml
disclosure: embargoed
embargo_condition: "FLEX-WP-0015-T02 ships to production"
embargo_since: "2026-08-19"
embargo_review: "2026-08-26"
```
`embargo_condition` must be an event someone can observe, not a mood. "Until
it is safer" is not a condition. `embargo_review` follows the finding's
severity interval from `docs/method/review.md`; when it passes, the embargo is
re-decided, not extended by default.
An embargo that has outlived two consecutive reviews without its condition
moving is itself a finding — the remediation has stalled, and the hold is now
doing the work the fix was supposed to do.
## The build-mode deferral, re-taken
`INTENT.md` recorded controlled disclosure as deferred to production, reasoning
that build mode has no users to expose. `RISK-F-0001` arrived and tested it: a
live authorization bypass in the service every other service trusts, with
publish-or-forget as the only available choice.
**The deferral is narrowed, not kept and not abandoned.**
What was right about it: build mode does have no consumers to protect, and
building an embargo *mechanism* — timed release, staged notification,
coordinated disclosure with third parties — before there is anyone to
coordinate with would be machinery for its own sake.
What was wrong about it: it conflated the mechanism with the decision. The
argument for publishing in build mode is that there are no users to expose.
That argument says nothing about attackers, and `RISK-F-0001` is exactly the
class where the two come apart — the finding names an unauthenticated
decision surface and the service that carries it. Publishing that while it is
live helps precisely one kind of reader.
So the ruling is:
1. **Build-mode default stays publish.** Architecture, method, fixed findings,
and findings whose exposure is already bounded go out. The estate publishing
what it knows is wrong remains the norm and does not need a case made for it
each time.
2. **Live-and-reachable is the exception, and it exists now.** A finding that
is unfixed *and* whose text shortens the path to the defect is `embargoed`
until the fix lands. That is the missing middle `INTENT.md` said did not
exist. It costs one front-matter field and a line in `REGISTER.md`.
3. **The mechanism stays deferred.** No timed release, no coordinated
disclosure protocol, no notification tiers. Those wait for real users, as
originally reasoned. What is not deferred is the *decision*, because
`RISK-F-0001` demonstrated the decision is needed before the machinery is.
This is a decision of this repo, taken 2026-08-19 with `RISK-F-0001`,
`RISK-F-0002` and `RISK-F-0003` in hand rather than hypothetically. It is
revisable, and the production transition is the scheduled moment to revisit it.
## Test for "shortens the path"
Ask: does the finding tell a reader something that materially reduces the work
of reaching the defect, beyond what reading the repo would give them?
- A file path and line number in a private repo — no, that is already there.
- "This surface authenticates nobody, here is its cluster address" — yes.
- "These five named lanes vend real secret values without the boundary firing"
— yes.
- "This system had no backups configured" — no, once backups exist; yes, while
they do not, because it names when destruction is unrecoverable.
When the answer is genuinely unclear, embargo and re-decide at the review. The
cost of a wrong embargo is a delayed publication; the cost of a wrong publish
is not recoverable.
## Publication happens elsewhere
A `public` finding is handed to `policy-nexus` under its publication contract
and gets a permanent address there. This repo never serves it and never
edits it after handover; corrections go through the same route as the original.
## The standing route, when an embargo lifts
`RISK-WP-0002-T03`. Written down because publication will arrive in a trickle
as conditions clear, not as a batch, and a route improvised each time is a
route that eventually is not taken.
1. **The check that lifts the embargo records it.** `make checked` on the
finding, with the lift as the reason. An embargo lifting is never a clean
check — something moved.
2. **The finding gets publication front-matter**, in the shape `policy-nexus`
already requires of everyone: `owner`, `revision`, `last_reviewed`,
`review_interval`. No body rewrite.
3. **This repo asks `policy-nexus` for an entry**, giving `source_repo`,
`source_path`, a proposed `canonical_path` under `findings/<id>/<version>/`,
and a one-line subtitle. Addressing and permanence are theirs
(`POLICY-NEXUS-WP-0001`); this repo does not invent a scheme.
4. **`publication: published` is recorded back on the finding**, with the URL.
A finding that says `public` but has no address is a claim, not a
publication — the same class of error as a backup nobody has restored from.
The contract publishes **a file from the owning repo**, so what is handed over
is exactly what a reader gets. That makes the whole-versus-summary decision
(T01) a decision about what a finding *file* contains, not about how it is
rendered.