Skip to content
Insights · Engineering

Which rule did that scan name?

Name the rule that scan named: the alert number, the rule id, and the state. A different alert can share a tool. Another repository omits it.

Scroll
EngineeringOct 30, 202612 min readBy Salman Naqvi, Founder & CEO
Which rule did that scan name?

A client says the scan is clean, or says the alert on the slide is the one that blocked the merge. Tonight, three proofs, in a repository the agency or the client can open. Name the rule that scan named: the alert number, the rule id, and the state. If no alert was stored, write that, and do not invent a rule to fill the hole. Show a different alert whose number, or whose rule id, is not this one. Show another client's repository that does not list this alert. If any of the three needs the person who pressed scan, you have not named the rule. You have a green check and a guess.

This is one code scanning alert. It is not the alert a dependency raised. Which alert did that dependency raise? is a Dependabot number, a package, and an advisory. A dependency alert can be open while this scan has not named a rule, and a GHSA id is not a code scanning rule id. It is not the invite a repository sent. Which invite did that repository send? is an invitation id and a permission. A permission is not a rule. It is not the note an invoice issued. Which note did that invoice issue? is a credit note id. It is not the purpose an upload named. Which purpose did that upload name? is a file id and a purpose. A rule id is none of those.

None of what follows is a finding on this client's tree, and none of it is a legal opinion about a license. The fields below are one host's current description of a code scanning alert, of a default setup, and of a variant analysis. The request that names two repositories does not name a rule id. The counts below that are a 2024 census of other people's leaks and fix times. A million secret leaks is not the rule the scan named tonight.

GitHub's alert object has a number, and the number identifies the alert inside its repository. The list and the single-alert schema both require state as one of open, dismissed, fixed, or null. Four names, and null is in that enum. The update body is a shorter list. It says state can be open or dismissed. Two names. fixed is not a value that patch sends. 4 is not 2. You must provide dismissed_reason when you set the state to dismissed. The example sends state dismissed, dismissed_reason false positive, create_request true, and a comment. false positive is 14 characters, including the space. The other reasons the same parameter allows are won't fix, used in tests, and mitigated, plus null. won't fix is 9 characters. mitigated is also 9 characters, and it is not the same string. used in tests is 13. 14 is not 9, and 13 is not 9. The comment in the example is 88 characters. dismissed_comment on the alert schema has maxLength 280. 88 is not 280. 280 minus 88 is 192, which the page does not print. A comment that fits is not a rule id. rule.severity is none, note, warning, or error. Four names. rule.security_severity_level is low, medium, high, or critical. Also four names, and none of the words match. none is not low. note is not low. warning is not medium. error is not critical. 4 equals 4 and the vocabularies still do not substitute. classifications on an instance are source, generated, test, or library. Four more names. test as a classification is not the dismissal reason used in tests. The header the about note names is X-GitHub-Api-Version: 2026-03-10. The date value is 10 characters. 10 is not 14 (GitHub, REST API endpoints for code scanning).

Default setup is a different object, and its language list is not the variant-analysis language list. state is configured or not-configured. Two names. runner_type is standard, labeled, or null. query_suite is default or extended. threat_model is remote or remote_and_local. schedule is weekly or null. languages on that configuration are actions, c-cpp, csharp, go, java-kotlin, javascript-typescript, python, ruby, and swift. Nine names. javascript-typescript is 21 characters. java-kotlin is 11. c-cpp is 5. The variant-analysis field query_language is actions, cpp, csharp, go, java, javascript, python, ruby, rust, and swift. Ten names. 9 is not 10. c-cpp is not cpp. java-kotlin is not java. javascript-typescript is not javascript. rust is in the ten and not in the nine. csharp is 6 characters and is in both lists, which is not a reason to treat the lists as one. The create-variant example sends language csharp, query_pack aGVsbG8=, and repositories octocat/Hello-World and octocat/example. Two repository strings. 2 is not 9, and 2 is not 10. aGVsbG8= is 8 characters and decodes to hello, which is 5 characters. 8 is not 5. The page does not print hello. A second example sends repository_owners with one string, octocat. 1 is not 2. Create returns status 201. The analysis-status values on a scanned repository are pending, in_progress, succeeded, failed, canceled, and timed_out. Six names. The variant's own status is in_progress, succeeded, failed, or cancelled. Four names. canceled is one ell. cancelled is two. They are not the same spelling, and 6 is not 4. failure_reason is no_repos_queried, actions_workflow_run_failed, or internal_error. Three names. A failure reason is not a rule id.

An analysis is not an alert, and a zero is not a missing row. The get-analysis text says rules_count is the number of rules that ran, and that for very old analyses the data is not available and 0 is returned in that field. 0 is a stored number. It is not the absence of an analysis id. results_count is a different integer on the same object. commit_sha is required, with minLength 40 and maxLength 64. 40 plus 24 is 64. The page's pattern is 40 hex characters, optionally 24 more. 40 is not 64. A short hash you pasted from a slide is not this field if it is not 40 or 64. The same endpoint can return SARIF version 2.1.0 when the accept header asks for it. 2 is not 1, and a version string is not an alert number. Instances of one alert paginate with page default 1 and per_page default 30, maximum 100. 1 is not 30. 30 is not 100. A page of instances is not a second rule. AI scan, on the organization, is a string pr_scan whose values are enabled or disabled. Two names. enabled is not state open. disabled is not state dismissed. A repository that opted out is not a rule you have named.

