Brief: the risk graph as a tool (to dev, from a collaborator's ideas)
Status: for dev@php.newsroom to act on; the steps below need no decision from the editor. Author: the Sherpa (sherpa@php.newsroom), at the editor's request on 23 October 2026, from the collaborator's message recorded as CI-002 (/sherpa/ideas/ci-002/), which continues CI-001. Each step is a board row (166 to 170). Two of his points wait for the editor and are listed at the end.
Why
The collaborator's reading of the risk graph: "the biggest opportunity is turning the graph from a visualization into an actionable tool for understanding security impact and making decisions." Measured on v0.10.10, the graph holds 442 nodes and 914 edges, every edge a verb with its named inverse. The overview draws all of it at once; nothing starts from one node; no edge says how it is known; nothing runs from code upwards; the gaps are not computed. Each step below fixes one of those, on the data the site already has.
The steps
| Step | What | His idea | Board |
|---|---|---|---|
| 1 | A focus view. Open the graph at any node (a CVE, a risk, a stakeholder, a function, a control): its direct neighbours, grouped by verb; expand any neighbour with a click; the path back to the start always shown; the focus and the expanded nodes in the address, so a view can be shared. In the browser, from data/grc-graph.json; no new data. | Progressive exploration (CI-002.3) | 166 |
| 2 | A basis on every edge. basis: source (with the capture's slug), code (with the commit), inferred (with the agent), confirmed (with who checked). Checked in build_grc(), which already stops on an unknown reference, so the gate's own files need no change. Inferred edges drawn dashed, with a switch to hide them; each edge links to what supports it. Start by marking what is known: edges built from data/code.json are code, edges from a claim are source; the rest inferred until checked. | Evidence and confidence (CI-002.5, CI-001.5) | 167 |
| 3 | Tests as nodes. The fix commit touched tests/, ext/zend_test and run-tests.php; today those are directory areas in the review graph. Each test file of the commit becomes a node, joined (tests / tested_by) to the remediation and code it exercises, read from the commit. | Traceability (CI-002.4, CI-001.8) | 168 |
| 4 | An impact view. Pick a function or file; climb the graph upwards: remediations, vulnerabilities, weaknesses, risks, controls, stakeholders, each with its path. User stories join when they exist. | Impact analysis (CI-002.6) | 169 |
| 5 | A gaps page. Computed at every build from rules written as data: a control with no path to a test; code with no owner; a risk with no story, treatment or holder; an edge with no basis (after step 2). Each gap with its count, its list and who could close it. On v0.10.10: none of the 16 code nodes has an owner one step away; none of the 95 controls reaches code or a test; no tests; 14 of 34 risks join no story directly. | Missing relationships (CI-002.8) | 170 |
Order: 2 before 5 (the gaps page reports edges with no basis); 1 and 4 share one component (a focus view that can climb). Each step is deterministic, built from the data, with a markdown twin, and works on a phone.
Waiting for the editor
- The design direction (CI-002.1): the collaborator prefers an editorial main experience with the graph behind an explicit step for depth. The redesign's mockups are under the editor's review (
/admin/design/). - Persona views of the graph (CI-002.7): which nodes and verbs each of the three views (executive, security leader, operator) shows by default, after the redesign is decided.
- User stories as a layer (CI-002.4): whose stories (PHP's own, or a reader's application's) is an editorial call.