Configuration as code
The complete .warpway.yml reference, the base-branch rule, and organization locks.
A .warpway.yml file versions your review policy with your code: which lenses are required, extra rules, who answers which questions, what blocks a merge, runtime verification profiles and auto-approval conditions. Configuration as code is part of the Team plan. Everything in the file can also be set in the dashboard, and the dashboard can turn your settings into a proposed .warpway.yml change for you to merge.
Where the file lives
Warpway reads the first of these files that exists:
.warpway.yml.warpway.yaml.github/warpway.yml.github/warpway.yaml
The base-branch rule
Important
The configuration used to review a pull request always comes from the pull request's base branch, at the base commit. A pull request cannot weaken the policy used to approve itself.
If a pull request edits .warpway.yml, that edit does not apply to its own review; Warpway notes in the summary that the pull request changes Warpway configuration. For example, a pull request that removes security from required_lenses is still reviewed with Security required. The change takes effect for pull requests opened against the branch after it merges.
How settings combine
Warpway resolves one effective policy per repository and base commit, in this order, later layers overriding earlier ones:
- Warpway's defaults: the built-in lenses, plus your organization's custom lenses;
- organization settings;
- organization lens settings (which lenses are on and required, edits to built-in and custom lenses, and lens locks);
- repository settings in the dashboard;
- repository lens settings;
.warpway.ymlon the base branch.
Sections such as merge_gate merge field by field, and a list inside a section replaces the list from the layer below. required_lenses, disabled_lenses and conditional_lenses add to the layers below, and a rule replaces a lower layer's rule with the same id. In repository lens settings and in .warpway.yml, a lens's instructions, required_evidence and runtime_profiles add to what it already has and its tools can only be narrowed, so a repository can extend a lens's guidance but never strip it.
Then three limits apply:
- Organization locks. Settings an Owner locked at the organization level cannot be changed by repository settings or by the file. A locked key in the file is ignored, and Warpway lists the ignored keys with the review.
- Plan limits. Features your plan does not include are switched off, and the trust level is capped at your plan's maximum. On the Free plan
.warpway.ymlis not applied at all. - Trust capping.
trust_levelin the file can lower the repository's trust level, never raise it.
The result is stored as a policy version identified by its hash, and every review records which version it used.
Validation
Warpway validates the file against the schema below and reports each problem in plain language with its line and column, for example 'severe' is not a valid severity for `merge_gate.block_on_severities[1]`. Use one of: critical, high, medium, low, info. Unknown keys are errors, which catches typos: merge_gates: is reported as Unknown setting 'merge_gates'. Did you mean 'merge_gate'?
If the base branch's file is invalid, Warpway does not guess what you meant and applies none of it. The review runs with your organization and repository settings, every error becomes a configuration blocker, and the review policy cannot be satisfied until the file is fixed. At Gate and above the check fails.
A complete example
version: 1
required_lenses:
- correctness
- security
- testing
rules:
- id: tenant-isolation
lens: security
applies_to:
paths:
- src/data/**
- src/api/**
instructions: >
Every access path to tenant-owned records must establish tenant
ownership before returning or mutating data.
routing:
security:
github_team: "@company/security"
slack_group: "security-team"
merge_gate:
require_all_required_lenses_resolved: true
require_zero_open_human_tasks: true
auto_approve:
enabled: falseThe smallest valid file is version: 1; every other key is optional.
Reference
version
Required. Must be 1.
trust_level
An integer from 0 to 4 that lowers the repository's trust level for reviews under this file. It can never raise the level set in the dashboard or allowed by your plan. See Trust levels.
required_lenses
Lens keys that are required: whenever a required lens applies to a pull request, it must run and be resolved before the policy is satisfied. Listing a disabled lens here also turns it on.
version: 1
required_lenses:
- correctness
- security
- testing
- database_safetyRequiring a lens does not change when it applies. Correctness, Security and Testing apply to every pull request; a lens with narrower applicability, such as database_safety, is required on the pull requests it applies to and does not run on the others. To require a lens on every pull request, also set its applies_when to always: true under lenses. required_lenses only adds requirements; to make a lens optional, set required: false under lenses.
disabled_lenses
Lens keys that do not run in this repository. A lens required by a locked organization setting cannot be disabled here.
conditional_lenses
Lenses that run, and become required, only when the change matches a condition, even if the lens would not otherwise apply.
| Field | Type | Description |
|---|---|---|
lens | lens key | The lens. |
when | applicability | When it applies. See Applicability. |
required | boolean | Whether it is required when it applies. Default true; false runs the lens as optional. |
version: 1
conditional_lenses:
- lens: database_safety
when:
paths:
- db/migrations/**
languages:
- sql
required: true
- lens: product_semantics
when:
categories:
- billing
- payments
required: truelenses
Custom lenses and changes to existing lenses, keyed by lens key. The key of a built-in lens, or of one of your organization's custom lenses, changes that lens; any other key defines a new custom lens, which needs name and instructions, or extends.
| Field | Type | Description |
|---|---|---|
name | string, 2–80 characters | Display name. |
description | string, up to 500 characters | One-line summary. |
extends | lens key | For a new lens: start from a built-in lens's instructions and settings. |
enabled | boolean | Turn the lens on or off. |
required | boolean | Whether the lens is required when it applies. false makes a lens optional, including a built-in lens that is required by default. |
applies_when | applicability | When the lens applies. See Applicability. A new lens without it applies to every pull request. |
instructions | string or list of strings | What the lens must check. Added to an existing lens's instructions. |
required_evidence | list of strings | Evidence the lens must gather before concluding; missing evidence makes it Incomplete. |
tools | list of tool names | Narrows the tools the lens may use. See Lenses. |
owners | list of strings | Who owns the lens's questions: @login, @org/team, an email address, slack:U0123ABCD (a Slack member ID) or slack-group:@handle. |
routing | routing target | Where the lens's questions go. See routing. |
human_signoff | never, when_uncertain, always, or an object | When a person must answer or sign off; see Lens settings. The object form takes required_when_uncertain and always booleans: always: true means always, required_when_uncertain: false means never. Default when_uncertain. |
ai_clear | boolean | Whether AI may clear the lens at trust level 3 (Clear) and above. When false, a required lens needs a person's sign-off at those levels. Default true. |
blocking | block, warn, none, or a boolean | What the lens's findings do: block the merge gate, warn (shown, never block) or none (ignored). true means block, false means none. Default block, except Architecture and Performance, which warn. |
runtime_profiles | list of profile names | Runtime verification profiles the lens needs. Each must be defined under runtime. |
version: 1
lenses:
performance:
blocking: block
applies_when:
paths:
- services/api/**
hipaa_phi:
name: HIPAA PHI Handling
applies_when:
paths:
- src/patient/**
instructions:
- Confirm PHI is not written to application logs.
- Confirm access remains tenant-scoped.
human_signoff: always
ai_clear: falserules
Extra instructions attached to an existing lens, optionally for specific paths. Up to 200 rules.
| Field | Type | Description |
|---|---|---|
id | string | Unique id: lowercase letters, digits, ., _ or -, 2–64 characters, starting with a letter or digit. |
lens | lens key | The lens that enforces the rule. |
applies_to | applicability | Where the rule applies. When it matches, the lens runs even if it would not otherwise apply. Omit it to apply the rule, and run its lens, on every pull request. |
instructions | string, up to 4,000 characters | What must hold. |
owner | string | Who answers questions this rule raises, in the same formats as lens owners. Routed before anyone else. |
severity | severity | How serious a violation of the rule is. The lens sees it with the rule and reports violations at that severity unless the evidence shows a different impact; each finding records the severity the lens chose. See Severities. |
routing
Who answers questions, keyed by lens key, or default for all lenses without their own entry. Each entry is a routing target:
| Field | Type | Description |
|---|---|---|
github_user | string | One GitHub username. |
github_users | list of strings | Several GitHub usernames. |
github_team | string | A GitHub team, such as @acme/security. |
slack_user | string | One Slack member, by member ID such as U0123ABCD. |
slack_user_group | string | A Slack user group, such as @privacy. |
slack_group | string | Same as slack_user_group; both spellings are accepted. |
email | email address | A person identified by verified email. |
prefer_slack | boolean | Reach engineers in Slack instead of GitHub. |
See Routing for how these combine with CODEOWNERS and history.
reviewer_requests
| Field | Type | Description |
|---|---|---|
enabled | boolean | Whether Warpway may request GitHub reviewers for human tasks. Default true, but it has no effect when the organization has turned reviewer requests off. |
max_per_pr | integer, 0–10 | The most reviewer requests Warpway makes on one pull request. Default 2. |
merge_gate
What must be true for the review policy to be satisfied. Enforced as a blocking check at trust level 2 (Gate) and above.
| Field | Type | Default | Description |
|---|---|---|---|
require_all_required_lenses_resolved | boolean | true | A required lens waiting on a human decision blocks until its questions are answered and the lens is re-evaluated, even when those questions are optional. |
require_zero_open_human_tasks | boolean | true | No required human task may be open. |
block_on_severities | list of severities | critical, high, medium | Open findings at these severities block, in lenses whose blocking is block. |
required_ci_checks | list of check names | none | CI checks that must pass on the head commit: the latest run of each must conclude success, neutral or skipped. A check that has not reported yet, or is still running, keeps the policy waiting. |
fail_on_incomplete | boolean | true | An Incomplete optional lens whose findings could block also blocks. An Incomplete required lens always blocks, whatever this says. |
version: 1
merge_gate:
require_all_required_lenses_resolved: true
require_zero_open_human_tasks: true
block_on_severities:
- critical
- high
required_ci_checks:
- build
- unit-tests
fail_on_incomplete: trueruntime
Approved runtime verification profiles under profiles, keyed by profile name (letters, digits, _ or -, up to 40 characters, starting with a letter or digit), up to 25 profiles. Warpway can dispatch only the profiles listed here, and only once runtime verification is enabled for the repository in the dashboard.
| Field | Type | Description |
|---|---|---|
workflow | file name | The workflow file in .github/workflows, such as warpway-verify.yml. |
input | string | The profile value passed to the workflow (letters, digits, ., _ or -, up to 64 characters, starting with a letter or digit). |
timeout_minutes | integer, 1–180 | How long the profile's commands may run. Default 30. Warpway waits 15 more minutes for queueing, checkout and the result upload before it records the run as timed out (the lens is then Incomplete). Keep it within the command timeout of your workflow (30 minutes in the template). |
required_for_lenses | list of lens keys | Lenses that need this profile. If it cannot run, they are Incomplete. |
run_when | applicability | Run the profile only when the change matches. |
version: 1
runtime:
profiles:
unit:
workflow: warpway-verify.yml
input: unit
timeout_minutes: 20
required_for_lenses:
- testing
integration:
workflow: warpway-verify.yml
input: integration
timeout_minutes: 30
run_when:
paths:
- services/**See Runtime verification for the workflow template.
auto_approve
Conditions for automatic approval. Auto-approval also requires the Team plan, trust level 4, and an Owner's explicit enablement in the dashboard; this section alone never turns it on. See Auto-approval.
| Field | Type | Description |
|---|---|---|
enabled | boolean | Whether this repository's policy allows auto-approval. Default false. |
max_changed_lines | positive integer | Only pull requests with at most this many changed lines (additions plus deletions). |
max_files | positive integer | Only pull requests touching at most this many files. |
allowed_authors | list of GitHub usernames | Only pull requests by these authors. |
dependabot_only | boolean | Only pull requests opened by Dependabot. |
docs_tests_only | boolean | Only pull requests that change nothing but documentation and test files, judged by file path. |
excluded_paths | list of globs | Never auto-approve a pull request touching these paths. |
excluded_categories | list of semantic categories | Never auto-approve changes tagged with these categories. |
require_preview_deployment | boolean | Require a successful preview deployment of the commit. Set preview_deployment_check with it. |
preview_deployment_check | string | The name of the check that reports the preview deployment. It must conclude success on the commit. |
required_ci_checks | list of check names | CI checks that must conclude success, in addition to merge_gate.required_ci_checks. |
version: 1
auto_approve:
enabled: true
docs_tests_only: true
max_changed_lines: 200
max_files: 10
excluded_paths:
- auth/**
- migrations/**
excluded_categories:
- auth
- authorization
- migration
required_ci_checks:
- unit-testsreview
Which pull requests and files Warpway reviews.
| Field | Type | Default | Description |
|---|---|---|---|
include_drafts | boolean | false | Review draft pull requests too. |
ignore_paths | list of globs | none | Files left out of the review, such as generated code or lockfiles. A pull request that changes only ignored files is not reviewed. |
max_changed_files | integer, 1–3,000 | 300 | The most changed files Warpway reviews in one pull request. A larger pull request is never passed silently: the review reports that it could not cover the change. |
ignore_authors | list of GitHub usernames | none | Pull requests by these authors are not reviewed. |
base_branches | list of branch names or globs | all | Review only pull requests into these branches, such as main or release/*. |
version: 1
review:
include_drafts: false
ignore_paths:
- "**/*.snap"
- "**/generated/**"
- pnpm-lock.yaml
ignore_authors:
- renovate[bot]
base_branches:
- main
- releaseknowledge
| Field | Type | Description |
|---|---|---|
enabled | boolean | Whether lenses may use approved organization knowledge in this repository. Default true on plans that include organization knowledge. |
slack
| Field | Type | Description |
|---|---|---|
enabled | boolean | Whether this repository's questions may be sent through Slack. Default true on plans that include Slack. |
Applicability
applies_when (lenses), applies_to (rules), when (conditional lenses) and run_when (runtime profiles) share one shape. A condition matches when any of its parts matches:
| Field | Type | Description |
|---|---|---|
always | boolean | Every eligible pull request. |
paths | list of globs | Any changed file matches. |
exclude_paths | list of globs | Changed files matching these are ignored before the other fields are checked. If every changed file matches, the condition does not match, even with always. |
categories | list of semantic categories | The change analysis tagged the pull request with any of these. |
languages | list of language names | Any changed file is in one of these languages, judged by file extension, such as sql or typescript. |
A condition with only exclude_paths matches every pull request that changes something outside those paths.
Globs match repository-relative paths with / separators: * matches within one directory, ** across directories, and files starting with . are matched like any other. Matching is case-sensitive. Each list holds up to 200 patterns of up to 300 characters.
Semantic categories
The change analysis tags each pull request with the categories that describe it. Use them in applicability conditions and in auto_approve.excluded_categories:
auth, authorization, billing, payments, pii, data_model, migration, api_contract, public_sdk, events, ui, infra, ci, dependencies, config, docs, tests, concurrency, caching, performance_sensitive, security_sensitive, feature_flag, business_logic, logging, external_integration.
Lens keys
Built-in lenses: correctness, security, testing, architecture, compatibility, performance, product_semantics, database_safety. Custom lens keys use lowercase letters, digits, _ or -, 2–63 characters, starting with a letter or digit.
Severities
From most to least severe: critical, high, medium, low, info. By default critical, high and medium findings block the merge gate; change that with merge_gate.block_on_severities.
Organization locks
An Owner can lock any of these top-level keys for the whole organization: trust_level, required_lenses, disabled_lenses, conditional_lenses, lenses, rules, routing, reviewer_requests, merge_gate, runtime, auto_approve, review, knowledge, slack. A single lens can be locked too. A locked key keeps the organization's value in every repository: neither repository settings nor .warpway.yml can override it, and an attempt is ignored and reported with the review.
Locks apply to what a change does, not only to how it is spelled. With required_lenses locked, a repository can neither make a lens the organization requires optional, disable it, nor change when it applies; with routing locked, a lens's own routing block is ignored as well.
Proposing changes from the dashboard
Changes made in the dashboard are saved as repository settings and apply from the next review. .warpway.yml on the base branch still overrides them wherever both set the same key. To keep policy in version control instead, generate the equivalent .warpway.yml change from the dashboard and merge it through a pull request like any other change. Because the file is read from the base branch, it takes effect once merged.
Something unclear or missing? Email marcus@cmglabs.ai.