| title | Rules |
|---|---|
| description | Built in rule categories, custom patterns, and Semgrep rules. |
Instalog runs three kinds of rules on every PR.
- Built in rules, grouped into categories (
security,performance,maintainability,style). - Custom patterns you define as regex inside each category.
- Custom rules with arbitrary patterns and severities.
The reviewer also runs Semgrep with our base ruleset. See How it works for the pipeline order.
rules:
security:
enabled: true
severity_threshold: medium
performance:
enabled: true
check_complexity: true
max_function_lines: 100
maintainability:
enabled: true
check_documentation: true
require_tests: false
style:
enabled: falseDetects hardcoded credentials, SQL injection, XSS sinks, weak crypto, unsafe deserialization, command injection, SSRF.
severity_threshold drops findings below the given level. Order: low < medium < high < critical.
check_complexity enables cyclomatic complexity checks. max_function_lines flags any function over the threshold.
Also detects N+1 queries, sequential awaits in loops, unbounded allocations, missing pagination.
check_documentation flags public symbols without doc comments. require_tests flags new public functions without an accompanying test.
Also detects dead code, copy paste blocks, unused imports, deeply nested conditionals.
Off by default. Formatters do this better. Turn on only if you do not have a formatter configured.
Add patterns inside any built in category. The reviewer treats them like first party rules and respects the category severity threshold.
rules:
security:
custom_patterns:
- pattern: "password\\s*=\\s*['\"].*['\"]"
message: "Hardcoded password."
severity: high
- pattern: "api_key\\s*=\\s*['\"].*['\"]"
message: "Hardcoded API key."
severity: criticalpattern is a regular expression (RE2 syntax). Use Semgrep rules instead when you need structural matching.
Top level rules with their own enable flag and severity.
rules:
custom_rules:
- name: "no-console-log"
pattern: "console\\.log\\("
message: "Remove console.log before merging."
severity: medium
enabled: true
- name: "no-todo-on-main"
pattern: "//\\s*TODO"
message: "TODOs must be tracked as issues, not left in code."
severity: low
enabled: true| Field | Required | Description |
|---|---|---|
name |
yes | Stable identifier shown in dashboard and Semgrep rule citations. |
pattern |
yes | RE2 regex. |
message |
yes | Posted as the inline comment body. |
severity |
yes | low medium high critical. |
enabled |
no | Default true. |
For structural patterns, write a real Semgrep rule. Drop it in .semgrep/ at the repository root.
# .semgrep/no-fetch-in-loop.yml
rules:
- id: no-fetch-in-loop
pattern: |
for (... of ...) {
...
await fetch(...)
...
}
message: "Sequential fetch in a loop. Use Promise.all or pagination."
severity: WARNING
languages: [typescript, javascript]The reviewer auto discovers .semgrep/*.yml and runs every rule alongside the base ruleset. No config needed.
Semgrep findings bypass confidence filtering when severity: ERROR. They never hallucinate, so they are treated as facts.
When a piece of code matches multiple rules, the reviewer ranks them:
- Semgrep
ERROR - Custom rule with
criticalseverity - Built in
securityfinding - Semgrep
WARNING - Everything else, by confidence
Only the highest ranked finding per location is posted. The rest appear in the dashboard's filtered view.
Inline comment to suppress one rule for one line:
const password = "hunter2"; // instalog-disable-next-line security/hardcoded-secretOr a block:
// instalog-disable security/hardcoded-secret
const password = "hunter2";
const apiKey = "abc";
// instalog-enable security/hardcoded-secretSuppressions show up in the dashboard so reviewers can audit them.
instalog rules hits --repo owner/repo --since 30dReturns a sorted list of rules by hit count, acceptance rate, and false positive rate. See CLI reference.