diff --git a/changelog.mdx b/changelog.mdx
index edec564..56455aa 100644
--- a/changelog.mdx
+++ b/changelog.mdx
@@ -49,7 +49,7 @@ rss: true
**API access through MCP protocol**: Connect external tools and scripts to Hacktron's finding-triage toolset through a new remote MCP server endpoint with OAuth and API key authentication.
- **Skip scans with repository configuration**: Use `.hacktron/config.yaml` to skip pull request scans based on file patterns, keywords in titles, or labels.
+ **Exclude scans with repository configuration**: Use `.hacktron/config.yaml` to exclude pull request scans based on file patterns, keywords in titles, or labels.
**[Secure your account with MFA →](/platform/account-settings)** · **[See MCP integration →](/mcp/get-started)** · **[Configure repository scanning →](/code-review/config)**
diff --git a/code-review/config.mdx b/code-review/config.mdx
index 26298be..aa77e84 100644
--- a/code-review/config.mdx
+++ b/code-review/config.mdx
@@ -5,11 +5,25 @@ description: "Use .hacktron/config.yaml to control which pull and merge requests
Add a `.hacktron/config.yaml` file to your repository to control Hacktron's Code Review behavior:
-- **Skip** specific pull and merge requests so they aren't scanned.
+- **Exclude** specific pull and merge requests so they aren't scanned.
+- **Include** specific pull and merge requests to be scanned.
- **Fail** the Hacktron check when a finding meets a severity threshold, so risky changes can't merge.
This is separate from [`.hacktron/rules.md`](/code-review/rules), which shapes the *quality* of a review. `config.yaml` controls *whether* a PR is scanned and *whether* its check passes.
+
+ Want to override these rules for a single PR? Comment `@hacktronai review` to force a scan.
+
+
+## Configuration hierarchy
+
+Each category (`exclude.*`, `include.*`, `fail_on.severity`) is resolved independently, not the whole file at once:
+
+1. **`config.yaml`** — used if the repo sets this category.
+2. **[Organization settings](/platform/organization-settings#scan-filters)** — used otherwise.
+
+See the [FAQ](#faq) for worked examples of how repo and org settings combine.
+
## File location
Place the file at the root of the repository, inside the `.hacktron` directory:
@@ -38,89 +52,137 @@ Either `.hacktron/config.yaml` or `.hacktron/config.yml` is accepted. If both ex
```yaml
# .hacktron/config.yaml
-# Skip a PR/MR from being scanned when any rule below matches.
-skip:
+# Exclude a PR/MR from being scanned when any rule below matches.
+exclude:
labels:
- - hacktron-skip
+ - hacktron-exclude
keywords:
- - "[skip hacktron]"
+ - "[exclude hacktron]"
paths:
- "vendor/**"
- "**/*.md"
+ authors:
+ - dependabot[bot]
# Fail the Hacktron check when a finding is at or above this severity.
fail_on:
severity: high
```
-Every key is optional. An empty or absent `config.yaml` means Hacktron behaves as it does today: it scans all covered PRs and the check stays green unless the scan itself errors.
+Every key is optional. An empty or absent `config.yaml` doesn't disable filtering; see [Configuration hierarchy](#configuration-hierarchy) for how org-wide filters still apply. With no repo or org filters set, Hacktron scans all covered PRs and the check stays green unless the scan itself errors.
-## Skip scans
+## Exclude scans
-Use the `skip` block to tell Hacktron not to scan a pull or merge request. When a PR matches, Hacktron records a **skipped** check on the PR/MR and posts a short comment naming the rule that matched. No scan runs, and **no developer seat is used**.
+The `exclude` block tells Hacktron not to scan a pull or merge request. A match records a **skipped** check with a comment naming the rule, and uses no developer seat.
-Rules are evaluated in this order; the first match wins:
+Rules are evaluated in this order, first match applies:
| Key | Matches when | Match style |
|---|---|---|
-| `skip.labels` | the PR/MR carries one of these labels | exact, case-insensitive |
-| `skip.keywords` | the PR/MR **title** contains one of these strings | case-insensitive substring |
-| `skip.paths` | **every** changed file matches one of these patterns | gitignore-style globs |
+| `exclude.branches` | the PR/MR targets one of these branches | case-insensitive glob |
+| `exclude.labels` | the PR/MR carries one of these labels | case-insensitive exact match|
+| `exclude.keywords` | the PR/MR **title** contains one of these strings | case-insensitive substring |
+| `exclude.paths` | **every** changed file matches one of these patterns | case-insensitive glob |
+| `exclude.authors` | the PR/MR was opened by one of these usernames | case-insensitive exact match|
+| any key set to `[]` | clears the org-wide default for that key ([Configuration hierarchy](#configuration-hierarchy)) | - |
```yaml
-skip:
+exclude:
+ branches:
+ - "release/legacy/**" # exclude PRs targeting a legacy release branch
labels:
- - hacktron-skip # label the PR "hacktron-skip" to skip it
+ - hacktron-exclude # label the PR "hacktron-exclude" to exclude it
keywords:
- - "[skip hacktron]" # put this anywhere in the PR/MR title to skip it
+ - "[exclude hacktron]" # put this anywhere in the PR/MR title to exclude it
paths:
- - "docs/**" # skip when the PR only touches these paths
+ - "docs/**" # exclude when the PR only touches these paths
- "**/*.md"
+ authors:
+ - "dependabot[bot]" # exclude all PRs opened by dependabot
```
- `skip.paths` skips a scan **only when every changed file matches** one of the
+ `exclude.paths` excludes a scan **only when every changed file matches** one of the
patterns. If even one changed file falls outside the patterns, the PR is
- scanned as usual. Patterns use the same syntax as `.gitignore` — for example
- `vendor/**`, `**/*.md`, or `docs/`.
+ scanned as usual. Patterns use the same glob syntax as `exclude.branches` — for
+ example `vendor/**`, `**/*.md`, or `docs/**`.
-A manual `@hacktronai review` comment always runs a scan, even when a `skip` rule would otherwise match — use it to force a one-off review of an otherwise-skipped PR.
+
+ `exclude.branches`, `exclude.paths`, and `include.branches` (and their org-wide
+ equivalents) accept glob patterns mixed with literals: `*`, `**`, `?`, and
+ `{a,b}` brace expansion. Matching is case-insensitive. `[`, `]`, and a
+ leading `!` are literal, not special syntax. Each category allows up to 50 entries.
+
+
+
+ `*` matches within one path segment; `**` also crosses `/`.
+
+ | Pattern | Matches | Doesn't match |
+ |---|---|---|
+ | `release/*` | `release/foo` | `release/foo/bar` |
+ | `release/**` | `release/foo`, `release/foo/bar` | — |
+ | `release/legacy/**` | `release/legacy/1`, `release/legacy/1/hotfix` | `release/other/1` |
+
+ Use `release/*` for one-level branches (e.g. `release/2.4`). Use `release/**`
+ to cover any depth. Add a literal segment like `release/legacy/**` to target
+ just that subtree.
+
+ Combine `exclude` and `include` to exclude a subtree: `include.branches:
+ ["release/**"]` with `exclude.branches: ["release/legacy/**"]` scans all
+ release branches except `release/legacy/**`.
+
+
+## Include scans
+
+Use the include block to scan **only** pull and merge requests that match specific rules. Hacktron records a skip check comment on PRs/MRs it doesn't scan.
+
+```yaml
+include:
+ branches:
+ - "main"
+ - "release/**" # only scan PRs targeting main or a release branch
+ labels:
+ - security-review # only scan PRs labelled "security-review"
+ authors:
+ - alice # ...and were opened by Alice or Bob
+ - bob
+ keywords:
+ - "please review" # ...and title contains "please review"
+```
+
+| Key | Matches when |
+|---|---|
+| `include.branches` | the PR/MR targets one of these branches (case-insensitive glob) |
+| `include.labels` | the PR/MR carries at least one of these labels (case-insensitive exact match) |
+| `include.authors` | the PR/MR was opened by one of these usernames (case-insensitive exact match) |
+| `include.keywords` | the PR/MR title contains one of these strings (case-insensitive substring) |
+| any key set to `[]` | clears the org-wide default for that key ([Configuration hierarchy](#configuration-hierarchy)) |
+
+`include.labels: [feature, bugfix]` matches either label. Across categories, `include` requires matching all: `include.branches: [main]` + `include.authors: [alice]` only scans Alice's PRs to `main`.
+
+
+ `exclude` and `include` can target the same category. See [glob matching](/code-review/config#matching-nested-branches-with-vs) for pattern syntax.
+
## Fail the check on findings
By default, the Hacktron check is green as long as the scan completes. Findings are posted as inline comments but don't block the merge. Configure a severity threshold to turn the check **red** when a finding is at or above that level.
-When a finding triggers the gate, the GitHub check run (or GitLab commit status) is marked failed.
-

The threshold is **inclusive**: `high` fails the check on `high` *and* `critical` findings, while `critical` fails only on `critical`.
- Triaging a finding updates the existing check directly. A finding only counts toward the threshold while it's still **open or confirmed valid**; triaging it as anything else removes it from the gate and immediately recomputes the check.
+ Only **open or confirmed valid** findings count toward the threshold. [Triaging](/code-review/findings-feedback#triage-comments) one recomputes the check immediately.
-You can set the threshold org-wide from the settings page, or per repository in `config.yaml`. The repository config always takes precedence.
+You can set the threshold org-wide from the settings page, or per repository in `config.yaml` (see [Configuration hierarchy](#configuration-hierarchy)).
- Set a default for all repositories in your organization:
-
-
-
- Select your organization, then go to **Settings**.
-
-
- Locate **Severity threshold**, above the SLA Thresholds card.
-
- 
-
-
- Pick a severity from the dropdown: **Critical**, **High**, **Medium**, or **Low**. Select **Off** to disable the gate org-wide.
-
-
+ Set a default for all repositories in your organization from [Organization settings](/platform/organization-settings#check-gate).
@@ -141,12 +203,45 @@ You can set the threshold org-wide from the settings page, or per repository in
## How invalid config is handled
-Hacktron is **fail-open** about configuration — a config problem never silently blocks your development:
+Hacktron is **fail-open** about configuration:
- A missing, empty, or malformed `config.yaml` is ignored. Hacktron scans normally and the check stays green.
- Unknown keys are ignored, so a config can carry settings for future features without breaking today's scans.
- A type mismatch on a known key (for example `fail_on.severity: 7`) causes the **whole file** to be ignored. Keep values in the shapes shown above.
+## FAQ
+
+
+
+ Org default: `include.labels: [security-review]` (only PRs labelled
+ `security-review` get scanned).
+
+ A repo can set its own `include.labels: [needs-review]` in `config.yaml`
+ to require a different label instead, or set `include.labels: []` to
+ remove the requirement entirely and scan PRs regardless of label. Either
+ way, the repo's setting **replaces** the org rule rather than merging
+ with it.
+
+
+
+ Org default: `fail_on.severity: critical`.
+
+ A repo handling payment code wants to fail on more than just critical
+ findings, so it sets `fail_on.severity: high` in `config.yaml`. That
+ repo's check now turns red on `high` or `critical` findings; every other
+ repo keeps using `critical`.
+
+
+
+ No, each filter category (`exclude.branches`, `exclude.labels`, `include.branches`, and so on) is inherited independently.
+
+ Org default: `exclude.labels: [wip]`. A repo adds `exclude.branches:
+ [release/legacy/**]` but doesn't set `exclude.labels`. That repo now excludes
+ legacy release branches **and** still excludes `wip`-labelled PRs. The org's
+ label rule keeps applying because the repo never overrode it.
+
+
+
## Related
diff --git a/code-review/findings-feedback.mdx b/code-review/findings-feedback.mdx
index 992bc3e..7c4583c 100644
--- a/code-review/findings-feedback.mdx
+++ b/code-review/findings-feedback.mdx
@@ -66,6 +66,7 @@ so reviews get sharper, with fewer false positives and more of the bugs that act
- `!fp ` to mark the finding as a false positive
- `!accepted_risk ` to mark the finding as an accepted risk
- `!valid ` to mark the finding as a true positive
+ - `!fixed ` to mark the finding as resolved
diff --git a/code-review/rules.mdx b/code-review/rules.mdx
index 63dd420..952cde2 100644
--- a/code-review/rules.mdx
+++ b/code-review/rules.mdx
@@ -46,6 +46,6 @@ Commit `.hacktron/rules.md` to the branch Hacktron reviews, such as your default
- Use `.hacktron/config.yaml` to skip scans and fail the check on findings.
+ Use `.hacktron/config.yaml` to exclude scans and fail the check on findings.
diff --git a/code-review/setup.mdx b/code-review/setup.mdx
index 6770d9c..cefbeda 100644
--- a/code-review/setup.mdx
+++ b/code-review/setup.mdx
@@ -41,12 +41,11 @@ You also need permission to connect your Git provider. For more details, choose
- For each repository, choose whether Hacktron should review pull requests or
- merge requests targeting all branches or only specific branches such as
- `main` or `production`.
-
-
-
+ Hacktron reviews all branches by default. Restrict this org-wide in
+ [Organization settings](/platform/organization-settings#scan-filters), or
+ per repository via `exclude.branches` / `include.branches` in
+ `.hacktron/config.yaml`. See [Repository
+ configuration](/code-review/config) for the syntax.
Go to an existing pull request or merge request and comment `@hacktronai review`.
diff --git a/docs.json b/docs.json
index 102437a..4d29841 100644
--- a/docs.json
+++ b/docs.json
@@ -73,7 +73,8 @@
"group": "Account",
"pages": [
"platform/account-settings",
- "platform/security-settings"
+ "platform/security-settings",
+ "platform/organization-settings"
]
},
{
diff --git a/images/scan_filters.png b/images/scan_filters.png
new file mode 100644
index 0000000..7504b86
Binary files /dev/null and b/images/scan_filters.png differ
diff --git a/platform/dashboard.mdx b/platform/dashboard.mdx
index 6628d20..249aec7 100644
--- a/platform/dashboard.mdx
+++ b/platform/dashboard.mdx
@@ -18,22 +18,11 @@ by clicking on **Export**.
## Resolution Health
- From the settings page, you can configure SLA tresholds for remediating findings of different severities.
-
-
-
- This is used to track your resolution health. Hacktron calculates your Mean Time to Resolution (MTTR),
- and the percentage of findings that are resolved within the SLA tresholds.
+ Hacktron calculates your Mean Time to Resolution (MTTR) and the percentage of findings resolved within your SLA thresholds.
- ## Check gate
-
- From the settings page, you can also set an org-wide **Severity threshold**.
-
-
-
- See [Fail the check on findings](/code-review/config#fail-the-check-on-findings) for details and per-repository overrides.
+ Configure the resolution window and compliance target per severity in [Organization settings](/platform/organization-settings#sla-thresholds).
diff --git a/platform/organization-settings.mdx b/platform/organization-settings.mdx
new file mode 100644
index 0000000..617a99e
--- /dev/null
+++ b/platform/organization-settings.mdx
@@ -0,0 +1,85 @@
+---
+title: "Organization settings"
+description: "Configure scan filters, the check gate, and SLA thresholds for your organization."
+---
+
+Organization settings apply to every repository unless a repository's `.hacktron/config.yaml` overrides them. Only organization admins and owners can change these settings.
+
+
+
+ Select your organization, then go to **Settings**.
+
+
+
+## Scan filters
+
+Choose which pull and merge requests Hacktron scans by default, across four categories: branches, labels, authors, and keywords.
+
+
+
+ Locate **Filters**.
+
+
+ Select **Add filter**. Choose a category and a direction, then enter one or more values.
+
+
+
+
+
+| Category | Match style |
+|---|---|
+| Branches | Glob pattern, case-insensitive (e.g. `release/*`) |
+| Labels | Exact name, case-insensitive |
+| Authors | Exact username, case-insensitive |
+| Keywords | Substring in the PR/MR title, case-insensitive |
+
+
+ **Include** and **Exclude** can both be set for the same category: Exclude takes priority within that category. Setting a filter for one category has no effect on the others.
+
+
+Want per-repo control? Override any category in `.hacktron/config.yaml`. See [Repository configuration](/code-review/config) for the glob syntax, limits, and how repo config overrides org defaults.
+
+## Check gate
+
+Set an org-wide severity threshold that fails a PR or MR check when a finding meets or exceeds it.
+
+
+
+ Locate **Severity threshold**.
+
+
+
+
+ Pick a severity: **Critical**, **High**, **Medium**, or **Low**. Select **Off** to disable the gate org-wide.
+
+
+
+See [Fail the check on findings](/code-review/config#fail-the-check-on-findings) for the full severity table and per-repository overrides.
+
+## SLA thresholds
+
+Set the resolution window and minimum compliance target for each severity.
+
+
+
+ Locate **SLA Thresholds**.
+
+
+
+
+ For each severity, set the number of days findings have to be resolved in, and the minimum percentage that should meet it.
+
+
+
+These values drive the Resolution Health widget on the [dashboard](/platform/dashboard#resolution-health), including Mean Time to Resolution (MTTR) and SLA compliance.
+
+## Related
+
+
+
+ Connect a Git provider, enable repositories, and choose covered branches.
+
+
+ Use `.hacktron/config.yaml` to override scan filters and the check gate per repository.
+
+