Docs

Configuration

bumpkit.yml Reference ​

Every key in bumpkit.yml, the policy file the release gate, agent hooks and checks read, with types, defaults and allowed values.

Release rules that live in people's heads aren't applied the same way twice; bumpkit.yml writes them down as policy, for whoever owns how a repository ships.

bumpkit.yml is the policy file for your repository. The Release Gate reads its gate: section to decide whether a release passes, needs approval or fails. Other top-level sections configure Agent Controls, Code Quality & Architecture and behavioral verification.

This page lists every key. Feature guides show the snippets you need and link back here.

Example ​

The Run a check tab on the dashboard's Checks page has a YAML editor and an expandable guide to the main policy fields. This is an editor for the actual policy, not a second rule format: indentation, YAML structure and rule names are validated when you run the check. Editing the trial policy does not save a repository policy or change the base branch.

This file uses every key. You won't need most of them: start from the default policy and add what your team asks for. Keys marked # Beta are covered by their own Beta sections below.

YAML
gate:
  block_on: [secret, data_loss]
  on_error: fail

  require_approval:
    - breaking
    - area: [billing, authentication]
      when: agent
      approvers: ["@acme/payments", alice]
      count: 2
    - untested: true
      when: agent_or_unknown
      codeowners: true
    - contract_breaking            # Beta
    - intent                       # Beta
    - agent_track_record_below: 0.8  # Beta
      min_releases: 3
      work_types: [migrations]

  require_checks: [test, lint]
  security_alerts: high
  vulnerabilities: high
  break_glass: true

  hotfix:
    block_on: [breaking, data_loss, migration]
    max_files: 20
    review_within: 72h
    backports: approve

  blast_radius:                    # Beta
    approve_areas: [billing, "@acme/payments"]
    max_depth: 4

  deploy:                          # Beta
    environments: [production]
    require: approved

  timezone: America/New_York          # Beta
  windows:                         # Beta
    - days: [mon-thu]
      from: "09:00"
      to: "16:00"
  outside_windows: approve         # Beta
  freezes:                         # Beta
    - name: Year-end freeze
      start: 2026-12-20
      end: 2027-01-02
      mode: block
      hotfix: approve

  exports:                         # Beta
    severity: high
    ignore_paths: [generated/**]
    max_findings: 100
  behavior:                        # Beta
    changes: approve
    hotspots: approve
    severity: medium
    hotspots_min: medium

  quality:                         # Beta
    architecture_drift: block
    code_quality:
      action: approve
      severity: medium
      when: agent
    performance: warn
    max_function_lines: 80
    max_complexity: 15
    clone_tokens: 40
    hot_path_depth: 4
    bench_threshold: 5

  cross_repo:                      # Beta
    block_on_consumer_break: false
    require_approval: true

  fix_tasks: block                 # Beta

  require_regression_evidence: true  # Beta
  regression_evidence_action: block  # Beta

  stacks:                          # Beta
    require_parent_merged: false

architecture:                      # Beta
  layers:
    - name: api
      paths: [services/api]
    - name: store
      paths: [services/db]
  forbidden:
    - from: store
      to: api

agents:                            # Beta
  claude-*:
    max_open_prs: 2
    max_changed_lines: 400
    paths_allow: [services/notify/**]
    paths_deny: [services/billing/**]
    areas_deny: [billing]
    spend_limit: 10
    on_violation: block

agent:                             # Beta
  ask: [rm_rf, "npm publish *"]
  deny: [force_push]
  allow: ["rm -rf ./dist*"]
  protected_branches: [main, "release/*"]
  remote: true
  timeout: 30s

memory:                            # Beta
  require_approval: true

verify:                            # Beta
  test: go test ./...
  timeout: 10m
  network: localhost
  http:
    start: ./bin/server
    ready: /healthz
  require_ci_attestation: true

train:                             # Beta
  label: "train:{slug}"
  require_approval:
    teams: ["@acme/release-managers"]
    count: 1

File name and location ​

Put the file at the root of your repository. Bumpkit looks for bumpkit.yml first and then .bumpkit.yml, and uses the first one it finds. If both exist, .bumpkit.yml is ignored.

All keys are lowercase with underscores. The gate rejects keys it doesn't know at the top level and under gate:, agent:, agents:, memory: and architecture:, so a typo such as requre_approval is an error, not a silently ignored line. Keys under train: and verify: are checked by their own features when they read the file, not by the gate.

Policy from the base commit ​

The gate reads bumpkit.yml as it is at the base of the change, never from the pull request itself. A pull request that edits bumpkit.yml can't loosen the rules it's judged by; its new policy applies to the pull requests after it merges. With the GitHub App, a pull request into any branch other than the default branch uses the default branch's copy, so a branch can't loosen the rules either.

Where the gate runs Policy it reads
Bumpkit GitHub App bumpkit.yml at the base commit of a pull request into the default branch, and on the default branch for every other pull request
bumpkit gate (CLI, locally or in CI) bumpkit.yml at --base, which defaults to the pull request's base commit, else the latest tag before HEAD^. --policy FILE reads a file instead
POST /v1/gate The policy text you send in the request body
Deployment protection (deploy) bumpkit.yml on the default branch, with your org policy applied
A GitHub Enterprise Server connection, through its webhook, bumpkit gate or POST /v1/gate bumpkit.yml from your server: on the default branch, or at the base commit of a pull request into the default branch
bumpkit gate or POST /v1/gate with the GitHub App installed on the repository for your workspace Bumpkit applies the bumpkit.yml it reads from GitHub itself, not the policy that was sent: on the default branch, or at the base commit of a pull request into the default branch. --base never picks the policy. If GitHub can't return it, 503 POLICY_UNAVAILABLE

The decision's policy_source says which applied: base_branch:<ref> (like base_branch:main) or client. A client policy carries a policy_source: client reason, because it wasn't verified from the base branch. See The policy comes from the base.

See the CLI Reference and API Reference for the flags and request fields.

Default policy ​

If the repository has no bumpkit.yml, the file is empty, or the file has no gate: section, the gate applies this policy:

YAML
gate:
  block_on: [secret, data_loss]
  require_approval:
    - breaking
    - area: [authentication, authorization, billing, cryptography]
      when: agent
    - untested: true
      when: agent
  vulnerabilities: high
  on_error: fail

Once you write a gate: section, it replaces the default as a whole: block_on and require_approval you leave out are empty, and vulnerabilities you leave out is off, not inherited from the default. Copy the default rules you want to keep. Keys that have their own default keep it when you leave them out: on_error is fail, break_glass is true, hotfix.block_on is [breaking, contract_breaking, data_loss, migration], hotfix.backports is approve, hotfix.review_within is 72h and, with Close the loop, fix_tasks is block.

Invalid policy ​

An invalid bumpkit.yml never falls back to the default. The gate fails closed and shows the parse error with its line number:

  • The GitHub App completes the check as a failure titled "Invalid bumpkit.yml". If it can't read the file at all, the check fails as well.
  • bumpkit gate prints the error and exits with code 2, even when on_error: pass.
  • POST /v1/gate returns 400 with the code INVALID_POLICY.
  • Deployment protection rejects the deployment.

Errors name the key, for example bumpkit.yml: gate.hotfix.backports must be block, approve or off. To try an edited file before you merge it, run bumpkit gate --policy bumpkit.yml, which uses that file instead of the base copy. See the CLI Reference.

gate ​

The gate: mapping holds the release gate policy. Every key in the sections below, up to architecture, lives under gate:.

A gate decision is pass, needs_approval or fail. Only proven findings count: block_on, require_approval and hotfix.block_on apply to findings that are deterministic and not suppressed. Blast radius and quality findings are built by Bumpkit's own checkers, so they always count as deterministic. See Release Checks & Blast Radius for the finding kinds.

block_on ​

Finding kinds that fail the release outright. A finding fails the gate when it is high severity, deterministic and not suppressed.

Type list of strings
Default [secret, data_loss, security_regression] with no gate: section; empty otherwise
Allowed values secret, data_loss, security_regression, breaking, contract_breaking (Beta), version_mismatch (Beta), compatibility_break (Beta)
YAML
gate:
  block_on: [secret, data_loss, breaking]

security_regression comes from the security regression check. contract_breaking comes from Contract Checks. version_mismatch comes from the version consistency check, which compares the decided version with your tags, package manifests, VERSION file and CHANGELOG headings. compatibility_break comes from the compatibility matrix: a proven break of a pair you declared as supported.

require_approval ​

Rules that ask a person to approve a release. Each rule that applies and is triggered needs approval; until it has enough, the decision is needs_approval.

Type list of rules; each rule is a string or a mapping
Default The three rules in the default policy with no gate: section; empty otherwise

A rule written as a string uses when: always:

String Triggered by
breaking A high-severity breaking change (a removed or changed public API or route), or a major version bump
untested An untested-change finding
contract_breaking A high-severity breaking API contract change (Beta)
intent An acceptance criterion with no evidence (Beta)
scanner_finding A CodeQL, Semgrep, Snyk or Socket finding on a line the change touches or in code it reaches
ai_review_incomplete An AI review that was partial or didn't run

The mapping form takes these keys. A rule needs at least one of breaking, untested, area, contract_breaking, intent, scanner_finding, ai_review_incomplete or agent_track_record_below.

Key Type Default Meaning
breaking bool false Trigger on breaking changes and major bumps. Also triggers on contract_breaking findings
untested bool false Trigger on untested changes
area list of strings none Trigger on sensitive-area findings for these areas
when string always Who wrote the change: always, agent or agent_or_unknown (both cover any change not confirmed as written by a person)
approvers list of strings any reviewer Who may approve: GitHub logins and teams
count int 1 Approvals needed, 1 to 10
codeowners bool false Code owners of the triggering files may approve
contract_breaking bool false Trigger on breaking contract changes (Beta)
intent bool false Trigger on unevidenced acceptance criteria (Beta)
scanner_finding bool false Trigger on scanner findings the change touches or reaches
ai_review_incomplete bool false Trigger when the AI review was partial or didn't run
agent_track_record_below number none Trigger when an agent on the change has a clean share below this, 0 to 1 (Beta)
min_releases int 3 With agent_track_record_below: ignore agents with fewer releases than this
work_types list of strings all work With agent_track_record_below: only these work types, from tests, migrations, auth, api, ui
YAML
gate:
  require_approval:
    - breaking
    - area: [billing]
      when: agent
      approvers: ["@acme/payments"]
      count: 2
    - untested: true
      codeowners: true

require_approval.area ​

The sensitive areas the release check reports: authentication, authorization, billing and cryptography. A rule triggers when the check finds a change in one of the listed areas. Names you list here also become named areas for blast_radius.

A change to bumpkit.yml, .bumpkit.yml or a CODEOWNERS file that targets the default branch needs one approval, with the built-in rule policy_change. No setting turns it off, and because the gate reads the policy from the default branch, a pull request can't remove it for itself.

require_approval.when ​

Value The rule applies when
always Always
agent The change isn't confirmed as written by a person: an agent signal, inferred included, or no signal at all. A blocking quality rule fails only on a declared or verified agent, and asks for an approval otherwise
agent_or_unknown The same as agent for approval rules

A change counts as written by a person only with no agent signal, hooks or telemetry on for the repository, and at least 90% of such changes measured as human across at least 20 verified releases. Without hooks or telemetry, every change that triggers one of these rules needs an approval.

Bumpkit detects coding agents with no setup. It recognizes claude (also anthropic), codex (also openai), cursor, copilot, devin, jules, amp (also ampcode), gemini, windsurf (also codeium), cline and aider. See Who wrote the change.

require_approval.approvers ​

GitHub logins (alice or @alice) and teams (@org/team). Only approvals from people on the list count toward count. Team membership can only be checked through the Bumpkit GitHub App or a repository host connection; elsewhere the decision says so and the team's approvals don't count.

Approvals count only when they are on the head commit. The author's own approval, bot approvals and approvals from agent accounts never count. See Approvals for Slack and dashboard approvals.

require_approval.count ​

How many qualifying approvals the rule needs, from 1 to 10. Leave it out for one approval.

require_approval.codeowners ​

With codeowners: true, the code owners of the files that triggered the rule may approve, in addition to anyone in approvers. Bumpkit reads .github/CODEOWNERS, CODEOWNERS or docs/CODEOWNERS from the same place as the policy, and the last matching pattern wins. If no entry covers the files and approvers is empty, any reviewer counts. CODEOWNERS can only be checked through the Bumpkit GitHub App or a repository host connection.

require_approval.contract_breaking ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: contract_checks.

Triggers on high-severity breaking changes to OpenAPI and Swagger specs, GraphQL schemas, protobuf files and JSON Schema payloads. Write it as the string contract_breaking or as contract_breaking: true in a mapping. See Contract Checks.

require_approval.agent_track_record_below ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: agent_track_records.

Asks a person to approve when an agent on the change has a poor record. Bumpkit counts each agent's releases over the last 90 days, overall and by work type, and the share that stayed clean (not reverted, not fixed up within 7 days, not blocked by the gate, no failed required checks). Put it in a rule of its own:

YAML
gate:
  require_approval:
    - agent_track_record_below: 0.8
      min_releases: 1
      work_types: [migrations]

With work_types, the rule applies only when the change touches those work types; without it, the agent's overall record counts. Agents with fewer than min_releases releases (default 3) are skipped. The reason states the numbers, for example "claude's overall record is 0% clean over 1 release in 90 days (1 reverted, 0 fixed up, 0 blocked by the gate, 0 failed required checks); the policy asks a person to approve below 80%." approvers and count work as in other rules. See bumpkit agents records.

require_approval.intent ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: intent_check.

Triggers when an acceptance criterion from the pull request, its linked issues or specs has no evidence in the changed files, tests or behavioral results. The intent rule only asks for approval; it never passes or fails a release on its own.

require_approval.scanner_finding ​

Triggers when a scanner result you send with --sarif or --socket lands on a line the change touches or in a file it reaches. Scanner findings never block on their own; this rule only asks for approval. See Scanner results.

require_approval.ai_review_incomplete ​

Off by default. Triggers when a check's AI review is partly_reviewed or could_not_review, including when no AI provider is set up, the check ran in fast mode, or the model refused. A generated or binary file in the change counts as not reviewed, so this rule triggers on those too. It only asks for approval; an AI review never blocks a release. With codeowners: true, the owners of the files not reviewed may approve. See AI review coverage.

on_error ​

What the gate does when Bumpkit can't decide, for example when the API is unreachable or a required provider is unavailable.

Type string
Default fail
Allowed values fail, pass

pass makes the gate advisory: an error lets the release through. An invalid bumpkit.yml fails even with on_error: pass, and so does any error on a pull request whose policy sets require_check_apps.

require_checks ​

CI checks that must pass on the head commit before the gate decides.

Type list of strings
Default none
Allowed values check run or commit status names, matched case-insensitively
YAML
gate:
  require_checks: [test, lint]

While a required check is still running, the GitHub App waits and decides when it finishes. A check that didn't run on the commit fails the gate. A check passes with the conclusion success, neutral or skipped; anything else fails.

CI results are only visible to the Bumpkit GitHub App and repository host connections. When the gate runs from the CLI or API, a person must approve to vouch for them.

require_check_apps ​

Required checks that only count when a specific GitHub App reported them on the exact head commit.

Type map of check name to GitHub App ID
Default none
Allowed values unique check names, matched case-insensitively, and positive App IDs; not behavior
YAML
gate:
  require_check_apps:
    test: 123456

A name here is required even if require_checks doesn't list it. The gate only counts a check run whose App ID matches and whose head SHA is the commit being gated. A check with the same name from another App, a commit status, or a run for another commit doesn't count, so the check fails with "test from GitHub App 123456 didn't run on this commit." When the same check reports more than once, the worst result wins: a failure or a run still in progress can't be hidden by a passing duplicate.

The GitHub App reads every check run on the commit, up to 1,000. More than that fails closed, and so does a check run GitHub returns for a different commit.

Only the Bumpkit GitHub App and a GitHub Enterprise Server connection can verify the issuer, using the App IDs on that server. When the gate runs from the CLI, the API or another code host, require_check_apps fails, and a person's approval can't replace it.

If Bumpkit can't load every check run on the commit, for example when there are more than 1,000 or GitHub returns an error, the gate fails with "Bumpkit couldn't verify the required check apps". With require_check_apps set, that happens whatever on_error says.

require_checks: behavior ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: behavioral_verification.

The name behavior (matched case-insensitively) requires a signed bumpkit verify report for the commit instead of a CI check. Regressions fail the gate and changed behavior needs approval. See verify.

YAML
gate:
  require_checks: [test, behavior]

security_alerts ​

Fails the gate when the pull request has open code scanning alerts at or above this severity.

Type string
Default off
Allowed values critical, high, medium, low

If code scanning results aren't available for the pull request, the gate fails. Like require_checks, this needs the GitHub App or a GitHub Enterprise Server connection; elsewhere a person must vouch.

vulnerabilities ​

Fails the gate when the release adds a dependency version with a known vulnerability at or above this severity.

Type string
Default high with no gate: section; off otherwise
Allowed values high, medium, low

If Bumpkit can't check for vulnerabilities, the release needs approval instead.

break_glass ​

Whether an owner, admin or policy admin may override a failing or waiting gate, signed in to the dashboard on the commit's check page. An override applies to one commit and records the reason.

Type bool
Default true

With break_glass: false, an override is still recorded but doesn't change the decision. See Hotfixes & Break Glass.

hotfix ​

Rules for hotfix releases. A release is a hotfix when bumpkit gate --hotfix is passed, or when the branch name starts with hotfix/, hotfixes/, release/ or releases/ (or the same with -). A hotfix must be a patch release with no feature commits; otherwise it needs approval.

YAML
gate:
  hotfix:
    block_on: [breaking, data_loss, migration]
    max_files: 20
    review_within: 72h
    backports: approve

hotfix.block_on ​

Finding kinds a hotfix may not carry. Any deterministic, unsuppressed finding of these kinds fails a hotfix, whatever its severity.

Type list of strings
Default [breaking, contract_breaking, data_loss, migration] (contract_breaking findings exist only with contract checks, Beta)
Allowed values breaking, contract_breaking (Beta), data_loss, migration, dependency, vulnerable_dependency, config, secret, risk_area, untested

hotfix.max_files ​

A hotfix that changes more files than this needs approval.

Type int
Default 0 (no limit)

hotfix.review_within ​

When someone overrides the gate with break glass, the override needs a post-hoc review within this time. Record it with bumpkit override review.

Type duration string, such as 24h or 72h
Default 72h
Allowed values more than 0 and at most 90 days (2160h)

hotfix.backports ​

What happens when a regular release would ship without fixes that went out in an earlier hotfix tag (from the last year) but never reached this branch.

Type string
Default approve
Allowed values block (fail), approve (needs approval), off

blast_radius ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: blast_radius.

The bumpkit CLI, locally or in CI, follows every caller of the changed functions through the code graph and report which product areas the change reaches. These keys decide which areas need approval and how far to follow calls.

YAML
gate:
  blast_radius:
    approve_areas: [billing, "@acme/payments"]
    max_depth: 4

blast_radius.approve_areas ​

Areas that need an approval when a change reaches them. A reached area in this list also raises the finding from low to medium severity.

Type list of strings
Default none
Allowed values plain area names, matched case-insensitively; no :, <, >, ` or `

Bumpkit names the area of a file in this order:

  1. A named area: a name from approve_areas or require_approval.area, or a built-in sensitive area, that appears as a word in the file's path.
  2. The file's CODEOWNERS owners, such as @acme/payments.
  3. The file's top directory, or the first two segments under internal, pkg, src, lib, libs, app, apps, packages, services, cmd or modules.

blast_radius.max_depth ​

How many calls deep to follow callers.

Type int
Default 4
Allowed values 1 to 10

deploy ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: deploy_protection.

With the Bumpkit GitHub App as a deployment protection rule, Bumpkit approves or rejects each deployment from the gate decision for the deployed commit, or the pull request it came from.

YAML
gate:
  deploy:
    environments: [production]
    require: approved

deploy.environments ​

Type list of strings
Default every environment
Allowed values GitHub environment names, matched case-insensitively

Deployments to environments not on the list are approved.

deploy.require ​

Type string
Default pass
Allowed values pass, approved

With pass, a passing gate approves the deployment. With approved, the gate decision must also have at least one approval. A failed gate always rejects the deployment, and a decision that needs approval leaves it pending.

timezone ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: change_freezes.

The default time zone for windows and freezes.

Type string
Default UTC
Allowed values an IANA name, such as America/New_York or America/Los_Angeles

windows ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: change_freezes.

Weekly release windows. Outside every window, a release needs approval or fails, depending on outside_windows. Hotfixes may ship outside the windows.

YAML
gate:
  timezone: America/New_York
  windows:
    - days: [mon-thu]
      from: "09:00"
      to: "16:00"
    - days: [fri]
      from: "09:00"
      to: "12:00"
Key Type Default Allowed values
days list of strings every day mon to sun, full names such as monday, or ranges like mon-fri
from string 00:00 a time like 09:00
to string 24:00 a time like 17:00, after from
timezone string timezone an IANA name

Quote times in YAML ("09:00").

outside_windows ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: change_freezes.

Type string
Default approve
Allowed values approve, block

freezes ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: change_freezes.

Scheduled change freezes. Each freeze is a date range, a list of dates, or a weekly time span. You can also declare a freeze on the spot with bumpkit freeze start or the Policy page. See Org Policies & Freezes.

YAML
gate:
  freezes:
    - name: Year-end freeze
      start: 2026-12-20
      end: 2027-01-02
      mode: block
      hotfix: approve
    - name: Public holidays
      dates: [2026-12-25, 2027-01-01]
    - name: Friday afternoons
      days: [fri]
      from: "15:00"
      mode: approve
Key Type Default Allowed values
name string required any text
start, end string none dates like 2026-12-24 or times like 2026-12-24T18:00; set both. A date-only end includes that whole day
dates list of strings none whole days, like 2026-12-25
days, from, to the same as in windows
timezone string timezone an IANA name
mode string block block (fail), approve (needs approval)
hotfix string approve allow, approve, block

During a block freeze, only a break-glass override lets a release through. hotfix sets what happens to hotfixes during the freeze.

areas ​

Beta, early access. Flag: proven_changes.

Names parts of the repository for proven changes. Each name maps to path patterns. A file can be in more than one area. Files in no named area use their directory. The gate doesn't read this.

YAML
areas:
  checkout: ["apps/web/checkout/**", "services/payments"]

proven ​

Beta, early access. Flag: proven_changes.

proven.never lists the kinds of change that are never proven in this repository: tests, migrations, auth, api, ui, deps, docs or code. Without it, deps, migrations and auth are excluded. An empty list measures every kind. The gate doesn't read this.

YAML
proven:
  never: [deps, migrations, auth, ui]

compatibility ​

Beta, early access. Flag: compatibility_matrix.

A top-level section, next to gate, that declares your components and the version pairs you support. It feeds the compatibility matrix. Add compatibility_break to block_on to block a release that breaks a pair.

YAML
compatibility:
  components:
    - name: web
      role: client
      repository: acme/web
    - name: api
      role: server
      paths: ["openapi/**"]
  supported:
    - consumer: web
      consumer_versions: ">=1.4.0 <2.0.0"
      provider: api
      provider_versions: ">=2.0.0"

components, 1 to 50:

Key Type Required Allowed values
name string Yes Letters, digits, dots, dashes or underscores, up to 64 characters; unique
role string Yes client, server, sdk, api, schema, app
repository string No owner/name; defaults to the repository this file is in
paths list of strings No Up to 50 path patterns such as openapi/**; only breaks in these paths count. Defaults to the whole repository

supported, 1 to 200:

Key Type Required Allowed values
consumer string Yes A component's name
consumer_versions string Yes A version range
provider string Yes A different component's name
provider_versions string Yes A version range

A version range looks like >=1.4.0 <2.0.0, >=2.0.0, ^1.4, ~1.4, 1.x or 2.3.1. Pre-release versions aren't in a range unless the range names one.

Removing the section removes the repository's pairs the next time Bumpkit reads the file from the base branch, or when you run bumpkit compatibility sync.

exports ​

Tunes the public API change findings, the removed or changed exports that count as breaking changes.

Key Type Default Allowed values
severity string high high, medium, low, info
ignore_paths list of strings none up to 100 path patterns, CODEOWNERS style, such as generated/**
max_findings int 0 (no cap) 0 to 1000; the rest are summarized in one finding

Only high-severity breaking findings trigger block_on and the breaking approval rule, so a lower severity makes export changes informational. These keys apply to every release check and gate; they don't need the behavior_checks flag.

behavior ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: behavior_checks.

Release checks catch small behavior changes in every supported language, such as removed guard clauses or changed defaults, and the CLI flags changed files with a history of reverts. These findings are informational until you turn them on here.

YAML
gate:
  behavior:
    changes: approve
    hotspots: block
    severity: medium
    hotspots_min: high
Key Type Default Allowed values
changes string off off, approve, block: what behavior-change findings do
hotspots string off off, approve, block: what hotspot findings do
severity string none high, medium, low: raises these findings to at least this severity
hotspots_min string medium high, medium, low: hotspots below this severity don't count

quality ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flags: architecture_drift, slop_tracker, performance_diff.

Decides what code quality findings do, and sets the thresholds the checks use. See Code Quality & Architecture.

YAML
gate:
  quality:
    architecture_drift: block
    code_quality:
      action: approve
      severity: medium
      when: agent
    performance: warn

quality.architecture_drift ​

New import cycles, breaks of the architecture layers, and coupling and complexity growth.

quality.code_quality ​

Copied code, interfaces with one implementation, functions that only forward, unreferenced new symbols, oversized functions and comment noise.

quality.performance ​

Queries inside loops, blocking IO and complexity growth on hot paths, unbounded allocations, and benchmark regressions.

Quality rules ​

Each of the three keys takes a string (the action) or a mapping:

Key Type Default Allowed values
action string warn warn (report only), approve (needs approval), block (fail)
severity string medium high, medium, low: findings at or above this count
when string always always, agent, agent_or_unknown

Quality thresholds ​

Key Type Default Allowed values
max_function_lines int 80 1 to 10000
max_complexity int 15 1 to 1000
clone_tokens int 40 10 to 1000: the smallest copied block reported
hot_path_depth int 4 1 to 10
bench_threshold number 5 0 to 1000: the benchmark slowdown in percent that counts

cross_repo ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: cross_repo_impact.

When a release breaks a contract or public API that other repositories in your workspace consume, the gate lists each consuming repository with its call sites. See Cross-Repo Impact.

Key Type Default Meaning
block_on_consumer_break bool false Fail the gate when a consumer breaks
require_approval bool true Ask for approval when a consumer breaks

If Bumpkit can't check the consumers, the release needs approval regardless of these settings.

fix_tasks ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: close_the_loop.

What open fix tasks do to the gate. A fix task lists every file:line caller still on the old version of a Go function or method this branch renamed, removed or changed, with the expected edit. Bumpkit opens mechanical edits (a rename, or one removed parameter) as a pull request into the branch and routes the rest to the authoring agent and the pull request. A task is done only when a later gate run proves every listed place clean, never because an agent says so.

Type string
Default block
Allowed values block (fail), approve (needs approval), off
YAML
gate:
  fix_tasks: approve

A task holds the gate once Bumpkit has confirmed it by reading the code at the commit through the GitHub App. Until then it shows as a fix_tasks: unconfirmed flag and doesn't hold the gate, so on GitLab, Bitbucket and Azure DevOps a task is a flag. Creating a task from a report takes a key with write access. Each confirmed task still open after the gate run adds one reason, fix_tasks: block or fix_tasks: approve, that names the places, the symbol, its old signature, what to change, who it was routed to and the fix pull request. With block, approval can't override it. With approve, any reviewer's approval counts. With off, tasks are still recorded and routed but don't change the outcome. An org policy can lock fix_tasks; a repository can then only tighten it. bumpkit loop --mine lists the tasks on your branch.

require_regression_evidence ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: regression_evidence.

Require test results on the exact commit before a release ships, with the tests picked by the change's blast radius. It's off until you turn it on.

Type bool
Default false

regression_evidence_action ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: regression_evidence.

What happens when the evidence isn't a clean pass. It needs require_regression_evidence: true.

Type string
Default block
Allowed values block (fail), approve (needs approval)
YAML
gate:
  require_regression_evidence: true
  regression_evidence_action: approve

The gate adds one reason, require_regression_evidence: block or require_regression_evidence: approve. It passes only when every expected test passed in results a CI run attested for this exact commit. Results from a plain API key or another commit don't count. No results, partial results, a failed test, an unreadable upload, or a change Bumpkit can't map to tests all fail under block, where approval can't override it, and need approval under approve, where any reviewer's approval counts. See Regression evidence for the setup. An org policy can lock both keys; a repository can then only tighten them.

stacks ​

Beta, early access. Flag: stacked_prs. Needs the Bumpkit GitHub App.

How the gate treats stacked pull requests. A pull request whose base branch is another open pull request's head branch in the same repository is stacked on it, so #128 → #130 → #131 is a stack of three. Bumpkit works the stack out from GitHub App events, never from what a client sends, and checks each pull request on its own changes: #131 is compared against #130's head, not against main. The policy and CODEOWNERS for a stacked pull request come from the default branch.

Every stacked pull request's decision carries a stacks reason that names its parent and what has to merge first. The result comment shows the whole stack, the pull request's position in it and the merge order.

Bumpkit keeps each decision tied to the exact head and base it checked:

  • When a parent gets new commits, its direct children are checked again against the new parent head.
  • When GitHub retargets a child after its parent merges, the child is checked again against its new base, and the decision against the old base no longer counts as current.
  • Approvals count only for the head commit they approved.
Type mapping
Default {require_parent_merged: false}

stacks.require_parent_merged ​

Holds a stacked pull request until the pull request it's stacked on has merged. While the parent is open, the child's decision fails with a stacks.require_parent_merged reason that names the pull requests to merge first. Approval can't override it. Once the parent merges, Bumpkit checks the child again and the hold clears.

Type boolean
Default false
YAML
gate:
  stacks:
    require_parent_merged: true

An org policy can lock stacks; a repository can then only turn require_parent_merged on. Run bumpkit stack list to see the repository's stacks, or bumpkit stack show NUMBER for one pull request's position and merge order.

architecture ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: architecture_drift.

A top-level key, next to gate:. It declares your layers and the imports between them that aren't allowed. Without it, Bumpkit infers layers from the base. gate.quality.architecture_drift decides what a break does.

YAML
architecture:
  layers:
    - name: api
      paths: [services/api]
    - name: store
      paths: [services/db, services/store]
    - web
  forbidden:
    - from: store
      to: api
Key Type Meaning
layers list Each layer is a name and its paths. A plain string is a layer whose name is also its path
layers[].name string A unique name
layers[].paths list of strings Relative path prefixes; defaults to the name
forbidden list Imports that aren't allowed
forbidden[].from, forbidden[].to string A layer name or path

agent ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: agent_pause.

A top-level key. It configures bumpkit pause, the hook that checks each shell command or file access a coding agent makes before it runs, and allows it, asks a human, or denies it. See Agent Controls.

YAML
agent:
  ask: [rm_rf, "npm publish *"]
  deny: [force_push, "terraform destroy*"]
  allow: ["rm -rf ./dist*"]
  protected_branches: [main, "release/*"]
  remote: true
  timeout: 45s
Key Type Default Meaning
ask list of strings none Rules or patterns that pause for a human
deny list of strings none Rules or patterns that are blocked
allow list of strings none Rules or patterns that are let through
protected_branches list of strings main, master, trunk, production, prod, release/*, releases/* Branch names or globs that force_push protects
remote bool false When a command pauses, a teammate can approve it from the Approvals page
timeout duration string 30s How long a remote approval waits, 5s to 120s

Each entry in ask, deny and allow is a built-in rule ID or a pattern. A pattern matches a command line or file path, with * and ? as wildcards. A single lowercase word that isn't a rule ID is an error; add a space or * to make it a pattern.

A deny pattern always wins. An allow pattern lets a command through unless one of its rules is in deny. Listing a rule ID moves that rule to the level of the list.

Rule ID Default Catches
rm_rf ask rm -r outside a temporary or build directory
rm_rf_root deny rm -r on /, the home directory, the repository root or a system directory
force_push deny git push --force or a branch delete on a protected branch
git_reset_hard ask git reset --hard
git_clean ask git clean -f
sql_drop ask DROP, TRUNCATE or an unfiltered DELETE sent to a database client
infra_apply ask terraform, tofu or pulumi apply and destroy
kubectl_delete ask kubectl delete or drain, helm uninstall
pipe_to_shell ask A downloaded or decoded script piped into a shell or interpreter
chmod_777 ask chmod -R that makes files world-writable
secret_write ask A write to .env, a key or a secrets file
credential_file ask Reading or copying a credential file such as .env, ~/.ssh or ~/.aws
package_publish ask Publishing a package or pushing an image
prod_database ask A database URL whose host isn't local
self_approval deny An agent approving or rejecting Bumpkit memories, lessons or Approvals items
agent_scope deny An agent writing outside the paths and areas agents: gives it
too_complex ask A command nested too deeply to check

bumpkit pause reads bumpkit.yml from the default branch (origin/HEAD, origin/main or origin/master, else HEAD), not from your uncommitted changes, so an agent can't edit its own rules. If the file doesn't parse, it uses the default rules.

agents ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: agent_budgets.

A top-level key with budgets and scopes for coding agents. Map an agent id, or a glob such as claude-*, to its limits:

YAML
agents:
  claude-*:
    max_open_prs: 2
    max_changed_lines: 400
    paths_allow: [services/notify/**]
    paths_deny: [services/billing/**]
    areas_deny: [billing]
    spend_limit: 10
    on_violation: block
Key Type Default Meaning
max_open_prs int no limit The most open pull requests the agent may have; this change fails the limit when the agent already has that many others open
max_changed_lines int no limit The most lines one change may touch
paths_allow list of strings every path Path patterns the agent may change, such as services/notify/**
paths_deny list of strings none Path patterns the agent may not change
areas_deny list of strings none Areas the agent stays out of: tests, migrations, auth, api, ui, authentication, authorization, billing, cryptography
spend_limit number no limit US dollars per calendar month (UTC), recorded with bumpkit agents spend
on_violation string block block fails the gate; approve asks for a person's approval

The gate checks every agent on the change, including the BUMPKIT_AGENT_ID or BUMPKIT_AGENT that bumpkit gate sends. Each broken limit becomes its own reason, named agents.<pattern>.paths, .areas_deny, .max_changed_lines, .max_open_prs or .spend_limit. bumpkit pause --hook claude also denies file writes outside an agent's paths before they happen. Every violation is recorded and audited; see bumpkit agents violations. Limits can't be negative, and an unknown key or area is an error. With the GitHub App installed, the gate uses the agents: section from the base branch.

memory ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: memory_approval.

A top-level key for codebase memory.

Key Type Default Meaning
require_approval bool false Memories agents save wait as pending until a person approves them on the Approvals page or with bumpkit memory approve. Only approved memories are recalled
YAML
memory:
  require_approval: true

If bumpkit.yml doesn't parse, new agent memories wait for approval.

verify ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: behavioral_verification.

A top-level key for bumpkit verify, which runs the base and the head side by side in your CI and uploads a signed report. Add behavior to require_checks to make the gate require it. bumpkit verify reads this section from the base commit, like the gate.

YAML
verify:
  test: go test ./...
  timeout: 15m
  network: localhost
  env: [DATABASE_URL]
  http:
    start: ./bin/server
    ready: /healthz
    port_env: PORT
    openapi: api/openapi.yaml
    ignore: [id, created_at]
  library:
    runs: 128
  browser:
    pages: [/, /pricing]
    threshold: 0.02
  require_ci_attestation: true
Key Type Default Meaning
test string detected: go test ./..., npm test or python -m pytest The test command
timeout duration string 10m Up to 2h
memory_mb int 16384 Memory limit for the sandbox
cpu_seconds int 1800 CPU limit for the sandbox
network string localhost localhost or allow
env list of strings none Names of environment variables to pass into the sandbox (names only, no =)
require_ci_attestation bool true gate.require_checks: [behavior] uses the latest report attested by GitHub Actions OIDC, so a later report signed only with an API key neither replaces nor blocks it. false opts out and trusts anyone with a key. Once the GitHub App is installed or a GitLab, Bitbucket or Azure DevOps connection is added, Bumpkit reads this setting from your repository's policy; with neither, it uses the policy your CI sends and the decision says policy_source: client. With the App installed, a report counts only if the pull request leaves .github/ and the local actions and scripts named in the default branch's workflow unchanged, and a report from a merge commit counts only while it is the pull request's current merge commit into your default branch. The workflow still runs the pull request's own code and tests. GitLab, Bitbucket and Azure DevOps have no GitHub Actions token, so set false there to use require_checks: [behavior]

verify.http ​

Replays HTTP requests against the base and head versions of your service.

Key Type Default Meaning
start string required The command that starts the service
ready string / The path that answers when the service is up
port_env string PORT The environment variable the service reads its port from
openapi string detected An OpenAPI spec to derive requests from
requests string none A file of recorded requests
ignore list of strings none JSON body fields to ignore when comparing, such as id or $.created_at
startup_timeout duration string 60s How long to wait for ready

verify.library ​

Generated calls to changed Go functions, compared between base and head.

Key Type Default Meaning
disabled bool false Turn it off
runs int 64 Calls per function, up to 1000
seed int 1 Random seed

verify.browser ​

Playwright screenshots of pages, compared pixel by pixel.

Key Type Default Meaning
disabled bool false Turn it off
pages list of strings [/] Pages to compare, up to 50
threshold number 0.01 The share of pixels, 0 to 1, that may differ

train ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: release_trains.

Top-level train: sets the rules for release trains cut from this branch. Bumpkit reads it from bumpkit.yml on the branch the train ships.

YAML
train:
  label: "train:{slug}"
  require_all_pass: true
  max_breaking: 0
  require_approval:
    teams: ["@acme/release-managers"]
    count: 1
  block_on_unhealthy_deploys: true
  release_workflow: release.yml
Key Type Default Meaning
label string train:{slug} The pull request label that joins a train. At most 50 characters, no surrounding spaces.
require_all_pass bool true Hold the train until every member passes the gate. A failing member always blocks it.
max_breaking int no limit The most breaking changes the train may carry. Must not be negative.
require_approval map none Release manager approvals: approvers (list), teams (list of @org/team) and count (up to 10; leave it out for one approval).
block_on_unhealthy_deploys bool false Block when a member is regressed or degraded in production.
release_workflow string none A workflow file name such as release.yml, dispatched with the train's name when the train is cut, instead of Bumpkit creating the GitHub Release.

locked ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: org_policies.

An org policy is one gate policy for the whole workspace. Workspace owners and admins save it on the Policy page, signed in to the dashboard; bumpkit policy set and PUT /v1/policy/org return 403 HUMAN_APPROVAL_REQUIRED with the link, since a key can't change org locks, or point it at a config repository whose bumpkit.yml on the default branch is read at gate time. Every version is kept and audited. See Org Policies & Freezes.

An org policy is a bumpkit.yml with one extra top-level key, locked:, the gate keys that repositories may only tighten:

YAML
locked: [block_on, require_approval, break_glass, freezes]
gate:
  block_on: [secret, data_loss]
  require_approval:
    - breaking
  break_glass: false
  freezes:
    - name: Year-end freeze
      start: 2026-12-20
      end: 2027-01-02

locked accepts block_on, require_approval, on_error, require_checks, security_alerts, vulnerabilities, break_glass, hotfix, blast_radius, deploy, cross_repo, timezone, windows, outside_windows, freezes, quality, exports, behavior, fix_tasks, require_regression_evidence, regression_evidence_action, require_check_apps and stacks.

How the org policy merges ​

The org policy is the starting point. For each key a repository's bumpkit.yml sets under gate::

  • An unlocked key replaces the org value.
  • A locked key can only be tightened. When the repository tries to loosen it, the org value stays and the gate decision notes it.
Locked key Effective value
block_on, require_checks Both lists combined
require_approval, freezes The org rules plus any new repository rules
on_error The org's fail stays fail
security_alerts, vulnerabilities The repository may only lower the threshold
break_glass The org's false stays false
hotfix The stricter of each setting: both block_on lists, the smaller max_files, the shorter review_within, the stricter backports
blast_radius Both approve_areas lists; the org's max_depth always applies
timezone The org's value
windows The org's windows, if it sets any; add freezes to narrow them
outside_windows The org's block stays block
fix_tasks The stricter of the two: off < approve < block
require_regression_evidence The org's true stays true
regression_evidence_action The stricter of the two: approve < block
deploy, cross_repo, quality, exports, behavior The org's value; a different repository value is ignored

Run bumpkit policy show --effective in a repository, or call POST /v1/policy/effective, to see the policy the gate applies and where each key came from. If the org policy doesn't parse or its config repository can't be read, the gate fails closed.

↑↓ to move, Enter to open