A review comment asks a human to act; a merge gate requires them to. CodePeel's pre-merge checks are the bridge between the two: after every pull-request review completes, the findings are evaluated against configurable thresholds and the result is posted as a GitHub commit status under the codepeel/premerge context. Combined with branch protection, a failed check becomes a PR that cannot be merged.
This guide explains how the evaluation works, what each check type measures, how severity decides whether a failure blocks a merge, and how to calibrate the gates so they enforce standards without grinding development to a halt.
A post-review evaluation pipeline
Pre-merge checks do not re-scan your code. They run immediately after a review completes and evaluate the aggregate metrics that review already produced: bugs caught, security issues found, performance issues detected, and the count of critical-severity findings.
The sequence for every pull request:
- A PR is opened or updated, and the standard review runs (deterministic checks, AI analysis, the security pass described in How CodePeel's OWASP Security Scanning Works).
- The review completes with metrics — the counts the checks will evaluate.
- Your enabled checks are loaded and each one compares its metric against its threshold.
- Every evaluation is recorded as a check event with the result, a human-readable explanation, the repository, commit SHA, and timestamp.
- Results are attached to the review, visible in the dashboard.
- One commit status is posted to the PR's head commit.
Because the gates consume findings that already exist, checks add no extra review cost and run on every plan. The one dependency: the review must complete. If a review fails — quota exhausted, provider outage — no checks are evaluated and no status is posted, so a broken review never blocks a PR.
The four check types
| Check type | What it evaluates | Threshold | Default severity |
|---|---|---|---|
security_blocker | Any security findings | none | error |
bug_density | Bug count | yes (default 5) | warning |
max_issues | Bugs + security + performance | yes (default 10) | error |
critical_findings | Any critical-severity finding | none | error |
Security blocker
Fails if the review found any security issue — a zero-tolerance gate with no threshold. Use it on repositories that handle authentication, payments, or sensitive data, where the argument for merging with a known security finding is never good. The security findings feeding this check are the same ones described in the security scanning article.
Bug density
Fails when the number of bug findings exceeds your threshold. A threshold of 5 means five or fewer bugs pass; six fails. This is the natural "trend" check — most teams run it at warning severity to watch how many bugs each PR introduces without blocking.
Max issues
Fails when the total of bugs + security + performance findings exceeds the threshold. Architecture-only findings are deliberately excluded from this count. It is the most flexible gate: a higher threshold tolerates large refactors or known debt; a low one protects critical services.
One subtlety worth knowing: a threshold-based check saved without a threshold value always passes — it is a no-op, not a zero-tolerance gate. If you want zero tolerance, set the threshold to 0.
Critical findings
Fails if any finding has critical severity, regardless of category: a critical bug, a critical security issue, a critical performance problem — any of them trips the gate. Critical findings are meant to be unambiguous (data-loss risks, crashes, exploitable vulnerabilities, race conditions), which is why this check needs no threshold.
Error versus warning severity
Each check carries a severity that decides what its failure means:
error— a failed error-severity check turns the commit status red. If branch protection requirescodepeel/premerge, the merge is blocked.warning— a failed warning-severity check is recorded and visible in the dashboard, but the commit status stays green. Nothing is blocked.
The aggregate status posted to GitHub follows directly: all checks pass, or only warning-severity checks failed → success; any error-severity check failed → failure.
The commit status itself
One status is posted per reviewed commit, aggregating every check:
| Field | Value |
|---|---|
| Context | codepeel/premerge |
| State | success or failure |
| Description | "All pre-merge checks passed" / "Pre-merge check failed" (capped at 140 characters, per GitHub's API) |
| Target URL | The pre-merge checks dashboard, for the per-check breakdown |
The status is written through GitHub's commit-status API, which requires the CodePeel GitHub App to hold the statuses:write permission. GitHub renders it in the PR's checks section next to your CI statuses.
To make failure blocking, require the status in your repository settings: Branches → Branch protection rules → Require status checks to pass before merging, then select codepeel/premerge. From that point, an error-severity failure is a hard stop — the merge button stays disabled until the findings are resolved or the check passes on a fresh commit.
A worked example
Say you have enabled security_blocker (error), critical_findings (error), and bug_density with threshold 5 (warning). A PR review finishes with: 2 security issues, 3 bugs, 0 critical findings.
security_blocker: 2 security issues → fail (error severity)critical_findings: 0 critical → passbug_density: 3 bugs, threshold 5 → pass
Because the failing check has error severity, the codepeel/premerge status posts as failure, and a protected branch refuses the merge. Fix the security issues, push, and the fresh review re-evaluates everything: with the security count at zero, the status posts success and the PR merges. (Note that bug_density failing alone would have kept the status green — warnings inform, they do not block.)
The audit trail
Every evaluation is stored as a check event: result, check name, repository, commit SHA, PR number, timestamp, and a details string like Check failed: 3 security issues found or Check passed: 1 bug found (threshold: 5). Counters accumulate per check — pass count, fail count, last-triggered — and the Recent History view in the dashboard paginates through events across all repositories.
This history is the calibration tool. A check that fails constantly is either protecting you from a real systemic problem or its threshold is wrong; a check that never fails may be too generous to matter. The trend line tells you which.
Calibrating your gates
A rollout that works for most teams:
- Start everything at
warning. Watch the failure rate for a couple of weeks without touching anyone's workflow. - Promote the unambiguous gates to
error:security_blockerandcritical_findingsfail on any occurrence, so their conditions are never arguable. - Keep density checks at
warninginitially, then tighten thresholds as your baseline improves. Start generous (5–10) and reduce. - Re-check after process changes. Thresholds that fit a two-person team strangle a ten-person team; the pass/fail history shows it before your developers do.
A failing gate with no escape hatch gets disabled by an annoyed team — the warning-first rollout exists to prevent that outcome.
Scope and limitations
- Account-level configuration. Checks apply to every repository where the GitHub App is installed; you cannot vary thresholds per repository today.
- Pull-request reviews only. Reviews from the VS Code extension or the MCP server do not trigger checks or post statuses — the gates evaluate the PR pipeline.
- One aggregate status. GitHub shows a single
codepeel/premergeresult; per-check detail lives behind the target URL in the dashboard. - No retroactive evaluation. Changing a check affects the next review. To re-evaluate an existing PR, push a commit to trigger a fresh review.
- Graceful degradation. If the evaluation itself errors, no status is posted — a system failure never blocks a merge.
For the operational reference — dashboard fields, event details, troubleshooting — see the pre-merge checks documentation. To make the findings feeding these gates more precise over time, combine the gates with auto-fix PR generation so the error-severity failures shrink on their own.