The LGTM Economy: What Approval Velocity Does to the Last Human Quality Gate

The approval button is a sensor on the release pipeline, and like any sensor it has a documented range, a documented failure mode, and a documented set of conditions under which it does not fire at all. Most teams read its output as a verdict on quality. The platform’s own documentation never makes that claim.

What the approval artifact actually says

GitHub documents three review decisions: Comment, Approve, and Request changes. The documented meaning of Approve is narrow: it “signals that the changes are ready to merge.” That is a statement about merge readiness, not about correctness, not about test coverage, and not about whether the reviewer read the diff. The documentation is careful here, and the care is the point. See About pull request reviews.

The second decision is weaker than most practitioners assume. GitHub states plainly that “the Request changes option is purely informational and will not prevent merging unless a ruleset or classic branch protection rule is configured with the ‘require a pull request’ option” (Approving a pull request with required reviews). A reviewer who believes they have blocked a merge by requesting changes has, in the default configuration, done nothing of the kind. The gate is configuration, not convention.

GitLab draws the same line from the other direction. In GitLab Free, “all users with at least the Developer role to approve merge requests,” and “these approvals are optional and don’t prevent merging without approval” (Merge request approvals). Required approvals that actually block a merge are a Premium and Ultimate feature. The button exists at every tier. The gate does not.

What branch protection enforces, and what it exempts

Once a team configures required approvals, the question shifts from whether the gate exists to who is standing outside it. GitHub’s branch protection documentation is explicit about the default: “the restrictions of a branch protection rule don’t apply to people with admin permissions to the repository or custom roles with the ‘bypass branch protections’ permission” (About protected branches). The exemption is not a bug or a misconfiguration. It is the shipped default, and it can be closed by enabling Do not allow bypassing the above settings.

Two other settings determine whether an approval is attached to the code that merges:

  • Dismiss stale pull request approvals when new commits are pushed. GitHub “records the state of the diff at the point when a pull request is approved,” and if the diff changes, the approval is dismissed as stale. Without this setting, an approval survives a force-push.
  • Require approval of the most recent reviewable push. This requires that “the most recent reviewable push must be approved by someone other than the person who pushed it.” It is a weaker guarantee than stale dismissal — the documentation itself notes that stale dismissal is safer if hijacking is the concern — but it is stronger than nothing.

There is also a structural ambiguity worth naming. GitHub documents that “only a single branch protection rule can apply at a time, which means it can be difficult to know which rule will apply when multiple versions of a rule target the same branch.” A gate whose governing rule is ambiguous is a gate whose audit is ambiguous. Rulesets exist partly to address this, but any organization still on classic rules should treat the ambiguity as a known property of the instrument, not a surprise to be discovered during an incident review.

The velocity frame, held loosely

The case for measuring approval speed usually rests on delivery-performance research. That research deserves a more careful reading than it typically gets. DORA’s own history of its metrics records that the metric known as mean time to recover was “renamed and redefined as failed deployment recovery time” in 2023, and that in 2024 researchers “identified that change failure rate—the percentage of deployments requiring hotfixes or rollbacks—acted as a proxy for the amount of rework a team must perform,” introducing deployment rework rate as a fifth metric (A history of DORA’s software delivery metrics).

Two things follow. First, the metric set is a living instrument, revised as its authors learn what it actually measures. Second, approval velocity is not one of DORA’s metrics at all. It is a local proxy that inherits none of their validation. A number that has been redefined repeatedly at the source is a poor foundation for a hard target downstream, and a number that was never validated at the source is a worse one.

DORA’s 2019 research summary also records that “heavyweight change approval processes negatively impact performance” (DORA research). This is often cited as an argument for faster approvals. It is more accurately an argument against heavyweight process — against approval chains that add latency without adding detection. It does not establish that a fast approval detects more. No retrieved source establishes a numeric relationship between approval speed and defect escape rate, and this essay will not invent one.

The steelman: fast approvals are usually a symptom of a healthy queue

The strongest counterargument is that approval latency is mostly a queueing metric, and a short queue is good. If reviewers are responsive, if pull requests are small, if the diff is legible, approval arrives quickly because the work is easy to review — not because the reviewer skipped it. On this reading, a rising approval latency is the alarm, not a falling one: it means reviewers are overloaded, batches are growing, and the gate is becoming a bottleneck that teams will route around. That reading is correct as far as it goes, and it is the reason approval latency belongs on a dashboard at all.

But it does not support approval latency as a target. The distinction matters because of incentive geometry. If approval latency is a performance target, the cheapest way to hit it is to approve faster. That is precisely the behavior the gate exists to prevent. A queueing diagnostic and a performance target look identical on a dashboard and behave oppositely in a review. The steelman wins the argument about measurement and loses the argument about targets.

The gate audit: a named artifact for the release owner

The recommendation is not to slow approvals down. It is to stop treating the approval button as a quality verdict and start auditing the configuration that gives it whatever meaning it has. The artifact is a table, one row per protected branch, reviewed on the same cadence as access reviews:

Field What it records Why it matters
Required approval count Number configured on the governing rule Zero means the gate is advisory
Admins and bypass roles included? Whether Do not allow bypassing is enabled Default exempts admins and bypass-permission roles
Stale approvals dismissed? Whether approvals are dropped when the diff changes Connects the approval to the merged content
Last-push approval required? Whether the most recent push needs a different approver Weaker than stale dismissal; still a real constraint
Bypass list membership Named actors allowed to skip required pull requests Every name is a documented exception to the gate
Governing rule identified Which rule actually applies when several target the branch Classic rules apply one at a time; ambiguity is an attack surface

This is a template, not a finding. It makes no claim about how any specific organization is configured. Its value is that every field is a documented setting with a documented default, and every default is auditable. A release owner who cannot fill in this table for their default branch does not know what their last human gate is doing.

The audit produces a specific kind of answer. It distinguishes the gate was passed from the gate was meaningful. A meaningful approval requires that the approver saw the diff state that actually merged. Stale-approval dismissal and last-push approval are the documented mechanisms that connect the two. Without them, an approval is a signature on a document that may have changed after signing.

What the audit cannot tell you

None of this proves that a fast-approving team is shipping defects. It proves something narrower and more useful: the meaning of the last human gate is only as strong as its configuration, and configuration is auditable in a way that reviewer attention is not. The audit will not tell you whether a reviewer read the diff. It will tell you whether the platform was configured to require that the diff they read is the diff that merged. That is the question a release owner can actually answer, and it is the one worth asking before the next green check.

FAQ

Does a fast approval mean the reviewer did not read the diff?

No. Approval latency is a queueing signal, and a short queue often reflects small, legible diffs and responsive reviewers. The platform documentation makes no claim about reviewer attention, and neither should an audit. The audit checks configuration, not cognition.

Is approval velocity a DORA metric?

No. DORA’s documented metrics are deployment frequency, change lead time, failed deployment recovery time, change fail rate, and deployment rework rate. Approval velocity is a local proxy that inherits none of DORA’s validation, and DORA’s own history shows the metric set has been revised repeatedly.

If we enable stale-approval dismissal, will approvals become meaningless?

They become more expensive, which is the point. GitHub documents that the approval is tied to the diff state at the time of approval, and that a changed diff dismisses the approval. Teams that find this onerous are usually pushing large diffs late; the setting surfaces that, it does not create it.

What is the single highest-leverage setting to check first?

Whether admins and bypass-permission roles are included in the rule. GitHub’s documented default exempts them. Until that is closed, the gate applies to everyone except the people most likely to be paged when it fails.

Related Post