Gate
Approvals
How Bumpkit counts approvals for the release gate, from GitHub reviews, Slack, the dashboard and deployment protection rules.
A rule that says "a person must approve" is useless if the wrong people's votes count; this page explains whose approvals count and where to give them, for reviewers and leads.
When the Release Gate returns needs_approval, a person has to approve the change. This page explains which approvals count, where people can give them, and how the gate re-runs once they do.
What needs approval
These parts of the policy ask for an approval:
| Rule | Who can approve |
|---|---|
require_approval rules (breaking, contract_breaking, untested, intent, area) |
Anyone, or only the rule's approvers and codeowners when set |
blast_radius.approve_areas |
Anyone |
hotfix.backports: approve |
Anyone |
fix_tasks: approve (Beta, flag close_the_loop) |
Anyone |
regression_evidence_action: approve (Beta, flag regression_evidence) |
Anyone |
agents limits with on_violation: approve (Beta, flag agent_budgets) |
Anyone |
agent_track_record_below rules (Beta, flag agent_track_records) |
Anyone, or only the rule's approvers when set |
Freezes and release windows set to approve (Beta, flag change_freezes) |
Anyone |
require_checks without the GitHub App |
Anyone, vouching for the CI results |
| A check that was too large to read in full | Anyone |
A rule with count: 2 needs two qualifying approvals. Each reason in the gate decision lists who approved it.
gate:
require_approval:
- area: [billing]
approvers: ["@acme/payments"]
count: 2
- breakingHere the billing rule needs two approvals from the payments team, and the breaking rule needs one from any reviewer.
GitHub review approvals
On GitHub, an approval is a pull request review. A review counts when all of these hold:
- Its latest state is Approved (a later "changes requested" or dismissal replaces it; comments don't).
- It was given on the pull request's current head commit. A new push needs new approvals.
- The reviewer isn't the pull request's author, isn't a bot, and isn't a coding agent's account.
- For rules with
approversorcodeowners, the reviewer is one of them.
@org/team approvers and codeowners: true are resolved through the Bumpkit GitHub App, which reads team membership and the CODEOWNERS file (.github/CODEOWNERS, CODEOWNERS or docs/CODEOWNERS) from the same place as the policy: the base commit of a pull request into the default branch, otherwise the default branch. Without the App, team membership and CODEOWNERS can't be checked, and the gate says so in its reason. If no CODEOWNERS entry covers the triggering files and the rule has no approvers, any reviewer counts.
The gate records where its approvals came from: github when Bumpkit verified them through the App, asserted when the CI job reported them with its own token and the App isn't installed, or none. With the App installed, approvals a client sends never count.
Approve from Slack
Beta, early access. A workspace without access gets
403 FEATURE_EARLY_ACCESSand a link to request it. Flag:slack_approvals.
When the gate needs approval on a pull request, Bumpkit posts the request to a Slack channel with Approve and Deny buttons. By default the channel gets every pull request; choose Only when approval is needed to post a pull request only once a check needs approval.
Each pull request gets one message per channel. New commits, votes and re-runs update that message in place. When the decision changes, for example from needs approval to ready to ship, or to blocked, Bumpkit adds a short reply in the message's thread; a new commit with the same decision adds nothing. Draft pull requests aren't posted: the message appears when the pull request is opened ready or marked ready for review. When the pull request is merged or closed, the message shows Merged or Closed without merging and stops changing. Reopening it picks up where it left off.
The message leads with the decision, the pull request's title and link, and one line with the commit, who committed it and which coding agent wrote it. Below that come the reasons the gate gave, then up to five findings that aren't already one of those reasons, most severe first, and Approve, Deny and Open in Bumpkit buttons. Long text is shortened at a word or path boundary, never mid-word, and file names stay whole. When a message would be too long for Slack, the least severe items are left out and counted.
Connect Slack
Slack approvals use the Bumpkit Slack app, which is separate from the incoming webhook that bumpkit integrations connect slack sets up for notifications.
- In the dashboard, open Integrations → Slack and choose Add to Slack. Slack shows the permissions the Bumpkit app asks for; approve them.
- Invite the app to the channel:
/invite @Bumpkit. - Pick the channel, or paste its ID (like
C0123ABCDEF, from the bottom of the channel's details in Slack), and save. Bumpkit posts a test message to confirm it can write there.
The Bumpkit app asks for these Slack permissions:
| Scope | What it's for |
|---|---|
chat:write |
Posting checks and approval requests |
users:read, users:read.email |
Matching a Slack voter to a workspace member |
commands |
The /bumpkit slash command |
channels:read, groups:read |
Showing channel names and listing the channels Bumpkit is in |
Only workspace owners and admins can choose the channel, update permissions or disconnect the app. The Bumpkit GitHub App must be installed on the repository, because votes are checked against the live pull request.
Update Slack permissions
Bumpkit stores the scopes Slack granted. When the features you have on need a scope the app doesn't have yet, or the app was connected before Bumpkit tracked scopes, the Slack card shows Update Slack permissions with what it unlocks. It sends you through Slack again and updates the existing connection in place: the token, scopes and Slack workspace name refresh, and the channel, posting mode and settings stay. Nothing is disconnected. Pick the same Slack workspace: switching to a different one clears the channel so you choose a new one. From the terminal, bumpkit integrations oauth-status slack-app lists missing scopes and bumpkit integrations slack-app reauthorize opens the same flow.
Slack commands
Type /bumpkit in any Slack channel or DM. Bumpkit answers only you, except prepare, which posts the release card for the channel.
| Command | What it does |
|---|---|
/bumpkit prepare owner/repo |
Draft the next release of a repository and post its card in this channel |
/bumpkit inbox |
List what needs your approval |
/bumpkit releases [owner/repo] |
List recent release drafts and releases |
/bumpkit link |
Check that your Slack account is linked to Bumpkit and GitHub |
/bumpkit help |
Show these commands |
Bumpkit matches you by your confirmed Slack email, which must belong to a member of the Bumpkit workspace. prepare and releases need grouped releases on, and inbox needs the approval inbox.
With prepare, Bumpkit posts a fresh draft card with the version, pull request count, top notes and verdict. Running it again refreshes the draft and posts a new card. Review opens Approve and Deny in place; after approval the card shows Publish, and it updates as the release moves on. Votes follow the dashboard rules: you need a role that can write. Invite Bumpkit to the channel first (/invite @Bumpkit) so it can post the card there.
The /bumpkit command comes with the Bumpkit Slack app. If your app was connected before the command existed, choose Update Slack permissions on Integrations → Slack.
Who can vote
A vote counts only when:
- The voter's confirmed Slack email matches a member of the Bumpkit workspace.
- That member's Bumpkit login is linked to their GitHub account, so the vote can be matched to the policy's approvers. Connect GitHub under Settings → GitHub account, from the Connect GitHub button Bumpkit shows when it refuses a vote, or with
bumpkit account link-github. It links the login you're signed in with: no new account, no sign-out. - The vote is for the pull request's latest commit. After a new push, vote on the new request.
- The voter didn't open the pull request, and isn't a coding agent's account.
- The voter is an approver for at least one rule the change needs, or a rule needs an approval from anyone.
Otherwise Bumpkit tells the voter why, privately, and doesn't record the vote. A recorded vote is answered with the gate's new outcome.
If your GitHub account is already linked to another Bumpkit login, Bumpkit tells you which one. When GitHub has verified that login's email for your account, you can merge the two logins: the other login's workspaces and API keys move to the one you're signed in with, and the other login is signed out for good. Otherwise you can move the GitHub link to the login you're signed in with after confirming with GitHub again. Each workspace's audit log records the link, merge or move.
Approve from the dashboard
Beta, early access. A workspace without access gets
403 FEATURE_EARLY_ACCESSand a link to request it. Flag:slack_approvals.
A release's page on the dashboard shows the latest gate decision for its pull request with the same Approve and Deny buttons. Dashboard votes follow the same rules as Slack votes, and the voter's workspace role must allow changes: viewers and auditors can't vote.
Approve from the CLI
Beta, early access. A workspace without access gets
403 FEATURE_EARLY_ACCESSand a link to request it. Flag:slack_approvals.
A vote is a person's call, so an API key, CLI token or MCP tool can't cast one on its own: POST /v1/decisions/{check_id}/approve answers 403 HUMAN_APPROVAL_REQUIRED. Run bumpkit approvals approve APPROVAL_OR_CHECK_ID or bumpkit decisions approve CHECK_ID (or deny) instead. bumpkit approvals list shows what waits for a person, and bumpkit approvals show ID shows one approval with its votes so far. It prints a link and a one-time code. Open the link signed in to Bumpkit, check that the code matches and confirm. The vote counts as yours, follows the same rules as a dashboard vote, and the CLI waits for the result. The link expires after ten minutes.
The Approvals page
The dashboard's Approvals page (/inbox) lists everything waiting for a person: gate approvals, paused agent commands, memories and lessons. Approving a gate item there isn't a vote. It records a break-glass override for that commit, needs a note of at least 10 characters, and is open only to owners, admins and policy admins. The gate's approval rules, such as "anyone except the author", don't count it; the page says Overridden, the pull request's GitHub check re-runs with the override right away, and someone else reviews the override later. A gate item can't be denied there. Gate items and paused commands need a person signed in to the dashboard: an API key is refused with 403 HUMAN_APPROVAL_REQUIRED from the CLI, MCP and the API, and a paused command also needs a write role. If the Approvals page is off for your workspace, an override is on the commit's check page.
Denials
A Deny vote from Slack, the dashboard or the CLI fails the gate, with a denied reason naming who denied it and where. A person's latest vote on a commit replaces their earlier one.
The author's vote never counts
Whatever the channel, the pull request's author can't approve their own change, and neither can bots or coding agents. This holds for GitHub reviews, Slack, the dashboard and deployment reviews.
Audit
Every Slack, dashboard and CLI-confirmed vote is written to the workspace audit log as gate.approve or gate.deny, with the voter's email, GitHub login, the repository, pull request and commit, and where the vote came from. Gate decisions keep the list of approvers for each reason, and are part of the compliance evidence. See Security and Compliance for the change-management controls they provide evidence for.
bumpkit audit --limit 100Re-running the gate
The gate decides again, and updates its check, comment and the pull request's Slack message, when:
- someone pushes to the pull request
- a review is submitted or dismissed (with the App, or with a workflow on
pull_request_review) - someone re-runs the Bumpkit release gate check
- a vote is recorded from Slack, the dashboard or the CLI
- someone records an override with
--pr
Deployment protection rule
Beta, early access. A workspace without access gets
403 FEATURE_EARLY_ACCESSand a link to request it. Flag:deploy_protection.
The Bumpkit GitHub App can act as a GitHub deployment protection rule. Enable Bumpkit as a protection rule on your GitHub environments, and the App reviews every deployment to them from the gate decision for the deployed commit:
gate:
deploy:
environments: [production, staging]
require: approved| Key | Values | Meaning |
|---|---|---|
environments |
List of environment names | Environments Bumpkit gates; empty means every environment. Others are approved straight away. |
require |
pass (default), approved |
approved also rejects a passing deployment no one approved |
How a deployment is reviewed:
| Gate decision | Deployment |
|---|---|
fail |
Rejected, with the failing rules |
needs_approval |
Waits, and is approved or rejected when the gate re-runs after approval |
pass |
Approved (or rejected under require: approved with no approvals) |
| No decision for the commit or the pull request it came from | Rejected |
For deployments, bumpkit.yml is read from the default branch, with your org policy applied, so the deployed commit can't take its own environment out of the gate. If it can't be read or doesn't parse, the deployment is rejected. Only decisions Bumpkit made on a diff it fetched itself count. When another open pull request has the same commit and a stricter result, the stricter result applies. When the deployed commit has no gate decision, Bumpkit uses the decision for the head of the pull request that merged it. Every review is recorded in the audit log as deploy.approved or deploy.rejected by bumpkit[bot]. See deploy. A deployment also needs a decision on a pull request into your default branch, or on a merge group: a gate against any other branch shows what that branch's diff looks like, not what's being deployed.