// docs · v1.x

Rule IDs

The closed list of 30 rule ids every finding carries as rule_id — what each one means, its default SARIF level, and where the id is used (policy rules, inline markers, SARIF).

Updated October 18, 2026

A rule id is the stable name of the kind of problem a finding describes, written <category>.<rule> — for example sec.injection or correctness.error-handling. Every structured finding carries one in its rule_id field, next to a fingerprint. Requires v1.19.0 or later.

Key facts. The list is closed: 30 ids, listed below. The model must pick exactly one. An empty or unknown value becomes general.other — it is not a parse error and triggers no retry. Ids are never removed or renamed, so a policy file, an inline marker or a baseline that names one keeps working across releases. New ids are added, never repurposed.

Where a rule id is used

SurfaceHow
--jsonfindings[].rule_id — see Output formats.
Policy gaterules.deny / rules.allow take ids or <category>.*.
Inline suppressioncommitbrief-ignore[sec.injection]: reason silences that rule only.
BaselineThe fingerprint of a finding is a hash of file, rule id and symbol.
SARIFresults[].ruleId, and tool.driver.rules[] lists all 30.

The 30 rules

Categories: sec (security), correctness, concurrency, perf, api, test, arch, maint, style, docs, general.

Rule idDefault levelWhat it means
sec.injectionerrorUntrusted input reaches a query, shell, template or interpreter without neutralisation (SQL, command, LDAP, template)
sec.xsserrorUntrusted data is written into HTML or JS without context-appropriate escaping
sec.path-traversalerrorA user-controlled path reaches the file system without being confined
sec.ssrferrorA user-controlled URL or host is requested server-side without an allowlist
sec.hardcoded-secreterrorA credential, key or token literal is present in source
sec.authzerrorAn authentication or authorisation check is missing or can be bypassed
sec.unsafe-deserializationerrorUntrusted bytes are deserialised into objects or code
sec.crypto-misusewarningWeak algorithm, poor randomness, fixed IV or salt, or disabled TLS verification
sec.data-exposurewarningA secret or personal data is written to a log, an error or a response
correctness.nil-dereferrorA value that may be nil, null, undefined or None is dereferenced
correctness.logic-errorwarningA condition, operator or flow does not do what the code intends
correctness.boundarywarningOff-by-one, empty, overflow or other boundary cases are handled wrongly
correctness.error-handlingwarningAn error is ignored, swallowed, wrapped wrongly or not propagated
correctness.resource-leakwarningA file, connection, lock or goroutine is not released on every path
correctness.api-misusewarningA library or standard-library API is called against its contract
concurrency.raceerrorShared state is accessed concurrently without synchronisation
concurrency.deadlockerrorLock ordering or a channel wait can block forever
perf.algorithmicwarningAsymptotically poor algorithm or repeated work on a hot path
perf.n-plus-onewarningA per-item query or IO call inside a loop
perf.allocationnoteAvoidable memory allocation or copying on a hot path
api.breaking-changewarningA public interface or contract changes incompatibly
test.missingnoteNo test covers the changed behaviour
test.flakywarningTest depends on time, order, randomness or network (the static flaky pre-pass also produces this)
arch.boundary-violationwarningThe change violates a declared architectural constraint (architecture.json)
maint.complexitynoteStructure is hard to follow and could be simplified
maint.duplicationnoteLogic that should be shared has been copied
maint.dead-codenoteUnreachable or unused code
style.namingnoteMisleading or inconsistent identifier
docs.mismatchnoteA comment or document contradicts the code
general.othernoteNone of the above (the fallback)

Default level is the SARIF level the rule is published with (error, warning or note). It describes the rule, not the individual finding: a finding’s own severity decides the level of its SARIF result.

Two ids also produced without the model

Both ids are in the closed list the model chooses from, so a review can label a finding with either. They are also produced deterministically:

A policy entry on either id therefore covers both sources. rules.allow: [sec.hardcoded-secret] or rules.allow: [sec.*] also waives a hardcoded credential the model reported in a review, and rules.deny: [test.flaky] also blocks a flaky-test finding the model reported.

When the model picks the wrong id

The id is a model judgement, so it can be wrong. A finding that fits none of the 30 definitions lands in general.other. With --verbose (and without --quiet), the number of findings that fell back to general.other is written to stderr as a debug record, so you can see how often it happens on your code.

Because rule ids are a model’s classification, treat a rules.deny entry as a strong signal, not a proof: it blocks on whatever the model labelled, and it will not block on a problem the model labelled differently or did not report.