> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zenable.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Reviewer Configuration

> Configure Zenable automated code reviewers to match your team's standards

## How to Configure

To manage the reviewer configuration, customer admins can go to the [Company Settings](https://www.zenable.app/settings?utm_source=docs\&utm_medium=vcs-configuration\&utm_content=settings\&tab=configuration) page in the Zenable Management Console.

All configuration changes are applied immediately to your organization and affect all future code reviews.

## Configuration Profiles

Profiles let you maintain multiple independent configurations and assign them to specific repositories. Every tenant starts with a **Default** profile that applies to all repos unless overridden.

Each profile contains a complete, independent set of configuration options. Repos without a profile assignment use the **Default** configuration. Repos assigned to a profile use that profile's settings instead.

### Assigning Profiles to Repos

On the **Integrations** page, open a repository's settings (gear icon) and select a profile from the dropdown. Repos with an assigned profile display a colored badge showing the profile name.

### Automatic Profile Assignment

As you integrate Zenable with more repositories, manually attaching configuration profiles becomes tedious and error-prone. That's why profiles support **auto-attach policies**: define a scope and every repository it matches uses that profile automatically — by naming pattern (`acme/*-prototype`), by organization or namespace (every repo under `acme`), or by repository metadata such as GitHub [custom properties](https://docs.github.com/en/organizations/managing-organization-settings/managing-custom-properties-for-repositories-in-your-organization), e.g. `tier` is `production` (see [Repository Metadata Conditions](/requirements-and-guardrails#repository-metadata-conditions)).

To set one, pick the profile on the **Settings → Configuration** page and click the gear next to the profile selector.

Zenable re-evaluates policies continuously — when the GitHub App is installed, when new repositories appear, when a repository's custom properties change, and whenever a profile or its policy is edited — so new repos land on the right configuration without any clicks.

In case of conflicts, a manually assigned profile always wins: policies never touch that repo until you switch it back to **Default**. Only one policy can match a repository — saving a policy that would create an overlap is rejected with the conflicting repositories listed, and if an overlap emerges later (a new repo, a property change) the repo keeps its current assignment and the **Integrations** page shows a warning until you adjust the policies. Repositories matching no policy use the tenant's **Default** profile, as before.

<Note>
  Metadata-based policies require the Zenable GitHub App's **Custom properties** read permission — see [Repository Custom Properties](/integrations/vcs-reviewers/github#repository-custom-properties). Name- and organization-based policies work without it.
</Note>

### Use Cases

* **High-scrutiny repos** — enable AI reviews with premium mode, exhaustive context refinement and requirement suggestions, all finding types visible, lower preflight thresholds to catch more
* **Relaxed for prototypes** — disable preflight, hide lower-signal finding types like readability and complexity, skip clean PR comments to reduce noise
* **Team-specific defaults** — frontend repos get accessibility findings enabled with thorough context refinement; backend repos focus on security and performance with stricter quality filters

## Configuration Options

### Feature Toggles

Each profile carries the base on/off state for the three per-repository features:

* **PR reviews** (`pr_reviews.enabled`, default `true`) — whether pull/merge requests in repos using this profile are reviewed at all
* **Context refinement** (`repository_analyzer.refine_context_enabled`, default `true`) — whether the refine-context analysis runs
* **Requirement suggestions** (`repository_analyzer.suggest_requirements_enabled`, default `true`) — whether the suggest-requirements analysis runs

A repository follows its config profile by default. Flipping a switch on the **Integrations** page creates a per-repository **override** for that one setting, forcing the repo on or off regardless of the profile. Each switch is captioned so you can see where its value came from — `(from profile)` or `(override)` — and the tooltip names the profile and what it says. To drop an override, click the `(override)` caption; the switch goes back to following the profile when you save. Repositories toggled before profiles carried these settings keep their explicit values as overrides until you clear them. Subscription gating still applies — analyses stay unavailable on free plans regardless of profile settings.

### Review Check on Commits

Zenable adds a `Zenable Review` check on all PRs that are enabled for PR reviews, set as **passing** when the review has completed (naming the assessed risk level) and **skipped** for each commit that hasn't been reviewed. Reviews run when a PR is opened, reopened, or marked ready for review, for authors covered by your [Review Scope](#review-scope). Pushing new commits doesn't trigger a re-review — request one by commenting `/zenable` on the PR or, on GitHub, clicking **Re-run all checks** on the PR's checks tab; when that review completes, the commit's check moves from skipped to passing. See [Risk-Based Reviews](/integrations/vcs-reviewers/risk-based-reviews#review-check-no-gating).

**Default:** disabled

### Review Scope

Review Scope decides **which PR/MR authors get reviewed**. New workspaces start limited to authors linked to a Zenable user, so bots, outside contributors, and unlinked accounts are skipped rather than spending your review budget.

#### Turning it on or off

Edit **Review Scope** on the config profile (**Settings → Configuration**):

* **Off** — every author on repositories using this profile is reviewed, linked or not.
* **On** — pick the user and group scopes to review. An author is in scope if they match any selected scope.

Profile and per-repository scopes union, so a repository can widen its profile but not narrow it.

#### Identity linking is required

A group scope resolves membership through a Zenable user, so a GitHub or GitLab account matches only once it is **linked**. An unlinked author matches nothing and their PR/MR is skipped.

* **Link your own account:** **Profile → Linked Accounts**. Self-service — you do not need an admin.
* **Link someone else's:** **Settings → User Management**. Requires admin permissions.

Linking takes effect on the author's next PR/MR; nothing needs re-running.

<Note>
  Linking is asserted, not verified. You can claim an unclaimed account, but never one already linked to someone else, and only on a host Zenable has seen for your workspace.
</Note>

#### First-run notice

The first few times a skip happens because of an unlinked author, Zenable comments on the PR/MR to explain why — otherwise the skip is silent and reads as an outage.

* Posted only for the **unlinked author** case, never for an author you deliberately left out of scope.
* Capped at the first **5** affected PRs/MRs per integration, then it stops.
* Stops immediately once the cause is gone: link the account or turn the limit off, and reviews resume normally on the next PR/MR.

### Exclusions

#### Exclude Files

List of additional filenames or glob patterns to exclude from all Zenable integrations. This field accepts a list (array) of patterns and works like [gitignore](https://git-scm.com/docs/gitignore), including support for negation patterns.

<Note>
  A [standard list](#files-excluded-by-default) of lock files will automatically be added to the beginning of your configuration. These exclusions apply everywhere Zenable runs.
</Note>

Supports:

* **Exact filename matches** (e.g., `"package-lock.json"`)
* **Glob patterns** (e.g., `"**/*.rbi"`, `"foo/**/*.pyc"`)
* **Negation patterns** with `!` prefix (e.g., `"!keep-this.json"`)

<AccordionGroup>
  <Accordion title="Basic Glob Pattern Examples">
    - **`*.log`** - Skip all log files in any directory
    - **`**/*.tmp`** - Skip all .tmp files in any directory (recursive)
    - **`src/**/*.test.js`** - Skip all .test.js files under src/ directory
    - **`docs/*.md`** - Skip markdown files directly in docs/ directory
    - **`build/*`** - Skip all files directly in build/ directory
    - **`**/node_modules/**`** - Skip all files in any node\_modules directory
    - **`example.py`** - Skip files named example.py in any directory
    - **`**/example.tmp`** - Skip files named example.tmp in any directory (i.e. the same as `example.tmp`)
    - **`/example.py`** - Skip example.py only in the root directory
  </Accordion>

  <Accordion title="Negation Pattern Examples">
    Negation patterns start with `!` and allow you to include files that would otherwise be skipped. **Order matters** - the last matching pattern wins.

    **Skip all log files except important.log**

    * Add `*.log` to skip all log files
    * Add `!important.log` to include important.log

    **Skip all files in build/ except those in build/keep/**

    * Add `build/**/*` to skip all files in build/
    * Add `!build/keep/**/*` to include files in build/keep/

    **Escaping files that literally start with !**

    <Note>
      To skip files that **literally start with `!`** (fairly rare), escape the exclamation mark with a backslash: `\!filename.txt`
    </Note>
  </Accordion>
</AccordionGroup>

#### Exclude Branches

List of branches to skip. You can use [python regex](https://docs.python.org/3/library/re.html#regular-expression-syntax) to match the branch names. We will check all the patterns in the list, if any pattern match, the PR opened in that branch will be skipped.

### Smart Filters

#### Preflight Checks

Preflight lets you optionally skip reviews based on static analysis findings.

* enabled: Whether to enable preflight. (default: false)
* max\_changed\_lines: Maximum total changed lines allowed before skipping the review. (default: 2500)

#### PR Quality Filter

PR Quality Filter lets you optionally skip reviews based on the quality of the PR. We measure the PR quality based on analysis of the whole PR and the generated review. We measure multiple dimensions of quality, such as code quality, architecture quality, testing quality, documentation quality, security quality, and maintainability. This generates a final overall quality score for the PR, which is used to determine if the PR review will be sent or not.

Skip reviews with quality score below the threshold can be a useful way to skip reviews on pr that are not fully done, and reduce the noise in your PRs.

* enabled: Whether to enable pr\_quality\_filter. (default: false)
* quality\_threshold: The minimum quality score required to post a review. Valid values are between 0 and 1. (default: 0.5)

#### Review Drafts

Controls whether Zenable reviews draft pull requests (GitHub) and merge requests marked as draft / work-in-progress (GitLab).

* **`true`** — draft PRs/MRs are reviewed as soon as they are opened.
* **`false`** — draft PRs/MRs are skipped silently. They will be reviewed automatically when transitioned to "ready for review".

Setting this to `false` is useful if your team relies heavily on draft PRs for in-progress work and prefers to only receive Zenable reviews once the author explicitly marks the PR as ready.

* review\_drafts: Whether to review draft PRs/MRs. (default: true)

### Reviewer Context and Feedback

#### Reactions

Configuration section for controlling which reactions are added during reviews. This allows you to enable or disable specific reactions that the reviewer generates.

##### Taking a Look Reaction

Controls the "eyes" emoji reaction (👀) that is added at the start of a review. The reaction is automatically removed once the review is complete.

**Default:** `true` (👀 reaction is added)

#### Comments

Configuration section for controlling which comments are posted during reviews. This allows you to enable or disable specific informational comments that the reviewer generates.

##### No Findings Comment

When set to `true`, posts the "Nice work! 😎" comment when no issues are found in the PR. Set to `false` to disable this comment - when disabled and there are no findings, no review comment will be posted at all.

**Default:** `true` (comment is posted)

##### Finding Summaries

When set to `true`, each finding comment starts with a one-line summary before the detailed explanation.

**Default:** `true` (summary is shown)

##### More Review Information

When set to `true`, finding comments include additional context about the review,
such as the tools used during analysis.

**Default:** `false` (additional details are hidden)

##### Low Quality Comments

When set to `true`, comments judged as low quality are added to the review body in a collapsed section so you can see what the reviewer held back. They are never posted inline.

**Default:** `false` (low quality comments are not shown)

<Note>
  These settings only affect informational comments. Reviews with actual findings or suggestions will always be posted regardless of these settings.
</Note>

#### PR/MR Description

Adds a Zenable-generated summary of what the PR/MR does to the description. The summary is additive-only, so the author's own text is preserved.

Two independent settings control it: **Mode** (how much detail, or off entirely) and **Edit Trigger** (when to post).

##### Mode

Controls the verbosity of the generated summary.

* **`off`** — Never edit the description.
* **`short`** — Add a brief summary.
* **`full`** — Add a comprehensive description.

**Default:** `full`

##### Edit Trigger

When Mode is not `off`, controls when Zenable posts the summary.

* **`always`** — Post the summary on every reviewed PR/MR.
* **`when_inaccurate`** — Post only when the author's title/description is judged inaccurate; leave an accurate description untouched (less noise).

**Default:** `always`

<Note>
  The Edit Trigger setting only appears when Mode is not `off`.
</Note>

#### PR/MR Risk Assessment

Surfaces a Zenable-assessed risk level on each PR/MR. The LLM scores a set of rubric dimensions independently on a 0–10 scale; the final level is derived deterministically from the weighted composite score. This makes the outcome reproducible and auditable, and lets tenants tune it by customizing the dimensions rather than by adjusting prompts.

| Level | Indicator | Meaning |
| - | - | - |
| **Low** | 🟢 | Minor or well-contained change. |
| **Medium** | 🟡 | Reasonable change with some areas to double-check. |
| **High** | 🟠 | Noteworthy impact; review with care before merging. |
| **Critical** | 🔴 | High likelihood of severe impact (security, data loss, outages, or compliance violations). |

When enabled, Zenable appends a small `Risk: <emoji> <Level>` heading to the review body. The scoring behind that level — a table of every dimension, the weighted composite, and any [risk floor](#risk-floors) that raised it — is on the `Zenable Risk Assessment` check's output; see [Risk-Based Reviews](/integrations/vcs-reviewers/risk-based-reviews).

##### Mode

Controls how the PR risk assessment is surfaced.

* **`off`** — The PR risk assessment step is skipped entirely.
* **`comment_only`** — The risk section is included in the review body. No labels are applied to the PR/MR.
* **`comment_and_label`** — The risk section is included in the review body, and a matching label is applied to the PR/MR.

**Default:** `comment_and_label`

##### Labels (`comment_and_label` only)

When `comment_and_label` is selected, Zenable ensures the following four labels exist in the repository/project and applies the one matching the assessed level. The risk labels are mutually exclusive: if a previous review assigned a different level (for example `high`) and the code has since improved, the stale label is removed before the new one is applied.

* `zenable/risk:low`
* `zenable/risk:medium`
* `zenable/risk:high`
* `zenable/risk:critical`

##### Rubric Dimensions

The rubric dimensions are the inputs the LLM scores. Six built-in dimensions are active by default:

| Dimension | What it measures |
| - | - |
| Security impact | Likelihood and severity of security vulnerabilities introduced |
| Data integrity | Risk of data loss, corruption, or inconsistency |
| Blast radius | Scope of affected systems, services, or users if the change goes wrong |
| Reversibility | Ease of rolling back or hotfixing the change |
| Test coverage | Adequacy of tests relative to the change's surface area |
| Operational risk | Impact on availability, deployability, and on-call burden |

You can replace these with up to six custom dimensions from the **Settings → Config profiles → Rubric dimensions** section of the [management console](https://www.zenable.app?utm_source=docs\&utm_medium=vcs-config\&utm_content=rubric-dimensions). Each custom dimension needs a name and a description; you can enable or disable individual rows. When custom dimensions are saved, they replace the defaults entirely for that config profile. Use **Reset to defaults** to restore the built-in set.

<Note>
  The Rubric dimensions section only appears when the PR risk assessment mode is not `off`.
</Note>

##### Risk Floors

Deterministic rules that set a minimum risk level from a PR/MR's change metrics or from the findings its review produced. Each rule pairs a condition expression — metrics compared against thresholds, combinable with AND/OR/NOT — with a minimum level (`medium`, `high`, or `critical`). When a rule matches, the risk level is floored so that a lower level cannot be assigned; the strictest matching rule wins. Up to 20 rules per profile.

Available metrics:

* **Total LOC added** / **Total LOC removed** / **Total LOC changed** — whole-PR line counts, including files the review skips because of size or configuration.
* **Findings** — how many findings the review published.
* **Requirements with findings** — how many distinct requirements those findings were attributed to.

The two finding metrics can be narrowed to a single [finding type](#finding-types), so a rule can read "3 or more Security findings, at least `high`" or "10 or more Bug findings, at least `medium`". Leave the category as **Any category** to count them all together.

**Default:** no rules

<Note>
  The Risk floors section only appears when the PR risk assessment mode is not `off`. Floors only ever raise the assessed level — a rule can never lower one.
</Note>

<Warning>
  Line-count metrics cover the whole PR, but finding metrics count only what the review published. A file the review skipped, a finding type you hid, a low-quality comment, and a finding from an `audit`-mode requirement all contribute nothing to a finding rule.
</Warning>

##### Merge Gate

Zenable publishes a `Zenable Risk Assessment` status on each PR carrying its latest risk assessment — pending until the PR has been assessed, and carried forward to new commits on push. This can be used to define downstream policies, such as [risk-based reviews](/integrations/vcs-reviewers/risk-based-reviews). When enabled, Zenable will merge a PR only when the PR author applies the configured **Ready to merge label** (to indicate consent) and the configured risk threshold isn't exceeded. Adding the **Needs-review label** forces peer review at any risk level.

**Default:** disabled

Setup, branch protection, and the merge flow: [Risk-Based Reviews](/integrations/vcs-reviewers/risk-based-reviews).

<Note>
  The Merge gate section only appears when the PR risk assessment mode is not `off`. Review cadence is unchanged — a push simply invalidates the status until the next review (e.g. a `/zenable` comment).
</Note>

#### Finding Types

Each review comment is classified into one of the following labels. All are shown by default — deselect a type to hide comments with that label.

* **Bug** — Incorrect behavior, logic errors, or broken functionality
* **Readability** — Hard-to-follow code structure, unclear naming, or poor formatting
* **Performance** — Inefficient algorithms, unnecessary allocations, or scalability concerns
* **Complexity** — Overly complicated logic that could be simplified
* **Security** — Vulnerabilities, unsafe patterns, or missing input validation
* **Inconsistency** — Contradicts existing patterns, conventions, or nearby code
* **Accessibility** — Missing or incorrect accessibility support (ARIA, keyboard nav, color contrast)
* **Mistake** — Typos, copy-paste errors, or accidental omissions
* **Other** — Issues that don't fit the above categories

**Default:** All types visible. Deselect a type to suppress comments with that label.

### Review Targeting

Decide how confident Zenable must be prior to publishing a finding. Every requirement in scope is still judged against every reviewed file.

* **Thorough** — include lower confidence findings. Costs more per file.
* **Balanced** — the default, calibrated against real review outcomes. Right for most teams.
* **High signal** — high confidence findings only. Costs less per file.

**Default:** `Balanced`.

### IDE/Agent Hook

Settings that govern how the Zenable CLI emits findings to coding agents (Claude Code, Cursor, OpenCode, etc.) when the hook fires after edits.

#### Triage Instructions

The preamble emitted as `<instructions>...</instructions>` ahead of findings the first time findings surface in an agent session. The agent uses this preamble to decide how to triage each finding (label categories, fix-versus-defer guidance, output format).

Customize the text per config profile when your team wants a different triage protocol — for example, a stricter "fix everything before continuing" stance, or a more permissive "label only, don't fix" workflow. Leave the field empty to fall back to the in-binary default that ships with the CLI.

The block is always emitted; setting an empty value falls back to the default rather than suppressing it. To change the wording for a specific repo, assign that repo to a config profile with the desired text.

## Default Configuration

### Preflight

* **enabled**: `true`
* **max\_changed\_lines**: `2500`

### PR Quality Filter

* **enabled**: `true`
* **quality\_threshold**: `0.5`

### Review Drafts

* **review\_drafts**: `true`

### PR/MR Description

* **mode**: `full`
* **edit\_trigger**: `always`

### PR/MR Risk Assessment

* **mode**: `comment_and_label`

### IDE/Agent Hook

* **triage\_instructions**: built-in default (the CLI ships a multi-line preamble that labels findings as `addressed`, `deferred`, `out-of-scope`, `rule-mismatch`, or `already-mitigated`).

### Files Excluded by Default

The following files are automatically excluded by default across all Zenable integrations:

```toml expandable theme={null}
conda-lock.yml
bun.lock
go.mod
requirements.txt
uv.lock
.terraform.lock.hcl
Gemfile.lock
package-lock.json
pnpm-lock.yaml
yarn.lock
composer.lock
poetry.lock
pdm.lock
Cargo.lock
go.sum
Package.resolved
Podfile.lock
mix.lock
*.ico
*.jpeg
*.jpg
*.png
*.svg
```

By default, no branches are skipped.

## Troubleshooting

If you're having issues with the GitHub or GitLab reviewers, try the following:

* Verify your configuration in **Company Settings → Configurations** is correct.

* The skip\_branches option uses python regex to match the branch names. Ensure your regex patterns are valid.

* If any of these solutions don't work, contact our support team at [support@zenable.io](mailto:support@zenable.io).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.