feat: publish Risk Nexus findings and methods
All checks were successful
Build and publish policy-nexus image / build-and-push (push) Successful in 1m10s

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a058f3-8ba0-7692-a042-9a870fc3d663
This commit is contained in:
tegwick 2026-09-01 01:56:46 +02:00
parent 4c8a7b9666
commit c1b60f322e
70 changed files with 3888 additions and 198 deletions

View file

@ -0,0 +1,238 @@
<!doctype html>
<html lang="en"><meta charset="utf-8">
<meta name="policy-source-revision" content="c5517c754bd84b0ebf47878ba0f26df0ecb3b4a4">
<meta name="policy-source-digest" content="a5e7b42043b0bb366add9bbc5f606e134ef5b0454532480203d5d87099296240">
<title>Waiting</title>
<style>
:root{
--paper:#EDEEF0; --surface:#F6F7F8; --surface-2:#E4E6E9;
--ink:#171D24; --ink-2:#4A5561; --ink-3:#737E8A;
--rule:#D3D7DC; --rule-strong:#B6BCC3;
--brass:#8A6A2E; --brass-soft:#EFE5CD; --brass-line:#C9AE74;
--clay:#8A3A2C; --clay-soft:#F2DFDA;
--l0:#DCE0E2; --l1:#B9C4C7; --l2:#8CA1A6; --l3:#567D84; --l4:#23555E;
--chip-fg:#F6F7F8;
--font-display:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",sans-serif;
--font-body:"Iowan Old Style","Palatino Linotype",Palatino,Georgia,serif;
--font-mono:ui-monospace,"SF Mono","Cascadia Code",Menlo,Consolas,monospace;
--measure:66ch;
}
@media (prefers-color-scheme:dark){
:root:not([data-theme="light"]){
--paper:#12161A; --surface:#191E24; --surface-2:#222831;
--ink:#E6E9EC; --ink-2:#A3ADB7; --ink-3:#78838E;
--rule:#2A3138; --rule-strong:#3B444D;
--brass:#C9A45C; --brass-soft:#33290F; --brass-line:#6B5426;
--clay:#D08A76; --clay-soft:#3A211B;
--l0:#262C32; --l1:#35424A; --l2:#4A626B; --l3:#6A939D; --l4:#97C4CD;
--chip-fg:#12161A;
}
}
:root[data-theme="dark"]{
--paper:#12161A; --surface:#191E24; --surface-2:#222831;
--ink:#E6E9EC; --ink-2:#A3ADB7; --ink-3:#78838E;
--rule:#2A3138; --rule-strong:#3B444D;
--brass:#C9A45C; --brass-soft:#33290F; --brass-line:#6B5426;
--clay:#D08A76; --clay-soft:#3A211B;
--l0:#262C32; --l1:#35424A; --l2:#4A626B; --l3:#6A939D; --l4:#97C4CD;
--chip-fg:#12161A;
}
*{box-sizing:border-box}
body{
margin:0; background:var(--paper); color:var(--ink);
font-family:var(--font-body); font-size:17px; line-height:1.62;
-webkit-font-smoothing:antialiased;
}
.wrap{max-width:1180px;margin:0 auto;padding:0 24px 96px}
.layout{display:grid;grid-template-columns:180px minmax(0,1fr);gap:56px;align-items:start}
@media (max-width:960px){.layout{grid-template-columns:1fr;gap:0}.rail{display:none}}
/* ---------- rail ---------- */
.rail{position:sticky;top:28px;padding-top:8px;font-family:var(--font-display);font-size:12px;line-height:1.5}
.rail ol{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:7px}
.rail a{color:var(--ink-3);text-decoration:none;display:flex;gap:9px}
.rail a:hover,.rail a:focus-visible{color:var(--brass)}
.rail .n{font-family:var(--font-mono);font-size:10px;color:var(--rule-strong);min-width:16px;padding-top:1px}
.rail .grp{margin-top:14px;font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--rule-strong)}
/* ---------- header ---------- */
header{padding:64px 0 40px;border-bottom:2px solid var(--ink);margin-bottom:44px}
.eyebrow{font-family:var(--font-mono);font-size:11.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);display:flex;flex-wrap:wrap;gap:14px;margin-bottom:22px}
.eyebrow .stat{color:var(--clay)}
h1{font-family:var(--font-display);font-weight:800;letter-spacing:-.035em;line-height:.94;font-size:clamp(46px,9vw,92px);margin:0 0 6px;text-wrap:balance}
.sub{font-family:var(--font-display);font-weight:500;font-size:clamp(16px,2.4vw,21px);letter-spacing:-.01em;color:var(--ink-2);margin:0 0 30px;max-width:34ch;line-height:1.3}
.metagrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:20px 28px;border-top:1px solid var(--rule);padding-top:20px}
.metagrid dt{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);margin-bottom:5px}
.metagrid dd{margin:0;font-family:var(--font-display);font-size:13.5px;line-height:1.45;color:var(--ink)}
/* ---------- typography ---------- */
section{margin-bottom:60px;scroll-margin-top:24px}
h2{font-family:var(--font-display);font-weight:750;letter-spacing:-.022em;font-size:clamp(24px,3.4vw,31px);line-height:1.12;margin:0 0 18px;text-wrap:balance;display:flex;gap:14px;align-items:baseline}
h2 .sn{font-family:var(--font-mono);font-size:12px;font-weight:400;color:var(--brass);letter-spacing:.06em;flex:none;padding-top:2px}
h3{font-family:var(--font-display);font-weight:700;font-size:16px;letter-spacing:-.008em;margin:34px 0 10px;color:var(--ink)}
p{margin:0 0 15px;max-width:var(--measure)}
ul,ol{max-width:var(--measure);margin:0 0 15px;padding-left:20px}
li{margin-bottom:7px}
strong{font-weight:600}
em{font-style:italic}
code{font-family:var(--font-mono);font-size:.855em;background:var(--surface-2);padding:1px 5px;border-radius:2px}
a{color:var(--brass)}
.lede{font-size:19px;line-height:1.55;color:var(--ink-2);max-width:60ch}
/* ---------- devices ---------- */
.callout{border-left:3px solid var(--brass);background:var(--brass-soft);padding:18px 22px;margin:0 0 24px;max-width:var(--measure)}
.callout p:last-child{margin-bottom:0}
.callout .lbl{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--brass);display:block;margin-bottom:8px}
.rule-quote{border-top:2px solid var(--ink);border-bottom:2px solid var(--ink);padding:26px 0;margin:28px 0;max-width:var(--measure)}
.rule-quote p{font-family:var(--font-display);font-weight:600;font-size:19px;line-height:1.38;letter-spacing:-.014em;margin:0;text-wrap:balance}
.hard{border-left:3px solid var(--clay);background:var(--clay-soft);padding:18px 22px;margin:0 0 24px;max-width:var(--measure)}
.hard .lbl{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--clay);display:block;margin-bottom:8px}
.hard p:last-child{margin-bottom:0}
.dec{font-family:var(--font-mono);font-size:10.5px;letter-spacing:.08em;color:var(--brass);text-transform:uppercase}
.vec{font-family:var(--font-mono);font-size:.9em;font-weight:600;background:var(--surface-2);padding:2px 7px;border-radius:2px;white-space:nowrap;letter-spacing:.04em}
/* ---------- tables ---------- */
.scroll{overflow-x:auto;margin:0 0 24px;-webkit-overflow-scrolling:touch}
table{border-collapse:collapse;width:100%;min-width:520px;font-family:var(--font-display);font-size:13.5px;line-height:1.45}
th{text-align:left;font-family:var(--font-mono);font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);font-weight:400;padding:0 16px 8px 0;border-bottom:1px solid var(--rule-strong);vertical-align:bottom}
td{padding:11px 16px 11px 0;border-bottom:1px solid var(--rule);vertical-align:top;color:var(--ink-2)}
td:first-child{color:var(--ink);font-weight:600}
tbody tr:last-child td{border-bottom:none}
.lvl{font-family:var(--font-mono);font-weight:600;font-size:12px;letter-spacing:.04em;color:var(--ink)}
/* ---------- ladders ---------- */
.breakout{margin:34px 0 40px}
.bhead{display:flex;justify-content:space-between;align-items:baseline;gap:20px;border-bottom:1px solid var(--rule-strong);padding-bottom:9px;margin-bottom:22px;flex-wrap:wrap}
.bhead h3{margin:0;font-size:13px;letter-spacing:.1em;text-transform:uppercase;font-family:var(--font-mono);font-weight:400;color:var(--ink-3)}
.bhead .note{font-family:var(--font-display);font-size:12.5px;color:var(--ink-3)}
.ladders{display:grid;gap:26px}
.ladder{display:grid;grid-template-columns:126px minmax(0,1fr);gap:18px;align-items:start}
@media (max-width:700px){.ladder{grid-template-columns:1fr;gap:10px}}
.ladder .pname{font-family:var(--font-display);font-weight:700;font-size:14px;letter-spacing:-.01em;padding-top:2px}
.ladder .pname span{display:block;font-family:var(--font-mono);font-size:10px;font-weight:400;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);margin-top:3px}
.rungs{display:grid;gap:3px;grid-template-columns:repeat(5,minmax(0,1fr))}
@media (max-width:700px){.rungs{grid-template-columns:repeat(2,minmax(0,1fr))}}
.rung{padding:9px 10px 11px;background:var(--surface);border-top:4px solid var(--l0);min-width:0}
.rung.r1{border-top-color:var(--l1)} .rung.r2{border-top-color:var(--l2)}
.rung.r3{border-top-color:var(--l3)} .rung.r4{border-top-color:var(--l4)}
.rung .code{font-family:var(--font-mono);font-size:11px;font-weight:600;letter-spacing:.06em;color:var(--ink);display:block;margin-bottom:4px}
.rung .txt{font-family:var(--font-display);font-size:11.5px;line-height:1.34;color:var(--ink-2);display:block}
.rung.na{opacity:.42}
/* ---------- matrix ---------- */
.matrix-shell{display:grid;grid-template-columns:auto minmax(0,1fr);gap:12px;align-items:stretch;margin-bottom:14px}
.ylab{writing-mode:vertical-rl;transform:rotate(180deg);font-family:var(--font-mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);text-align:center;padding-bottom:22px}
.mgrid{display:grid;grid-template-columns:34px repeat(5,minmax(0,1fr));gap:3px}
.mcell{background:var(--surface);min-height:60px;padding:6px;display:flex;flex-direction:column;justify-content:flex-end;gap:4px;min-width:0}
.mcell.tint1{background:color-mix(in srgb,var(--l1) 26%,var(--surface))}
.mcell.tint2{background:color-mix(in srgb,var(--l2) 26%,var(--surface))}
.mcell.tint3{background:color-mix(in srgb,var(--l3) 24%,var(--surface))}
.mcell.tint4{background:color-mix(in srgb,var(--l4) 22%,var(--surface))}
.mcell.void{background:repeating-linear-gradient(135deg,transparent,transparent 5px,var(--rule) 5px,var(--rule) 6px);opacity:.55}
.rlab,.clab{font-family:var(--font-mono);font-size:10px;font-weight:600;letter-spacing:.05em;color:var(--ink-3);display:flex;align-items:center;justify-content:center}
.rlab{min-height:60px}
.clab{padding-top:7px;min-height:22px}
.pin{font-family:var(--font-mono);font-size:9.5px;font-weight:600;letter-spacing:.02em;background:var(--ink);color:var(--paper);padding:2px 5px;border-radius:2px;line-height:1.3;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pin.ghost{background:transparent;color:var(--ink-2);border:1px dashed var(--rule-strong)}
.mnote{display:flex;gap:22px;flex-wrap:wrap;font-family:var(--font-display);font-size:12px;color:var(--ink-3);padding-top:6px}
.mnote .k{display:flex;align-items:center;gap:7px}
.sw{width:13px;height:13px;flex:none;background:var(--ink)}
.sw.g{background:transparent;border:1px dashed var(--rule-strong)}
.sw.v{background:repeating-linear-gradient(135deg,transparent,transparent 4px,var(--rule) 4px,var(--rule) 5px);border:1px solid var(--rule)}
@media (max-width:640px){
.mgrid{grid-template-columns:28px repeat(5,minmax(0,1fr))}
.mcell{min-height:52px;padding:4px}
.pin{font-size:8px;padding:1px 3px}
.rlab{min-height:52px}
}
/* ---------- methodology ---------- */
.verbs{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:2px;background:var(--rule);border:1px solid var(--rule)}
.verb{background:var(--surface);padding:18px 18px 20px}
.verb h4{font-family:var(--font-display);font-weight:750;font-size:15px;margin:0 0 7px;letter-spacing:-.01em}
.verb p{font-family:var(--font-display);font-size:12.5px;line-height:1.46;color:var(--ink-2);margin:0;max-width:none}
.verb .step{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.13em;color:var(--brass);display:block;margin-bottom:9px}
/* ---------- questions ---------- */
.qs{display:flex;flex-direction:column;gap:0;border-top:1px solid var(--rule-strong)}
.q{display:grid;grid-template-columns:34px minmax(0,1fr) 170px;gap:18px;padding:16px 0;border-bottom:1px solid var(--rule);align-items:start}
@media (max-width:760px){.q{grid-template-columns:28px minmax(0,1fr);gap:12px}.q .owner{grid-column:2}}
.q .qn{font-family:var(--font-mono);font-size:11px;color:var(--brass);padding-top:3px}
.q .qt{font-family:var(--font-display);font-size:14px;line-height:1.48;color:var(--ink-2)}
.q .qt b{color:var(--ink);font-weight:700;display:block;margin-bottom:2px;font-size:14.5px}
.owner{font-family:var(--font-mono);font-size:10px;letter-spacing:.05em;color:var(--ink-3);padding-top:4px}
.owner .tag{display:inline-block;border:1px solid var(--rule-strong);padding:2px 7px;border-radius:2px}
.owner .tag.need{border-color:var(--clay);color:var(--clay)}
/* ---------- misc ---------- */
.numbers{font-family:var(--font-mono);font-size:12.5px;line-height:1.85;background:var(--surface);border-left:3px solid var(--l3);padding:16px 20px;margin:0 0 22px;overflow-x:auto;max-width:var(--measure)}
.numbers .v{color:var(--ink);font-weight:600}
.numbers .k{color:var(--ink-3)}
pre{font-family:var(--font-mono);font-size:12.5px;line-height:1.68;background:var(--surface);border-left:3px solid var(--rule-strong);padding:16px 20px;overflow-x:auto;margin:0 0 22px;max-width:var(--measure);color:var(--ink-2)}
.alt{border-bottom:1px solid var(--rule);padding:14px 0;max-width:var(--measure)}
.alt:last-of-type{border-bottom:none}
.alt b{font-family:var(--font-display);font-size:14px;display:block;margin-bottom:3px}
.alt p{font-size:14.5px;margin:0;color:var(--ink-2)}
.alt .verdict{font-family:var(--font-mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--clay)}
footer{border-top:2px solid var(--ink);margin-top:20px;padding-top:22px;font-family:var(--font-mono);font-size:11px;letter-spacing:.06em;color:var(--ink-3);display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap}
.tm td,.tm th{text-align:center}
.tm td:first-child,.tm th:first-child{text-align:left}
.yes{color:var(--l4);font-weight:700}
.no{color:var(--clay);font-weight:700}
.kind{font-family:var(--font-mono);font-size:9px;letter-spacing:.09em;text-transform:uppercase;padding:2px 6px;border-radius:2px;white-space:nowrap;border:1px solid var(--rule-strong);color:var(--ink-3)}
.kind.adv{border-color:var(--clay);color:var(--clay)}
.routes{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:2px;background:var(--rule);border:1px solid var(--rule);margin:0 0 22px}
.route{background:var(--surface);padding:16px 18px}
.route h4{font-family:var(--font-display);font-weight:750;font-size:14px;margin:0 0 6px}
.route p{font-family:var(--font-display);font-size:12.5px;line-height:1.45;color:var(--ink-2);margin:0;max-width:none}
.route .tag{font-family:var(--font-mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:var(--brass);display:block;margin-bottom:8px}
a:focus-visible,.rail a:focus-visible{outline:2px solid var(--brass);outline-offset:3px}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
<div class="wrap"><header><div class="eyebrow"><span>RISK-METHOD-DEPENDENCIES</span> <span class="stat">adopted · adopted-1</span> <span>risk-nexus</span> <span>reviewed 2026-08-20</span><span>generated from canonical source — do not edit</span></div><h1>Waiting</h1><p class="sub">Source: <code>risk-nexus · docs/method/dependencies.md · c5517c754bd84b0ebf47878ba0f26df0ecb3b4a4</code></p><p class="sub">Review due: 2027-02-20</p></header><div class="layout"><nav class="rail" aria-label="Sections"><ol><li><a href="#the-principle"><span class="n">·</span>The principle</a></li><li><a href="#the-four-rules"><span class="n">·</span>The four rules</a></li><li><a href="#what-this-does-not-solve"><span class="n">·</span>What this does not solve</a></li><li><a href="#waits-outlive-statuses"><span class="n">·</span>Waits outlive statuses</a></li><li><a href="#a-wait-is-not-a-findings-only-idea"><span class="n">·</span>A wait is not a findings-only idea</a></li><li><a href="#where-the-waits-are-visible"><span class="n">·</span>Where the waits are visible</a></li></ol></nav><main><p>By 2026-08-20 the register had accumulated nine waits in four days, one of them four hops deep: <code>RISK-F-0003</code>'s embargo waited on <code>RISK-F-0009</code>, which waited on <code>railiance-platform</code> fixing a deny set, which waited on someone verifying it against live OpenBao, which waited on a credential nobody has.</p>
<p>Nothing in that chain is anyone's fault, and every link was individually reasonable. That is exactly why it needs a rule: deep dependencies are not built deliberately, they accrete one sensible step at a time.</p>
<section id="the-principle"><h2>The principle</h2>
<p><strong>The register never waits to decide. It decides, and revises when told.</strong></p>
<p>A wait is a <em>refinement</em> pending, not a decision pending. If the register cannot act until someone answers, the register has made that person's silence into its own paralysis — and <code>INTENT.md</code> is explicit that a register nobody acts on is worse than none.</p>
</section>
<section id="the-four-rules"><h2>The four rules</h2>
<h3>1. Every wait is typed</h3>
<p>No record may say "waiting on X". A wait carries six things:</p>
<pre>waiting_on:
- who: tenant-engine
what: &quot;confirm or correct the unfiltered events() read; open fix tracking&quot;
since: &quot;2026-08-19&quot;
would_change: &quot;grade rises if the log carries payload rather than metadata&quot;
default: &quot;grade stands as recorded; absent fix tracking noted as a stall&quot;
default_at: &quot;2026-09-03&quot;</pre>
<p><code>would_change</code> is the discipline. If nobody can say what the answer would change, there is nothing being waited for, and the wait should be deleted rather than carried.</p>
<h3>2. Depth one</h3>
<p><strong>A record may wait on at most one other record, and never on a record that is itself waiting.</strong></p>
<p>When the chain would go deeper, the far end is cut: the record takes its own default and says which unresolved thing it declined to wait for. Two hops is the point at which nobody can see the whole line any more, and a wait nobody can see is indistinguishable from a thing that was dropped.</p>
<p>Applied 2026-08-20: <code>RISK-F-0009</code>'s embargo condition was "verified against live OpenBao", which no one in the estate can currently do. It now lifts on <strong><code>railiance-platform</code> reporting the coverage</strong>, with live verification recorded as a refinement rather than a condition. That cut the <code>RISK-F-0003</code> chain from four hops to two.</p>
<h3>3. Defaults are dates, and defaults are pessimistic</h3>
<p>Every wait resolves on a date whether or not anyone answers. The default is <strong>the reading the stated facts already support</strong> — never a hold, never a downgrade earned by silence.</p>
<p>This is what removes the incentive to wait. Silence does not buy an owner a softer grade or a quieter register; it costs them the grade the evidence supports, which is usually the one they would want corrected. Answering is how a grade improves, and that is the right shape for the incentive.</p>
<p>The register says so in advance, to the owner, in writing. A default nobody was warned about is an ambush, not a rule.</p>
<h3>4. A condition naming somebody else's action carries a date beside it</h3>
<p>"Embargo lifts when X ships" is a dependency with no end. "Lifts when X ships, or is re-decided on 2026-09-20" terminates.</p>
<p>Re-decided is not the same as lifted — the re-decision may extend the hold with a fresh reason. What it may not do is extend by default, which is how holds quietly become permanent.</p>
</section>
<section id="what-this-does-not-solve"><h2>What this does not solve</h2>
<p>Some dependencies are real and cannot be defaulted away. Nobody can verify an OpenBao policy without a token, and no rule here conjures one.</p>
<p>What the rules do is stop that from propagating: the register grades on what is stated, records what it could not verify, and keeps its own position independent of the blockage. <code>docs/method/verification.md</code> bounds what this repo can establish itself, and every grade resting on a document rather than a probe says so on its face.</p>
</section>
<section id="waits-outlive-statuses"><h2>Waits outlive statuses</h2>
<p>A finding that is <code>fixed</code> can still owe something. <code>RISK-F-0001</code> was closed on 2026-08-19 and is still waiting on <code>policy-nexus</code> for the publication entry that turns <code>disclosure: public</code> into an actual address.</p>
<p>So the waiting list is built from <strong>every</strong> finding, not from the watched ones. A closed record with an open obligation is precisely the thing that goes quiet, because nothing is prompting anyone to look at it any more.</p>
</section>
<section id="a-wait-is-not-a-findings-only-idea"><h2>A wait is not a findings-only idea</h2>
<p>Adopting a rule is nobody's finding. Registering a canon kind is nobody's finding. Publishing a document is nobody's finding. All three are obligations someone owes, and each one that lived outside the mechanism was invisible to it.</p>
<p>So waits attach to <strong>any</strong> record this repo keeps — findings, regulatory records, workplans — and <code>make check</code> reports them together. <code>RISK-WP-0001</code> carries two: the escalation rule that is producing decisions while still <code>status: proposed</code>, and the canon question about what kind of thing a finding is.</p>
<p>The first of those has the most uncomfortable default in the register, and it points inward: <strong>if the rule is not adopted by 2026-09-17, it is recorded as de facto in force but unratified, and every escalation sent under it says so on its face.</strong> That is worse than either adopting or rejecting it, which is the point — a draft that quietly governs is the thing this register was built to notice.</p>
</section>
<section id="where-the-waits-are-visible"><h2>Where the waits are visible</h2>
<p><code>make check</code> reports every open wait with its age, its owner and its default date, flags any default that has come due, and flags any wait that points at a record which is itself waiting — a depth-two violation, caught by tooling rather than by someone noticing.</p>
</section><footer><span>RISK-METHOD-DEPENDENCIES · adopted-1 · adopted</span><span>risk-nexus · docs/method/dependencies.md · c5517c754bd84b0ebf47878ba0f26df0ecb3b4a4</span></footer></main></div></div></html>

View file

@ -0,0 +1,238 @@
<!doctype html>
<html lang="en"><meta charset="utf-8">
<meta name="policy-source-revision" content="a13d954f8597fd92201746e2d52f031a5a88d969">
<meta name="policy-source-digest" content="a5e7b42043b0bb366add9bbc5f606e134ef5b0454532480203d5d87099296240">
<title>Waiting</title>
<style>
:root{
--paper:#EDEEF0; --surface:#F6F7F8; --surface-2:#E4E6E9;
--ink:#171D24; --ink-2:#4A5561; --ink-3:#737E8A;
--rule:#D3D7DC; --rule-strong:#B6BCC3;
--brass:#8A6A2E; --brass-soft:#EFE5CD; --brass-line:#C9AE74;
--clay:#8A3A2C; --clay-soft:#F2DFDA;
--l0:#DCE0E2; --l1:#B9C4C7; --l2:#8CA1A6; --l3:#567D84; --l4:#23555E;
--chip-fg:#F6F7F8;
--font-display:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",sans-serif;
--font-body:"Iowan Old Style","Palatino Linotype",Palatino,Georgia,serif;
--font-mono:ui-monospace,"SF Mono","Cascadia Code",Menlo,Consolas,monospace;
--measure:66ch;
}
@media (prefers-color-scheme:dark){
:root:not([data-theme="light"]){
--paper:#12161A; --surface:#191E24; --surface-2:#222831;
--ink:#E6E9EC; --ink-2:#A3ADB7; --ink-3:#78838E;
--rule:#2A3138; --rule-strong:#3B444D;
--brass:#C9A45C; --brass-soft:#33290F; --brass-line:#6B5426;
--clay:#D08A76; --clay-soft:#3A211B;
--l0:#262C32; --l1:#35424A; --l2:#4A626B; --l3:#6A939D; --l4:#97C4CD;
--chip-fg:#12161A;
}
}
:root[data-theme="dark"]{
--paper:#12161A; --surface:#191E24; --surface-2:#222831;
--ink:#E6E9EC; --ink-2:#A3ADB7; --ink-3:#78838E;
--rule:#2A3138; --rule-strong:#3B444D;
--brass:#C9A45C; --brass-soft:#33290F; --brass-line:#6B5426;
--clay:#D08A76; --clay-soft:#3A211B;
--l0:#262C32; --l1:#35424A; --l2:#4A626B; --l3:#6A939D; --l4:#97C4CD;
--chip-fg:#12161A;
}
*{box-sizing:border-box}
body{
margin:0; background:var(--paper); color:var(--ink);
font-family:var(--font-body); font-size:17px; line-height:1.62;
-webkit-font-smoothing:antialiased;
}
.wrap{max-width:1180px;margin:0 auto;padding:0 24px 96px}
.layout{display:grid;grid-template-columns:180px minmax(0,1fr);gap:56px;align-items:start}
@media (max-width:960px){.layout{grid-template-columns:1fr;gap:0}.rail{display:none}}
/* ---------- rail ---------- */
.rail{position:sticky;top:28px;padding-top:8px;font-family:var(--font-display);font-size:12px;line-height:1.5}
.rail ol{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:7px}
.rail a{color:var(--ink-3);text-decoration:none;display:flex;gap:9px}
.rail a:hover,.rail a:focus-visible{color:var(--brass)}
.rail .n{font-family:var(--font-mono);font-size:10px;color:var(--rule-strong);min-width:16px;padding-top:1px}
.rail .grp{margin-top:14px;font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--rule-strong)}
/* ---------- header ---------- */
header{padding:64px 0 40px;border-bottom:2px solid var(--ink);margin-bottom:44px}
.eyebrow{font-family:var(--font-mono);font-size:11.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);display:flex;flex-wrap:wrap;gap:14px;margin-bottom:22px}
.eyebrow .stat{color:var(--clay)}
h1{font-family:var(--font-display);font-weight:800;letter-spacing:-.035em;line-height:.94;font-size:clamp(46px,9vw,92px);margin:0 0 6px;text-wrap:balance}
.sub{font-family:var(--font-display);font-weight:500;font-size:clamp(16px,2.4vw,21px);letter-spacing:-.01em;color:var(--ink-2);margin:0 0 30px;max-width:34ch;line-height:1.3}
.metagrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:20px 28px;border-top:1px solid var(--rule);padding-top:20px}
.metagrid dt{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);margin-bottom:5px}
.metagrid dd{margin:0;font-family:var(--font-display);font-size:13.5px;line-height:1.45;color:var(--ink)}
/* ---------- typography ---------- */
section{margin-bottom:60px;scroll-margin-top:24px}
h2{font-family:var(--font-display);font-weight:750;letter-spacing:-.022em;font-size:clamp(24px,3.4vw,31px);line-height:1.12;margin:0 0 18px;text-wrap:balance;display:flex;gap:14px;align-items:baseline}
h2 .sn{font-family:var(--font-mono);font-size:12px;font-weight:400;color:var(--brass);letter-spacing:.06em;flex:none;padding-top:2px}
h3{font-family:var(--font-display);font-weight:700;font-size:16px;letter-spacing:-.008em;margin:34px 0 10px;color:var(--ink)}
p{margin:0 0 15px;max-width:var(--measure)}
ul,ol{max-width:var(--measure);margin:0 0 15px;padding-left:20px}
li{margin-bottom:7px}
strong{font-weight:600}
em{font-style:italic}
code{font-family:var(--font-mono);font-size:.855em;background:var(--surface-2);padding:1px 5px;border-radius:2px}
a{color:var(--brass)}
.lede{font-size:19px;line-height:1.55;color:var(--ink-2);max-width:60ch}
/* ---------- devices ---------- */
.callout{border-left:3px solid var(--brass);background:var(--brass-soft);padding:18px 22px;margin:0 0 24px;max-width:var(--measure)}
.callout p:last-child{margin-bottom:0}
.callout .lbl{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--brass);display:block;margin-bottom:8px}
.rule-quote{border-top:2px solid var(--ink);border-bottom:2px solid var(--ink);padding:26px 0;margin:28px 0;max-width:var(--measure)}
.rule-quote p{font-family:var(--font-display);font-weight:600;font-size:19px;line-height:1.38;letter-spacing:-.014em;margin:0;text-wrap:balance}
.hard{border-left:3px solid var(--clay);background:var(--clay-soft);padding:18px 22px;margin:0 0 24px;max-width:var(--measure)}
.hard .lbl{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--clay);display:block;margin-bottom:8px}
.hard p:last-child{margin-bottom:0}
.dec{font-family:var(--font-mono);font-size:10.5px;letter-spacing:.08em;color:var(--brass);text-transform:uppercase}
.vec{font-family:var(--font-mono);font-size:.9em;font-weight:600;background:var(--surface-2);padding:2px 7px;border-radius:2px;white-space:nowrap;letter-spacing:.04em}
/* ---------- tables ---------- */
.scroll{overflow-x:auto;margin:0 0 24px;-webkit-overflow-scrolling:touch}
table{border-collapse:collapse;width:100%;min-width:520px;font-family:var(--font-display);font-size:13.5px;line-height:1.45}
th{text-align:left;font-family:var(--font-mono);font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);font-weight:400;padding:0 16px 8px 0;border-bottom:1px solid var(--rule-strong);vertical-align:bottom}
td{padding:11px 16px 11px 0;border-bottom:1px solid var(--rule);vertical-align:top;color:var(--ink-2)}
td:first-child{color:var(--ink);font-weight:600}
tbody tr:last-child td{border-bottom:none}
.lvl{font-family:var(--font-mono);font-weight:600;font-size:12px;letter-spacing:.04em;color:var(--ink)}
/* ---------- ladders ---------- */
.breakout{margin:34px 0 40px}
.bhead{display:flex;justify-content:space-between;align-items:baseline;gap:20px;border-bottom:1px solid var(--rule-strong);padding-bottom:9px;margin-bottom:22px;flex-wrap:wrap}
.bhead h3{margin:0;font-size:13px;letter-spacing:.1em;text-transform:uppercase;font-family:var(--font-mono);font-weight:400;color:var(--ink-3)}
.bhead .note{font-family:var(--font-display);font-size:12.5px;color:var(--ink-3)}
.ladders{display:grid;gap:26px}
.ladder{display:grid;grid-template-columns:126px minmax(0,1fr);gap:18px;align-items:start}
@media (max-width:700px){.ladder{grid-template-columns:1fr;gap:10px}}
.ladder .pname{font-family:var(--font-display);font-weight:700;font-size:14px;letter-spacing:-.01em;padding-top:2px}
.ladder .pname span{display:block;font-family:var(--font-mono);font-size:10px;font-weight:400;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);margin-top:3px}
.rungs{display:grid;gap:3px;grid-template-columns:repeat(5,minmax(0,1fr))}
@media (max-width:700px){.rungs{grid-template-columns:repeat(2,minmax(0,1fr))}}
.rung{padding:9px 10px 11px;background:var(--surface);border-top:4px solid var(--l0);min-width:0}
.rung.r1{border-top-color:var(--l1)} .rung.r2{border-top-color:var(--l2)}
.rung.r3{border-top-color:var(--l3)} .rung.r4{border-top-color:var(--l4)}
.rung .code{font-family:var(--font-mono);font-size:11px;font-weight:600;letter-spacing:.06em;color:var(--ink);display:block;margin-bottom:4px}
.rung .txt{font-family:var(--font-display);font-size:11.5px;line-height:1.34;color:var(--ink-2);display:block}
.rung.na{opacity:.42}
/* ---------- matrix ---------- */
.matrix-shell{display:grid;grid-template-columns:auto minmax(0,1fr);gap:12px;align-items:stretch;margin-bottom:14px}
.ylab{writing-mode:vertical-rl;transform:rotate(180deg);font-family:var(--font-mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);text-align:center;padding-bottom:22px}
.mgrid{display:grid;grid-template-columns:34px repeat(5,minmax(0,1fr));gap:3px}
.mcell{background:var(--surface);min-height:60px;padding:6px;display:flex;flex-direction:column;justify-content:flex-end;gap:4px;min-width:0}
.mcell.tint1{background:color-mix(in srgb,var(--l1) 26%,var(--surface))}
.mcell.tint2{background:color-mix(in srgb,var(--l2) 26%,var(--surface))}
.mcell.tint3{background:color-mix(in srgb,var(--l3) 24%,var(--surface))}
.mcell.tint4{background:color-mix(in srgb,var(--l4) 22%,var(--surface))}
.mcell.void{background:repeating-linear-gradient(135deg,transparent,transparent 5px,var(--rule) 5px,var(--rule) 6px);opacity:.55}
.rlab,.clab{font-family:var(--font-mono);font-size:10px;font-weight:600;letter-spacing:.05em;color:var(--ink-3);display:flex;align-items:center;justify-content:center}
.rlab{min-height:60px}
.clab{padding-top:7px;min-height:22px}
.pin{font-family:var(--font-mono);font-size:9.5px;font-weight:600;letter-spacing:.02em;background:var(--ink);color:var(--paper);padding:2px 5px;border-radius:2px;line-height:1.3;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pin.ghost{background:transparent;color:var(--ink-2);border:1px dashed var(--rule-strong)}
.mnote{display:flex;gap:22px;flex-wrap:wrap;font-family:var(--font-display);font-size:12px;color:var(--ink-3);padding-top:6px}
.mnote .k{display:flex;align-items:center;gap:7px}
.sw{width:13px;height:13px;flex:none;background:var(--ink)}
.sw.g{background:transparent;border:1px dashed var(--rule-strong)}
.sw.v{background:repeating-linear-gradient(135deg,transparent,transparent 4px,var(--rule) 4px,var(--rule) 5px);border:1px solid var(--rule)}
@media (max-width:640px){
.mgrid{grid-template-columns:28px repeat(5,minmax(0,1fr))}
.mcell{min-height:52px;padding:4px}
.pin{font-size:8px;padding:1px 3px}
.rlab{min-height:52px}
}
/* ---------- methodology ---------- */
.verbs{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:2px;background:var(--rule);border:1px solid var(--rule)}
.verb{background:var(--surface);padding:18px 18px 20px}
.verb h4{font-family:var(--font-display);font-weight:750;font-size:15px;margin:0 0 7px;letter-spacing:-.01em}
.verb p{font-family:var(--font-display);font-size:12.5px;line-height:1.46;color:var(--ink-2);margin:0;max-width:none}
.verb .step{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.13em;color:var(--brass);display:block;margin-bottom:9px}
/* ---------- questions ---------- */
.qs{display:flex;flex-direction:column;gap:0;border-top:1px solid var(--rule-strong)}
.q{display:grid;grid-template-columns:34px minmax(0,1fr) 170px;gap:18px;padding:16px 0;border-bottom:1px solid var(--rule);align-items:start}
@media (max-width:760px){.q{grid-template-columns:28px minmax(0,1fr);gap:12px}.q .owner{grid-column:2}}
.q .qn{font-family:var(--font-mono);font-size:11px;color:var(--brass);padding-top:3px}
.q .qt{font-family:var(--font-display);font-size:14px;line-height:1.48;color:var(--ink-2)}
.q .qt b{color:var(--ink);font-weight:700;display:block;margin-bottom:2px;font-size:14.5px}
.owner{font-family:var(--font-mono);font-size:10px;letter-spacing:.05em;color:var(--ink-3);padding-top:4px}
.owner .tag{display:inline-block;border:1px solid var(--rule-strong);padding:2px 7px;border-radius:2px}
.owner .tag.need{border-color:var(--clay);color:var(--clay)}
/* ---------- misc ---------- */
.numbers{font-family:var(--font-mono);font-size:12.5px;line-height:1.85;background:var(--surface);border-left:3px solid var(--l3);padding:16px 20px;margin:0 0 22px;overflow-x:auto;max-width:var(--measure)}
.numbers .v{color:var(--ink);font-weight:600}
.numbers .k{color:var(--ink-3)}
pre{font-family:var(--font-mono);font-size:12.5px;line-height:1.68;background:var(--surface);border-left:3px solid var(--rule-strong);padding:16px 20px;overflow-x:auto;margin:0 0 22px;max-width:var(--measure);color:var(--ink-2)}
.alt{border-bottom:1px solid var(--rule);padding:14px 0;max-width:var(--measure)}
.alt:last-of-type{border-bottom:none}
.alt b{font-family:var(--font-display);font-size:14px;display:block;margin-bottom:3px}
.alt p{font-size:14.5px;margin:0;color:var(--ink-2)}
.alt .verdict{font-family:var(--font-mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--clay)}
footer{border-top:2px solid var(--ink);margin-top:20px;padding-top:22px;font-family:var(--font-mono);font-size:11px;letter-spacing:.06em;color:var(--ink-3);display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap}
.tm td,.tm th{text-align:center}
.tm td:first-child,.tm th:first-child{text-align:left}
.yes{color:var(--l4);font-weight:700}
.no{color:var(--clay);font-weight:700}
.kind{font-family:var(--font-mono);font-size:9px;letter-spacing:.09em;text-transform:uppercase;padding:2px 6px;border-radius:2px;white-space:nowrap;border:1px solid var(--rule-strong);color:var(--ink-3)}
.kind.adv{border-color:var(--clay);color:var(--clay)}
.routes{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:2px;background:var(--rule);border:1px solid var(--rule);margin:0 0 22px}
.route{background:var(--surface);padding:16px 18px}
.route h4{font-family:var(--font-display);font-weight:750;font-size:14px;margin:0 0 6px}
.route p{font-family:var(--font-display);font-size:12.5px;line-height:1.45;color:var(--ink-2);margin:0;max-width:none}
.route .tag{font-family:var(--font-mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:var(--brass);display:block;margin-bottom:8px}
a:focus-visible,.rail a:focus-visible{outline:2px solid var(--brass);outline-offset:3px}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
<div class="wrap"><header><div class="eyebrow"><span>RISK-METHOD-DEPENDENCIES</span> <span class="stat">adopted · adopted-1</span> <span>risk-nexus</span> <span>reviewed 2026-08-20</span><span>generated from canonical source — do not edit</span></div><h1>Waiting</h1><p class="sub">Source: <code>risk-nexus · docs/method/dependencies.md · a13d954f8597fd92201746e2d52f031a5a88d969</code></p><p class="sub">Review due: 2027-02-20</p></header><div class="layout"><nav class="rail" aria-label="Sections"><ol><li><a href="#the-principle"><span class="n">·</span>The principle</a></li><li><a href="#the-four-rules"><span class="n">·</span>The four rules</a></li><li><a href="#what-this-does-not-solve"><span class="n">·</span>What this does not solve</a></li><li><a href="#waits-outlive-statuses"><span class="n">·</span>Waits outlive statuses</a></li><li><a href="#a-wait-is-not-a-findings-only-idea"><span class="n">·</span>A wait is not a findings-only idea</a></li><li><a href="#where-the-waits-are-visible"><span class="n">·</span>Where the waits are visible</a></li></ol></nav><main><p>By 2026-08-20 the register had accumulated nine waits in four days, one of them four hops deep: <code>RISK-F-0003</code>'s embargo waited on <code>RISK-F-0009</code>, which waited on <code>railiance-platform</code> fixing a deny set, which waited on someone verifying it against live OpenBao, which waited on a credential nobody has.</p>
<p>Nothing in that chain is anyone's fault, and every link was individually reasonable. That is exactly why it needs a rule: deep dependencies are not built deliberately, they accrete one sensible step at a time.</p>
<section id="the-principle"><h2>The principle</h2>
<p><strong>The register never waits to decide. It decides, and revises when told.</strong></p>
<p>A wait is a <em>refinement</em> pending, not a decision pending. If the register cannot act until someone answers, the register has made that person's silence into its own paralysis — and <code>INTENT.md</code> is explicit that a register nobody acts on is worse than none.</p>
</section>
<section id="the-four-rules"><h2>The four rules</h2>
<h3>1. Every wait is typed</h3>
<p>No record may say "waiting on X". A wait carries six things:</p>
<pre>waiting_on:
- who: tenant-engine
what: &quot;confirm or correct the unfiltered events() read; open fix tracking&quot;
since: &quot;2026-08-19&quot;
would_change: &quot;grade rises if the log carries payload rather than metadata&quot;
default: &quot;grade stands as recorded; absent fix tracking noted as a stall&quot;
default_at: &quot;2026-09-03&quot;</pre>
<p><code>would_change</code> is the discipline. If nobody can say what the answer would change, there is nothing being waited for, and the wait should be deleted rather than carried.</p>
<h3>2. Depth one</h3>
<p><strong>A record may wait on at most one other record, and never on a record that is itself waiting.</strong></p>
<p>When the chain would go deeper, the far end is cut: the record takes its own default and says which unresolved thing it declined to wait for. Two hops is the point at which nobody can see the whole line any more, and a wait nobody can see is indistinguishable from a thing that was dropped.</p>
<p>Applied 2026-08-20: <code>RISK-F-0009</code>'s embargo condition was "verified against live OpenBao", which no one in the estate can currently do. It now lifts on <strong><code>railiance-platform</code> reporting the coverage</strong>, with live verification recorded as a refinement rather than a condition. That cut the <code>RISK-F-0003</code> chain from four hops to two.</p>
<h3>3. Defaults are dates, and defaults are pessimistic</h3>
<p>Every wait resolves on a date whether or not anyone answers. The default is <strong>the reading the stated facts already support</strong> — never a hold, never a downgrade earned by silence.</p>
<p>This is what removes the incentive to wait. Silence does not buy an owner a softer grade or a quieter register; it costs them the grade the evidence supports, which is usually the one they would want corrected. Answering is how a grade improves, and that is the right shape for the incentive.</p>
<p>The register says so in advance, to the owner, in writing. A default nobody was warned about is an ambush, not a rule.</p>
<h3>4. A condition naming somebody else's action carries a date beside it</h3>
<p>"Embargo lifts when X ships" is a dependency with no end. "Lifts when X ships, or is re-decided on 2026-09-20" terminates.</p>
<p>Re-decided is not the same as lifted — the re-decision may extend the hold with a fresh reason. What it may not do is extend by default, which is how holds quietly become permanent.</p>
</section>
<section id="what-this-does-not-solve"><h2>What this does not solve</h2>
<p>Some dependencies are real and cannot be defaulted away. Nobody can verify an OpenBao policy without a token, and no rule here conjures one.</p>
<p>What the rules do is stop that from propagating: the register grades on what is stated, records what it could not verify, and keeps its own position independent of the blockage. <code>docs/method/verification.md</code> bounds what this repo can establish itself, and every grade resting on a document rather than a probe says so on its face.</p>
</section>
<section id="waits-outlive-statuses"><h2>Waits outlive statuses</h2>
<p>A finding that is <code>fixed</code> can still owe something. <code>RISK-F-0001</code> was closed on 2026-08-19 and is still waiting on <code>policy-nexus</code> for the publication entry that turns <code>disclosure: public</code> into an actual address.</p>
<p>So the waiting list is built from <strong>every</strong> finding, not from the watched ones. A closed record with an open obligation is precisely the thing that goes quiet, because nothing is prompting anyone to look at it any more.</p>
</section>
<section id="a-wait-is-not-a-findings-only-idea"><h2>A wait is not a findings-only idea</h2>
<p>Adopting a rule is nobody's finding. Registering a canon kind is nobody's finding. Publishing a document is nobody's finding. All three are obligations someone owes, and each one that lived outside the mechanism was invisible to it.</p>
<p>So waits attach to <strong>any</strong> record this repo keeps — findings, regulatory records, workplans — and <code>make check</code> reports them together. <code>RISK-WP-0001</code> carries two: the escalation rule that is producing decisions while still <code>status: proposed</code>, and the canon question about what kind of thing a finding is.</p>
<p>The first of those has the most uncomfortable default in the register, and it points inward: <strong>if the rule is not adopted by 2026-09-17, it is recorded as de facto in force but unratified, and every escalation sent under it says so on its face.</strong> That is worse than either adopting or rejecting it, which is the point — a draft that quietly governs is the thing this register was built to notice.</p>
</section>
<section id="where-the-waits-are-visible"><h2>Where the waits are visible</h2>
<p><code>make check</code> reports every open wait with its age, its owner and its default date, flags any default that has come due, and flags any wait that points at a record which is itself waiting — a depth-two violation, caught by tooling rather than by someone noticing.</p>
</section><footer><span>RISK-METHOD-DEPENDENCIES · adopted-1 · adopted</span><span>risk-nexus · docs/method/dependencies.md · a13d954f8597fd92201746e2d52f031a5a88d969</span></footer></main></div></div></html>

View file

@ -0,0 +1,232 @@
<!doctype html>
<html lang="en"><meta charset="utf-8">
<meta name="policy-source-revision" content="c5517c754bd84b0ebf47878ba0f26df0ecb3b4a4">
<meta name="policy-source-digest" content="bd825a87736c8fb019d4224c3ef4fe3882b8f3028035225b4b8ff8cad62fdb81">
<title>Disclosure</title>
<style>
:root{
--paper:#EDEEF0; --surface:#F6F7F8; --surface-2:#E4E6E9;
--ink:#171D24; --ink-2:#4A5561; --ink-3:#737E8A;
--rule:#D3D7DC; --rule-strong:#B6BCC3;
--brass:#8A6A2E; --brass-soft:#EFE5CD; --brass-line:#C9AE74;
--clay:#8A3A2C; --clay-soft:#F2DFDA;
--l0:#DCE0E2; --l1:#B9C4C7; --l2:#8CA1A6; --l3:#567D84; --l4:#23555E;
--chip-fg:#F6F7F8;
--font-display:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",sans-serif;
--font-body:"Iowan Old Style","Palatino Linotype",Palatino,Georgia,serif;
--font-mono:ui-monospace,"SF Mono","Cascadia Code",Menlo,Consolas,monospace;
--measure:66ch;
}
@media (prefers-color-scheme:dark){
:root:not([data-theme="light"]){
--paper:#12161A; --surface:#191E24; --surface-2:#222831;
--ink:#E6E9EC; --ink-2:#A3ADB7; --ink-3:#78838E;
--rule:#2A3138; --rule-strong:#3B444D;
--brass:#C9A45C; --brass-soft:#33290F; --brass-line:#6B5426;
--clay:#D08A76; --clay-soft:#3A211B;
--l0:#262C32; --l1:#35424A; --l2:#4A626B; --l3:#6A939D; --l4:#97C4CD;
--chip-fg:#12161A;
}
}
:root[data-theme="dark"]{
--paper:#12161A; --surface:#191E24; --surface-2:#222831;
--ink:#E6E9EC; --ink-2:#A3ADB7; --ink-3:#78838E;
--rule:#2A3138; --rule-strong:#3B444D;
--brass:#C9A45C; --brass-soft:#33290F; --brass-line:#6B5426;
--clay:#D08A76; --clay-soft:#3A211B;
--l0:#262C32; --l1:#35424A; --l2:#4A626B; --l3:#6A939D; --l4:#97C4CD;
--chip-fg:#12161A;
}
*{box-sizing:border-box}
body{
margin:0; background:var(--paper); color:var(--ink);
font-family:var(--font-body); font-size:17px; line-height:1.62;
-webkit-font-smoothing:antialiased;
}
.wrap{max-width:1180px;margin:0 auto;padding:0 24px 96px}
.layout{display:grid;grid-template-columns:180px minmax(0,1fr);gap:56px;align-items:start}
@media (max-width:960px){.layout{grid-template-columns:1fr;gap:0}.rail{display:none}}
/* ---------- rail ---------- */
.rail{position:sticky;top:28px;padding-top:8px;font-family:var(--font-display);font-size:12px;line-height:1.5}
.rail ol{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:7px}
.rail a{color:var(--ink-3);text-decoration:none;display:flex;gap:9px}
.rail a:hover,.rail a:focus-visible{color:var(--brass)}
.rail .n{font-family:var(--font-mono);font-size:10px;color:var(--rule-strong);min-width:16px;padding-top:1px}
.rail .grp{margin-top:14px;font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--rule-strong)}
/* ---------- header ---------- */
header{padding:64px 0 40px;border-bottom:2px solid var(--ink);margin-bottom:44px}
.eyebrow{font-family:var(--font-mono);font-size:11.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);display:flex;flex-wrap:wrap;gap:14px;margin-bottom:22px}
.eyebrow .stat{color:var(--clay)}
h1{font-family:var(--font-display);font-weight:800;letter-spacing:-.035em;line-height:.94;font-size:clamp(46px,9vw,92px);margin:0 0 6px;text-wrap:balance}
.sub{font-family:var(--font-display);font-weight:500;font-size:clamp(16px,2.4vw,21px);letter-spacing:-.01em;color:var(--ink-2);margin:0 0 30px;max-width:34ch;line-height:1.3}
.metagrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:20px 28px;border-top:1px solid var(--rule);padding-top:20px}
.metagrid dt{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);margin-bottom:5px}
.metagrid dd{margin:0;font-family:var(--font-display);font-size:13.5px;line-height:1.45;color:var(--ink)}
/* ---------- typography ---------- */
section{margin-bottom:60px;scroll-margin-top:24px}
h2{font-family:var(--font-display);font-weight:750;letter-spacing:-.022em;font-size:clamp(24px,3.4vw,31px);line-height:1.12;margin:0 0 18px;text-wrap:balance;display:flex;gap:14px;align-items:baseline}
h2 .sn{font-family:var(--font-mono);font-size:12px;font-weight:400;color:var(--brass);letter-spacing:.06em;flex:none;padding-top:2px}
h3{font-family:var(--font-display);font-weight:700;font-size:16px;letter-spacing:-.008em;margin:34px 0 10px;color:var(--ink)}
p{margin:0 0 15px;max-width:var(--measure)}
ul,ol{max-width:var(--measure);margin:0 0 15px;padding-left:20px}
li{margin-bottom:7px}
strong{font-weight:600}
em{font-style:italic}
code{font-family:var(--font-mono);font-size:.855em;background:var(--surface-2);padding:1px 5px;border-radius:2px}
a{color:var(--brass)}
.lede{font-size:19px;line-height:1.55;color:var(--ink-2);max-width:60ch}
/* ---------- devices ---------- */
.callout{border-left:3px solid var(--brass);background:var(--brass-soft);padding:18px 22px;margin:0 0 24px;max-width:var(--measure)}
.callout p:last-child{margin-bottom:0}
.callout .lbl{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--brass);display:block;margin-bottom:8px}
.rule-quote{border-top:2px solid var(--ink);border-bottom:2px solid var(--ink);padding:26px 0;margin:28px 0;max-width:var(--measure)}
.rule-quote p{font-family:var(--font-display);font-weight:600;font-size:19px;line-height:1.38;letter-spacing:-.014em;margin:0;text-wrap:balance}
.hard{border-left:3px solid var(--clay);background:var(--clay-soft);padding:18px 22px;margin:0 0 24px;max-width:var(--measure)}
.hard .lbl{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--clay);display:block;margin-bottom:8px}
.hard p:last-child{margin-bottom:0}
.dec{font-family:var(--font-mono);font-size:10.5px;letter-spacing:.08em;color:var(--brass);text-transform:uppercase}
.vec{font-family:var(--font-mono);font-size:.9em;font-weight:600;background:var(--surface-2);padding:2px 7px;border-radius:2px;white-space:nowrap;letter-spacing:.04em}
/* ---------- tables ---------- */
.scroll{overflow-x:auto;margin:0 0 24px;-webkit-overflow-scrolling:touch}
table{border-collapse:collapse;width:100%;min-width:520px;font-family:var(--font-display);font-size:13.5px;line-height:1.45}
th{text-align:left;font-family:var(--font-mono);font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);font-weight:400;padding:0 16px 8px 0;border-bottom:1px solid var(--rule-strong);vertical-align:bottom}
td{padding:11px 16px 11px 0;border-bottom:1px solid var(--rule);vertical-align:top;color:var(--ink-2)}
td:first-child{color:var(--ink);font-weight:600}
tbody tr:last-child td{border-bottom:none}
.lvl{font-family:var(--font-mono);font-weight:600;font-size:12px;letter-spacing:.04em;color:var(--ink)}
/* ---------- ladders ---------- */
.breakout{margin:34px 0 40px}
.bhead{display:flex;justify-content:space-between;align-items:baseline;gap:20px;border-bottom:1px solid var(--rule-strong);padding-bottom:9px;margin-bottom:22px;flex-wrap:wrap}
.bhead h3{margin:0;font-size:13px;letter-spacing:.1em;text-transform:uppercase;font-family:var(--font-mono);font-weight:400;color:var(--ink-3)}
.bhead .note{font-family:var(--font-display);font-size:12.5px;color:var(--ink-3)}
.ladders{display:grid;gap:26px}
.ladder{display:grid;grid-template-columns:126px minmax(0,1fr);gap:18px;align-items:start}
@media (max-width:700px){.ladder{grid-template-columns:1fr;gap:10px}}
.ladder .pname{font-family:var(--font-display);font-weight:700;font-size:14px;letter-spacing:-.01em;padding-top:2px}
.ladder .pname span{display:block;font-family:var(--font-mono);font-size:10px;font-weight:400;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);margin-top:3px}
.rungs{display:grid;gap:3px;grid-template-columns:repeat(5,minmax(0,1fr))}
@media (max-width:700px){.rungs{grid-template-columns:repeat(2,minmax(0,1fr))}}
.rung{padding:9px 10px 11px;background:var(--surface);border-top:4px solid var(--l0);min-width:0}
.rung.r1{border-top-color:var(--l1)} .rung.r2{border-top-color:var(--l2)}
.rung.r3{border-top-color:var(--l3)} .rung.r4{border-top-color:var(--l4)}
.rung .code{font-family:var(--font-mono);font-size:11px;font-weight:600;letter-spacing:.06em;color:var(--ink);display:block;margin-bottom:4px}
.rung .txt{font-family:var(--font-display);font-size:11.5px;line-height:1.34;color:var(--ink-2);display:block}
.rung.na{opacity:.42}
/* ---------- matrix ---------- */
.matrix-shell{display:grid;grid-template-columns:auto minmax(0,1fr);gap:12px;align-items:stretch;margin-bottom:14px}
.ylab{writing-mode:vertical-rl;transform:rotate(180deg);font-family:var(--font-mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);text-align:center;padding-bottom:22px}
.mgrid{display:grid;grid-template-columns:34px repeat(5,minmax(0,1fr));gap:3px}
.mcell{background:var(--surface);min-height:60px;padding:6px;display:flex;flex-direction:column;justify-content:flex-end;gap:4px;min-width:0}
.mcell.tint1{background:color-mix(in srgb,var(--l1) 26%,var(--surface))}
.mcell.tint2{background:color-mix(in srgb,var(--l2) 26%,var(--surface))}
.mcell.tint3{background:color-mix(in srgb,var(--l3) 24%,var(--surface))}
.mcell.tint4{background:color-mix(in srgb,var(--l4) 22%,var(--surface))}
.mcell.void{background:repeating-linear-gradient(135deg,transparent,transparent 5px,var(--rule) 5px,var(--rule) 6px);opacity:.55}
.rlab,.clab{font-family:var(--font-mono);font-size:10px;font-weight:600;letter-spacing:.05em;color:var(--ink-3);display:flex;align-items:center;justify-content:center}
.rlab{min-height:60px}
.clab{padding-top:7px;min-height:22px}
.pin{font-family:var(--font-mono);font-size:9.5px;font-weight:600;letter-spacing:.02em;background:var(--ink);color:var(--paper);padding:2px 5px;border-radius:2px;line-height:1.3;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pin.ghost{background:transparent;color:var(--ink-2);border:1px dashed var(--rule-strong)}
.mnote{display:flex;gap:22px;flex-wrap:wrap;font-family:var(--font-display);font-size:12px;color:var(--ink-3);padding-top:6px}
.mnote .k{display:flex;align-items:center;gap:7px}
.sw{width:13px;height:13px;flex:none;background:var(--ink)}
.sw.g{background:transparent;border:1px dashed var(--rule-strong)}
.sw.v{background:repeating-linear-gradient(135deg,transparent,transparent 4px,var(--rule) 4px,var(--rule) 5px);border:1px solid var(--rule)}
@media (max-width:640px){
.mgrid{grid-template-columns:28px repeat(5,minmax(0,1fr))}
.mcell{min-height:52px;padding:4px}
.pin{font-size:8px;padding:1px 3px}
.rlab{min-height:52px}
}
/* ---------- methodology ---------- */
.verbs{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:2px;background:var(--rule);border:1px solid var(--rule)}
.verb{background:var(--surface);padding:18px 18px 20px}
.verb h4{font-family:var(--font-display);font-weight:750;font-size:15px;margin:0 0 7px;letter-spacing:-.01em}
.verb p{font-family:var(--font-display);font-size:12.5px;line-height:1.46;color:var(--ink-2);margin:0;max-width:none}
.verb .step{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.13em;color:var(--brass);display:block;margin-bottom:9px}
/* ---------- questions ---------- */
.qs{display:flex;flex-direction:column;gap:0;border-top:1px solid var(--rule-strong)}
.q{display:grid;grid-template-columns:34px minmax(0,1fr) 170px;gap:18px;padding:16px 0;border-bottom:1px solid var(--rule);align-items:start}
@media (max-width:760px){.q{grid-template-columns:28px minmax(0,1fr);gap:12px}.q .owner{grid-column:2}}
.q .qn{font-family:var(--font-mono);font-size:11px;color:var(--brass);padding-top:3px}
.q .qt{font-family:var(--font-display);font-size:14px;line-height:1.48;color:var(--ink-2)}
.q .qt b{color:var(--ink);font-weight:700;display:block;margin-bottom:2px;font-size:14.5px}
.owner{font-family:var(--font-mono);font-size:10px;letter-spacing:.05em;color:var(--ink-3);padding-top:4px}
.owner .tag{display:inline-block;border:1px solid var(--rule-strong);padding:2px 7px;border-radius:2px}
.owner .tag.need{border-color:var(--clay);color:var(--clay)}
/* ---------- misc ---------- */
.numbers{font-family:var(--font-mono);font-size:12.5px;line-height:1.85;background:var(--surface);border-left:3px solid var(--l3);padding:16px 20px;margin:0 0 22px;overflow-x:auto;max-width:var(--measure)}
.numbers .v{color:var(--ink);font-weight:600}
.numbers .k{color:var(--ink-3)}
pre{font-family:var(--font-mono);font-size:12.5px;line-height:1.68;background:var(--surface);border-left:3px solid var(--rule-strong);padding:16px 20px;overflow-x:auto;margin:0 0 22px;max-width:var(--measure);color:var(--ink-2)}
.alt{border-bottom:1px solid var(--rule);padding:14px 0;max-width:var(--measure)}
.alt:last-of-type{border-bottom:none}
.alt b{font-family:var(--font-display);font-size:14px;display:block;margin-bottom:3px}
.alt p{font-size:14.5px;margin:0;color:var(--ink-2)}
.alt .verdict{font-family:var(--font-mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--clay)}
footer{border-top:2px solid var(--ink);margin-top:20px;padding-top:22px;font-family:var(--font-mono);font-size:11px;letter-spacing:.06em;color:var(--ink-3);display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap}
.tm td,.tm th{text-align:center}
.tm td:first-child,.tm th:first-child{text-align:left}
.yes{color:var(--l4);font-weight:700}
.no{color:var(--clay);font-weight:700}
.kind{font-family:var(--font-mono);font-size:9px;letter-spacing:.09em;text-transform:uppercase;padding:2px 6px;border-radius:2px;white-space:nowrap;border:1px solid var(--rule-strong);color:var(--ink-3)}
.kind.adv{border-color:var(--clay);color:var(--clay)}
.routes{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:2px;background:var(--rule);border:1px solid var(--rule);margin:0 0 22px}
.route{background:var(--surface);padding:16px 18px}
.route h4{font-family:var(--font-display);font-weight:750;font-size:14px;margin:0 0 6px}
.route p{font-family:var(--font-display);font-size:12.5px;line-height:1.45;color:var(--ink-2);margin:0;max-width:none}
.route .tag{font-family:var(--font-mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:var(--brass);display:block;margin-bottom:8px}
a:focus-visible,.rail a:focus-visible{outline:2px solid var(--brass);outline-offset:3px}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
<div class="wrap"><header><div class="eyebrow"><span>RISK-METHOD-DISCLOSURE</span> <span class="stat">adopted · adopted-1</span> <span>risk-nexus</span> <span>reviewed 2026-08-20</span><span>generated from canonical source — do not edit</span></div><h1>Disclosure</h1><p class="sub">Source: <code>risk-nexus · docs/method/disclosure.md · c5517c754bd84b0ebf47878ba0f26df0ecb3b4a4</code></p><p class="sub">Review due: 2027-02-20</p></header><div class="layout"><nav class="rail" aria-label="Sections"><ol><li><a href="#what-disclosure-is-not"><span class="n">·</span>What disclosure is not</a></li><li><a href="#the-states"><span class="n">·</span>The states</a></li><li><a href="#embargo-is-a-record-not-a-silence"><span class="n">·</span>Embargo is a record, not a silence</a></li><li><a href="#the-build-mode-deferral-re-taken"><span class="n">·</span>The build-mode deferral, re-taken</a></li><li><a href="#test-for-shortens-the-path"><span class="n">·</span>Test for &quot;shortens the path&quot;</a></li><li><a href="#publication-happens-elsewhere"><span class="n">·</span>Publication happens elsewhere</a></li><li><a href="#the-standing-route-when-an-embargo-lifts"><span class="n">·</span>The standing route, when an embargo lifts</a></li></ol></nav><main><p>Whether and when a finding is published. <code>policy-nexus</code> is the surface; this document decides what it is handed.</p>
<section id="what-disclosure-is-not"><h2>What disclosure is not</h2>
<p><strong>A finding file in this repo is not a publication.</strong> This repo is a private checkout on a private forge. Holding a finding means not routing it to <code>policy-nexus</code>; it does not mean hiding it from the estate, from the owning repo, or from the operator. Every state below is fully visible internally.</p>
</section>
<section id="the-states"><h2>The states</h2>
<div class="scroll"><table><thead><tr><th>State</th><th>Meaning</th><th>Entry condition</th></tr></thead><tbody><tr><td><code>public</code></td><td>Published through <code>policy-nexus</code> now.</td><td>The finding is fixed, or reading it gives no one an advantage they do not already have.</td></tr><tr><td><code>embargoed</code></td><td>Held, with a stated condition that lifts it.</td><td>Live, unfixed, and the text would help someone reach the defect faster than they could without it.</td></tr><tr><td><code>restricted</code></td><td>Held with no expected lift.</td><td>Publication would remain harmful after the fix — third-party material, a named person, or a credential-shaped detail that survives remediation.</td></tr></tbody></table></div>
<p>There is no fourth state and no <code>unset</code> after grading. A finding whose disclosure has not been decided is an ungraded finding.</p>
</section>
<section id="embargo-is-a-record-not-a-silence"><h2>Embargo is a record, not a silence</h2>
<p><code>INTENT.md</code> requires the record that a delay was deliberate rather than a document quietly going missing. An <code>embargoed</code> finding therefore carries:</p>
<pre>disclosure: embargoed
embargo_condition: &quot;FLEX-WP-0015-T02 ships to production&quot;
embargo_since: &quot;2026-08-19&quot;
embargo_review: &quot;2026-08-26&quot;</pre>
<p><code>embargo_condition</code> must be an event someone can observe, not a mood. "Until it is safer" is not a condition. <code>embargo_review</code> follows the finding's severity interval from <code>docs/method/review.md</code>; when it passes, the embargo is re-decided, not extended by default.</p>
<p>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.</p>
</section>
<section id="the-build-mode-deferral-re-taken"><h2>The build-mode deferral, re-taken</h2>
<p><code>INTENT.md</code> recorded controlled disclosure as deferred to production, reasoning that build mode has no users to expose. <code>RISK-F-0001</code> arrived and tested it: a live authorization bypass in the service every other service trusts, with publish-or-forget as the only available choice.</p>
<p><strong>The deferral is narrowed, not kept and not abandoned.</strong></p>
<p>What was right about it: build mode does have no consumers to protect, and building an embargo <em>mechanism</em> — timed release, staged notification, coordinated disclosure with third parties — before there is anyone to coordinate with would be machinery for its own sake.</p>
<p>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 <code>RISK-F-0001</code> 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.</p>
<p>So the ruling is:</p>
<ol><li><strong>Build-mode default stays publish.</strong> 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.</li><li><strong>Live-and-reachable is the exception, and it exists now.</strong> A finding that is unfixed <em>and</em> whose text shortens the path to the defect is <code>embargoed</code> until the fix lands. That is the missing middle <code>INTENT.md</code> said did not exist. It costs one front-matter field and a line in <code>REGISTER.md</code>.</li><li><strong>The mechanism stays deferred.</strong> No timed release, no coordinated disclosure protocol, no notification tiers. Those wait for real users, as originally reasoned. What is not deferred is the <em>decision</em>, because <code>RISK-F-0001</code> demonstrated the decision is needed before the machinery is.</li></ol>
<p>This is a decision of this repo, taken 2026-08-19 with <code>RISK-F-0001</code>, <code>RISK-F-0002</code> and <code>RISK-F-0003</code> in hand rather than hypothetically. It is revisable, and the production transition is the scheduled moment to revisit it.</p>
</section>
<section id="test-for-shortens-the-path"><h2>Test for "shortens the path"</h2>
<p>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?</p>
<ul><li>A file path and line number in a private repo — no, that is already there.</li><li>"This surface authenticates nobody, here is its cluster address" — yes.</li><li>"These five named lanes vend real secret values without the boundary firing" — yes.</li><li>"This system had no backups configured" — no, once backups exist; yes, while they do not, because it names when destruction is unrecoverable.</li></ul>
<p>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.</p>
</section>
<section id="publication-happens-elsewhere"><h2>Publication happens elsewhere</h2>
<p>A <code>public</code> finding is handed to <code>policy-nexus</code> 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.</p>
</section>
<section id="the-standing-route-when-an-embargo-lifts"><h2>The standing route, when an embargo lifts</h2>
<p><code>RISK-WP-0002-T03</code>. 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.</p>
<ol><li><strong>The check that lifts the embargo records it.</strong> <code>make checked</code> on the finding, with the lift as the reason. An embargo lifting is never a clean check — something moved.</li><li><strong>The finding gets publication front-matter</strong>, in the shape <code>policy-nexus</code> already requires of everyone: <code>owner</code>, <code>revision</code>, <code>last_reviewed</code>, <code>review_interval</code>. No body rewrite.</li><li><strong>This repo asks <code>policy-nexus</code> for an entry</strong>, giving <code>source_repo</code>, <code>source_path</code>, a proposed <code>canonical_path</code> under <code>findings/&lt;id&gt;/&lt;version&gt;/</code>, and a one-line subtitle. Addressing and permanence are theirs (<code>POLICY-NEXUS-WP-0001</code>); this repo does not invent a scheme.</li><li><strong><code>publication: published</code> is recorded back on the finding</strong>, with the URL. A finding that says <code>public</code> but has no address is a claim, not a publication — the same class of error as a backup nobody has restored from.</li></ol>
<p>The contract publishes <strong>a file from the owning repo</strong>, 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 <em>file</em> contains, not about how it is rendered.</p>
</section><footer><span>RISK-METHOD-DISCLOSURE · adopted-1 · adopted</span><span>risk-nexus · docs/method/disclosure.md · c5517c754bd84b0ebf47878ba0f26df0ecb3b4a4</span></footer></main></div></div></html>

View file

@ -0,0 +1,232 @@
<!doctype html>
<html lang="en"><meta charset="utf-8">
<meta name="policy-source-revision" content="a13d954f8597fd92201746e2d52f031a5a88d969">
<meta name="policy-source-digest" content="bd825a87736c8fb019d4224c3ef4fe3882b8f3028035225b4b8ff8cad62fdb81">
<title>Disclosure</title>
<style>
:root{
--paper:#EDEEF0; --surface:#F6F7F8; --surface-2:#E4E6E9;
--ink:#171D24; --ink-2:#4A5561; --ink-3:#737E8A;
--rule:#D3D7DC; --rule-strong:#B6BCC3;
--brass:#8A6A2E; --brass-soft:#EFE5CD; --brass-line:#C9AE74;
--clay:#8A3A2C; --clay-soft:#F2DFDA;
--l0:#DCE0E2; --l1:#B9C4C7; --l2:#8CA1A6; --l3:#567D84; --l4:#23555E;
--chip-fg:#F6F7F8;
--font-display:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",sans-serif;
--font-body:"Iowan Old Style","Palatino Linotype",Palatino,Georgia,serif;
--font-mono:ui-monospace,"SF Mono","Cascadia Code",Menlo,Consolas,monospace;
--measure:66ch;
}
@media (prefers-color-scheme:dark){
:root:not([data-theme="light"]){
--paper:#12161A; --surface:#191E24; --surface-2:#222831;
--ink:#E6E9EC; --ink-2:#A3ADB7; --ink-3:#78838E;
--rule:#2A3138; --rule-strong:#3B444D;
--brass:#C9A45C; --brass-soft:#33290F; --brass-line:#6B5426;
--clay:#D08A76; --clay-soft:#3A211B;
--l0:#262C32; --l1:#35424A; --l2:#4A626B; --l3:#6A939D; --l4:#97C4CD;
--chip-fg:#12161A;
}
}
:root[data-theme="dark"]{
--paper:#12161A; --surface:#191E24; --surface-2:#222831;
--ink:#E6E9EC; --ink-2:#A3ADB7; --ink-3:#78838E;
--rule:#2A3138; --rule-strong:#3B444D;
--brass:#C9A45C; --brass-soft:#33290F; --brass-line:#6B5426;
--clay:#D08A76; --clay-soft:#3A211B;
--l0:#262C32; --l1:#35424A; --l2:#4A626B; --l3:#6A939D; --l4:#97C4CD;
--chip-fg:#12161A;
}
*{box-sizing:border-box}
body{
margin:0; background:var(--paper); color:var(--ink);
font-family:var(--font-body); font-size:17px; line-height:1.62;
-webkit-font-smoothing:antialiased;
}
.wrap{max-width:1180px;margin:0 auto;padding:0 24px 96px}
.layout{display:grid;grid-template-columns:180px minmax(0,1fr);gap:56px;align-items:start}
@media (max-width:960px){.layout{grid-template-columns:1fr;gap:0}.rail{display:none}}
/* ---------- rail ---------- */
.rail{position:sticky;top:28px;padding-top:8px;font-family:var(--font-display);font-size:12px;line-height:1.5}
.rail ol{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:7px}
.rail a{color:var(--ink-3);text-decoration:none;display:flex;gap:9px}
.rail a:hover,.rail a:focus-visible{color:var(--brass)}
.rail .n{font-family:var(--font-mono);font-size:10px;color:var(--rule-strong);min-width:16px;padding-top:1px}
.rail .grp{margin-top:14px;font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--rule-strong)}
/* ---------- header ---------- */
header{padding:64px 0 40px;border-bottom:2px solid var(--ink);margin-bottom:44px}
.eyebrow{font-family:var(--font-mono);font-size:11.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);display:flex;flex-wrap:wrap;gap:14px;margin-bottom:22px}
.eyebrow .stat{color:var(--clay)}
h1{font-family:var(--font-display);font-weight:800;letter-spacing:-.035em;line-height:.94;font-size:clamp(46px,9vw,92px);margin:0 0 6px;text-wrap:balance}
.sub{font-family:var(--font-display);font-weight:500;font-size:clamp(16px,2.4vw,21px);letter-spacing:-.01em;color:var(--ink-2);margin:0 0 30px;max-width:34ch;line-height:1.3}
.metagrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:20px 28px;border-top:1px solid var(--rule);padding-top:20px}
.metagrid dt{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);margin-bottom:5px}
.metagrid dd{margin:0;font-family:var(--font-display);font-size:13.5px;line-height:1.45;color:var(--ink)}
/* ---------- typography ---------- */
section{margin-bottom:60px;scroll-margin-top:24px}
h2{font-family:var(--font-display);font-weight:750;letter-spacing:-.022em;font-size:clamp(24px,3.4vw,31px);line-height:1.12;margin:0 0 18px;text-wrap:balance;display:flex;gap:14px;align-items:baseline}
h2 .sn{font-family:var(--font-mono);font-size:12px;font-weight:400;color:var(--brass);letter-spacing:.06em;flex:none;padding-top:2px}
h3{font-family:var(--font-display);font-weight:700;font-size:16px;letter-spacing:-.008em;margin:34px 0 10px;color:var(--ink)}
p{margin:0 0 15px;max-width:var(--measure)}
ul,ol{max-width:var(--measure);margin:0 0 15px;padding-left:20px}
li{margin-bottom:7px}
strong{font-weight:600}
em{font-style:italic}
code{font-family:var(--font-mono);font-size:.855em;background:var(--surface-2);padding:1px 5px;border-radius:2px}
a{color:var(--brass)}
.lede{font-size:19px;line-height:1.55;color:var(--ink-2);max-width:60ch}
/* ---------- devices ---------- */
.callout{border-left:3px solid var(--brass);background:var(--brass-soft);padding:18px 22px;margin:0 0 24px;max-width:var(--measure)}
.callout p:last-child{margin-bottom:0}
.callout .lbl{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--brass);display:block;margin-bottom:8px}
.rule-quote{border-top:2px solid var(--ink);border-bottom:2px solid var(--ink);padding:26px 0;margin:28px 0;max-width:var(--measure)}
.rule-quote p{font-family:var(--font-display);font-weight:600;font-size:19px;line-height:1.38;letter-spacing:-.014em;margin:0;text-wrap:balance}
.hard{border-left:3px solid var(--clay);background:var(--clay-soft);padding:18px 22px;margin:0 0 24px;max-width:var(--measure)}
.hard .lbl{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--clay);display:block;margin-bottom:8px}
.hard p:last-child{margin-bottom:0}
.dec{font-family:var(--font-mono);font-size:10.5px;letter-spacing:.08em;color:var(--brass);text-transform:uppercase}
.vec{font-family:var(--font-mono);font-size:.9em;font-weight:600;background:var(--surface-2);padding:2px 7px;border-radius:2px;white-space:nowrap;letter-spacing:.04em}
/* ---------- tables ---------- */
.scroll{overflow-x:auto;margin:0 0 24px;-webkit-overflow-scrolling:touch}
table{border-collapse:collapse;width:100%;min-width:520px;font-family:var(--font-display);font-size:13.5px;line-height:1.45}
th{text-align:left;font-family:var(--font-mono);font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);font-weight:400;padding:0 16px 8px 0;border-bottom:1px solid var(--rule-strong);vertical-align:bottom}
td{padding:11px 16px 11px 0;border-bottom:1px solid var(--rule);vertical-align:top;color:var(--ink-2)}
td:first-child{color:var(--ink);font-weight:600}
tbody tr:last-child td{border-bottom:none}
.lvl{font-family:var(--font-mono);font-weight:600;font-size:12px;letter-spacing:.04em;color:var(--ink)}
/* ---------- ladders ---------- */
.breakout{margin:34px 0 40px}
.bhead{display:flex;justify-content:space-between;align-items:baseline;gap:20px;border-bottom:1px solid var(--rule-strong);padding-bottom:9px;margin-bottom:22px;flex-wrap:wrap}
.bhead h3{margin:0;font-size:13px;letter-spacing:.1em;text-transform:uppercase;font-family:var(--font-mono);font-weight:400;color:var(--ink-3)}
.bhead .note{font-family:var(--font-display);font-size:12.5px;color:var(--ink-3)}
.ladders{display:grid;gap:26px}
.ladder{display:grid;grid-template-columns:126px minmax(0,1fr);gap:18px;align-items:start}
@media (max-width:700px){.ladder{grid-template-columns:1fr;gap:10px}}
.ladder .pname{font-family:var(--font-display);font-weight:700;font-size:14px;letter-spacing:-.01em;padding-top:2px}
.ladder .pname span{display:block;font-family:var(--font-mono);font-size:10px;font-weight:400;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);margin-top:3px}
.rungs{display:grid;gap:3px;grid-template-columns:repeat(5,minmax(0,1fr))}
@media (max-width:700px){.rungs{grid-template-columns:repeat(2,minmax(0,1fr))}}
.rung{padding:9px 10px 11px;background:var(--surface);border-top:4px solid var(--l0);min-width:0}
.rung.r1{border-top-color:var(--l1)} .rung.r2{border-top-color:var(--l2)}
.rung.r3{border-top-color:var(--l3)} .rung.r4{border-top-color:var(--l4)}
.rung .code{font-family:var(--font-mono);font-size:11px;font-weight:600;letter-spacing:.06em;color:var(--ink);display:block;margin-bottom:4px}
.rung .txt{font-family:var(--font-display);font-size:11.5px;line-height:1.34;color:var(--ink-2);display:block}
.rung.na{opacity:.42}
/* ---------- matrix ---------- */
.matrix-shell{display:grid;grid-template-columns:auto minmax(0,1fr);gap:12px;align-items:stretch;margin-bottom:14px}
.ylab{writing-mode:vertical-rl;transform:rotate(180deg);font-family:var(--font-mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);text-align:center;padding-bottom:22px}
.mgrid{display:grid;grid-template-columns:34px repeat(5,minmax(0,1fr));gap:3px}
.mcell{background:var(--surface);min-height:60px;padding:6px;display:flex;flex-direction:column;justify-content:flex-end;gap:4px;min-width:0}
.mcell.tint1{background:color-mix(in srgb,var(--l1) 26%,var(--surface))}
.mcell.tint2{background:color-mix(in srgb,var(--l2) 26%,var(--surface))}
.mcell.tint3{background:color-mix(in srgb,var(--l3) 24%,var(--surface))}
.mcell.tint4{background:color-mix(in srgb,var(--l4) 22%,var(--surface))}
.mcell.void{background:repeating-linear-gradient(135deg,transparent,transparent 5px,var(--rule) 5px,var(--rule) 6px);opacity:.55}
.rlab,.clab{font-family:var(--font-mono);font-size:10px;font-weight:600;letter-spacing:.05em;color:var(--ink-3);display:flex;align-items:center;justify-content:center}
.rlab{min-height:60px}
.clab{padding-top:7px;min-height:22px}
.pin{font-family:var(--font-mono);font-size:9.5px;font-weight:600;letter-spacing:.02em;background:var(--ink);color:var(--paper);padding:2px 5px;border-radius:2px;line-height:1.3;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pin.ghost{background:transparent;color:var(--ink-2);border:1px dashed var(--rule-strong)}
.mnote{display:flex;gap:22px;flex-wrap:wrap;font-family:var(--font-display);font-size:12px;color:var(--ink-3);padding-top:6px}
.mnote .k{display:flex;align-items:center;gap:7px}
.sw{width:13px;height:13px;flex:none;background:var(--ink)}
.sw.g{background:transparent;border:1px dashed var(--rule-strong)}
.sw.v{background:repeating-linear-gradient(135deg,transparent,transparent 4px,var(--rule) 4px,var(--rule) 5px);border:1px solid var(--rule)}
@media (max-width:640px){
.mgrid{grid-template-columns:28px repeat(5,minmax(0,1fr))}
.mcell{min-height:52px;padding:4px}
.pin{font-size:8px;padding:1px 3px}
.rlab{min-height:52px}
}
/* ---------- methodology ---------- */
.verbs{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:2px;background:var(--rule);border:1px solid var(--rule)}
.verb{background:var(--surface);padding:18px 18px 20px}
.verb h4{font-family:var(--font-display);font-weight:750;font-size:15px;margin:0 0 7px;letter-spacing:-.01em}
.verb p{font-family:var(--font-display);font-size:12.5px;line-height:1.46;color:var(--ink-2);margin:0;max-width:none}
.verb .step{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.13em;color:var(--brass);display:block;margin-bottom:9px}
/* ---------- questions ---------- */
.qs{display:flex;flex-direction:column;gap:0;border-top:1px solid var(--rule-strong)}
.q{display:grid;grid-template-columns:34px minmax(0,1fr) 170px;gap:18px;padding:16px 0;border-bottom:1px solid var(--rule);align-items:start}
@media (max-width:760px){.q{grid-template-columns:28px minmax(0,1fr);gap:12px}.q .owner{grid-column:2}}
.q .qn{font-family:var(--font-mono);font-size:11px;color:var(--brass);padding-top:3px}
.q .qt{font-family:var(--font-display);font-size:14px;line-height:1.48;color:var(--ink-2)}
.q .qt b{color:var(--ink);font-weight:700;display:block;margin-bottom:2px;font-size:14.5px}
.owner{font-family:var(--font-mono);font-size:10px;letter-spacing:.05em;color:var(--ink-3);padding-top:4px}
.owner .tag{display:inline-block;border:1px solid var(--rule-strong);padding:2px 7px;border-radius:2px}
.owner .tag.need{border-color:var(--clay);color:var(--clay)}
/* ---------- misc ---------- */
.numbers{font-family:var(--font-mono);font-size:12.5px;line-height:1.85;background:var(--surface);border-left:3px solid var(--l3);padding:16px 20px;margin:0 0 22px;overflow-x:auto;max-width:var(--measure)}
.numbers .v{color:var(--ink);font-weight:600}
.numbers .k{color:var(--ink-3)}
pre{font-family:var(--font-mono);font-size:12.5px;line-height:1.68;background:var(--surface);border-left:3px solid var(--rule-strong);padding:16px 20px;overflow-x:auto;margin:0 0 22px;max-width:var(--measure);color:var(--ink-2)}
.alt{border-bottom:1px solid var(--rule);padding:14px 0;max-width:var(--measure)}
.alt:last-of-type{border-bottom:none}
.alt b{font-family:var(--font-display);font-size:14px;display:block;margin-bottom:3px}
.alt p{font-size:14.5px;margin:0;color:var(--ink-2)}
.alt .verdict{font-family:var(--font-mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--clay)}
footer{border-top:2px solid var(--ink);margin-top:20px;padding-top:22px;font-family:var(--font-mono);font-size:11px;letter-spacing:.06em;color:var(--ink-3);display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap}
.tm td,.tm th{text-align:center}
.tm td:first-child,.tm th:first-child{text-align:left}
.yes{color:var(--l4);font-weight:700}
.no{color:var(--clay);font-weight:700}
.kind{font-family:var(--font-mono);font-size:9px;letter-spacing:.09em;text-transform:uppercase;padding:2px 6px;border-radius:2px;white-space:nowrap;border:1px solid var(--rule-strong);color:var(--ink-3)}
.kind.adv{border-color:var(--clay);color:var(--clay)}
.routes{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:2px;background:var(--rule);border:1px solid var(--rule);margin:0 0 22px}
.route{background:var(--surface);padding:16px 18px}
.route h4{font-family:var(--font-display);font-weight:750;font-size:14px;margin:0 0 6px}
.route p{font-family:var(--font-display);font-size:12.5px;line-height:1.45;color:var(--ink-2);margin:0;max-width:none}
.route .tag{font-family:var(--font-mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:var(--brass);display:block;margin-bottom:8px}
a:focus-visible,.rail a:focus-visible{outline:2px solid var(--brass);outline-offset:3px}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
<div class="wrap"><header><div class="eyebrow"><span>RISK-METHOD-DISCLOSURE</span> <span class="stat">adopted · adopted-1</span> <span>risk-nexus</span> <span>reviewed 2026-08-20</span><span>generated from canonical source — do not edit</span></div><h1>Disclosure</h1><p class="sub">Source: <code>risk-nexus · docs/method/disclosure.md · a13d954f8597fd92201746e2d52f031a5a88d969</code></p><p class="sub">Review due: 2027-02-20</p></header><div class="layout"><nav class="rail" aria-label="Sections"><ol><li><a href="#what-disclosure-is-not"><span class="n">·</span>What disclosure is not</a></li><li><a href="#the-states"><span class="n">·</span>The states</a></li><li><a href="#embargo-is-a-record-not-a-silence"><span class="n">·</span>Embargo is a record, not a silence</a></li><li><a href="#the-build-mode-deferral-re-taken"><span class="n">·</span>The build-mode deferral, re-taken</a></li><li><a href="#test-for-shortens-the-path"><span class="n">·</span>Test for &quot;shortens the path&quot;</a></li><li><a href="#publication-happens-elsewhere"><span class="n">·</span>Publication happens elsewhere</a></li><li><a href="#the-standing-route-when-an-embargo-lifts"><span class="n">·</span>The standing route, when an embargo lifts</a></li></ol></nav><main><p>Whether and when a finding is published. <code>policy-nexus</code> is the surface; this document decides what it is handed.</p>
<section id="what-disclosure-is-not"><h2>What disclosure is not</h2>
<p><strong>A finding file in this repo is not a publication.</strong> This repo is a private checkout on a private forge. Holding a finding means not routing it to <code>policy-nexus</code>; it does not mean hiding it from the estate, from the owning repo, or from the operator. Every state below is fully visible internally.</p>
</section>
<section id="the-states"><h2>The states</h2>
<div class="scroll"><table><thead><tr><th>State</th><th>Meaning</th><th>Entry condition</th></tr></thead><tbody><tr><td><code>public</code></td><td>Published through <code>policy-nexus</code> now.</td><td>The finding is fixed, or reading it gives no one an advantage they do not already have.</td></tr><tr><td><code>embargoed</code></td><td>Held, with a stated condition that lifts it.</td><td>Live, unfixed, and the text would help someone reach the defect faster than they could without it.</td></tr><tr><td><code>restricted</code></td><td>Held with no expected lift.</td><td>Publication would remain harmful after the fix — third-party material, a named person, or a credential-shaped detail that survives remediation.</td></tr></tbody></table></div>
<p>There is no fourth state and no <code>unset</code> after grading. A finding whose disclosure has not been decided is an ungraded finding.</p>
</section>
<section id="embargo-is-a-record-not-a-silence"><h2>Embargo is a record, not a silence</h2>
<p><code>INTENT.md</code> requires the record that a delay was deliberate rather than a document quietly going missing. An <code>embargoed</code> finding therefore carries:</p>
<pre>disclosure: embargoed
embargo_condition: &quot;FLEX-WP-0015-T02 ships to production&quot;
embargo_since: &quot;2026-08-19&quot;
embargo_review: &quot;2026-08-26&quot;</pre>
<p><code>embargo_condition</code> must be an event someone can observe, not a mood. "Until it is safer" is not a condition. <code>embargo_review</code> follows the finding's severity interval from <code>docs/method/review.md</code>; when it passes, the embargo is re-decided, not extended by default.</p>
<p>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.</p>
</section>
<section id="the-build-mode-deferral-re-taken"><h2>The build-mode deferral, re-taken</h2>
<p><code>INTENT.md</code> recorded controlled disclosure as deferred to production, reasoning that build mode has no users to expose. <code>RISK-F-0001</code> arrived and tested it: a live authorization bypass in the service every other service trusts, with publish-or-forget as the only available choice.</p>
<p><strong>The deferral is narrowed, not kept and not abandoned.</strong></p>
<p>What was right about it: build mode does have no consumers to protect, and building an embargo <em>mechanism</em> — timed release, staged notification, coordinated disclosure with third parties — before there is anyone to coordinate with would be machinery for its own sake.</p>
<p>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 <code>RISK-F-0001</code> 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.</p>
<p>So the ruling is:</p>
<ol><li><strong>Build-mode default stays publish.</strong> 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.</li><li><strong>Live-and-reachable is the exception, and it exists now.</strong> A finding that is unfixed <em>and</em> whose text shortens the path to the defect is <code>embargoed</code> until the fix lands. That is the missing middle <code>INTENT.md</code> said did not exist. It costs one front-matter field and a line in <code>REGISTER.md</code>.</li><li><strong>The mechanism stays deferred.</strong> No timed release, no coordinated disclosure protocol, no notification tiers. Those wait for real users, as originally reasoned. What is not deferred is the <em>decision</em>, because <code>RISK-F-0001</code> demonstrated the decision is needed before the machinery is.</li></ol>
<p>This is a decision of this repo, taken 2026-08-19 with <code>RISK-F-0001</code>, <code>RISK-F-0002</code> and <code>RISK-F-0003</code> in hand rather than hypothetically. It is revisable, and the production transition is the scheduled moment to revisit it.</p>
</section>
<section id="test-for-shortens-the-path"><h2>Test for "shortens the path"</h2>
<p>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?</p>
<ul><li>A file path and line number in a private repo — no, that is already there.</li><li>"This surface authenticates nobody, here is its cluster address" — yes.</li><li>"These five named lanes vend real secret values without the boundary firing" — yes.</li><li>"This system had no backups configured" — no, once backups exist; yes, while they do not, because it names when destruction is unrecoverable.</li></ul>
<p>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.</p>
</section>
<section id="publication-happens-elsewhere"><h2>Publication happens elsewhere</h2>
<p>A <code>public</code> finding is handed to <code>policy-nexus</code> 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.</p>
</section>
<section id="the-standing-route-when-an-embargo-lifts"><h2>The standing route, when an embargo lifts</h2>
<p><code>RISK-WP-0002-T03</code>. 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.</p>
<ol><li><strong>The check that lifts the embargo records it.</strong> <code>make checked</code> on the finding, with the lift as the reason. An embargo lifting is never a clean check — something moved.</li><li><strong>The finding gets publication front-matter</strong>, in the shape <code>policy-nexus</code> already requires of everyone: <code>owner</code>, <code>revision</code>, <code>last_reviewed</code>, <code>review_interval</code>. No body rewrite.</li><li><strong>This repo asks <code>policy-nexus</code> for an entry</strong>, giving <code>source_repo</code>, <code>source_path</code>, a proposed <code>canonical_path</code> under <code>findings/&lt;id&gt;/&lt;version&gt;/</code>, and a one-line subtitle. Addressing and permanence are theirs (<code>POLICY-NEXUS-WP-0001</code>); this repo does not invent a scheme.</li><li><strong><code>publication: published</code> is recorded back on the finding</strong>, with the URL. A finding that says <code>public</code> but has no address is a claim, not a publication — the same class of error as a backup nobody has restored from.</li></ol>
<p>The contract publishes <strong>a file from the owning repo</strong>, 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 <em>file</em> contains, not about how it is rendered.</p>
</section><footer><span>RISK-METHOD-DISCLOSURE · adopted-1 · adopted</span><span>risk-nexus · docs/method/disclosure.md · a13d954f8597fd92201746e2d52f031a5a88d969</span></footer></main></div></div></html>

View file

@ -0,0 +1,244 @@
<!doctype html>
<html lang="en"><meta charset="utf-8">
<meta name="policy-source-revision" content="c5517c754bd84b0ebf47878ba0f26df0ecb3b4a4">
<meta name="policy-source-digest" content="8f873d105bf6bd711a1a15ebd739b2abe97365b4e854be9d1c82e3ff3b162cfd">
<title>Review and expiry</title>
<style>
:root{
--paper:#EDEEF0; --surface:#F6F7F8; --surface-2:#E4E6E9;
--ink:#171D24; --ink-2:#4A5561; --ink-3:#737E8A;
--rule:#D3D7DC; --rule-strong:#B6BCC3;
--brass:#8A6A2E; --brass-soft:#EFE5CD; --brass-line:#C9AE74;
--clay:#8A3A2C; --clay-soft:#F2DFDA;
--l0:#DCE0E2; --l1:#B9C4C7; --l2:#8CA1A6; --l3:#567D84; --l4:#23555E;
--chip-fg:#F6F7F8;
--font-display:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",sans-serif;
--font-body:"Iowan Old Style","Palatino Linotype",Palatino,Georgia,serif;
--font-mono:ui-monospace,"SF Mono","Cascadia Code",Menlo,Consolas,monospace;
--measure:66ch;
}
@media (prefers-color-scheme:dark){
:root:not([data-theme="light"]){
--paper:#12161A; --surface:#191E24; --surface-2:#222831;
--ink:#E6E9EC; --ink-2:#A3ADB7; --ink-3:#78838E;
--rule:#2A3138; --rule-strong:#3B444D;
--brass:#C9A45C; --brass-soft:#33290F; --brass-line:#6B5426;
--clay:#D08A76; --clay-soft:#3A211B;
--l0:#262C32; --l1:#35424A; --l2:#4A626B; --l3:#6A939D; --l4:#97C4CD;
--chip-fg:#12161A;
}
}
:root[data-theme="dark"]{
--paper:#12161A; --surface:#191E24; --surface-2:#222831;
--ink:#E6E9EC; --ink-2:#A3ADB7; --ink-3:#78838E;
--rule:#2A3138; --rule-strong:#3B444D;
--brass:#C9A45C; --brass-soft:#33290F; --brass-line:#6B5426;
--clay:#D08A76; --clay-soft:#3A211B;
--l0:#262C32; --l1:#35424A; --l2:#4A626B; --l3:#6A939D; --l4:#97C4CD;
--chip-fg:#12161A;
}
*{box-sizing:border-box}
body{
margin:0; background:var(--paper); color:var(--ink);
font-family:var(--font-body); font-size:17px; line-height:1.62;
-webkit-font-smoothing:antialiased;
}
.wrap{max-width:1180px;margin:0 auto;padding:0 24px 96px}
.layout{display:grid;grid-template-columns:180px minmax(0,1fr);gap:56px;align-items:start}
@media (max-width:960px){.layout{grid-template-columns:1fr;gap:0}.rail{display:none}}
/* ---------- rail ---------- */
.rail{position:sticky;top:28px;padding-top:8px;font-family:var(--font-display);font-size:12px;line-height:1.5}
.rail ol{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:7px}
.rail a{color:var(--ink-3);text-decoration:none;display:flex;gap:9px}
.rail a:hover,.rail a:focus-visible{color:var(--brass)}
.rail .n{font-family:var(--font-mono);font-size:10px;color:var(--rule-strong);min-width:16px;padding-top:1px}
.rail .grp{margin-top:14px;font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--rule-strong)}
/* ---------- header ---------- */
header{padding:64px 0 40px;border-bottom:2px solid var(--ink);margin-bottom:44px}
.eyebrow{font-family:var(--font-mono);font-size:11.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);display:flex;flex-wrap:wrap;gap:14px;margin-bottom:22px}
.eyebrow .stat{color:var(--clay)}
h1{font-family:var(--font-display);font-weight:800;letter-spacing:-.035em;line-height:.94;font-size:clamp(46px,9vw,92px);margin:0 0 6px;text-wrap:balance}
.sub{font-family:var(--font-display);font-weight:500;font-size:clamp(16px,2.4vw,21px);letter-spacing:-.01em;color:var(--ink-2);margin:0 0 30px;max-width:34ch;line-height:1.3}
.metagrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:20px 28px;border-top:1px solid var(--rule);padding-top:20px}
.metagrid dt{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);margin-bottom:5px}
.metagrid dd{margin:0;font-family:var(--font-display);font-size:13.5px;line-height:1.45;color:var(--ink)}
/* ---------- typography ---------- */
section{margin-bottom:60px;scroll-margin-top:24px}
h2{font-family:var(--font-display);font-weight:750;letter-spacing:-.022em;font-size:clamp(24px,3.4vw,31px);line-height:1.12;margin:0 0 18px;text-wrap:balance;display:flex;gap:14px;align-items:baseline}
h2 .sn{font-family:var(--font-mono);font-size:12px;font-weight:400;color:var(--brass);letter-spacing:.06em;flex:none;padding-top:2px}
h3{font-family:var(--font-display);font-weight:700;font-size:16px;letter-spacing:-.008em;margin:34px 0 10px;color:var(--ink)}
p{margin:0 0 15px;max-width:var(--measure)}
ul,ol{max-width:var(--measure);margin:0 0 15px;padding-left:20px}
li{margin-bottom:7px}
strong{font-weight:600}
em{font-style:italic}
code{font-family:var(--font-mono);font-size:.855em;background:var(--surface-2);padding:1px 5px;border-radius:2px}
a{color:var(--brass)}
.lede{font-size:19px;line-height:1.55;color:var(--ink-2);max-width:60ch}
/* ---------- devices ---------- */
.callout{border-left:3px solid var(--brass);background:var(--brass-soft);padding:18px 22px;margin:0 0 24px;max-width:var(--measure)}
.callout p:last-child{margin-bottom:0}
.callout .lbl{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--brass);display:block;margin-bottom:8px}
.rule-quote{border-top:2px solid var(--ink);border-bottom:2px solid var(--ink);padding:26px 0;margin:28px 0;max-width:var(--measure)}
.rule-quote p{font-family:var(--font-display);font-weight:600;font-size:19px;line-height:1.38;letter-spacing:-.014em;margin:0;text-wrap:balance}
.hard{border-left:3px solid var(--clay);background:var(--clay-soft);padding:18px 22px;margin:0 0 24px;max-width:var(--measure)}
.hard .lbl{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--clay);display:block;margin-bottom:8px}
.hard p:last-child{margin-bottom:0}
.dec{font-family:var(--font-mono);font-size:10.5px;letter-spacing:.08em;color:var(--brass);text-transform:uppercase}
.vec{font-family:var(--font-mono);font-size:.9em;font-weight:600;background:var(--surface-2);padding:2px 7px;border-radius:2px;white-space:nowrap;letter-spacing:.04em}
/* ---------- tables ---------- */
.scroll{overflow-x:auto;margin:0 0 24px;-webkit-overflow-scrolling:touch}
table{border-collapse:collapse;width:100%;min-width:520px;font-family:var(--font-display);font-size:13.5px;line-height:1.45}
th{text-align:left;font-family:var(--font-mono);font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);font-weight:400;padding:0 16px 8px 0;border-bottom:1px solid var(--rule-strong);vertical-align:bottom}
td{padding:11px 16px 11px 0;border-bottom:1px solid var(--rule);vertical-align:top;color:var(--ink-2)}
td:first-child{color:var(--ink);font-weight:600}
tbody tr:last-child td{border-bottom:none}
.lvl{font-family:var(--font-mono);font-weight:600;font-size:12px;letter-spacing:.04em;color:var(--ink)}
/* ---------- ladders ---------- */
.breakout{margin:34px 0 40px}
.bhead{display:flex;justify-content:space-between;align-items:baseline;gap:20px;border-bottom:1px solid var(--rule-strong);padding-bottom:9px;margin-bottom:22px;flex-wrap:wrap}
.bhead h3{margin:0;font-size:13px;letter-spacing:.1em;text-transform:uppercase;font-family:var(--font-mono);font-weight:400;color:var(--ink-3)}
.bhead .note{font-family:var(--font-display);font-size:12.5px;color:var(--ink-3)}
.ladders{display:grid;gap:26px}
.ladder{display:grid;grid-template-columns:126px minmax(0,1fr);gap:18px;align-items:start}
@media (max-width:700px){.ladder{grid-template-columns:1fr;gap:10px}}
.ladder .pname{font-family:var(--font-display);font-weight:700;font-size:14px;letter-spacing:-.01em;padding-top:2px}
.ladder .pname span{display:block;font-family:var(--font-mono);font-size:10px;font-weight:400;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);margin-top:3px}
.rungs{display:grid;gap:3px;grid-template-columns:repeat(5,minmax(0,1fr))}
@media (max-width:700px){.rungs{grid-template-columns:repeat(2,minmax(0,1fr))}}
.rung{padding:9px 10px 11px;background:var(--surface);border-top:4px solid var(--l0);min-width:0}
.rung.r1{border-top-color:var(--l1)} .rung.r2{border-top-color:var(--l2)}
.rung.r3{border-top-color:var(--l3)} .rung.r4{border-top-color:var(--l4)}
.rung .code{font-family:var(--font-mono);font-size:11px;font-weight:600;letter-spacing:.06em;color:var(--ink);display:block;margin-bottom:4px}
.rung .txt{font-family:var(--font-display);font-size:11.5px;line-height:1.34;color:var(--ink-2);display:block}
.rung.na{opacity:.42}
/* ---------- matrix ---------- */
.matrix-shell{display:grid;grid-template-columns:auto minmax(0,1fr);gap:12px;align-items:stretch;margin-bottom:14px}
.ylab{writing-mode:vertical-rl;transform:rotate(180deg);font-family:var(--font-mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);text-align:center;padding-bottom:22px}
.mgrid{display:grid;grid-template-columns:34px repeat(5,minmax(0,1fr));gap:3px}
.mcell{background:var(--surface);min-height:60px;padding:6px;display:flex;flex-direction:column;justify-content:flex-end;gap:4px;min-width:0}
.mcell.tint1{background:color-mix(in srgb,var(--l1) 26%,var(--surface))}
.mcell.tint2{background:color-mix(in srgb,var(--l2) 26%,var(--surface))}
.mcell.tint3{background:color-mix(in srgb,var(--l3) 24%,var(--surface))}
.mcell.tint4{background:color-mix(in srgb,var(--l4) 22%,var(--surface))}
.mcell.void{background:repeating-linear-gradient(135deg,transparent,transparent 5px,var(--rule) 5px,var(--rule) 6px);opacity:.55}
.rlab,.clab{font-family:var(--font-mono);font-size:10px;font-weight:600;letter-spacing:.05em;color:var(--ink-3);display:flex;align-items:center;justify-content:center}
.rlab{min-height:60px}
.clab{padding-top:7px;min-height:22px}
.pin{font-family:var(--font-mono);font-size:9.5px;font-weight:600;letter-spacing:.02em;background:var(--ink);color:var(--paper);padding:2px 5px;border-radius:2px;line-height:1.3;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pin.ghost{background:transparent;color:var(--ink-2);border:1px dashed var(--rule-strong)}
.mnote{display:flex;gap:22px;flex-wrap:wrap;font-family:var(--font-display);font-size:12px;color:var(--ink-3);padding-top:6px}
.mnote .k{display:flex;align-items:center;gap:7px}
.sw{width:13px;height:13px;flex:none;background:var(--ink)}
.sw.g{background:transparent;border:1px dashed var(--rule-strong)}
.sw.v{background:repeating-linear-gradient(135deg,transparent,transparent 4px,var(--rule) 4px,var(--rule) 5px);border:1px solid var(--rule)}
@media (max-width:640px){
.mgrid{grid-template-columns:28px repeat(5,minmax(0,1fr))}
.mcell{min-height:52px;padding:4px}
.pin{font-size:8px;padding:1px 3px}
.rlab{min-height:52px}
}
/* ---------- methodology ---------- */
.verbs{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:2px;background:var(--rule);border:1px solid var(--rule)}
.verb{background:var(--surface);padding:18px 18px 20px}
.verb h4{font-family:var(--font-display);font-weight:750;font-size:15px;margin:0 0 7px;letter-spacing:-.01em}
.verb p{font-family:var(--font-display);font-size:12.5px;line-height:1.46;color:var(--ink-2);margin:0;max-width:none}
.verb .step{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.13em;color:var(--brass);display:block;margin-bottom:9px}
/* ---------- questions ---------- */
.qs{display:flex;flex-direction:column;gap:0;border-top:1px solid var(--rule-strong)}
.q{display:grid;grid-template-columns:34px minmax(0,1fr) 170px;gap:18px;padding:16px 0;border-bottom:1px solid var(--rule);align-items:start}
@media (max-width:760px){.q{grid-template-columns:28px minmax(0,1fr);gap:12px}.q .owner{grid-column:2}}
.q .qn{font-family:var(--font-mono);font-size:11px;color:var(--brass);padding-top:3px}
.q .qt{font-family:var(--font-display);font-size:14px;line-height:1.48;color:var(--ink-2)}
.q .qt b{color:var(--ink);font-weight:700;display:block;margin-bottom:2px;font-size:14.5px}
.owner{font-family:var(--font-mono);font-size:10px;letter-spacing:.05em;color:var(--ink-3);padding-top:4px}
.owner .tag{display:inline-block;border:1px solid var(--rule-strong);padding:2px 7px;border-radius:2px}
.owner .tag.need{border-color:var(--clay);color:var(--clay)}
/* ---------- misc ---------- */
.numbers{font-family:var(--font-mono);font-size:12.5px;line-height:1.85;background:var(--surface);border-left:3px solid var(--l3);padding:16px 20px;margin:0 0 22px;overflow-x:auto;max-width:var(--measure)}
.numbers .v{color:var(--ink);font-weight:600}
.numbers .k{color:var(--ink-3)}
pre{font-family:var(--font-mono);font-size:12.5px;line-height:1.68;background:var(--surface);border-left:3px solid var(--rule-strong);padding:16px 20px;overflow-x:auto;margin:0 0 22px;max-width:var(--measure);color:var(--ink-2)}
.alt{border-bottom:1px solid var(--rule);padding:14px 0;max-width:var(--measure)}
.alt:last-of-type{border-bottom:none}
.alt b{font-family:var(--font-display);font-size:14px;display:block;margin-bottom:3px}
.alt p{font-size:14.5px;margin:0;color:var(--ink-2)}
.alt .verdict{font-family:var(--font-mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--clay)}
footer{border-top:2px solid var(--ink);margin-top:20px;padding-top:22px;font-family:var(--font-mono);font-size:11px;letter-spacing:.06em;color:var(--ink-3);display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap}
.tm td,.tm th{text-align:center}
.tm td:first-child,.tm th:first-child{text-align:left}
.yes{color:var(--l4);font-weight:700}
.no{color:var(--clay);font-weight:700}
.kind{font-family:var(--font-mono);font-size:9px;letter-spacing:.09em;text-transform:uppercase;padding:2px 6px;border-radius:2px;white-space:nowrap;border:1px solid var(--rule-strong);color:var(--ink-3)}
.kind.adv{border-color:var(--clay);color:var(--clay)}
.routes{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:2px;background:var(--rule);border:1px solid var(--rule);margin:0 0 22px}
.route{background:var(--surface);padding:16px 18px}
.route h4{font-family:var(--font-display);font-weight:750;font-size:14px;margin:0 0 6px}
.route p{font-family:var(--font-display);font-size:12.5px;line-height:1.45;color:var(--ink-2);margin:0;max-width:none}
.route .tag{font-family:var(--font-mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:var(--brass);display:block;margin-bottom:8px}
a:focus-visible,.rail a:focus-visible{outline:2px solid var(--brass);outline-offset:3px}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
<div class="wrap"><header><div class="eyebrow"><span>RISK-METHOD-REVIEW</span> <span class="stat">adopted · adopted-1</span> <span>risk-nexus</span> <span>reviewed 2026-08-20</span><span>generated from canonical source — do not edit</span></div><h1>Review and expiry</h1><p class="sub">Source: <code>risk-nexus · docs/method/review.md · c5517c754bd84b0ebf47878ba0f26df0ecb3b4a4</code></p><p class="sub">Review due: 2027-02-20</p></header><div class="layout"><nav class="rail" aria-label="Sections"><ol><li><a href="#the-cadence-ladder"><span class="n">·</span>The cadence ladder</a></li><li><a href="#what-a-review-is"><span class="n">·</span>What a review is</a></li><li><a href="#when-a-check-is-missed"><span class="n">·</span>When a check is missed</a></li><li><a href="#the-production-re-score"><span class="n">·</span>The production re-score</a></li><li><a href="#front-matter-this-adds"><span class="n">·</span>Front-matter this adds</a></li><li><a href="#closing-a-finding"><span class="n">·</span>Closing a finding</a></li></ol></nav><main><p><code>INTENT.md</code>: a finding that has sat untouched past its review date is itself a finding. Silence is not resolution. This document makes that operable.</p>
<section id="the-cadence-ladder"><h2>The cadence ladder</h2>
<p>Operator ruling, 2026-08-20. <strong>Intervals are not set by severity. They are earned by outcomes.</strong></p>
<p>A finding is checked, and the check comes back clean or it does not. Clean climbs one rung. Anything wrong drops straight back to the bottom.</p>
<div class="scroll"><table><thead><tr><th>Rung</th><th>Wait before the next check</th></tr></thead><tbody><tr><td><code>instant</code></td><td>now, and again immediately until a check comes back clean</td></tr><tr><td><code>1h</code></td><td>one hour</td></tr><tr><td><code>8h</code></td><td>eight hours</td></tr><tr><td><code>24h</code></td><td>one day</td></tr><tr><td><code>48h</code></td><td>two days</td></tr><tr><td><code>96h</code></td><td>four days</td></tr><tr><td><code>7d</code></td><td>one week</td></tr><tr><td><code>14d</code></td><td>two weeks</td></tr><tr><td><code>1mo</code></td><td>one month</td></tr><tr><td><code>1q</code></td><td>one quarter — <strong>the ceiling; nothing is ever checked less often than this</strong></td></tr></tbody></table></div>
<p>Two rules and one escape:</p>
<ul><li><strong>Climb on clean.</strong> One rung per clean check, never two.</li><li><strong>Reset on anything wrong.</strong> Not a slide down one rung — straight to <code>instant</code>. A matter that has just moved has no track record, whatever it had before.</li><li><strong>The operator may defer.</strong> An <code>instant</code> finding can be deferred to a stated future date by explicit operator decision, recorded as <code>deferred_to</code>. That is the only way out of the bottom rung other than a clean check, and it is a decision with a name on it rather than a check quietly not happening.</li></ul>
<h3>Who checked, and when anyone last did</h3>
<p><code>RISK-WP-0005-T06</code>. Two defences against the rung telling a lie:</p>
<ul><li><strong><code>checked_by</code> on every check.</strong> <code>record_check.py</code> writes it. A rung earned by nobody in particular is visible as such.</li><li><strong>A heartbeat.</strong> If nothing anywhere in the register has been checked for two days, <code>make check</code> says so <strong>before anything else</strong>. A <code>1q</code> rung means "stable for a quarter" and "nobody looked for a quarter", and those read identically from the outside — the heartbeat is what separates them.</li></ul>
<h3>The rung is the signal</h3>
<p>This is the point of the design, not a side effect. <strong>The cadence a finding sits on is a statement about how stable the estate has been on that matter.</strong></p>
<p><code>RISK-F-0002</code> at <code>1q (9)</code> says the signing gate has been examined ten times over three months and nothing has moved. <code>RISK-F-0002</code> at <code>instant (0)</code> says something changed within the day. The number carries information that no severity does — severity says how bad it would be, the rung says how settled it is — and the two are independent. A <code>low</code> finding that keeps resetting is telling you something a <code>critical</code> one at the ceiling is not.</p>
<p>It is also self-correcting in the direction that matters. Anything volatile gets attention often, automatically, without anyone deciding it deserves it; anything genuinely quiet stops consuming attention, without anyone deciding to stop looking. Neither of those judgements has to be made by a person who might be wrong or busy.</p>
<h3>What "clean" means</h3>
<p>A check is <strong>clean</strong> when nothing about the assessment moved: the grade still holds, every stated blocker is still true, the fix state is unchanged, the disclosure state is still right, and no new fact has arrived.</p>
<p>A check is <strong>not clean</strong> when any of those moved — including when they moved in a good direction. <code>RISK-F-0001</code> being fixed is not a clean check; it is a large change, and the next check comes immediately. Good news resets the ladder exactly like bad news, because the ladder measures stillness, not health.</p>
<h3>Starting position</h3>
<p>Every finding starts at <code>instant</code>. A register with no check history has no grounds to wait, and the first clean check is what buys the first hour.</p>
<p>The whole register sat at <code>instant (0)</code> on 2026-08-20, which is correct and temporary: everything in it had been graded, re-graded or ruled on within the preceding day.</p>
</section>
<section id="what-a-review-is"><h2>What a review is</h2>
<p>Five questions, answered in writing on the finding. It takes minutes; it is not an investigation.</p>
<ol><li><strong>Has the inbox said anything?</strong> Read the messages addressed to this repo before anything else. This is question zero because on 2026-08-19 the register graded <code>RISK-F-0001</code> <code>critical</code> while two messages sat unread in its own inbox — one narrowing the exposure, one reporting the fix. Both changed the grade. A register that does not read its own inbox is guessing with a straight face.</li><li><strong>Is the grade still right?</strong> Re-read impact and likelihood against what has changed. New facts move the grade in both directions.</li><li><strong>Is the blocker still true?</strong> This is the one <code>RISK-F-0002</code> bought with evidence: <em>a blocker is a claim about the world at a date</em>. Its own stated blocker — "<code>flex-auth</code> is not deployed yet" — was invalidated within a day by <code>RISK-F-0001</code>, and nothing would have re-checked it. Every review re-checks every stated blocker.</li><li><strong>Has the fix moved?</strong> Read the owner's tracking record, not our memory of it. Confirm the record still exists and still refers to this defect.</li><li><strong>Is the disclosure state still right?</strong> An embargo whose condition has been met is published; an embargo whose condition has not moved in two reviews is a stall.</li></ol>
<p>The finding gets a dated line under <code>## Reviews</code>, <code>last_reviewed</code> is updated, and <code>review_by</code> is pushed by one interval. A review that changes nothing still writes the line — "checked, nothing moved" is the evidence that the silence was observed rather than accidental.</p>
</section>
<section id="when-a-check-is-missed"><h2>When a check is missed</h2>
<p>Overdue is not a status change on the finding. It is a fact about <em>this repo</em>, and it surfaces in three places:</p>
<ul><li><code>make check</code> lists it under "Checks due", with how late it is and which rung it is on.</li><li><code>REGISTER.md</code> shows the next check as <strong>due</strong>.</li><li>A finding sitting at the bottom rung for more than fourteen days with no movement fires escalation trigger 5. Bottom rung means it keeps failing or keeps being skipped; fourteen days of that is a stall whichever it is.</li></ul>
<p>The register does not auto-escalate severity for lateness and does not auto-close anything. Both would be the register lying about its own state to make a number look better.</p>
</section>
<section id="the-production-re-score"><h2>The production re-score</h2>
<p>Every finding carries <code>severity_at_production</code> alongside <code>severity</code> (<code>docs/method/severity.md</code>). Where the two differ, the finding is flagged <code>production_rescore: true</code>.</p>
<p>On the day any part of the estate declares production readiness, every flagged finding is re-scored before that declaration completes. This is not a review date — it is an event, and it fires regardless of where the review dates happen to sit.</p>
<p>Until then, <code>make check</code> lists the flagged findings so the size of that obligation is visible rather than discovered on the day.</p>
</section>
<section id="front-matter-this-adds"><h2>Front-matter this adds</h2>
<pre>last_checked: &quot;2026-08-20T05:40:00Z&quot;
next_check: &quot;2026-08-20T06:40:00Z&quot;
cadence: 1h
clean_streak: 1
production_rescore: true
deferred_to: &quot;&quot; # only by explicit operator decision</pre>
<p><code>next_check</code> is what the nag reads, and it is an absolute moment rather than a duration, so nothing has to recompute an interval to know whether a check is late. The rungs run in hours as well as days, so it carries a time.</p>
</section>
<section id="closing-a-finding"><h2>Closing a finding</h2>
<p>A finding leaves <code>open</code> for exactly one of:</p>
<ul><li><code>fixed</code> — the owner's record shows the defect gone, and this repo has read something concrete rather than been told. Publication follows if the disclosure state was <code>embargoed</code>.</li><li><code>accepted</code> — the estate is deliberately carrying it. Requires who accepted it, why, and what ends the acceptance. <code>accepted</code> is not closed: it stays on the ladder forever, and it climbs like anything else.</li><li><code>mitigated</code> — the live gap is closed but the finding is not. <code>RISK-F-0003</code> is the case: the boundary now fires, and the omission that let it not fire is still there. Stays watched.</li><li><code>withdrawn</code> — the finding was wrong, or the defect never existed. Say which.</li></ul>
<p><strong>Any status the tooling does not recognise keeps the finding watched, and the unrecognised word is reported.</strong> <code>RISK-F-0003</code> arrived as <code>mitigated</code> on 2026-08-20, before that word existed here, and dropped silently out of <code>make check</code> — a finding vanishing from the nag because someone used an unfamiliar word is precisely the failure this register exists to prevent. The tooling now fails loud instead of quiet.</p>
<p>There is no <code>stale</code>, no <code>wontfix</code> and no silent expiry. A finding that nobody will fix and nobody will accept stays <code>open</code> and keeps arriving in the nag, because that is the true state.</p>
</section><footer><span>RISK-METHOD-REVIEW · adopted-1 · adopted</span><span>risk-nexus · docs/method/review.md · c5517c754bd84b0ebf47878ba0f26df0ecb3b4a4</span></footer></main></div></div></html>

View file

@ -0,0 +1,244 @@
<!doctype html>
<html lang="en"><meta charset="utf-8">
<meta name="policy-source-revision" content="a13d954f8597fd92201746e2d52f031a5a88d969">
<meta name="policy-source-digest" content="8f873d105bf6bd711a1a15ebd739b2abe97365b4e854be9d1c82e3ff3b162cfd">
<title>Review and expiry</title>
<style>
:root{
--paper:#EDEEF0; --surface:#F6F7F8; --surface-2:#E4E6E9;
--ink:#171D24; --ink-2:#4A5561; --ink-3:#737E8A;
--rule:#D3D7DC; --rule-strong:#B6BCC3;
--brass:#8A6A2E; --brass-soft:#EFE5CD; --brass-line:#C9AE74;
--clay:#8A3A2C; --clay-soft:#F2DFDA;
--l0:#DCE0E2; --l1:#B9C4C7; --l2:#8CA1A6; --l3:#567D84; --l4:#23555E;
--chip-fg:#F6F7F8;
--font-display:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",sans-serif;
--font-body:"Iowan Old Style","Palatino Linotype",Palatino,Georgia,serif;
--font-mono:ui-monospace,"SF Mono","Cascadia Code",Menlo,Consolas,monospace;
--measure:66ch;
}
@media (prefers-color-scheme:dark){
:root:not([data-theme="light"]){
--paper:#12161A; --surface:#191E24; --surface-2:#222831;
--ink:#E6E9EC; --ink-2:#A3ADB7; --ink-3:#78838E;
--rule:#2A3138; --rule-strong:#3B444D;
--brass:#C9A45C; --brass-soft:#33290F; --brass-line:#6B5426;
--clay:#D08A76; --clay-soft:#3A211B;
--l0:#262C32; --l1:#35424A; --l2:#4A626B; --l3:#6A939D; --l4:#97C4CD;
--chip-fg:#12161A;
}
}
:root[data-theme="dark"]{
--paper:#12161A; --surface:#191E24; --surface-2:#222831;
--ink:#E6E9EC; --ink-2:#A3ADB7; --ink-3:#78838E;
--rule:#2A3138; --rule-strong:#3B444D;
--brass:#C9A45C; --brass-soft:#33290F; --brass-line:#6B5426;
--clay:#D08A76; --clay-soft:#3A211B;
--l0:#262C32; --l1:#35424A; --l2:#4A626B; --l3:#6A939D; --l4:#97C4CD;
--chip-fg:#12161A;
}
*{box-sizing:border-box}
body{
margin:0; background:var(--paper); color:var(--ink);
font-family:var(--font-body); font-size:17px; line-height:1.62;
-webkit-font-smoothing:antialiased;
}
.wrap{max-width:1180px;margin:0 auto;padding:0 24px 96px}
.layout{display:grid;grid-template-columns:180px minmax(0,1fr);gap:56px;align-items:start}
@media (max-width:960px){.layout{grid-template-columns:1fr;gap:0}.rail{display:none}}
/* ---------- rail ---------- */
.rail{position:sticky;top:28px;padding-top:8px;font-family:var(--font-display);font-size:12px;line-height:1.5}
.rail ol{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:7px}
.rail a{color:var(--ink-3);text-decoration:none;display:flex;gap:9px}
.rail a:hover,.rail a:focus-visible{color:var(--brass)}
.rail .n{font-family:var(--font-mono);font-size:10px;color:var(--rule-strong);min-width:16px;padding-top:1px}
.rail .grp{margin-top:14px;font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--rule-strong)}
/* ---------- header ---------- */
header{padding:64px 0 40px;border-bottom:2px solid var(--ink);margin-bottom:44px}
.eyebrow{font-family:var(--font-mono);font-size:11.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);display:flex;flex-wrap:wrap;gap:14px;margin-bottom:22px}
.eyebrow .stat{color:var(--clay)}
h1{font-family:var(--font-display);font-weight:800;letter-spacing:-.035em;line-height:.94;font-size:clamp(46px,9vw,92px);margin:0 0 6px;text-wrap:balance}
.sub{font-family:var(--font-display);font-weight:500;font-size:clamp(16px,2.4vw,21px);letter-spacing:-.01em;color:var(--ink-2);margin:0 0 30px;max-width:34ch;line-height:1.3}
.metagrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:20px 28px;border-top:1px solid var(--rule);padding-top:20px}
.metagrid dt{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);margin-bottom:5px}
.metagrid dd{margin:0;font-family:var(--font-display);font-size:13.5px;line-height:1.45;color:var(--ink)}
/* ---------- typography ---------- */
section{margin-bottom:60px;scroll-margin-top:24px}
h2{font-family:var(--font-display);font-weight:750;letter-spacing:-.022em;font-size:clamp(24px,3.4vw,31px);line-height:1.12;margin:0 0 18px;text-wrap:balance;display:flex;gap:14px;align-items:baseline}
h2 .sn{font-family:var(--font-mono);font-size:12px;font-weight:400;color:var(--brass);letter-spacing:.06em;flex:none;padding-top:2px}
h3{font-family:var(--font-display);font-weight:700;font-size:16px;letter-spacing:-.008em;margin:34px 0 10px;color:var(--ink)}
p{margin:0 0 15px;max-width:var(--measure)}
ul,ol{max-width:var(--measure);margin:0 0 15px;padding-left:20px}
li{margin-bottom:7px}
strong{font-weight:600}
em{font-style:italic}
code{font-family:var(--font-mono);font-size:.855em;background:var(--surface-2);padding:1px 5px;border-radius:2px}
a{color:var(--brass)}
.lede{font-size:19px;line-height:1.55;color:var(--ink-2);max-width:60ch}
/* ---------- devices ---------- */
.callout{border-left:3px solid var(--brass);background:var(--brass-soft);padding:18px 22px;margin:0 0 24px;max-width:var(--measure)}
.callout p:last-child{margin-bottom:0}
.callout .lbl{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--brass);display:block;margin-bottom:8px}
.rule-quote{border-top:2px solid var(--ink);border-bottom:2px solid var(--ink);padding:26px 0;margin:28px 0;max-width:var(--measure)}
.rule-quote p{font-family:var(--font-display);font-weight:600;font-size:19px;line-height:1.38;letter-spacing:-.014em;margin:0;text-wrap:balance}
.hard{border-left:3px solid var(--clay);background:var(--clay-soft);padding:18px 22px;margin:0 0 24px;max-width:var(--measure)}
.hard .lbl{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--clay);display:block;margin-bottom:8px}
.hard p:last-child{margin-bottom:0}
.dec{font-family:var(--font-mono);font-size:10.5px;letter-spacing:.08em;color:var(--brass);text-transform:uppercase}
.vec{font-family:var(--font-mono);font-size:.9em;font-weight:600;background:var(--surface-2);padding:2px 7px;border-radius:2px;white-space:nowrap;letter-spacing:.04em}
/* ---------- tables ---------- */
.scroll{overflow-x:auto;margin:0 0 24px;-webkit-overflow-scrolling:touch}
table{border-collapse:collapse;width:100%;min-width:520px;font-family:var(--font-display);font-size:13.5px;line-height:1.45}
th{text-align:left;font-family:var(--font-mono);font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);font-weight:400;padding:0 16px 8px 0;border-bottom:1px solid var(--rule-strong);vertical-align:bottom}
td{padding:11px 16px 11px 0;border-bottom:1px solid var(--rule);vertical-align:top;color:var(--ink-2)}
td:first-child{color:var(--ink);font-weight:600}
tbody tr:last-child td{border-bottom:none}
.lvl{font-family:var(--font-mono);font-weight:600;font-size:12px;letter-spacing:.04em;color:var(--ink)}
/* ---------- ladders ---------- */
.breakout{margin:34px 0 40px}
.bhead{display:flex;justify-content:space-between;align-items:baseline;gap:20px;border-bottom:1px solid var(--rule-strong);padding-bottom:9px;margin-bottom:22px;flex-wrap:wrap}
.bhead h3{margin:0;font-size:13px;letter-spacing:.1em;text-transform:uppercase;font-family:var(--font-mono);font-weight:400;color:var(--ink-3)}
.bhead .note{font-family:var(--font-display);font-size:12.5px;color:var(--ink-3)}
.ladders{display:grid;gap:26px}
.ladder{display:grid;grid-template-columns:126px minmax(0,1fr);gap:18px;align-items:start}
@media (max-width:700px){.ladder{grid-template-columns:1fr;gap:10px}}
.ladder .pname{font-family:var(--font-display);font-weight:700;font-size:14px;letter-spacing:-.01em;padding-top:2px}
.ladder .pname span{display:block;font-family:var(--font-mono);font-size:10px;font-weight:400;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);margin-top:3px}
.rungs{display:grid;gap:3px;grid-template-columns:repeat(5,minmax(0,1fr))}
@media (max-width:700px){.rungs{grid-template-columns:repeat(2,minmax(0,1fr))}}
.rung{padding:9px 10px 11px;background:var(--surface);border-top:4px solid var(--l0);min-width:0}
.rung.r1{border-top-color:var(--l1)} .rung.r2{border-top-color:var(--l2)}
.rung.r3{border-top-color:var(--l3)} .rung.r4{border-top-color:var(--l4)}
.rung .code{font-family:var(--font-mono);font-size:11px;font-weight:600;letter-spacing:.06em;color:var(--ink);display:block;margin-bottom:4px}
.rung .txt{font-family:var(--font-display);font-size:11.5px;line-height:1.34;color:var(--ink-2);display:block}
.rung.na{opacity:.42}
/* ---------- matrix ---------- */
.matrix-shell{display:grid;grid-template-columns:auto minmax(0,1fr);gap:12px;align-items:stretch;margin-bottom:14px}
.ylab{writing-mode:vertical-rl;transform:rotate(180deg);font-family:var(--font-mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);text-align:center;padding-bottom:22px}
.mgrid{display:grid;grid-template-columns:34px repeat(5,minmax(0,1fr));gap:3px}
.mcell{background:var(--surface);min-height:60px;padding:6px;display:flex;flex-direction:column;justify-content:flex-end;gap:4px;min-width:0}
.mcell.tint1{background:color-mix(in srgb,var(--l1) 26%,var(--surface))}
.mcell.tint2{background:color-mix(in srgb,var(--l2) 26%,var(--surface))}
.mcell.tint3{background:color-mix(in srgb,var(--l3) 24%,var(--surface))}
.mcell.tint4{background:color-mix(in srgb,var(--l4) 22%,var(--surface))}
.mcell.void{background:repeating-linear-gradient(135deg,transparent,transparent 5px,var(--rule) 5px,var(--rule) 6px);opacity:.55}
.rlab,.clab{font-family:var(--font-mono);font-size:10px;font-weight:600;letter-spacing:.05em;color:var(--ink-3);display:flex;align-items:center;justify-content:center}
.rlab{min-height:60px}
.clab{padding-top:7px;min-height:22px}
.pin{font-family:var(--font-mono);font-size:9.5px;font-weight:600;letter-spacing:.02em;background:var(--ink);color:var(--paper);padding:2px 5px;border-radius:2px;line-height:1.3;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pin.ghost{background:transparent;color:var(--ink-2);border:1px dashed var(--rule-strong)}
.mnote{display:flex;gap:22px;flex-wrap:wrap;font-family:var(--font-display);font-size:12px;color:var(--ink-3);padding-top:6px}
.mnote .k{display:flex;align-items:center;gap:7px}
.sw{width:13px;height:13px;flex:none;background:var(--ink)}
.sw.g{background:transparent;border:1px dashed var(--rule-strong)}
.sw.v{background:repeating-linear-gradient(135deg,transparent,transparent 4px,var(--rule) 4px,var(--rule) 5px);border:1px solid var(--rule)}
@media (max-width:640px){
.mgrid{grid-template-columns:28px repeat(5,minmax(0,1fr))}
.mcell{min-height:52px;padding:4px}
.pin{font-size:8px;padding:1px 3px}
.rlab{min-height:52px}
}
/* ---------- methodology ---------- */
.verbs{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:2px;background:var(--rule);border:1px solid var(--rule)}
.verb{background:var(--surface);padding:18px 18px 20px}
.verb h4{font-family:var(--font-display);font-weight:750;font-size:15px;margin:0 0 7px;letter-spacing:-.01em}
.verb p{font-family:var(--font-display);font-size:12.5px;line-height:1.46;color:var(--ink-2);margin:0;max-width:none}
.verb .step{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.13em;color:var(--brass);display:block;margin-bottom:9px}
/* ---------- questions ---------- */
.qs{display:flex;flex-direction:column;gap:0;border-top:1px solid var(--rule-strong)}
.q{display:grid;grid-template-columns:34px minmax(0,1fr) 170px;gap:18px;padding:16px 0;border-bottom:1px solid var(--rule);align-items:start}
@media (max-width:760px){.q{grid-template-columns:28px minmax(0,1fr);gap:12px}.q .owner{grid-column:2}}
.q .qn{font-family:var(--font-mono);font-size:11px;color:var(--brass);padding-top:3px}
.q .qt{font-family:var(--font-display);font-size:14px;line-height:1.48;color:var(--ink-2)}
.q .qt b{color:var(--ink);font-weight:700;display:block;margin-bottom:2px;font-size:14.5px}
.owner{font-family:var(--font-mono);font-size:10px;letter-spacing:.05em;color:var(--ink-3);padding-top:4px}
.owner .tag{display:inline-block;border:1px solid var(--rule-strong);padding:2px 7px;border-radius:2px}
.owner .tag.need{border-color:var(--clay);color:var(--clay)}
/* ---------- misc ---------- */
.numbers{font-family:var(--font-mono);font-size:12.5px;line-height:1.85;background:var(--surface);border-left:3px solid var(--l3);padding:16px 20px;margin:0 0 22px;overflow-x:auto;max-width:var(--measure)}
.numbers .v{color:var(--ink);font-weight:600}
.numbers .k{color:var(--ink-3)}
pre{font-family:var(--font-mono);font-size:12.5px;line-height:1.68;background:var(--surface);border-left:3px solid var(--rule-strong);padding:16px 20px;overflow-x:auto;margin:0 0 22px;max-width:var(--measure);color:var(--ink-2)}
.alt{border-bottom:1px solid var(--rule);padding:14px 0;max-width:var(--measure)}
.alt:last-of-type{border-bottom:none}
.alt b{font-family:var(--font-display);font-size:14px;display:block;margin-bottom:3px}
.alt p{font-size:14.5px;margin:0;color:var(--ink-2)}
.alt .verdict{font-family:var(--font-mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--clay)}
footer{border-top:2px solid var(--ink);margin-top:20px;padding-top:22px;font-family:var(--font-mono);font-size:11px;letter-spacing:.06em;color:var(--ink-3);display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap}
.tm td,.tm th{text-align:center}
.tm td:first-child,.tm th:first-child{text-align:left}
.yes{color:var(--l4);font-weight:700}
.no{color:var(--clay);font-weight:700}
.kind{font-family:var(--font-mono);font-size:9px;letter-spacing:.09em;text-transform:uppercase;padding:2px 6px;border-radius:2px;white-space:nowrap;border:1px solid var(--rule-strong);color:var(--ink-3)}
.kind.adv{border-color:var(--clay);color:var(--clay)}
.routes{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:2px;background:var(--rule);border:1px solid var(--rule);margin:0 0 22px}
.route{background:var(--surface);padding:16px 18px}
.route h4{font-family:var(--font-display);font-weight:750;font-size:14px;margin:0 0 6px}
.route p{font-family:var(--font-display);font-size:12.5px;line-height:1.45;color:var(--ink-2);margin:0;max-width:none}
.route .tag{font-family:var(--font-mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:var(--brass);display:block;margin-bottom:8px}
a:focus-visible,.rail a:focus-visible{outline:2px solid var(--brass);outline-offset:3px}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
<div class="wrap"><header><div class="eyebrow"><span>RISK-METHOD-REVIEW</span> <span class="stat">adopted · adopted-1</span> <span>risk-nexus</span> <span>reviewed 2026-08-20</span><span>generated from canonical source — do not edit</span></div><h1>Review and expiry</h1><p class="sub">Source: <code>risk-nexus · docs/method/review.md · a13d954f8597fd92201746e2d52f031a5a88d969</code></p><p class="sub">Review due: 2027-02-20</p></header><div class="layout"><nav class="rail" aria-label="Sections"><ol><li><a href="#the-cadence-ladder"><span class="n">·</span>The cadence ladder</a></li><li><a href="#what-a-review-is"><span class="n">·</span>What a review is</a></li><li><a href="#when-a-check-is-missed"><span class="n">·</span>When a check is missed</a></li><li><a href="#the-production-re-score"><span class="n">·</span>The production re-score</a></li><li><a href="#front-matter-this-adds"><span class="n">·</span>Front-matter this adds</a></li><li><a href="#closing-a-finding"><span class="n">·</span>Closing a finding</a></li></ol></nav><main><p><code>INTENT.md</code>: a finding that has sat untouched past its review date is itself a finding. Silence is not resolution. This document makes that operable.</p>
<section id="the-cadence-ladder"><h2>The cadence ladder</h2>
<p>Operator ruling, 2026-08-20. <strong>Intervals are not set by severity. They are earned by outcomes.</strong></p>
<p>A finding is checked, and the check comes back clean or it does not. Clean climbs one rung. Anything wrong drops straight back to the bottom.</p>
<div class="scroll"><table><thead><tr><th>Rung</th><th>Wait before the next check</th></tr></thead><tbody><tr><td><code>instant</code></td><td>now, and again immediately until a check comes back clean</td></tr><tr><td><code>1h</code></td><td>one hour</td></tr><tr><td><code>8h</code></td><td>eight hours</td></tr><tr><td><code>24h</code></td><td>one day</td></tr><tr><td><code>48h</code></td><td>two days</td></tr><tr><td><code>96h</code></td><td>four days</td></tr><tr><td><code>7d</code></td><td>one week</td></tr><tr><td><code>14d</code></td><td>two weeks</td></tr><tr><td><code>1mo</code></td><td>one month</td></tr><tr><td><code>1q</code></td><td>one quarter — <strong>the ceiling; nothing is ever checked less often than this</strong></td></tr></tbody></table></div>
<p>Two rules and one escape:</p>
<ul><li><strong>Climb on clean.</strong> One rung per clean check, never two.</li><li><strong>Reset on anything wrong.</strong> Not a slide down one rung — straight to <code>instant</code>. A matter that has just moved has no track record, whatever it had before.</li><li><strong>The operator may defer.</strong> An <code>instant</code> finding can be deferred to a stated future date by explicit operator decision, recorded as <code>deferred_to</code>. That is the only way out of the bottom rung other than a clean check, and it is a decision with a name on it rather than a check quietly not happening.</li></ul>
<h3>Who checked, and when anyone last did</h3>
<p><code>RISK-WP-0005-T06</code>. Two defences against the rung telling a lie:</p>
<ul><li><strong><code>checked_by</code> on every check.</strong> <code>record_check.py</code> writes it. A rung earned by nobody in particular is visible as such.</li><li><strong>A heartbeat.</strong> If nothing anywhere in the register has been checked for two days, <code>make check</code> says so <strong>before anything else</strong>. A <code>1q</code> rung means "stable for a quarter" and "nobody looked for a quarter", and those read identically from the outside — the heartbeat is what separates them.</li></ul>
<h3>The rung is the signal</h3>
<p>This is the point of the design, not a side effect. <strong>The cadence a finding sits on is a statement about how stable the estate has been on that matter.</strong></p>
<p><code>RISK-F-0002</code> at <code>1q (9)</code> says the signing gate has been examined ten times over three months and nothing has moved. <code>RISK-F-0002</code> at <code>instant (0)</code> says something changed within the day. The number carries information that no severity does — severity says how bad it would be, the rung says how settled it is — and the two are independent. A <code>low</code> finding that keeps resetting is telling you something a <code>critical</code> one at the ceiling is not.</p>
<p>It is also self-correcting in the direction that matters. Anything volatile gets attention often, automatically, without anyone deciding it deserves it; anything genuinely quiet stops consuming attention, without anyone deciding to stop looking. Neither of those judgements has to be made by a person who might be wrong or busy.</p>
<h3>What "clean" means</h3>
<p>A check is <strong>clean</strong> when nothing about the assessment moved: the grade still holds, every stated blocker is still true, the fix state is unchanged, the disclosure state is still right, and no new fact has arrived.</p>
<p>A check is <strong>not clean</strong> when any of those moved — including when they moved in a good direction. <code>RISK-F-0001</code> being fixed is not a clean check; it is a large change, and the next check comes immediately. Good news resets the ladder exactly like bad news, because the ladder measures stillness, not health.</p>
<h3>Starting position</h3>
<p>Every finding starts at <code>instant</code>. A register with no check history has no grounds to wait, and the first clean check is what buys the first hour.</p>
<p>The whole register sat at <code>instant (0)</code> on 2026-08-20, which is correct and temporary: everything in it had been graded, re-graded or ruled on within the preceding day.</p>
</section>
<section id="what-a-review-is"><h2>What a review is</h2>
<p>Five questions, answered in writing on the finding. It takes minutes; it is not an investigation.</p>
<ol><li><strong>Has the inbox said anything?</strong> Read the messages addressed to this repo before anything else. This is question zero because on 2026-08-19 the register graded <code>RISK-F-0001</code> <code>critical</code> while two messages sat unread in its own inbox — one narrowing the exposure, one reporting the fix. Both changed the grade. A register that does not read its own inbox is guessing with a straight face.</li><li><strong>Is the grade still right?</strong> Re-read impact and likelihood against what has changed. New facts move the grade in both directions.</li><li><strong>Is the blocker still true?</strong> This is the one <code>RISK-F-0002</code> bought with evidence: <em>a blocker is a claim about the world at a date</em>. Its own stated blocker — "<code>flex-auth</code> is not deployed yet" — was invalidated within a day by <code>RISK-F-0001</code>, and nothing would have re-checked it. Every review re-checks every stated blocker.</li><li><strong>Has the fix moved?</strong> Read the owner's tracking record, not our memory of it. Confirm the record still exists and still refers to this defect.</li><li><strong>Is the disclosure state still right?</strong> An embargo whose condition has been met is published; an embargo whose condition has not moved in two reviews is a stall.</li></ol>
<p>The finding gets a dated line under <code>## Reviews</code>, <code>last_reviewed</code> is updated, and <code>review_by</code> is pushed by one interval. A review that changes nothing still writes the line — "checked, nothing moved" is the evidence that the silence was observed rather than accidental.</p>
</section>
<section id="when-a-check-is-missed"><h2>When a check is missed</h2>
<p>Overdue is not a status change on the finding. It is a fact about <em>this repo</em>, and it surfaces in three places:</p>
<ul><li><code>make check</code> lists it under "Checks due", with how late it is and which rung it is on.</li><li><code>REGISTER.md</code> shows the next check as <strong>due</strong>.</li><li>A finding sitting at the bottom rung for more than fourteen days with no movement fires escalation trigger 5. Bottom rung means it keeps failing or keeps being skipped; fourteen days of that is a stall whichever it is.</li></ul>
<p>The register does not auto-escalate severity for lateness and does not auto-close anything. Both would be the register lying about its own state to make a number look better.</p>
</section>
<section id="the-production-re-score"><h2>The production re-score</h2>
<p>Every finding carries <code>severity_at_production</code> alongside <code>severity</code> (<code>docs/method/severity.md</code>). Where the two differ, the finding is flagged <code>production_rescore: true</code>.</p>
<p>On the day any part of the estate declares production readiness, every flagged finding is re-scored before that declaration completes. This is not a review date — it is an event, and it fires regardless of where the review dates happen to sit.</p>
<p>Until then, <code>make check</code> lists the flagged findings so the size of that obligation is visible rather than discovered on the day.</p>
</section>
<section id="front-matter-this-adds"><h2>Front-matter this adds</h2>
<pre>last_checked: &quot;2026-08-20T05:40:00Z&quot;
next_check: &quot;2026-08-20T06:40:00Z&quot;
cadence: 1h
clean_streak: 1
production_rescore: true
deferred_to: &quot;&quot; # only by explicit operator decision</pre>
<p><code>next_check</code> is what the nag reads, and it is an absolute moment rather than a duration, so nothing has to recompute an interval to know whether a check is late. The rungs run in hours as well as days, so it carries a time.</p>
</section>
<section id="closing-a-finding"><h2>Closing a finding</h2>
<p>A finding leaves <code>open</code> for exactly one of:</p>
<ul><li><code>fixed</code> — the owner's record shows the defect gone, and this repo has read something concrete rather than been told. Publication follows if the disclosure state was <code>embargoed</code>.</li><li><code>accepted</code> — the estate is deliberately carrying it. Requires who accepted it, why, and what ends the acceptance. <code>accepted</code> is not closed: it stays on the ladder forever, and it climbs like anything else.</li><li><code>mitigated</code> — the live gap is closed but the finding is not. <code>RISK-F-0003</code> is the case: the boundary now fires, and the omission that let it not fire is still there. Stays watched.</li><li><code>withdrawn</code> — the finding was wrong, or the defect never existed. Say which.</li></ul>
<p><strong>Any status the tooling does not recognise keeps the finding watched, and the unrecognised word is reported.</strong> <code>RISK-F-0003</code> arrived as <code>mitigated</code> on 2026-08-20, before that word existed here, and dropped silently out of <code>make check</code> — a finding vanishing from the nag because someone used an unfamiliar word is precisely the failure this register exists to prevent. The tooling now fails loud instead of quiet.</p>
<p>There is no <code>stale</code>, no <code>wontfix</code> and no silent expiry. A finding that nobody will fix and nobody will accept stays <code>open</code> and keeps arriving in the nag, because that is the true state.</p>
</section><footer><span>RISK-METHOD-REVIEW · adopted-1 · adopted</span><span>risk-nexus · docs/method/review.md · a13d954f8597fd92201746e2d52f031a5a88d969</span></footer></main></div></div></html>

View file

@ -0,0 +1,256 @@
<!doctype html>
<html lang="en"><meta charset="utf-8">
<meta name="policy-source-revision" content="c5517c754bd84b0ebf47878ba0f26df0ecb3b4a4">
<meta name="policy-source-digest" content="f064c591aeef9425bbfbd5fa2aae659abb0ef83b8586848300077f41dd4ffaab">
<title>Severity</title>
<style>
:root{
--paper:#EDEEF0; --surface:#F6F7F8; --surface-2:#E4E6E9;
--ink:#171D24; --ink-2:#4A5561; --ink-3:#737E8A;
--rule:#D3D7DC; --rule-strong:#B6BCC3;
--brass:#8A6A2E; --brass-soft:#EFE5CD; --brass-line:#C9AE74;
--clay:#8A3A2C; --clay-soft:#F2DFDA;
--l0:#DCE0E2; --l1:#B9C4C7; --l2:#8CA1A6; --l3:#567D84; --l4:#23555E;
--chip-fg:#F6F7F8;
--font-display:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",sans-serif;
--font-body:"Iowan Old Style","Palatino Linotype",Palatino,Georgia,serif;
--font-mono:ui-monospace,"SF Mono","Cascadia Code",Menlo,Consolas,monospace;
--measure:66ch;
}
@media (prefers-color-scheme:dark){
:root:not([data-theme="light"]){
--paper:#12161A; --surface:#191E24; --surface-2:#222831;
--ink:#E6E9EC; --ink-2:#A3ADB7; --ink-3:#78838E;
--rule:#2A3138; --rule-strong:#3B444D;
--brass:#C9A45C; --brass-soft:#33290F; --brass-line:#6B5426;
--clay:#D08A76; --clay-soft:#3A211B;
--l0:#262C32; --l1:#35424A; --l2:#4A626B; --l3:#6A939D; --l4:#97C4CD;
--chip-fg:#12161A;
}
}
:root[data-theme="dark"]{
--paper:#12161A; --surface:#191E24; --surface-2:#222831;
--ink:#E6E9EC; --ink-2:#A3ADB7; --ink-3:#78838E;
--rule:#2A3138; --rule-strong:#3B444D;
--brass:#C9A45C; --brass-soft:#33290F; --brass-line:#6B5426;
--clay:#D08A76; --clay-soft:#3A211B;
--l0:#262C32; --l1:#35424A; --l2:#4A626B; --l3:#6A939D; --l4:#97C4CD;
--chip-fg:#12161A;
}
*{box-sizing:border-box}
body{
margin:0; background:var(--paper); color:var(--ink);
font-family:var(--font-body); font-size:17px; line-height:1.62;
-webkit-font-smoothing:antialiased;
}
.wrap{max-width:1180px;margin:0 auto;padding:0 24px 96px}
.layout{display:grid;grid-template-columns:180px minmax(0,1fr);gap:56px;align-items:start}
@media (max-width:960px){.layout{grid-template-columns:1fr;gap:0}.rail{display:none}}
/* ---------- rail ---------- */
.rail{position:sticky;top:28px;padding-top:8px;font-family:var(--font-display);font-size:12px;line-height:1.5}
.rail ol{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:7px}
.rail a{color:var(--ink-3);text-decoration:none;display:flex;gap:9px}
.rail a:hover,.rail a:focus-visible{color:var(--brass)}
.rail .n{font-family:var(--font-mono);font-size:10px;color:var(--rule-strong);min-width:16px;padding-top:1px}
.rail .grp{margin-top:14px;font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--rule-strong)}
/* ---------- header ---------- */
header{padding:64px 0 40px;border-bottom:2px solid var(--ink);margin-bottom:44px}
.eyebrow{font-family:var(--font-mono);font-size:11.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);display:flex;flex-wrap:wrap;gap:14px;margin-bottom:22px}
.eyebrow .stat{color:var(--clay)}
h1{font-family:var(--font-display);font-weight:800;letter-spacing:-.035em;line-height:.94;font-size:clamp(46px,9vw,92px);margin:0 0 6px;text-wrap:balance}
.sub{font-family:var(--font-display);font-weight:500;font-size:clamp(16px,2.4vw,21px);letter-spacing:-.01em;color:var(--ink-2);margin:0 0 30px;max-width:34ch;line-height:1.3}
.metagrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:20px 28px;border-top:1px solid var(--rule);padding-top:20px}
.metagrid dt{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);margin-bottom:5px}
.metagrid dd{margin:0;font-family:var(--font-display);font-size:13.5px;line-height:1.45;color:var(--ink)}
/* ---------- typography ---------- */
section{margin-bottom:60px;scroll-margin-top:24px}
h2{font-family:var(--font-display);font-weight:750;letter-spacing:-.022em;font-size:clamp(24px,3.4vw,31px);line-height:1.12;margin:0 0 18px;text-wrap:balance;display:flex;gap:14px;align-items:baseline}
h2 .sn{font-family:var(--font-mono);font-size:12px;font-weight:400;color:var(--brass);letter-spacing:.06em;flex:none;padding-top:2px}
h3{font-family:var(--font-display);font-weight:700;font-size:16px;letter-spacing:-.008em;margin:34px 0 10px;color:var(--ink)}
p{margin:0 0 15px;max-width:var(--measure)}
ul,ol{max-width:var(--measure);margin:0 0 15px;padding-left:20px}
li{margin-bottom:7px}
strong{font-weight:600}
em{font-style:italic}
code{font-family:var(--font-mono);font-size:.855em;background:var(--surface-2);padding:1px 5px;border-radius:2px}
a{color:var(--brass)}
.lede{font-size:19px;line-height:1.55;color:var(--ink-2);max-width:60ch}
/* ---------- devices ---------- */
.callout{border-left:3px solid var(--brass);background:var(--brass-soft);padding:18px 22px;margin:0 0 24px;max-width:var(--measure)}
.callout p:last-child{margin-bottom:0}
.callout .lbl{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--brass);display:block;margin-bottom:8px}
.rule-quote{border-top:2px solid var(--ink);border-bottom:2px solid var(--ink);padding:26px 0;margin:28px 0;max-width:var(--measure)}
.rule-quote p{font-family:var(--font-display);font-weight:600;font-size:19px;line-height:1.38;letter-spacing:-.014em;margin:0;text-wrap:balance}
.hard{border-left:3px solid var(--clay);background:var(--clay-soft);padding:18px 22px;margin:0 0 24px;max-width:var(--measure)}
.hard .lbl{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--clay);display:block;margin-bottom:8px}
.hard p:last-child{margin-bottom:0}
.dec{font-family:var(--font-mono);font-size:10.5px;letter-spacing:.08em;color:var(--brass);text-transform:uppercase}
.vec{font-family:var(--font-mono);font-size:.9em;font-weight:600;background:var(--surface-2);padding:2px 7px;border-radius:2px;white-space:nowrap;letter-spacing:.04em}
/* ---------- tables ---------- */
.scroll{overflow-x:auto;margin:0 0 24px;-webkit-overflow-scrolling:touch}
table{border-collapse:collapse;width:100%;min-width:520px;font-family:var(--font-display);font-size:13.5px;line-height:1.45}
th{text-align:left;font-family:var(--font-mono);font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);font-weight:400;padding:0 16px 8px 0;border-bottom:1px solid var(--rule-strong);vertical-align:bottom}
td{padding:11px 16px 11px 0;border-bottom:1px solid var(--rule);vertical-align:top;color:var(--ink-2)}
td:first-child{color:var(--ink);font-weight:600}
tbody tr:last-child td{border-bottom:none}
.lvl{font-family:var(--font-mono);font-weight:600;font-size:12px;letter-spacing:.04em;color:var(--ink)}
/* ---------- ladders ---------- */
.breakout{margin:34px 0 40px}
.bhead{display:flex;justify-content:space-between;align-items:baseline;gap:20px;border-bottom:1px solid var(--rule-strong);padding-bottom:9px;margin-bottom:22px;flex-wrap:wrap}
.bhead h3{margin:0;font-size:13px;letter-spacing:.1em;text-transform:uppercase;font-family:var(--font-mono);font-weight:400;color:var(--ink-3)}
.bhead .note{font-family:var(--font-display);font-size:12.5px;color:var(--ink-3)}
.ladders{display:grid;gap:26px}
.ladder{display:grid;grid-template-columns:126px minmax(0,1fr);gap:18px;align-items:start}
@media (max-width:700px){.ladder{grid-template-columns:1fr;gap:10px}}
.ladder .pname{font-family:var(--font-display);font-weight:700;font-size:14px;letter-spacing:-.01em;padding-top:2px}
.ladder .pname span{display:block;font-family:var(--font-mono);font-size:10px;font-weight:400;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);margin-top:3px}
.rungs{display:grid;gap:3px;grid-template-columns:repeat(5,minmax(0,1fr))}
@media (max-width:700px){.rungs{grid-template-columns:repeat(2,minmax(0,1fr))}}
.rung{padding:9px 10px 11px;background:var(--surface);border-top:4px solid var(--l0);min-width:0}
.rung.r1{border-top-color:var(--l1)} .rung.r2{border-top-color:var(--l2)}
.rung.r3{border-top-color:var(--l3)} .rung.r4{border-top-color:var(--l4)}
.rung .code{font-family:var(--font-mono);font-size:11px;font-weight:600;letter-spacing:.06em;color:var(--ink);display:block;margin-bottom:4px}
.rung .txt{font-family:var(--font-display);font-size:11.5px;line-height:1.34;color:var(--ink-2);display:block}
.rung.na{opacity:.42}
/* ---------- matrix ---------- */
.matrix-shell{display:grid;grid-template-columns:auto minmax(0,1fr);gap:12px;align-items:stretch;margin-bottom:14px}
.ylab{writing-mode:vertical-rl;transform:rotate(180deg);font-family:var(--font-mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);text-align:center;padding-bottom:22px}
.mgrid{display:grid;grid-template-columns:34px repeat(5,minmax(0,1fr));gap:3px}
.mcell{background:var(--surface);min-height:60px;padding:6px;display:flex;flex-direction:column;justify-content:flex-end;gap:4px;min-width:0}
.mcell.tint1{background:color-mix(in srgb,var(--l1) 26%,var(--surface))}
.mcell.tint2{background:color-mix(in srgb,var(--l2) 26%,var(--surface))}
.mcell.tint3{background:color-mix(in srgb,var(--l3) 24%,var(--surface))}
.mcell.tint4{background:color-mix(in srgb,var(--l4) 22%,var(--surface))}
.mcell.void{background:repeating-linear-gradient(135deg,transparent,transparent 5px,var(--rule) 5px,var(--rule) 6px);opacity:.55}
.rlab,.clab{font-family:var(--font-mono);font-size:10px;font-weight:600;letter-spacing:.05em;color:var(--ink-3);display:flex;align-items:center;justify-content:center}
.rlab{min-height:60px}
.clab{padding-top:7px;min-height:22px}
.pin{font-family:var(--font-mono);font-size:9.5px;font-weight:600;letter-spacing:.02em;background:var(--ink);color:var(--paper);padding:2px 5px;border-radius:2px;line-height:1.3;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pin.ghost{background:transparent;color:var(--ink-2);border:1px dashed var(--rule-strong)}
.mnote{display:flex;gap:22px;flex-wrap:wrap;font-family:var(--font-display);font-size:12px;color:var(--ink-3);padding-top:6px}
.mnote .k{display:flex;align-items:center;gap:7px}
.sw{width:13px;height:13px;flex:none;background:var(--ink)}
.sw.g{background:transparent;border:1px dashed var(--rule-strong)}
.sw.v{background:repeating-linear-gradient(135deg,transparent,transparent 4px,var(--rule) 4px,var(--rule) 5px);border:1px solid var(--rule)}
@media (max-width:640px){
.mgrid{grid-template-columns:28px repeat(5,minmax(0,1fr))}
.mcell{min-height:52px;padding:4px}
.pin{font-size:8px;padding:1px 3px}
.rlab{min-height:52px}
}
/* ---------- methodology ---------- */
.verbs{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:2px;background:var(--rule);border:1px solid var(--rule)}
.verb{background:var(--surface);padding:18px 18px 20px}
.verb h4{font-family:var(--font-display);font-weight:750;font-size:15px;margin:0 0 7px;letter-spacing:-.01em}
.verb p{font-family:var(--font-display);font-size:12.5px;line-height:1.46;color:var(--ink-2);margin:0;max-width:none}
.verb .step{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.13em;color:var(--brass);display:block;margin-bottom:9px}
/* ---------- questions ---------- */
.qs{display:flex;flex-direction:column;gap:0;border-top:1px solid var(--rule-strong)}
.q{display:grid;grid-template-columns:34px minmax(0,1fr) 170px;gap:18px;padding:16px 0;border-bottom:1px solid var(--rule);align-items:start}
@media (max-width:760px){.q{grid-template-columns:28px minmax(0,1fr);gap:12px}.q .owner{grid-column:2}}
.q .qn{font-family:var(--font-mono);font-size:11px;color:var(--brass);padding-top:3px}
.q .qt{font-family:var(--font-display);font-size:14px;line-height:1.48;color:var(--ink-2)}
.q .qt b{color:var(--ink);font-weight:700;display:block;margin-bottom:2px;font-size:14.5px}
.owner{font-family:var(--font-mono);font-size:10px;letter-spacing:.05em;color:var(--ink-3);padding-top:4px}
.owner .tag{display:inline-block;border:1px solid var(--rule-strong);padding:2px 7px;border-radius:2px}
.owner .tag.need{border-color:var(--clay);color:var(--clay)}
/* ---------- misc ---------- */
.numbers{font-family:var(--font-mono);font-size:12.5px;line-height:1.85;background:var(--surface);border-left:3px solid var(--l3);padding:16px 20px;margin:0 0 22px;overflow-x:auto;max-width:var(--measure)}
.numbers .v{color:var(--ink);font-weight:600}
.numbers .k{color:var(--ink-3)}
pre{font-family:var(--font-mono);font-size:12.5px;line-height:1.68;background:var(--surface);border-left:3px solid var(--rule-strong);padding:16px 20px;overflow-x:auto;margin:0 0 22px;max-width:var(--measure);color:var(--ink-2)}
.alt{border-bottom:1px solid var(--rule);padding:14px 0;max-width:var(--measure)}
.alt:last-of-type{border-bottom:none}
.alt b{font-family:var(--font-display);font-size:14px;display:block;margin-bottom:3px}
.alt p{font-size:14.5px;margin:0;color:var(--ink-2)}
.alt .verdict{font-family:var(--font-mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--clay)}
footer{border-top:2px solid var(--ink);margin-top:20px;padding-top:22px;font-family:var(--font-mono);font-size:11px;letter-spacing:.06em;color:var(--ink-3);display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap}
.tm td,.tm th{text-align:center}
.tm td:first-child,.tm th:first-child{text-align:left}
.yes{color:var(--l4);font-weight:700}
.no{color:var(--clay);font-weight:700}
.kind{font-family:var(--font-mono);font-size:9px;letter-spacing:.09em;text-transform:uppercase;padding:2px 6px;border-radius:2px;white-space:nowrap;border:1px solid var(--rule-strong);color:var(--ink-3)}
.kind.adv{border-color:var(--clay);color:var(--clay)}
.routes{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:2px;background:var(--rule);border:1px solid var(--rule);margin:0 0 22px}
.route{background:var(--surface);padding:16px 18px}
.route h4{font-family:var(--font-display);font-weight:750;font-size:14px;margin:0 0 6px}
.route p{font-family:var(--font-display);font-size:12.5px;line-height:1.45;color:var(--ink-2);margin:0;max-width:none}
.route .tag{font-family:var(--font-mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:var(--brass);display:block;margin-bottom:8px}
a:focus-visible,.rail a:focus-visible{outline:2px solid var(--brass);outline-offset:3px}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
<div class="wrap"><header><div class="eyebrow"><span>RISK-METHOD-SEVERITY</span> <span class="stat">adopted · adopted-1</span> <span>risk-nexus</span> <span>reviewed 2026-08-20</span><span>generated from canonical source — do not edit</span></div><h1>Severity</h1><p class="sub">Source: <code>risk-nexus · docs/method/severity.md · c5517c754bd84b0ebf47878ba0f26df0ecb3b4a4</code></p><p class="sub">Review due: 2027-02-20</p></header><div class="layout"><nav class="rail" aria-label="Sections"><ol><li><a href="#the-two-axes"><span class="n">·</span>The two axes</a></li><li><a href="#the-grid"><span class="n">·</span>The grid</a></li><li><a href="#the-fidelity-modifier"><span class="n">·</span>The fidelity modifier</a></li><li><a href="#which-state-is-scored"><span class="n">·</span>Which state is scored</a></li><li><a href="#build-mode"><span class="n">·</span>Build mode</a></li><li><a href="#non-adversarial-findings"><span class="n">·</span>Non-adversarial findings</a></li><li><a href="#live-incidents"><span class="n">·</span>Live incidents</a></li><li><a href="#the-floor"><span class="n">·</span>The floor</a></li><li><a href="#provenance-is-a-grading-input"><span class="n">·</span>Provenance is a grading input</a></li><li><a href="#recording-a-grade"><span class="n">·</span>Recording a grade</a></li></ol></nav><main><p>This is <code>risk-nexus</code>'s judgement instrument. It is not canon, it is not a standard, and it binds nobody else. It exists so that two findings graded a month apart are graded the same way, and so that a grade can be argued with.</p>
<p>It was written against three real findings (<code>RISK-F-0001</code>, <code>RISK-F-0002</code>, <code>RISK-F-0003</code>) and it must keep grading those three sensibly or it is wrong.</p>
<section id="the-two-axes"><h2>The two axes</h2>
<h3>Impact — what happens if it goes wrong once</h3>
<div class="scroll"><table><thead><tr><th>Band</th><th>Name</th><th>Test</th></tr></thead><tbody><tr><td><code>I1</code></td><td>negligible</td><td>Confined to one component. No data leaves it, no record is falsified, no recovery is lost.</td></tr><tr><td><code>I2</code></td><td>limited</td><td>One system's data or availability. Recoverable. Confined to a single tenant, actor or lane.</td></tr><tr><td><code>I3</code></td><td>serious</td><td>Crosses a boundary — tenant, system, or trust — or removes recoverability for one system.</td></tr><tr><td><code>I4</code></td><td>severe</td><td>Crosses the estate. What is compromised here propagates to everything that trusts it, or the data loss is unbounded.</td></tr></tbody></table></div>
<p>Impact is scored at <strong>one occurrence</strong>, not at the worst imaginable campaign. "An attacker who already owns the cluster could do this too" is not an impact argument.</p>
<h3>Likelihood — how far anyone has to reach</h3>
<div class="scroll"><table><thead><tr><th>Band</th><th>Name</th><th>Test</th></tr></thead><tbody><tr><td><code>L1</code></td><td>remote</td><td>Requires access nobody currently holds and no ordinary process grants.</td></tr><tr><td><code>L2</code></td><td>possible</td><td>Requires a foothold the estate does grant somewhere — an in-cluster workload, an agent session, a scoped token.</td></tr><tr><td><code>L3</code></td><td>likely</td><td>Reachable from inside the normal working set with no additional step.</td></tr><tr><td><code>L4</code></td><td>present</td><td>No barrier at all, or it is already happening.</td></tr></tbody></table></div>
<p>Likelihood is about <strong>reach</strong>, not about intent or about whether anyone has bothered. <code>risk-nexus</code> does not model attackers; it models what the system permits.</p>
<p>Where the reporter has not established exposure, the finding says so and the grade uses the band the <em>stated</em> facts support — not the worst case, and not zero. <code>RISK-F-0001</code> explicitly declines to assume a default-deny NetworkPolicy exists; the grade must decline with it, and the unverified fact becomes a review item rather than a silent assumption in either direction.</p>
</section>
<section id="the-grid"><h2>The grid</h2>
<div class="scroll"><table><thead><tr><th></th><th><code>L1</code></th><th><code>L2</code></th><th><code>L3</code></th><th><code>L4</code></th></tr></thead><tbody><tr><td><code>I4</code></td><td>medium</td><td>high</td><td><strong>critical</strong></td><td><strong>critical</strong></td></tr><tr><td><code>I3</code></td><td>low</td><td>medium</td><td>high</td><td><strong>critical</strong></td></tr><tr><td><code>I2</code></td><td>low</td><td>low</td><td>medium</td><td>high</td></tr><tr><td><code>I1</code></td><td>note</td><td>low</td><td>low</td><td>medium</td></tr></tbody></table></div>
<p>Four severities: <code>low</code>, <code>medium</code>, <code>high</code>, <code>critical</code>. <code>note</code> is not a severity; see the floor.</p>
</section>
<section id="the-fidelity-modifier"><h2>The fidelity modifier</h2>
<p><strong>A control that lies is one impact band worse than the same control absent.</strong></p>
<p>Apply <code>+1</code> impact band (capped at <code>I4</code>) when the failure mode produces a <em>false record</em> rather than <em>no record</em>: an attestation that a check passed when nothing checked, an audit line asserting an authorization that was never made, a green signal derived from an unreachable test.</p>
<p>The reasoning is <code>RISK-F-0002</code>'s and the register adopts it: an absent control is a gap you can find by looking; a lying control is a gap that survives looking, because the evidence you would look at is the thing that is wrong. Only one of the two states misleads the person investigating afterwards.</p>
<p>The modifier applies to the state being scored. A finding that describes both states — control absent today, control lying if switched on in the wrong order — gets <strong>two scores and one of them is the register's headline</strong>; see "Which state is scored".</p>
</section>
<section id="which-state-is-scored"><h2>Which state is scored</h2>
<p>The headline <code>severity</code> is the state of the world <strong>today</strong>. A hazard that would be created by a <em>future</em> action is not the headline, because a register that scores hypotheticals stops describing the estate.</p>
<p>The hazard is not lost. It is recorded on the finding as a named <strong>constraint</strong> with its own grade, and it attaches to whatever action would trigger it — usually another finding's remediation. <code>RISK-F-0002</code> is the worked example: the gate being off is today (headline), the gate being switched on while the oracle is forgeable is a constraint on <code>RISK-F-0001</code>'s fix, graded separately and higher.</p>
<p>If the constraint's grade is higher than the headline, the finding says so in its ruling. A reader must not be able to come away with the low number and miss the high one.</p>
</section>
<section id="build-mode"><h2>Build mode</h2>
<p>Every finding is graded twice:</p>
<ul><li><code>severity</code> — today, in build mode, with today's likelihood.</li><li><code>severity_at_production</code> — the same impact, with likelihood re-read for a system carrying real users and real tenant data.</li></ul>
<p>Build mode legitimately lowers <strong>both</strong> axes, for different reasons: likelihood, where the reach itself depends on a production deployment that has not happened; and impact, where the data that would be exposed does not exist yet. What it must never lower is <code>severity_at_production</code> — the defect does not improve because the calendar has not reached it.</p>
<div class="rule-quote"><p><em>Amended 2026-08-19 (<code>RISK-WP-0001-T07</code>).</em> This paragraph originally said build mode was a likelihood input and never an impact one. Grading the unverified tenant boundary broke that: what build mode changes there is the consequence of an occurrence, not the reach of it. The instrument was wrong on first hard use and is corrected rather than worked around.</p></div>
<p>Where the two grades differ, the production transition is a mandatory re-score. <code>docs/method/review.md</code> binds the review date to it, so the re-score is a scheduled event and not somebody's memory.</p>
</section>
<section id="non-adversarial-findings"><h2>Non-adversarial findings</h2>
<p>Likelihood is written as reach because most findings are about someone getting somewhere. Where a finding is about loss, corruption or outage — no backup, no recovery path, an eviction-prone deployment — there is no attacker to model.</p>
<p>For those, likelihood reads as <strong>the chance of the triggering event inside one review interval</strong>: <code>L1</code> would be surprising, <code>L2</code> is an ordinary failure the estate has seen before, <code>L3</code> is expected in the normal course of running, <code>L4</code> is already happening. Impact is unchanged: what is lost, and whether it comes back.</p>
<div class="rule-quote"><p><em>Added 2026-08-19 (<code>RISK-WP-0001-T07</code>).</em> Forced by <code>RISK-F-0006</code>, where the defect is an absent backup and the reach reading produced nonsense.</p></div>
</section>
<section id="live-incidents"><h2>Live incidents</h2>
<p>Everything above assumes a latent defect — something reachable that nobody is currently reaching. When someone is, three things change:</p>
<ul><li><strong>Likelihood is <code>L4</code>.</strong> The band means "already happening" and this is what it is for.</li><li><strong>Impact is scored on what has occurred plus what is still reachable</strong>, not on the worst case. An incident in progress has facts; use them.</li><li><strong>The grade is provisional and expected to move.</strong> File first, grade within the hour, re-grade as facts arrive. <code>docs/method/intake.md</code> has the rest, including the 72-hour clock that <code>first_observed</code> starts.</li></ul>
</section>
<section id="the-floor"><h2>The floor</h2>
<p><code>INTENT.md</code>: if a finding would not change anyone's decision, it is a note, not a risk. Concretely, a register entry requires <strong>both</strong>:</p>
<ol><li><strong>An owner who could act.</strong> Some repo, or the operator, can do something about it. No actor, no entry.</li><li><strong>A decision that changes.</strong> Recording it alters what someone does, when they do it, or what they must not do first.</li></ol>
<p>Fails either test → it is a note in <code>notes/</code>, not a finding in <code>findings/</code>. Notes are not graded, not reviewed, and not published. They exist so that "we saw it" survives without inflating the register.</p>
<p>An <code>I1</code>/<code>L1</code> cell is <code>note</code> in the grid for the same reason: something that is both negligible and unreachable is a thing we know, not a risk we carry.</p>
<p>Two things the floor does <strong>not</strong> exclude:</p>
<ul><li><strong>Known and deliberate.</strong> <code>RISK-F-0002</code> is a decision somebody made on purpose. It still passes the floor, because it changes what may be switched on and in what order. Deliberate is not the same as tracked.</li><li><strong>Omission-shaped.</strong> <code>RISK-F-0003</code> is a default that silently produces ungoverned lanes. The individual lane is small; the default is not.</li></ul>
</section>
<section id="provenance-is-a-grading-input"><h2>Provenance is a grading input</h2>
<p>All four defects known to this register were found by repos reading their own code against a ladder, within days of each other. None was found by monitoring.</p>
<p>Where a finding's provenance is "we happened to look", the register does not get to assume that similar defects would have been caught. That raises likelihood for the class, not for the instance, and it belongs in the ruling's reasoning rather than in a modifier — the register grades what is filed, and notes when the filing was luck.</p>
</section>
<section id="recording-a-grade"><h2>Recording a grade</h2>
<p>The finding's front-matter carries:</p>
<pre>severity: critical # headline, today
severity_at_production: critical
impact: I4 # band, before modifiers
likelihood: L3
fidelity_modifier: false # true if +1 applied, with the reason in the ruling</pre>
<p>and the ruling section states impact, likelihood, any modifier, and the one sentence that would have to become false for the grade to change.</p>
</section><footer><span>RISK-METHOD-SEVERITY · adopted-1 · adopted</span><span>risk-nexus · docs/method/severity.md · c5517c754bd84b0ebf47878ba0f26df0ecb3b4a4</span></footer></main></div></div></html>

View file

@ -0,0 +1,256 @@
<!doctype html>
<html lang="en"><meta charset="utf-8">
<meta name="policy-source-revision" content="a13d954f8597fd92201746e2d52f031a5a88d969">
<meta name="policy-source-digest" content="f064c591aeef9425bbfbd5fa2aae659abb0ef83b8586848300077f41dd4ffaab">
<title>Severity</title>
<style>
:root{
--paper:#EDEEF0; --surface:#F6F7F8; --surface-2:#E4E6E9;
--ink:#171D24; --ink-2:#4A5561; --ink-3:#737E8A;
--rule:#D3D7DC; --rule-strong:#B6BCC3;
--brass:#8A6A2E; --brass-soft:#EFE5CD; --brass-line:#C9AE74;
--clay:#8A3A2C; --clay-soft:#F2DFDA;
--l0:#DCE0E2; --l1:#B9C4C7; --l2:#8CA1A6; --l3:#567D84; --l4:#23555E;
--chip-fg:#F6F7F8;
--font-display:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",sans-serif;
--font-body:"Iowan Old Style","Palatino Linotype",Palatino,Georgia,serif;
--font-mono:ui-monospace,"SF Mono","Cascadia Code",Menlo,Consolas,monospace;
--measure:66ch;
}
@media (prefers-color-scheme:dark){
:root:not([data-theme="light"]){
--paper:#12161A; --surface:#191E24; --surface-2:#222831;
--ink:#E6E9EC; --ink-2:#A3ADB7; --ink-3:#78838E;
--rule:#2A3138; --rule-strong:#3B444D;
--brass:#C9A45C; --brass-soft:#33290F; --brass-line:#6B5426;
--clay:#D08A76; --clay-soft:#3A211B;
--l0:#262C32; --l1:#35424A; --l2:#4A626B; --l3:#6A939D; --l4:#97C4CD;
--chip-fg:#12161A;
}
}
:root[data-theme="dark"]{
--paper:#12161A; --surface:#191E24; --surface-2:#222831;
--ink:#E6E9EC; --ink-2:#A3ADB7; --ink-3:#78838E;
--rule:#2A3138; --rule-strong:#3B444D;
--brass:#C9A45C; --brass-soft:#33290F; --brass-line:#6B5426;
--clay:#D08A76; --clay-soft:#3A211B;
--l0:#262C32; --l1:#35424A; --l2:#4A626B; --l3:#6A939D; --l4:#97C4CD;
--chip-fg:#12161A;
}
*{box-sizing:border-box}
body{
margin:0; background:var(--paper); color:var(--ink);
font-family:var(--font-body); font-size:17px; line-height:1.62;
-webkit-font-smoothing:antialiased;
}
.wrap{max-width:1180px;margin:0 auto;padding:0 24px 96px}
.layout{display:grid;grid-template-columns:180px minmax(0,1fr);gap:56px;align-items:start}
@media (max-width:960px){.layout{grid-template-columns:1fr;gap:0}.rail{display:none}}
/* ---------- rail ---------- */
.rail{position:sticky;top:28px;padding-top:8px;font-family:var(--font-display);font-size:12px;line-height:1.5}
.rail ol{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:7px}
.rail a{color:var(--ink-3);text-decoration:none;display:flex;gap:9px}
.rail a:hover,.rail a:focus-visible{color:var(--brass)}
.rail .n{font-family:var(--font-mono);font-size:10px;color:var(--rule-strong);min-width:16px;padding-top:1px}
.rail .grp{margin-top:14px;font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--rule-strong)}
/* ---------- header ---------- */
header{padding:64px 0 40px;border-bottom:2px solid var(--ink);margin-bottom:44px}
.eyebrow{font-family:var(--font-mono);font-size:11.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);display:flex;flex-wrap:wrap;gap:14px;margin-bottom:22px}
.eyebrow .stat{color:var(--clay)}
h1{font-family:var(--font-display);font-weight:800;letter-spacing:-.035em;line-height:.94;font-size:clamp(46px,9vw,92px);margin:0 0 6px;text-wrap:balance}
.sub{font-family:var(--font-display);font-weight:500;font-size:clamp(16px,2.4vw,21px);letter-spacing:-.01em;color:var(--ink-2);margin:0 0 30px;max-width:34ch;line-height:1.3}
.metagrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:20px 28px;border-top:1px solid var(--rule);padding-top:20px}
.metagrid dt{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);margin-bottom:5px}
.metagrid dd{margin:0;font-family:var(--font-display);font-size:13.5px;line-height:1.45;color:var(--ink)}
/* ---------- typography ---------- */
section{margin-bottom:60px;scroll-margin-top:24px}
h2{font-family:var(--font-display);font-weight:750;letter-spacing:-.022em;font-size:clamp(24px,3.4vw,31px);line-height:1.12;margin:0 0 18px;text-wrap:balance;display:flex;gap:14px;align-items:baseline}
h2 .sn{font-family:var(--font-mono);font-size:12px;font-weight:400;color:var(--brass);letter-spacing:.06em;flex:none;padding-top:2px}
h3{font-family:var(--font-display);font-weight:700;font-size:16px;letter-spacing:-.008em;margin:34px 0 10px;color:var(--ink)}
p{margin:0 0 15px;max-width:var(--measure)}
ul,ol{max-width:var(--measure);margin:0 0 15px;padding-left:20px}
li{margin-bottom:7px}
strong{font-weight:600}
em{font-style:italic}
code{font-family:var(--font-mono);font-size:.855em;background:var(--surface-2);padding:1px 5px;border-radius:2px}
a{color:var(--brass)}
.lede{font-size:19px;line-height:1.55;color:var(--ink-2);max-width:60ch}
/* ---------- devices ---------- */
.callout{border-left:3px solid var(--brass);background:var(--brass-soft);padding:18px 22px;margin:0 0 24px;max-width:var(--measure)}
.callout p:last-child{margin-bottom:0}
.callout .lbl{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--brass);display:block;margin-bottom:8px}
.rule-quote{border-top:2px solid var(--ink);border-bottom:2px solid var(--ink);padding:26px 0;margin:28px 0;max-width:var(--measure)}
.rule-quote p{font-family:var(--font-display);font-weight:600;font-size:19px;line-height:1.38;letter-spacing:-.014em;margin:0;text-wrap:balance}
.hard{border-left:3px solid var(--clay);background:var(--clay-soft);padding:18px 22px;margin:0 0 24px;max-width:var(--measure)}
.hard .lbl{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--clay);display:block;margin-bottom:8px}
.hard p:last-child{margin-bottom:0}
.dec{font-family:var(--font-mono);font-size:10.5px;letter-spacing:.08em;color:var(--brass);text-transform:uppercase}
.vec{font-family:var(--font-mono);font-size:.9em;font-weight:600;background:var(--surface-2);padding:2px 7px;border-radius:2px;white-space:nowrap;letter-spacing:.04em}
/* ---------- tables ---------- */
.scroll{overflow-x:auto;margin:0 0 24px;-webkit-overflow-scrolling:touch}
table{border-collapse:collapse;width:100%;min-width:520px;font-family:var(--font-display);font-size:13.5px;line-height:1.45}
th{text-align:left;font-family:var(--font-mono);font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);font-weight:400;padding:0 16px 8px 0;border-bottom:1px solid var(--rule-strong);vertical-align:bottom}
td{padding:11px 16px 11px 0;border-bottom:1px solid var(--rule);vertical-align:top;color:var(--ink-2)}
td:first-child{color:var(--ink);font-weight:600}
tbody tr:last-child td{border-bottom:none}
.lvl{font-family:var(--font-mono);font-weight:600;font-size:12px;letter-spacing:.04em;color:var(--ink)}
/* ---------- ladders ---------- */
.breakout{margin:34px 0 40px}
.bhead{display:flex;justify-content:space-between;align-items:baseline;gap:20px;border-bottom:1px solid var(--rule-strong);padding-bottom:9px;margin-bottom:22px;flex-wrap:wrap}
.bhead h3{margin:0;font-size:13px;letter-spacing:.1em;text-transform:uppercase;font-family:var(--font-mono);font-weight:400;color:var(--ink-3)}
.bhead .note{font-family:var(--font-display);font-size:12.5px;color:var(--ink-3)}
.ladders{display:grid;gap:26px}
.ladder{display:grid;grid-template-columns:126px minmax(0,1fr);gap:18px;align-items:start}
@media (max-width:700px){.ladder{grid-template-columns:1fr;gap:10px}}
.ladder .pname{font-family:var(--font-display);font-weight:700;font-size:14px;letter-spacing:-.01em;padding-top:2px}
.ladder .pname span{display:block;font-family:var(--font-mono);font-size:10px;font-weight:400;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);margin-top:3px}
.rungs{display:grid;gap:3px;grid-template-columns:repeat(5,minmax(0,1fr))}
@media (max-width:700px){.rungs{grid-template-columns:repeat(2,minmax(0,1fr))}}
.rung{padding:9px 10px 11px;background:var(--surface);border-top:4px solid var(--l0);min-width:0}
.rung.r1{border-top-color:var(--l1)} .rung.r2{border-top-color:var(--l2)}
.rung.r3{border-top-color:var(--l3)} .rung.r4{border-top-color:var(--l4)}
.rung .code{font-family:var(--font-mono);font-size:11px;font-weight:600;letter-spacing:.06em;color:var(--ink);display:block;margin-bottom:4px}
.rung .txt{font-family:var(--font-display);font-size:11.5px;line-height:1.34;color:var(--ink-2);display:block}
.rung.na{opacity:.42}
/* ---------- matrix ---------- */
.matrix-shell{display:grid;grid-template-columns:auto minmax(0,1fr);gap:12px;align-items:stretch;margin-bottom:14px}
.ylab{writing-mode:vertical-rl;transform:rotate(180deg);font-family:var(--font-mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);text-align:center;padding-bottom:22px}
.mgrid{display:grid;grid-template-columns:34px repeat(5,minmax(0,1fr));gap:3px}
.mcell{background:var(--surface);min-height:60px;padding:6px;display:flex;flex-direction:column;justify-content:flex-end;gap:4px;min-width:0}
.mcell.tint1{background:color-mix(in srgb,var(--l1) 26%,var(--surface))}
.mcell.tint2{background:color-mix(in srgb,var(--l2) 26%,var(--surface))}
.mcell.tint3{background:color-mix(in srgb,var(--l3) 24%,var(--surface))}
.mcell.tint4{background:color-mix(in srgb,var(--l4) 22%,var(--surface))}
.mcell.void{background:repeating-linear-gradient(135deg,transparent,transparent 5px,var(--rule) 5px,var(--rule) 6px);opacity:.55}
.rlab,.clab{font-family:var(--font-mono);font-size:10px;font-weight:600;letter-spacing:.05em;color:var(--ink-3);display:flex;align-items:center;justify-content:center}
.rlab{min-height:60px}
.clab{padding-top:7px;min-height:22px}
.pin{font-family:var(--font-mono);font-size:9.5px;font-weight:600;letter-spacing:.02em;background:var(--ink);color:var(--paper);padding:2px 5px;border-radius:2px;line-height:1.3;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pin.ghost{background:transparent;color:var(--ink-2);border:1px dashed var(--rule-strong)}
.mnote{display:flex;gap:22px;flex-wrap:wrap;font-family:var(--font-display);font-size:12px;color:var(--ink-3);padding-top:6px}
.mnote .k{display:flex;align-items:center;gap:7px}
.sw{width:13px;height:13px;flex:none;background:var(--ink)}
.sw.g{background:transparent;border:1px dashed var(--rule-strong)}
.sw.v{background:repeating-linear-gradient(135deg,transparent,transparent 4px,var(--rule) 4px,var(--rule) 5px);border:1px solid var(--rule)}
@media (max-width:640px){
.mgrid{grid-template-columns:28px repeat(5,minmax(0,1fr))}
.mcell{min-height:52px;padding:4px}
.pin{font-size:8px;padding:1px 3px}
.rlab{min-height:52px}
}
/* ---------- methodology ---------- */
.verbs{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:2px;background:var(--rule);border:1px solid var(--rule)}
.verb{background:var(--surface);padding:18px 18px 20px}
.verb h4{font-family:var(--font-display);font-weight:750;font-size:15px;margin:0 0 7px;letter-spacing:-.01em}
.verb p{font-family:var(--font-display);font-size:12.5px;line-height:1.46;color:var(--ink-2);margin:0;max-width:none}
.verb .step{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.13em;color:var(--brass);display:block;margin-bottom:9px}
/* ---------- questions ---------- */
.qs{display:flex;flex-direction:column;gap:0;border-top:1px solid var(--rule-strong)}
.q{display:grid;grid-template-columns:34px minmax(0,1fr) 170px;gap:18px;padding:16px 0;border-bottom:1px solid var(--rule);align-items:start}
@media (max-width:760px){.q{grid-template-columns:28px minmax(0,1fr);gap:12px}.q .owner{grid-column:2}}
.q .qn{font-family:var(--font-mono);font-size:11px;color:var(--brass);padding-top:3px}
.q .qt{font-family:var(--font-display);font-size:14px;line-height:1.48;color:var(--ink-2)}
.q .qt b{color:var(--ink);font-weight:700;display:block;margin-bottom:2px;font-size:14.5px}
.owner{font-family:var(--font-mono);font-size:10px;letter-spacing:.05em;color:var(--ink-3);padding-top:4px}
.owner .tag{display:inline-block;border:1px solid var(--rule-strong);padding:2px 7px;border-radius:2px}
.owner .tag.need{border-color:var(--clay);color:var(--clay)}
/* ---------- misc ---------- */
.numbers{font-family:var(--font-mono);font-size:12.5px;line-height:1.85;background:var(--surface);border-left:3px solid var(--l3);padding:16px 20px;margin:0 0 22px;overflow-x:auto;max-width:var(--measure)}
.numbers .v{color:var(--ink);font-weight:600}
.numbers .k{color:var(--ink-3)}
pre{font-family:var(--font-mono);font-size:12.5px;line-height:1.68;background:var(--surface);border-left:3px solid var(--rule-strong);padding:16px 20px;overflow-x:auto;margin:0 0 22px;max-width:var(--measure);color:var(--ink-2)}
.alt{border-bottom:1px solid var(--rule);padding:14px 0;max-width:var(--measure)}
.alt:last-of-type{border-bottom:none}
.alt b{font-family:var(--font-display);font-size:14px;display:block;margin-bottom:3px}
.alt p{font-size:14.5px;margin:0;color:var(--ink-2)}
.alt .verdict{font-family:var(--font-mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--clay)}
footer{border-top:2px solid var(--ink);margin-top:20px;padding-top:22px;font-family:var(--font-mono);font-size:11px;letter-spacing:.06em;color:var(--ink-3);display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap}
.tm td,.tm th{text-align:center}
.tm td:first-child,.tm th:first-child{text-align:left}
.yes{color:var(--l4);font-weight:700}
.no{color:var(--clay);font-weight:700}
.kind{font-family:var(--font-mono);font-size:9px;letter-spacing:.09em;text-transform:uppercase;padding:2px 6px;border-radius:2px;white-space:nowrap;border:1px solid var(--rule-strong);color:var(--ink-3)}
.kind.adv{border-color:var(--clay);color:var(--clay)}
.routes{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:2px;background:var(--rule);border:1px solid var(--rule);margin:0 0 22px}
.route{background:var(--surface);padding:16px 18px}
.route h4{font-family:var(--font-display);font-weight:750;font-size:14px;margin:0 0 6px}
.route p{font-family:var(--font-display);font-size:12.5px;line-height:1.45;color:var(--ink-2);margin:0;max-width:none}
.route .tag{font-family:var(--font-mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:var(--brass);display:block;margin-bottom:8px}
a:focus-visible,.rail a:focus-visible{outline:2px solid var(--brass);outline-offset:3px}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
<div class="wrap"><header><div class="eyebrow"><span>RISK-METHOD-SEVERITY</span> <span class="stat">adopted · adopted-1</span> <span>risk-nexus</span> <span>reviewed 2026-08-20</span><span>generated from canonical source — do not edit</span></div><h1>Severity</h1><p class="sub">Source: <code>risk-nexus · docs/method/severity.md · a13d954f8597fd92201746e2d52f031a5a88d969</code></p><p class="sub">Review due: 2027-02-20</p></header><div class="layout"><nav class="rail" aria-label="Sections"><ol><li><a href="#the-two-axes"><span class="n">·</span>The two axes</a></li><li><a href="#the-grid"><span class="n">·</span>The grid</a></li><li><a href="#the-fidelity-modifier"><span class="n">·</span>The fidelity modifier</a></li><li><a href="#which-state-is-scored"><span class="n">·</span>Which state is scored</a></li><li><a href="#build-mode"><span class="n">·</span>Build mode</a></li><li><a href="#non-adversarial-findings"><span class="n">·</span>Non-adversarial findings</a></li><li><a href="#live-incidents"><span class="n">·</span>Live incidents</a></li><li><a href="#the-floor"><span class="n">·</span>The floor</a></li><li><a href="#provenance-is-a-grading-input"><span class="n">·</span>Provenance is a grading input</a></li><li><a href="#recording-a-grade"><span class="n">·</span>Recording a grade</a></li></ol></nav><main><p>This is <code>risk-nexus</code>'s judgement instrument. It is not canon, it is not a standard, and it binds nobody else. It exists so that two findings graded a month apart are graded the same way, and so that a grade can be argued with.</p>
<p>It was written against three real findings (<code>RISK-F-0001</code>, <code>RISK-F-0002</code>, <code>RISK-F-0003</code>) and it must keep grading those three sensibly or it is wrong.</p>
<section id="the-two-axes"><h2>The two axes</h2>
<h3>Impact — what happens if it goes wrong once</h3>
<div class="scroll"><table><thead><tr><th>Band</th><th>Name</th><th>Test</th></tr></thead><tbody><tr><td><code>I1</code></td><td>negligible</td><td>Confined to one component. No data leaves it, no record is falsified, no recovery is lost.</td></tr><tr><td><code>I2</code></td><td>limited</td><td>One system's data or availability. Recoverable. Confined to a single tenant, actor or lane.</td></tr><tr><td><code>I3</code></td><td>serious</td><td>Crosses a boundary — tenant, system, or trust — or removes recoverability for one system.</td></tr><tr><td><code>I4</code></td><td>severe</td><td>Crosses the estate. What is compromised here propagates to everything that trusts it, or the data loss is unbounded.</td></tr></tbody></table></div>
<p>Impact is scored at <strong>one occurrence</strong>, not at the worst imaginable campaign. "An attacker who already owns the cluster could do this too" is not an impact argument.</p>
<h3>Likelihood — how far anyone has to reach</h3>
<div class="scroll"><table><thead><tr><th>Band</th><th>Name</th><th>Test</th></tr></thead><tbody><tr><td><code>L1</code></td><td>remote</td><td>Requires access nobody currently holds and no ordinary process grants.</td></tr><tr><td><code>L2</code></td><td>possible</td><td>Requires a foothold the estate does grant somewhere — an in-cluster workload, an agent session, a scoped token.</td></tr><tr><td><code>L3</code></td><td>likely</td><td>Reachable from inside the normal working set with no additional step.</td></tr><tr><td><code>L4</code></td><td>present</td><td>No barrier at all, or it is already happening.</td></tr></tbody></table></div>
<p>Likelihood is about <strong>reach</strong>, not about intent or about whether anyone has bothered. <code>risk-nexus</code> does not model attackers; it models what the system permits.</p>
<p>Where the reporter has not established exposure, the finding says so and the grade uses the band the <em>stated</em> facts support — not the worst case, and not zero. <code>RISK-F-0001</code> explicitly declines to assume a default-deny NetworkPolicy exists; the grade must decline with it, and the unverified fact becomes a review item rather than a silent assumption in either direction.</p>
</section>
<section id="the-grid"><h2>The grid</h2>
<div class="scroll"><table><thead><tr><th></th><th><code>L1</code></th><th><code>L2</code></th><th><code>L3</code></th><th><code>L4</code></th></tr></thead><tbody><tr><td><code>I4</code></td><td>medium</td><td>high</td><td><strong>critical</strong></td><td><strong>critical</strong></td></tr><tr><td><code>I3</code></td><td>low</td><td>medium</td><td>high</td><td><strong>critical</strong></td></tr><tr><td><code>I2</code></td><td>low</td><td>low</td><td>medium</td><td>high</td></tr><tr><td><code>I1</code></td><td>note</td><td>low</td><td>low</td><td>medium</td></tr></tbody></table></div>
<p>Four severities: <code>low</code>, <code>medium</code>, <code>high</code>, <code>critical</code>. <code>note</code> is not a severity; see the floor.</p>
</section>
<section id="the-fidelity-modifier"><h2>The fidelity modifier</h2>
<p><strong>A control that lies is one impact band worse than the same control absent.</strong></p>
<p>Apply <code>+1</code> impact band (capped at <code>I4</code>) when the failure mode produces a <em>false record</em> rather than <em>no record</em>: an attestation that a check passed when nothing checked, an audit line asserting an authorization that was never made, a green signal derived from an unreachable test.</p>
<p>The reasoning is <code>RISK-F-0002</code>'s and the register adopts it: an absent control is a gap you can find by looking; a lying control is a gap that survives looking, because the evidence you would look at is the thing that is wrong. Only one of the two states misleads the person investigating afterwards.</p>
<p>The modifier applies to the state being scored. A finding that describes both states — control absent today, control lying if switched on in the wrong order — gets <strong>two scores and one of them is the register's headline</strong>; see "Which state is scored".</p>
</section>
<section id="which-state-is-scored"><h2>Which state is scored</h2>
<p>The headline <code>severity</code> is the state of the world <strong>today</strong>. A hazard that would be created by a <em>future</em> action is not the headline, because a register that scores hypotheticals stops describing the estate.</p>
<p>The hazard is not lost. It is recorded on the finding as a named <strong>constraint</strong> with its own grade, and it attaches to whatever action would trigger it — usually another finding's remediation. <code>RISK-F-0002</code> is the worked example: the gate being off is today (headline), the gate being switched on while the oracle is forgeable is a constraint on <code>RISK-F-0001</code>'s fix, graded separately and higher.</p>
<p>If the constraint's grade is higher than the headline, the finding says so in its ruling. A reader must not be able to come away with the low number and miss the high one.</p>
</section>
<section id="build-mode"><h2>Build mode</h2>
<p>Every finding is graded twice:</p>
<ul><li><code>severity</code> — today, in build mode, with today's likelihood.</li><li><code>severity_at_production</code> — the same impact, with likelihood re-read for a system carrying real users and real tenant data.</li></ul>
<p>Build mode legitimately lowers <strong>both</strong> axes, for different reasons: likelihood, where the reach itself depends on a production deployment that has not happened; and impact, where the data that would be exposed does not exist yet. What it must never lower is <code>severity_at_production</code> — the defect does not improve because the calendar has not reached it.</p>
<div class="rule-quote"><p><em>Amended 2026-08-19 (<code>RISK-WP-0001-T07</code>).</em> This paragraph originally said build mode was a likelihood input and never an impact one. Grading the unverified tenant boundary broke that: what build mode changes there is the consequence of an occurrence, not the reach of it. The instrument was wrong on first hard use and is corrected rather than worked around.</p></div>
<p>Where the two grades differ, the production transition is a mandatory re-score. <code>docs/method/review.md</code> binds the review date to it, so the re-score is a scheduled event and not somebody's memory.</p>
</section>
<section id="non-adversarial-findings"><h2>Non-adversarial findings</h2>
<p>Likelihood is written as reach because most findings are about someone getting somewhere. Where a finding is about loss, corruption or outage — no backup, no recovery path, an eviction-prone deployment — there is no attacker to model.</p>
<p>For those, likelihood reads as <strong>the chance of the triggering event inside one review interval</strong>: <code>L1</code> would be surprising, <code>L2</code> is an ordinary failure the estate has seen before, <code>L3</code> is expected in the normal course of running, <code>L4</code> is already happening. Impact is unchanged: what is lost, and whether it comes back.</p>
<div class="rule-quote"><p><em>Added 2026-08-19 (<code>RISK-WP-0001-T07</code>).</em> Forced by <code>RISK-F-0006</code>, where the defect is an absent backup and the reach reading produced nonsense.</p></div>
</section>
<section id="live-incidents"><h2>Live incidents</h2>
<p>Everything above assumes a latent defect — something reachable that nobody is currently reaching. When someone is, three things change:</p>
<ul><li><strong>Likelihood is <code>L4</code>.</strong> The band means "already happening" and this is what it is for.</li><li><strong>Impact is scored on what has occurred plus what is still reachable</strong>, not on the worst case. An incident in progress has facts; use them.</li><li><strong>The grade is provisional and expected to move.</strong> File first, grade within the hour, re-grade as facts arrive. <code>docs/method/intake.md</code> has the rest, including the 72-hour clock that <code>first_observed</code> starts.</li></ul>
</section>
<section id="the-floor"><h2>The floor</h2>
<p><code>INTENT.md</code>: if a finding would not change anyone's decision, it is a note, not a risk. Concretely, a register entry requires <strong>both</strong>:</p>
<ol><li><strong>An owner who could act.</strong> Some repo, or the operator, can do something about it. No actor, no entry.</li><li><strong>A decision that changes.</strong> Recording it alters what someone does, when they do it, or what they must not do first.</li></ol>
<p>Fails either test → it is a note in <code>notes/</code>, not a finding in <code>findings/</code>. Notes are not graded, not reviewed, and not published. They exist so that "we saw it" survives without inflating the register.</p>
<p>An <code>I1</code>/<code>L1</code> cell is <code>note</code> in the grid for the same reason: something that is both negligible and unreachable is a thing we know, not a risk we carry.</p>
<p>Two things the floor does <strong>not</strong> exclude:</p>
<ul><li><strong>Known and deliberate.</strong> <code>RISK-F-0002</code> is a decision somebody made on purpose. It still passes the floor, because it changes what may be switched on and in what order. Deliberate is not the same as tracked.</li><li><strong>Omission-shaped.</strong> <code>RISK-F-0003</code> is a default that silently produces ungoverned lanes. The individual lane is small; the default is not.</li></ul>
</section>
<section id="provenance-is-a-grading-input"><h2>Provenance is a grading input</h2>
<p>All four defects known to this register were found by repos reading their own code against a ladder, within days of each other. None was found by monitoring.</p>
<p>Where a finding's provenance is "we happened to look", the register does not get to assume that similar defects would have been caught. That raises likelihood for the class, not for the instance, and it belongs in the ruling's reasoning rather than in a modifier — the register grades what is filed, and notes when the filing was luck.</p>
</section>
<section id="recording-a-grade"><h2>Recording a grade</h2>
<p>The finding's front-matter carries:</p>
<pre>severity: critical # headline, today
severity_at_production: critical
impact: I4 # band, before modifiers
likelihood: L3
fidelity_modifier: false # true if +1 applied, with the reason in the ruling</pre>
<p>and the ruling section states impact, likelihood, any modifier, and the one sentence that would have to become false for the grade to change.</p>
</section><footer><span>RISK-METHOD-SEVERITY · adopted-1 · adopted</span><span>risk-nexus · docs/method/severity.md · a13d954f8597fd92201746e2d52f031a5a88d969</span></footer></main></div></div></html>

View file

@ -0,0 +1,222 @@
<!doctype html>
<html lang="en"><meta charset="utf-8">
<meta name="policy-source-revision" content="c5517c754bd84b0ebf47878ba0f26df0ecb3b4a4">
<meta name="policy-source-digest" content="562b6eb3031ffe35e712c5e11e35aae23ce84a90e0090438dc89513f9685052b">
<title>What this register may verify for itself, and what it must take from owners</title>
<style>
:root{
--paper:#EDEEF0; --surface:#F6F7F8; --surface-2:#E4E6E9;
--ink:#171D24; --ink-2:#4A5561; --ink-3:#737E8A;
--rule:#D3D7DC; --rule-strong:#B6BCC3;
--brass:#8A6A2E; --brass-soft:#EFE5CD; --brass-line:#C9AE74;
--clay:#8A3A2C; --clay-soft:#F2DFDA;
--l0:#DCE0E2; --l1:#B9C4C7; --l2:#8CA1A6; --l3:#567D84; --l4:#23555E;
--chip-fg:#F6F7F8;
--font-display:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",sans-serif;
--font-body:"Iowan Old Style","Palatino Linotype",Palatino,Georgia,serif;
--font-mono:ui-monospace,"SF Mono","Cascadia Code",Menlo,Consolas,monospace;
--measure:66ch;
}
@media (prefers-color-scheme:dark){
:root:not([data-theme="light"]){
--paper:#12161A; --surface:#191E24; --surface-2:#222831;
--ink:#E6E9EC; --ink-2:#A3ADB7; --ink-3:#78838E;
--rule:#2A3138; --rule-strong:#3B444D;
--brass:#C9A45C; --brass-soft:#33290F; --brass-line:#6B5426;
--clay:#D08A76; --clay-soft:#3A211B;
--l0:#262C32; --l1:#35424A; --l2:#4A626B; --l3:#6A939D; --l4:#97C4CD;
--chip-fg:#12161A;
}
}
:root[data-theme="dark"]{
--paper:#12161A; --surface:#191E24; --surface-2:#222831;
--ink:#E6E9EC; --ink-2:#A3ADB7; --ink-3:#78838E;
--rule:#2A3138; --rule-strong:#3B444D;
--brass:#C9A45C; --brass-soft:#33290F; --brass-line:#6B5426;
--clay:#D08A76; --clay-soft:#3A211B;
--l0:#262C32; --l1:#35424A; --l2:#4A626B; --l3:#6A939D; --l4:#97C4CD;
--chip-fg:#12161A;
}
*{box-sizing:border-box}
body{
margin:0; background:var(--paper); color:var(--ink);
font-family:var(--font-body); font-size:17px; line-height:1.62;
-webkit-font-smoothing:antialiased;
}
.wrap{max-width:1180px;margin:0 auto;padding:0 24px 96px}
.layout{display:grid;grid-template-columns:180px minmax(0,1fr);gap:56px;align-items:start}
@media (max-width:960px){.layout{grid-template-columns:1fr;gap:0}.rail{display:none}}
/* ---------- rail ---------- */
.rail{position:sticky;top:28px;padding-top:8px;font-family:var(--font-display);font-size:12px;line-height:1.5}
.rail ol{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:7px}
.rail a{color:var(--ink-3);text-decoration:none;display:flex;gap:9px}
.rail a:hover,.rail a:focus-visible{color:var(--brass)}
.rail .n{font-family:var(--font-mono);font-size:10px;color:var(--rule-strong);min-width:16px;padding-top:1px}
.rail .grp{margin-top:14px;font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--rule-strong)}
/* ---------- header ---------- */
header{padding:64px 0 40px;border-bottom:2px solid var(--ink);margin-bottom:44px}
.eyebrow{font-family:var(--font-mono);font-size:11.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);display:flex;flex-wrap:wrap;gap:14px;margin-bottom:22px}
.eyebrow .stat{color:var(--clay)}
h1{font-family:var(--font-display);font-weight:800;letter-spacing:-.035em;line-height:.94;font-size:clamp(46px,9vw,92px);margin:0 0 6px;text-wrap:balance}
.sub{font-family:var(--font-display);font-weight:500;font-size:clamp(16px,2.4vw,21px);letter-spacing:-.01em;color:var(--ink-2);margin:0 0 30px;max-width:34ch;line-height:1.3}
.metagrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:20px 28px;border-top:1px solid var(--rule);padding-top:20px}
.metagrid dt{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);margin-bottom:5px}
.metagrid dd{margin:0;font-family:var(--font-display);font-size:13.5px;line-height:1.45;color:var(--ink)}
/* ---------- typography ---------- */
section{margin-bottom:60px;scroll-margin-top:24px}
h2{font-family:var(--font-display);font-weight:750;letter-spacing:-.022em;font-size:clamp(24px,3.4vw,31px);line-height:1.12;margin:0 0 18px;text-wrap:balance;display:flex;gap:14px;align-items:baseline}
h2 .sn{font-family:var(--font-mono);font-size:12px;font-weight:400;color:var(--brass);letter-spacing:.06em;flex:none;padding-top:2px}
h3{font-family:var(--font-display);font-weight:700;font-size:16px;letter-spacing:-.008em;margin:34px 0 10px;color:var(--ink)}
p{margin:0 0 15px;max-width:var(--measure)}
ul,ol{max-width:var(--measure);margin:0 0 15px;padding-left:20px}
li{margin-bottom:7px}
strong{font-weight:600}
em{font-style:italic}
code{font-family:var(--font-mono);font-size:.855em;background:var(--surface-2);padding:1px 5px;border-radius:2px}
a{color:var(--brass)}
.lede{font-size:19px;line-height:1.55;color:var(--ink-2);max-width:60ch}
/* ---------- devices ---------- */
.callout{border-left:3px solid var(--brass);background:var(--brass-soft);padding:18px 22px;margin:0 0 24px;max-width:var(--measure)}
.callout p:last-child{margin-bottom:0}
.callout .lbl{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--brass);display:block;margin-bottom:8px}
.rule-quote{border-top:2px solid var(--ink);border-bottom:2px solid var(--ink);padding:26px 0;margin:28px 0;max-width:var(--measure)}
.rule-quote p{font-family:var(--font-display);font-weight:600;font-size:19px;line-height:1.38;letter-spacing:-.014em;margin:0;text-wrap:balance}
.hard{border-left:3px solid var(--clay);background:var(--clay-soft);padding:18px 22px;margin:0 0 24px;max-width:var(--measure)}
.hard .lbl{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--clay);display:block;margin-bottom:8px}
.hard p:last-child{margin-bottom:0}
.dec{font-family:var(--font-mono);font-size:10.5px;letter-spacing:.08em;color:var(--brass);text-transform:uppercase}
.vec{font-family:var(--font-mono);font-size:.9em;font-weight:600;background:var(--surface-2);padding:2px 7px;border-radius:2px;white-space:nowrap;letter-spacing:.04em}
/* ---------- tables ---------- */
.scroll{overflow-x:auto;margin:0 0 24px;-webkit-overflow-scrolling:touch}
table{border-collapse:collapse;width:100%;min-width:520px;font-family:var(--font-display);font-size:13.5px;line-height:1.45}
th{text-align:left;font-family:var(--font-mono);font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);font-weight:400;padding:0 16px 8px 0;border-bottom:1px solid var(--rule-strong);vertical-align:bottom}
td{padding:11px 16px 11px 0;border-bottom:1px solid var(--rule);vertical-align:top;color:var(--ink-2)}
td:first-child{color:var(--ink);font-weight:600}
tbody tr:last-child td{border-bottom:none}
.lvl{font-family:var(--font-mono);font-weight:600;font-size:12px;letter-spacing:.04em;color:var(--ink)}
/* ---------- ladders ---------- */
.breakout{margin:34px 0 40px}
.bhead{display:flex;justify-content:space-between;align-items:baseline;gap:20px;border-bottom:1px solid var(--rule-strong);padding-bottom:9px;margin-bottom:22px;flex-wrap:wrap}
.bhead h3{margin:0;font-size:13px;letter-spacing:.1em;text-transform:uppercase;font-family:var(--font-mono);font-weight:400;color:var(--ink-3)}
.bhead .note{font-family:var(--font-display);font-size:12.5px;color:var(--ink-3)}
.ladders{display:grid;gap:26px}
.ladder{display:grid;grid-template-columns:126px minmax(0,1fr);gap:18px;align-items:start}
@media (max-width:700px){.ladder{grid-template-columns:1fr;gap:10px}}
.ladder .pname{font-family:var(--font-display);font-weight:700;font-size:14px;letter-spacing:-.01em;padding-top:2px}
.ladder .pname span{display:block;font-family:var(--font-mono);font-size:10px;font-weight:400;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);margin-top:3px}
.rungs{display:grid;gap:3px;grid-template-columns:repeat(5,minmax(0,1fr))}
@media (max-width:700px){.rungs{grid-template-columns:repeat(2,minmax(0,1fr))}}
.rung{padding:9px 10px 11px;background:var(--surface);border-top:4px solid var(--l0);min-width:0}
.rung.r1{border-top-color:var(--l1)} .rung.r2{border-top-color:var(--l2)}
.rung.r3{border-top-color:var(--l3)} .rung.r4{border-top-color:var(--l4)}
.rung .code{font-family:var(--font-mono);font-size:11px;font-weight:600;letter-spacing:.06em;color:var(--ink);display:block;margin-bottom:4px}
.rung .txt{font-family:var(--font-display);font-size:11.5px;line-height:1.34;color:var(--ink-2);display:block}
.rung.na{opacity:.42}
/* ---------- matrix ---------- */
.matrix-shell{display:grid;grid-template-columns:auto minmax(0,1fr);gap:12px;align-items:stretch;margin-bottom:14px}
.ylab{writing-mode:vertical-rl;transform:rotate(180deg);font-family:var(--font-mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);text-align:center;padding-bottom:22px}
.mgrid{display:grid;grid-template-columns:34px repeat(5,minmax(0,1fr));gap:3px}
.mcell{background:var(--surface);min-height:60px;padding:6px;display:flex;flex-direction:column;justify-content:flex-end;gap:4px;min-width:0}
.mcell.tint1{background:color-mix(in srgb,var(--l1) 26%,var(--surface))}
.mcell.tint2{background:color-mix(in srgb,var(--l2) 26%,var(--surface))}
.mcell.tint3{background:color-mix(in srgb,var(--l3) 24%,var(--surface))}
.mcell.tint4{background:color-mix(in srgb,var(--l4) 22%,var(--surface))}
.mcell.void{background:repeating-linear-gradient(135deg,transparent,transparent 5px,var(--rule) 5px,var(--rule) 6px);opacity:.55}
.rlab,.clab{font-family:var(--font-mono);font-size:10px;font-weight:600;letter-spacing:.05em;color:var(--ink-3);display:flex;align-items:center;justify-content:center}
.rlab{min-height:60px}
.clab{padding-top:7px;min-height:22px}
.pin{font-family:var(--font-mono);font-size:9.5px;font-weight:600;letter-spacing:.02em;background:var(--ink);color:var(--paper);padding:2px 5px;border-radius:2px;line-height:1.3;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pin.ghost{background:transparent;color:var(--ink-2);border:1px dashed var(--rule-strong)}
.mnote{display:flex;gap:22px;flex-wrap:wrap;font-family:var(--font-display);font-size:12px;color:var(--ink-3);padding-top:6px}
.mnote .k{display:flex;align-items:center;gap:7px}
.sw{width:13px;height:13px;flex:none;background:var(--ink)}
.sw.g{background:transparent;border:1px dashed var(--rule-strong)}
.sw.v{background:repeating-linear-gradient(135deg,transparent,transparent 4px,var(--rule) 4px,var(--rule) 5px);border:1px solid var(--rule)}
@media (max-width:640px){
.mgrid{grid-template-columns:28px repeat(5,minmax(0,1fr))}
.mcell{min-height:52px;padding:4px}
.pin{font-size:8px;padding:1px 3px}
.rlab{min-height:52px}
}
/* ---------- methodology ---------- */
.verbs{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:2px;background:var(--rule);border:1px solid var(--rule)}
.verb{background:var(--surface);padding:18px 18px 20px}
.verb h4{font-family:var(--font-display);font-weight:750;font-size:15px;margin:0 0 7px;letter-spacing:-.01em}
.verb p{font-family:var(--font-display);font-size:12.5px;line-height:1.46;color:var(--ink-2);margin:0;max-width:none}
.verb .step{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.13em;color:var(--brass);display:block;margin-bottom:9px}
/* ---------- questions ---------- */
.qs{display:flex;flex-direction:column;gap:0;border-top:1px solid var(--rule-strong)}
.q{display:grid;grid-template-columns:34px minmax(0,1fr) 170px;gap:18px;padding:16px 0;border-bottom:1px solid var(--rule);align-items:start}
@media (max-width:760px){.q{grid-template-columns:28px minmax(0,1fr);gap:12px}.q .owner{grid-column:2}}
.q .qn{font-family:var(--font-mono);font-size:11px;color:var(--brass);padding-top:3px}
.q .qt{font-family:var(--font-display);font-size:14px;line-height:1.48;color:var(--ink-2)}
.q .qt b{color:var(--ink);font-weight:700;display:block;margin-bottom:2px;font-size:14.5px}
.owner{font-family:var(--font-mono);font-size:10px;letter-spacing:.05em;color:var(--ink-3);padding-top:4px}
.owner .tag{display:inline-block;border:1px solid var(--rule-strong);padding:2px 7px;border-radius:2px}
.owner .tag.need{border-color:var(--clay);color:var(--clay)}
/* ---------- misc ---------- */
.numbers{font-family:var(--font-mono);font-size:12.5px;line-height:1.85;background:var(--surface);border-left:3px solid var(--l3);padding:16px 20px;margin:0 0 22px;overflow-x:auto;max-width:var(--measure)}
.numbers .v{color:var(--ink);font-weight:600}
.numbers .k{color:var(--ink-3)}
pre{font-family:var(--font-mono);font-size:12.5px;line-height:1.68;background:var(--surface);border-left:3px solid var(--rule-strong);padding:16px 20px;overflow-x:auto;margin:0 0 22px;max-width:var(--measure);color:var(--ink-2)}
.alt{border-bottom:1px solid var(--rule);padding:14px 0;max-width:var(--measure)}
.alt:last-of-type{border-bottom:none}
.alt b{font-family:var(--font-display);font-size:14px;display:block;margin-bottom:3px}
.alt p{font-size:14.5px;margin:0;color:var(--ink-2)}
.alt .verdict{font-family:var(--font-mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--clay)}
footer{border-top:2px solid var(--ink);margin-top:20px;padding-top:22px;font-family:var(--font-mono);font-size:11px;letter-spacing:.06em;color:var(--ink-3);display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap}
.tm td,.tm th{text-align:center}
.tm td:first-child,.tm th:first-child{text-align:left}
.yes{color:var(--l4);font-weight:700}
.no{color:var(--clay);font-weight:700}
.kind{font-family:var(--font-mono);font-size:9px;letter-spacing:.09em;text-transform:uppercase;padding:2px 6px;border-radius:2px;white-space:nowrap;border:1px solid var(--rule-strong);color:var(--ink-3)}
.kind.adv{border-color:var(--clay);color:var(--clay)}
.routes{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:2px;background:var(--rule);border:1px solid var(--rule);margin:0 0 22px}
.route{background:var(--surface);padding:16px 18px}
.route h4{font-family:var(--font-display);font-weight:750;font-size:14px;margin:0 0 6px}
.route p{font-family:var(--font-display);font-size:12.5px;line-height:1.45;color:var(--ink-2);margin:0;max-width:none}
.route .tag{font-family:var(--font-mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:var(--brass);display:block;margin-bottom:8px}
a:focus-visible,.rail a:focus-visible{outline:2px solid var(--brass);outline-offset:3px}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
<div class="wrap"><header><div class="eyebrow"><span>RISK-METHOD-VERIFICATION</span> <span class="stat">adopted · adopted-1</span> <span>risk-nexus</span> <span>reviewed 2026-08-20</span><span>generated from canonical source — do not edit</span></div><h1>What this register may verify for itself, and what it must take from owners</h1><p class="sub">Source: <code>risk-nexus · docs/method/verification.md · c5517c754bd84b0ebf47878ba0f26df0ecb3b4a4</code></p><p class="sub">Review due: 2027-02-20</p></header><div class="layout"><nav class="rail" aria-label="Sections"><ol><li><a href="#the-rule"><span class="n">·</span>The rule</a></li><li><a href="#what-this-host-can-actually-reach-established-2026-08-20"><span class="n">·</span>What this host can actually reach — established 2026-08-20</a></li><li><a href="#a-file-is-not-a-safe-proxy-for-the-server"><span class="n">·</span>A file is not a safe proxy for the server</a></li><li><a href="#recording-a-verification"><span class="n">·</span>Recording a verification</a></li><li><a href="#verification-and-the-cadence-ladder"><span class="n">·</span>Verification and the cadence ladder</a></li></ol></nav><main><p><code>RISK-WP-0004-T05</code> asked what this repo can legitimately establish itself, because two gradings were resting on file comparison. The answer was found by trying, on 2026-08-20, rather than by reasoning about it.</p>
<section id="the-rule"><h2>The rule</h2>
<p><strong>A register may look. It may not touch, and it may not conclude on a system's behalf.</strong></p>
<p>Verification here means: running a read-only command a reporter has already named, or that answers a question the register itself wrote down as open, and recording exactly what came back.</p>
<p>Permitted:</p>
<ul><li>read-only reads of live state (<code>kubectl get</code>, <code>bao policy read</code>, an HTTP probe of a documented endpoint);</li><li>comparing what is deployed against what a repo said is deployed;</li><li>recording the discrepancy and routing it as a <strong>question</strong>.</li></ul>
<p>Not permitted:</p>
<ul><li>any write, apply, patch, restart or rotation — including one that would obviously improve things;</li><li>concluding what a defect means for a system this repo does not own. The system stays authoritative about itself (<code>INTENT.md</code>);</li><li>verifying instead of asking. The owner is asked first; verification settles what an owner cannot see or has invited someone to check.</li></ul>
<p><code>rapp-postgres</code> declined to check the NetworkPolicy on <code>flex-auth</code>'s behalf, saying that would be reporting on a system they do not own. That was right <strong>for a reporter</strong>. This register is the downstream party whose grade depended on the answer, and <code>flex-auth</code> explicitly named the command and asked for someone with credentials to run it. Those two positions are compatible.</p>
</section>
<section id="what-this-host-can-actually-reach-established-2026-08-20"><h2>What this host can actually reach — established 2026-08-20</h2>
<div class="scroll"><table><thead><tr><th>Target</th><th>Result</th><th>Consequence</th></tr></thead><tbody><tr><td>Kubernetes (<code>railiance01</code>)</td><td><strong>reads work</strong><code>kubectl get ns</code>, <code>get networkpolicy -o json</code></td><td>Live cluster state is verifiable by this register</td></tr><tr><td>OpenBao (<code>bao.coulomb.social</code>)</td><td><strong>403 permission denied</strong> on <code>token lookup</code> and <code>policy read</code></td><td>Policy claims are not verifiable here; <code>RISK-F-0009</code> rests on file comparison</td></tr></tbody></table></div>
<p>The asymmetry is worth stating plainly: <strong>the register can check what the cluster admits, and cannot check what the secret store permits.</strong> Every grade touching an OpenBao policy is therefore a grade on a document, and says so.</p>
<p>That is not a gap to close by acquiring credentials. A risk register holding production secret-store access has traded a verification problem for a much worse one. If OpenBao claims need verifying, the right answer is for the owner to run the read and report it, which is what <code>ops-warden</code> did — the obstacle there was an expired token, not the arrangement.</p>
</section>
<section id="a-file-is-not-a-safe-proxy-for-the-server"><h2>A file is not a safe proxy for the server</h2>
<p>Established 2026-08-21, by evidence rather than by caution. <code>ops-warden</code> ran the live OpenBao read that <code>RISK-F-0009</code> had been graded without, and <strong>the deployed policy differs from the committed file.</strong> No lane maps to the drifted path, so nothing was exposed — but the general claim is now proven rather than suspected.</p>
<p>Consequences this register accepts:</p>
<ul><li><strong>Every grade made off a checkout is a grade on a document</strong>, and says so on its face. <code>RISK-F-0009</code> does.</li><li>A verification that reads a file is a <strong>weaker artifact</strong> than one that reads a server, and the record must not blur them. <code>RISK-V-0001</code> reads a server; the OpenBao comparison in <code>RISK-F-0009</code> reads a file.</li><li>Where only the owner can reach the server, the owner's probe is the evidence and the register says whose it is. That is not a lesser standard — it is the correct one, given <code>verification.md</code>'s own limits.</li></ul>
<p>The corollary is uncomfortable and worth stating: <strong>drift between file and server is invisible to anyone reading files</strong>, which is most of this estate's tooling, including <code>fix_tracker.py</code>. What that tool reads is what a repo <em>recorded</em>, and a record can be as stale as any other claim — as four self-reported stale blockers in twelve hours demonstrated on 2026-08-21.</p>
</section>
<section id="recording-a-verification"><h2>Recording a verification</h2>
<p>One file per verification in <code>docs/verifications/</code>, <code>RISK-V-NNNN</code>, stating the command, the raw result, what it confirms, what it contradicts, and what it does not establish. It names the findings it bears on, and those findings link back.</p>
<p>A verification is evidence, not a ruling. It can move a grade; it does not close a finding on its own, and it never speaks for the owning repo.</p>
</section>
<section id="verification-and-the-cadence-ladder"><h2>Verification and the cadence ladder</h2>
<p>A verification that contradicts something is a check that is <strong>not clean</strong>: the affected findings reset to <code>instant</code>. A verification that confirms what was already recorded is clean, and may be exactly the evidence a rung is built on.</p>
<p>The first one (<code>RISK-V-0001</code>) did both — it confirmed the ingress claim <code>RISK-F-0001</code> was graded on, contradicted the egress claim in the same message, and surfaced a third policy nobody had mentioned that bears on <code>RISK-F-0002</code>.</p>
</section><footer><span>RISK-METHOD-VERIFICATION · adopted-1 · adopted</span><span>risk-nexus · docs/method/verification.md · c5517c754bd84b0ebf47878ba0f26df0ecb3b4a4</span></footer></main></div></div></html>

View file

@ -0,0 +1,222 @@
<!doctype html>
<html lang="en"><meta charset="utf-8">
<meta name="policy-source-revision" content="a13d954f8597fd92201746e2d52f031a5a88d969">
<meta name="policy-source-digest" content="562b6eb3031ffe35e712c5e11e35aae23ce84a90e0090438dc89513f9685052b">
<title>What this register may verify for itself, and what it must take from owners</title>
<style>
:root{
--paper:#EDEEF0; --surface:#F6F7F8; --surface-2:#E4E6E9;
--ink:#171D24; --ink-2:#4A5561; --ink-3:#737E8A;
--rule:#D3D7DC; --rule-strong:#B6BCC3;
--brass:#8A6A2E; --brass-soft:#EFE5CD; --brass-line:#C9AE74;
--clay:#8A3A2C; --clay-soft:#F2DFDA;
--l0:#DCE0E2; --l1:#B9C4C7; --l2:#8CA1A6; --l3:#567D84; --l4:#23555E;
--chip-fg:#F6F7F8;
--font-display:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",sans-serif;
--font-body:"Iowan Old Style","Palatino Linotype",Palatino,Georgia,serif;
--font-mono:ui-monospace,"SF Mono","Cascadia Code",Menlo,Consolas,monospace;
--measure:66ch;
}
@media (prefers-color-scheme:dark){
:root:not([data-theme="light"]){
--paper:#12161A; --surface:#191E24; --surface-2:#222831;
--ink:#E6E9EC; --ink-2:#A3ADB7; --ink-3:#78838E;
--rule:#2A3138; --rule-strong:#3B444D;
--brass:#C9A45C; --brass-soft:#33290F; --brass-line:#6B5426;
--clay:#D08A76; --clay-soft:#3A211B;
--l0:#262C32; --l1:#35424A; --l2:#4A626B; --l3:#6A939D; --l4:#97C4CD;
--chip-fg:#12161A;
}
}
:root[data-theme="dark"]{
--paper:#12161A; --surface:#191E24; --surface-2:#222831;
--ink:#E6E9EC; --ink-2:#A3ADB7; --ink-3:#78838E;
--rule:#2A3138; --rule-strong:#3B444D;
--brass:#C9A45C; --brass-soft:#33290F; --brass-line:#6B5426;
--clay:#D08A76; --clay-soft:#3A211B;
--l0:#262C32; --l1:#35424A; --l2:#4A626B; --l3:#6A939D; --l4:#97C4CD;
--chip-fg:#12161A;
}
*{box-sizing:border-box}
body{
margin:0; background:var(--paper); color:var(--ink);
font-family:var(--font-body); font-size:17px; line-height:1.62;
-webkit-font-smoothing:antialiased;
}
.wrap{max-width:1180px;margin:0 auto;padding:0 24px 96px}
.layout{display:grid;grid-template-columns:180px minmax(0,1fr);gap:56px;align-items:start}
@media (max-width:960px){.layout{grid-template-columns:1fr;gap:0}.rail{display:none}}
/* ---------- rail ---------- */
.rail{position:sticky;top:28px;padding-top:8px;font-family:var(--font-display);font-size:12px;line-height:1.5}
.rail ol{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:7px}
.rail a{color:var(--ink-3);text-decoration:none;display:flex;gap:9px}
.rail a:hover,.rail a:focus-visible{color:var(--brass)}
.rail .n{font-family:var(--font-mono);font-size:10px;color:var(--rule-strong);min-width:16px;padding-top:1px}
.rail .grp{margin-top:14px;font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--rule-strong)}
/* ---------- header ---------- */
header{padding:64px 0 40px;border-bottom:2px solid var(--ink);margin-bottom:44px}
.eyebrow{font-family:var(--font-mono);font-size:11.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);display:flex;flex-wrap:wrap;gap:14px;margin-bottom:22px}
.eyebrow .stat{color:var(--clay)}
h1{font-family:var(--font-display);font-weight:800;letter-spacing:-.035em;line-height:.94;font-size:clamp(46px,9vw,92px);margin:0 0 6px;text-wrap:balance}
.sub{font-family:var(--font-display);font-weight:500;font-size:clamp(16px,2.4vw,21px);letter-spacing:-.01em;color:var(--ink-2);margin:0 0 30px;max-width:34ch;line-height:1.3}
.metagrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:20px 28px;border-top:1px solid var(--rule);padding-top:20px}
.metagrid dt{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);margin-bottom:5px}
.metagrid dd{margin:0;font-family:var(--font-display);font-size:13.5px;line-height:1.45;color:var(--ink)}
/* ---------- typography ---------- */
section{margin-bottom:60px;scroll-margin-top:24px}
h2{font-family:var(--font-display);font-weight:750;letter-spacing:-.022em;font-size:clamp(24px,3.4vw,31px);line-height:1.12;margin:0 0 18px;text-wrap:balance;display:flex;gap:14px;align-items:baseline}
h2 .sn{font-family:var(--font-mono);font-size:12px;font-weight:400;color:var(--brass);letter-spacing:.06em;flex:none;padding-top:2px}
h3{font-family:var(--font-display);font-weight:700;font-size:16px;letter-spacing:-.008em;margin:34px 0 10px;color:var(--ink)}
p{margin:0 0 15px;max-width:var(--measure)}
ul,ol{max-width:var(--measure);margin:0 0 15px;padding-left:20px}
li{margin-bottom:7px}
strong{font-weight:600}
em{font-style:italic}
code{font-family:var(--font-mono);font-size:.855em;background:var(--surface-2);padding:1px 5px;border-radius:2px}
a{color:var(--brass)}
.lede{font-size:19px;line-height:1.55;color:var(--ink-2);max-width:60ch}
/* ---------- devices ---------- */
.callout{border-left:3px solid var(--brass);background:var(--brass-soft);padding:18px 22px;margin:0 0 24px;max-width:var(--measure)}
.callout p:last-child{margin-bottom:0}
.callout .lbl{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--brass);display:block;margin-bottom:8px}
.rule-quote{border-top:2px solid var(--ink);border-bottom:2px solid var(--ink);padding:26px 0;margin:28px 0;max-width:var(--measure)}
.rule-quote p{font-family:var(--font-display);font-weight:600;font-size:19px;line-height:1.38;letter-spacing:-.014em;margin:0;text-wrap:balance}
.hard{border-left:3px solid var(--clay);background:var(--clay-soft);padding:18px 22px;margin:0 0 24px;max-width:var(--measure)}
.hard .lbl{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--clay);display:block;margin-bottom:8px}
.hard p:last-child{margin-bottom:0}
.dec{font-family:var(--font-mono);font-size:10.5px;letter-spacing:.08em;color:var(--brass);text-transform:uppercase}
.vec{font-family:var(--font-mono);font-size:.9em;font-weight:600;background:var(--surface-2);padding:2px 7px;border-radius:2px;white-space:nowrap;letter-spacing:.04em}
/* ---------- tables ---------- */
.scroll{overflow-x:auto;margin:0 0 24px;-webkit-overflow-scrolling:touch}
table{border-collapse:collapse;width:100%;min-width:520px;font-family:var(--font-display);font-size:13.5px;line-height:1.45}
th{text-align:left;font-family:var(--font-mono);font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);font-weight:400;padding:0 16px 8px 0;border-bottom:1px solid var(--rule-strong);vertical-align:bottom}
td{padding:11px 16px 11px 0;border-bottom:1px solid var(--rule);vertical-align:top;color:var(--ink-2)}
td:first-child{color:var(--ink);font-weight:600}
tbody tr:last-child td{border-bottom:none}
.lvl{font-family:var(--font-mono);font-weight:600;font-size:12px;letter-spacing:.04em;color:var(--ink)}
/* ---------- ladders ---------- */
.breakout{margin:34px 0 40px}
.bhead{display:flex;justify-content:space-between;align-items:baseline;gap:20px;border-bottom:1px solid var(--rule-strong);padding-bottom:9px;margin-bottom:22px;flex-wrap:wrap}
.bhead h3{margin:0;font-size:13px;letter-spacing:.1em;text-transform:uppercase;font-family:var(--font-mono);font-weight:400;color:var(--ink-3)}
.bhead .note{font-family:var(--font-display);font-size:12.5px;color:var(--ink-3)}
.ladders{display:grid;gap:26px}
.ladder{display:grid;grid-template-columns:126px minmax(0,1fr);gap:18px;align-items:start}
@media (max-width:700px){.ladder{grid-template-columns:1fr;gap:10px}}
.ladder .pname{font-family:var(--font-display);font-weight:700;font-size:14px;letter-spacing:-.01em;padding-top:2px}
.ladder .pname span{display:block;font-family:var(--font-mono);font-size:10px;font-weight:400;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);margin-top:3px}
.rungs{display:grid;gap:3px;grid-template-columns:repeat(5,minmax(0,1fr))}
@media (max-width:700px){.rungs{grid-template-columns:repeat(2,minmax(0,1fr))}}
.rung{padding:9px 10px 11px;background:var(--surface);border-top:4px solid var(--l0);min-width:0}
.rung.r1{border-top-color:var(--l1)} .rung.r2{border-top-color:var(--l2)}
.rung.r3{border-top-color:var(--l3)} .rung.r4{border-top-color:var(--l4)}
.rung .code{font-family:var(--font-mono);font-size:11px;font-weight:600;letter-spacing:.06em;color:var(--ink);display:block;margin-bottom:4px}
.rung .txt{font-family:var(--font-display);font-size:11.5px;line-height:1.34;color:var(--ink-2);display:block}
.rung.na{opacity:.42}
/* ---------- matrix ---------- */
.matrix-shell{display:grid;grid-template-columns:auto minmax(0,1fr);gap:12px;align-items:stretch;margin-bottom:14px}
.ylab{writing-mode:vertical-rl;transform:rotate(180deg);font-family:var(--font-mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);text-align:center;padding-bottom:22px}
.mgrid{display:grid;grid-template-columns:34px repeat(5,minmax(0,1fr));gap:3px}
.mcell{background:var(--surface);min-height:60px;padding:6px;display:flex;flex-direction:column;justify-content:flex-end;gap:4px;min-width:0}
.mcell.tint1{background:color-mix(in srgb,var(--l1) 26%,var(--surface))}
.mcell.tint2{background:color-mix(in srgb,var(--l2) 26%,var(--surface))}
.mcell.tint3{background:color-mix(in srgb,var(--l3) 24%,var(--surface))}
.mcell.tint4{background:color-mix(in srgb,var(--l4) 22%,var(--surface))}
.mcell.void{background:repeating-linear-gradient(135deg,transparent,transparent 5px,var(--rule) 5px,var(--rule) 6px);opacity:.55}
.rlab,.clab{font-family:var(--font-mono);font-size:10px;font-weight:600;letter-spacing:.05em;color:var(--ink-3);display:flex;align-items:center;justify-content:center}
.rlab{min-height:60px}
.clab{padding-top:7px;min-height:22px}
.pin{font-family:var(--font-mono);font-size:9.5px;font-weight:600;letter-spacing:.02em;background:var(--ink);color:var(--paper);padding:2px 5px;border-radius:2px;line-height:1.3;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pin.ghost{background:transparent;color:var(--ink-2);border:1px dashed var(--rule-strong)}
.mnote{display:flex;gap:22px;flex-wrap:wrap;font-family:var(--font-display);font-size:12px;color:var(--ink-3);padding-top:6px}
.mnote .k{display:flex;align-items:center;gap:7px}
.sw{width:13px;height:13px;flex:none;background:var(--ink)}
.sw.g{background:transparent;border:1px dashed var(--rule-strong)}
.sw.v{background:repeating-linear-gradient(135deg,transparent,transparent 4px,var(--rule) 4px,var(--rule) 5px);border:1px solid var(--rule)}
@media (max-width:640px){
.mgrid{grid-template-columns:28px repeat(5,minmax(0,1fr))}
.mcell{min-height:52px;padding:4px}
.pin{font-size:8px;padding:1px 3px}
.rlab{min-height:52px}
}
/* ---------- methodology ---------- */
.verbs{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:2px;background:var(--rule);border:1px solid var(--rule)}
.verb{background:var(--surface);padding:18px 18px 20px}
.verb h4{font-family:var(--font-display);font-weight:750;font-size:15px;margin:0 0 7px;letter-spacing:-.01em}
.verb p{font-family:var(--font-display);font-size:12.5px;line-height:1.46;color:var(--ink-2);margin:0;max-width:none}
.verb .step{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.13em;color:var(--brass);display:block;margin-bottom:9px}
/* ---------- questions ---------- */
.qs{display:flex;flex-direction:column;gap:0;border-top:1px solid var(--rule-strong)}
.q{display:grid;grid-template-columns:34px minmax(0,1fr) 170px;gap:18px;padding:16px 0;border-bottom:1px solid var(--rule);align-items:start}
@media (max-width:760px){.q{grid-template-columns:28px minmax(0,1fr);gap:12px}.q .owner{grid-column:2}}
.q .qn{font-family:var(--font-mono);font-size:11px;color:var(--brass);padding-top:3px}
.q .qt{font-family:var(--font-display);font-size:14px;line-height:1.48;color:var(--ink-2)}
.q .qt b{color:var(--ink);font-weight:700;display:block;margin-bottom:2px;font-size:14.5px}
.owner{font-family:var(--font-mono);font-size:10px;letter-spacing:.05em;color:var(--ink-3);padding-top:4px}
.owner .tag{display:inline-block;border:1px solid var(--rule-strong);padding:2px 7px;border-radius:2px}
.owner .tag.need{border-color:var(--clay);color:var(--clay)}
/* ---------- misc ---------- */
.numbers{font-family:var(--font-mono);font-size:12.5px;line-height:1.85;background:var(--surface);border-left:3px solid var(--l3);padding:16px 20px;margin:0 0 22px;overflow-x:auto;max-width:var(--measure)}
.numbers .v{color:var(--ink);font-weight:600}
.numbers .k{color:var(--ink-3)}
pre{font-family:var(--font-mono);font-size:12.5px;line-height:1.68;background:var(--surface);border-left:3px solid var(--rule-strong);padding:16px 20px;overflow-x:auto;margin:0 0 22px;max-width:var(--measure);color:var(--ink-2)}
.alt{border-bottom:1px solid var(--rule);padding:14px 0;max-width:var(--measure)}
.alt:last-of-type{border-bottom:none}
.alt b{font-family:var(--font-display);font-size:14px;display:block;margin-bottom:3px}
.alt p{font-size:14.5px;margin:0;color:var(--ink-2)}
.alt .verdict{font-family:var(--font-mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--clay)}
footer{border-top:2px solid var(--ink);margin-top:20px;padding-top:22px;font-family:var(--font-mono);font-size:11px;letter-spacing:.06em;color:var(--ink-3);display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap}
.tm td,.tm th{text-align:center}
.tm td:first-child,.tm th:first-child{text-align:left}
.yes{color:var(--l4);font-weight:700}
.no{color:var(--clay);font-weight:700}
.kind{font-family:var(--font-mono);font-size:9px;letter-spacing:.09em;text-transform:uppercase;padding:2px 6px;border-radius:2px;white-space:nowrap;border:1px solid var(--rule-strong);color:var(--ink-3)}
.kind.adv{border-color:var(--clay);color:var(--clay)}
.routes{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:2px;background:var(--rule);border:1px solid var(--rule);margin:0 0 22px}
.route{background:var(--surface);padding:16px 18px}
.route h4{font-family:var(--font-display);font-weight:750;font-size:14px;margin:0 0 6px}
.route p{font-family:var(--font-display);font-size:12.5px;line-height:1.45;color:var(--ink-2);margin:0;max-width:none}
.route .tag{font-family:var(--font-mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:var(--brass);display:block;margin-bottom:8px}
a:focus-visible,.rail a:focus-visible{outline:2px solid var(--brass);outline-offset:3px}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
<div class="wrap"><header><div class="eyebrow"><span>RISK-METHOD-VERIFICATION</span> <span class="stat">adopted · adopted-1</span> <span>risk-nexus</span> <span>reviewed 2026-08-20</span><span>generated from canonical source — do not edit</span></div><h1>What this register may verify for itself, and what it must take from owners</h1><p class="sub">Source: <code>risk-nexus · docs/method/verification.md · a13d954f8597fd92201746e2d52f031a5a88d969</code></p><p class="sub">Review due: 2027-02-20</p></header><div class="layout"><nav class="rail" aria-label="Sections"><ol><li><a href="#the-rule"><span class="n">·</span>The rule</a></li><li><a href="#what-this-host-can-actually-reach-established-2026-08-20"><span class="n">·</span>What this host can actually reach — established 2026-08-20</a></li><li><a href="#a-file-is-not-a-safe-proxy-for-the-server"><span class="n">·</span>A file is not a safe proxy for the server</a></li><li><a href="#recording-a-verification"><span class="n">·</span>Recording a verification</a></li><li><a href="#verification-and-the-cadence-ladder"><span class="n">·</span>Verification and the cadence ladder</a></li></ol></nav><main><p><code>RISK-WP-0004-T05</code> asked what this repo can legitimately establish itself, because two gradings were resting on file comparison. The answer was found by trying, on 2026-08-20, rather than by reasoning about it.</p>
<section id="the-rule"><h2>The rule</h2>
<p><strong>A register may look. It may not touch, and it may not conclude on a system's behalf.</strong></p>
<p>Verification here means: running a read-only command a reporter has already named, or that answers a question the register itself wrote down as open, and recording exactly what came back.</p>
<p>Permitted:</p>
<ul><li>read-only reads of live state (<code>kubectl get</code>, <code>bao policy read</code>, an HTTP probe of a documented endpoint);</li><li>comparing what is deployed against what a repo said is deployed;</li><li>recording the discrepancy and routing it as a <strong>question</strong>.</li></ul>
<p>Not permitted:</p>
<ul><li>any write, apply, patch, restart or rotation — including one that would obviously improve things;</li><li>concluding what a defect means for a system this repo does not own. The system stays authoritative about itself (<code>INTENT.md</code>);</li><li>verifying instead of asking. The owner is asked first; verification settles what an owner cannot see or has invited someone to check.</li></ul>
<p><code>rapp-postgres</code> declined to check the NetworkPolicy on <code>flex-auth</code>'s behalf, saying that would be reporting on a system they do not own. That was right <strong>for a reporter</strong>. This register is the downstream party whose grade depended on the answer, and <code>flex-auth</code> explicitly named the command and asked for someone with credentials to run it. Those two positions are compatible.</p>
</section>
<section id="what-this-host-can-actually-reach-established-2026-08-20"><h2>What this host can actually reach — established 2026-08-20</h2>
<div class="scroll"><table><thead><tr><th>Target</th><th>Result</th><th>Consequence</th></tr></thead><tbody><tr><td>Kubernetes (<code>railiance01</code>)</td><td><strong>reads work</strong><code>kubectl get ns</code>, <code>get networkpolicy -o json</code></td><td>Live cluster state is verifiable by this register</td></tr><tr><td>OpenBao (<code>bao.coulomb.social</code>)</td><td><strong>403 permission denied</strong> on <code>token lookup</code> and <code>policy read</code></td><td>Policy claims are not verifiable here; <code>RISK-F-0009</code> rests on file comparison</td></tr></tbody></table></div>
<p>The asymmetry is worth stating plainly: <strong>the register can check what the cluster admits, and cannot check what the secret store permits.</strong> Every grade touching an OpenBao policy is therefore a grade on a document, and says so.</p>
<p>That is not a gap to close by acquiring credentials. A risk register holding production secret-store access has traded a verification problem for a much worse one. If OpenBao claims need verifying, the right answer is for the owner to run the read and report it, which is what <code>ops-warden</code> did — the obstacle there was an expired token, not the arrangement.</p>
</section>
<section id="a-file-is-not-a-safe-proxy-for-the-server"><h2>A file is not a safe proxy for the server</h2>
<p>Established 2026-08-21, by evidence rather than by caution. <code>ops-warden</code> ran the live OpenBao read that <code>RISK-F-0009</code> had been graded without, and <strong>the deployed policy differs from the committed file.</strong> No lane maps to the drifted path, so nothing was exposed — but the general claim is now proven rather than suspected.</p>
<p>Consequences this register accepts:</p>
<ul><li><strong>Every grade made off a checkout is a grade on a document</strong>, and says so on its face. <code>RISK-F-0009</code> does.</li><li>A verification that reads a file is a <strong>weaker artifact</strong> than one that reads a server, and the record must not blur them. <code>RISK-V-0001</code> reads a server; the OpenBao comparison in <code>RISK-F-0009</code> reads a file.</li><li>Where only the owner can reach the server, the owner's probe is the evidence and the register says whose it is. That is not a lesser standard — it is the correct one, given <code>verification.md</code>'s own limits.</li></ul>
<p>The corollary is uncomfortable and worth stating: <strong>drift between file and server is invisible to anyone reading files</strong>, which is most of this estate's tooling, including <code>fix_tracker.py</code>. What that tool reads is what a repo <em>recorded</em>, and a record can be as stale as any other claim — as four self-reported stale blockers in twelve hours demonstrated on 2026-08-21.</p>
</section>
<section id="recording-a-verification"><h2>Recording a verification</h2>
<p>One file per verification in <code>docs/verifications/</code>, <code>RISK-V-NNNN</code>, stating the command, the raw result, what it confirms, what it contradicts, and what it does not establish. It names the findings it bears on, and those findings link back.</p>
<p>A verification is evidence, not a ruling. It can move a grade; it does not close a finding on its own, and it never speaks for the owning repo.</p>
</section>
<section id="verification-and-the-cadence-ladder"><h2>Verification and the cadence ladder</h2>
<p>A verification that contradicts something is a check that is <strong>not clean</strong>: the affected findings reset to <code>instant</code>. A verification that confirms what was already recorded is clean, and may be exactly the evidence a rung is built on.</p>
<p>The first one (<code>RISK-V-0001</code>) did both — it confirmed the ingress claim <code>RISK-F-0001</code> was graded on, contradicted the egress claim in the same message, and surfaced a third policy nobody had mentioned that bears on <code>RISK-F-0002</code>.</p>
</section><footer><span>RISK-METHOD-VERIFICATION · adopted-1 · adopted</span><span>risk-nexus · docs/method/verification.md · a13d954f8597fd92201746e2d52f031a5a88d969</span></footer></main></div></div></html>