The census of other people's leaks is not this alert. GitHub's Octoverse write-up of 2024 says developers used secret scanning to detect more than 39 million secret leaks. 39 million is not an alert number, and secret scanning is not code scanning. The same section says injection was the most common vulnerability type found via CodeQL across public and private repositories, and that Security Logging and Monitoring Failures were found more often in private repositories. It does not print a count beside either sentence. A category without a number is not a rule id. It says Copilot Autofix reduced time to fix for a pull-request-time alert from 1.5 hours to 28 minutes, and calls that more than three times faster. 1.5 hours is 90 minutes. 90 divided by 28 is not an integer, and the page does not print the quotient. 28 times 3 is 84 minutes, which is 1.4 hours, not 1.5. The gap is 6 minutes. The page does not print 6. It says cross-site scripting was fixed seven times faster, to 22 minutes, compared with almost three hours. 22 times 7 is 154 minutes, which is 2 hours and 34 minutes, not three hours. Three hours is 180 minutes. 180 divided by 22 is not 7. The page does not print 154. It says SQL injection was fixed twelve times faster, to 18 minutes, compared with 3.7 hours. 3.7 times 60 is 222 minutes. 222 divided by 18 is 12 and a third, not 12. 18 times 12 is 216 minutes, which is 3.6 hours, not 3.7. The gap is 6 minutes again, on a different pair. The page does not print 12.333 or 3.6. It also says 94 percent of the top 50 open source projects use the OpenSSF Scorecard, evaluated on roughly 1 million repositories. 0.94 times 50 is 47. The page does not print 47. 1 million is not 39 million. 94 is not an alert number, and 28 minutes is not rule severity note (GitHub, Octoverse 2024).

Do the three proofs on one real alert, in the repository that actually holds it. First, the binding. Copy the alert number, the rule id, the rule severity, the security severity, and the state. If the rule id is null, write null. If state is fixed, write fixed, and do not send a patch that the update body does not allow. If dismissed_reason is set, copy the reason exactly, including the space in false positive. Second, the other alert. A different number, even with the same rule id, is not this one. A language list of nine or ten names is not that second alert. A million leaks is not that second alert. Third, the other repository. A list that belongs to another client does not contain this number. If the only list is one shared organization and you cannot say whose repository it is, write that. A tenant you cannot name is the finding.

Three moves feel like the proof and are a second problem. Dismissing the alert because the comment was embarrassing, and then describing the missing row as a cleanup. The example comment is 88 characters under a ceiling of 280, and a dismissal reason is not a rule id. Quoting 39 million or 28 minutes because they look precise, while the alert you were asked about is one number, and the write-up that printed them had already failed to make seven times land on three hours. Asking a model which rule the scan named. The model will pick a plausible id. It will not open the alert. An invitation you have not kept is which invite did that repository send?. Opening that invitation does not name this rule.

The path is ordinary when an operator can open one client's repository without opening the next client's repository as the way to prove it. Gigbase is one agency workspace: projects, teams, and clients, distinct from the next workspace. The shape that matters here is one client's repository you can point at. That case is not a code-scanning ledger. Nothing in that sentence is a headcount, a duration, or a result figure. If the only control on the screen changes every client's alerts together, you do not have this proof. You have a directory.

There is a version of this afternoon where taking the work is the wrong purchase. The work is not sold under the agency's name. The client asked to meet the builders. The room only has a slide. The buyer only wants a template. Or the buyer wants a legal opinion about whether a finding is a vulnerability. A slide that says injection was the most common type is not the rule on this repository, and canceled is not cancelled, and a default setup in csharp is not an alert number. Do not take the work in order to narrate someone else's census.

When the client is real and the repository cannot name the rule, the missing object is specific. A record the agency or the client can open, that shows one alert number, one rule id, and one state, shows a different alert that is not that one, and shows another client's repository without it. A white label software development partner that expects this will have put that record where the client can open it, under the client's name, before a security review is the way the client discovers the scan lives in a vendor tenant. One that needs a call in order for the client to see which rule was named is telling you who holds the number. If the first slice is a fixed capability, an AI integration sprint is the shape where the acceptance sentence can include the three proofs. If you do not yet know which repository the scan writes to, a two-week AI readiness assessment maps the systems. The findings are yours. They are not a promise that 39 million leaks will appear on this client.

Before you tell them which rule the scan named, do the three proofs and write the number. Name the alert number, the rule id, and the state. Show a different alert that is not that one, even if the tool name matches. Show another repository's list that does not contain it. Do not paste fixed onto a patch that only sends open or dismissed, and do not paste 22 minutes onto a rule id. The binding is the alert you can defend.

Questions

Three records, in a repository the agency or the client can open. The alert number, the rule id, and the state, or a written line that no alert was stored. A different alert whose number or rule id is not this one. Another client's repository that does not list this alert. A language list is not a rule id, and fixed is not a state the update example sends.

No. A count of other people's secret leaks is not the rule id on this alert. A rule you can defend is the alert number, the rule id, and the state. 39 million leaks is not a code scanning number, and 28 minutes on a write-up is not your rule.

When the work is not sold under the agency's name, when the client asked to meet the builders, when the room only has a slide, when the buyer only wants a template, or when the buyer wants a legal opinion.

Find this useful? Tell Google to show you more of it.

Let's put AI to work in your business.

A 30-minute call. You bring the workflow or the roadmap — we'll tell you what's feasible, what it costs, and what we'd build first.

Book a call→