There are two ways to flag a problem in a pull request. One is to say 'this looks like it might not be compliant.' The other is to say 'this deletes the audit log for a privileged action, which ISO 27001 A.8.15 expects you to keep.' The first is noise. The second is something an engineer can act on, or argue with. The difference is the clause.
Citing the exact clause is the core of how heygrc reports a finding, and it is also a constraint we accept: when we cannot name the clause, we would rather say nothing. Here is why.
The vague finding is worse than nothing
A finding without a clause hands the reader the work it skipped. Is this real? Which rule? Where do I even check? The first time, they look it up. After a few that turn out to be nothing, they stop reading the findings at all, including the true ones. A compliance reviewer that cries wolf does not get a second chance, it gets muted.
The scarce resource is not coverage. It is trust, and a vague finding spends it.
A citation is a falsifiable claim
Naming the exact clause turns a vibe into a claim you can check. It tells the reader which control, at a grain they can verify, and invites them to disagree. That is the feature, not a side effect: a finding you can refute is a finding you can trust when it holds.
async function runExport(userId, rows) {- await audit.log("data.export", { userId, count: rows.length }) return write(rows)}Not 'this looks non-compliant'. The specific claim: this removes the record of a bulk data export, the kind of event A.8.15 expects you to log. You can open A.8.15, look at the diff, and decide for yourself whether the claim holds. That is the point.
Grain is the hard part
The clause has to be at the right grain. 'This touches ISO 27001' is almost as useless as silence; 'this removes the logging A.8.15 asks for' is actionable. Getting there means mapping the actual change, the behavior that moved in the diff, to the specific control that governs it. Not the framework, not the control family, the clause.
Most of the difficulty in building a compliance reviewer lives here. Noticing that something changed is the easy part. Naming exactly which control it changed, correctly, is the work.
When we cannot cite, we stay silent
This is the trade we make, especially early: precision over recall. If we cannot map a change to a specific clause we are confident in, we do not emit a softer, vaguer warning just to be safe. A wrong or unverifiable finding costs more trust than a missed one, and trust is what makes the true findings land at all.
Silence is a feature when the alternative is noise. A reviewer earns the right to be believed by being quiet when it is unsure.
It matters more when the reader is an agent
When a coding agent is the one reading the finding, an uncheckable 'this looks non-compliant' is worse still: the agent cannot reason about it or act on it, so it ignores it or guesses. A finding that names the control and the clause is something a human and an agent can both use: look up the control, see what it expects, decide. The citation is the interface.
The bar is simple to state and hard to hold: every finding names the clause, or there is no finding. We are pre-launch, so the honest measure of whether we are holding it is the grain-correctness of our citations on real diffs, something we will report from our own evals when we have run them, with numbers or not at all.