skip to content

How do you design a policy gate that the team it blocks cannot skip or edit away?

level: seniorimportance: should knowfreq 44%

answer

  1. who can rewrite the rule at merge time
  2. two copies, one authority
  3. delete the pipeline file — still mergeable?
  4. silence and error are denials
  5. the name is an interface

basics

~10 s

Resolve the rule and the decision from somewhere the gated change cannot rewrite, record the requirement outside the repository content, and make a missing or errored decision block the merge instead of passing silently.

solid answer

~50 s

Three properties make a check unskippable. First, **authority lives outside the artifact under review**: the enforcer fetches the rule from a trusted source it pins itself, rather than executing whatever rule file happens to be in the commit. Second, **the obligation is recorded outside the repository content**, so deleting a job from the pipeline removes the check but not the requirement — the merge still waits for a decision that will never come. Third, **absence and error are fatal**: the enforcer emits a decision for every change under a stable name, an evaluation error reports as a failure, and you verify your platform does not count a skipped result as satisfied. You still owe the team a fast local copy of the rule for feedback, but when the local copy and the authoritative one disagree, the authoritative one decides and the report says which version it used.

go deeper

for a junior

Know the basic shape: a check is only as strong as the merge rule that demands it, and a rule stored next to the code can be edited by the change being checked.

for a middle

Be able to explain the trusted-copy split — a vendored copy for feedback, an authoritative copy that decides — and why the report must say which version decided.

for a senior

Show you would test the gate by trying to bypass it: delete the job, rename it, narrow the trigger, lower the threshold, and confirm the pull request stays blocked each time.

for a principal

Own the trade: an unskippable gate puts your service on every team's merge path, so you must argue the uptime, feedback quality and escape-path obligations that come with taking that authority.

## The problem restated A gate whose definition lives in the branch it guards can be removed by the change it was meant to stop, and a gate that only reports when it happens to trigger cannot distinguish "clean" from "never ran". Making it unskippable means moving each of those properties out of reach of the team being gated — without making the rule impossible for that team to work with. ## Property 1 — the decision is resolved from outside the gated repository The enforcer must not execute whatever rule file is sitting in the commit. It resolves the rule from a source it controls, and the repository under review has no write path to that source on the timescale of a pull request. The practical form is a **trusted-copy split**: - a copy of the rule vendored beside the code, used for local runs and pre-push feedback; - an authoritative copy fetched by the enforcer, which is what actually decides. Developers get a fast loop; the decision is not theirs to edit. The critical detail is that the reported result must say **which copy decided and which version of the rule it was**, so that "it passed on my machine" resolves to "your vendored copy is stale" rather than to an argument. Without that, the split creates confusion instead of authority. The same logic pushes evaluation itself out of the repository's pipeline where you can: a decision computed by a service the team cannot reconfigure is stronger than a job the team declares, because the team's ability to define the job is the ability to undefine it. ## Property 2 — the requirement is recorded where the change cannot reach Deleting the job must not delete the obligation. That means the fact that *a decision with this name must exist and must pass* is held somewhere other than the repository's own content — as configuration of the merge rules, owned by whoever owns enforcement rather than by whoever owns the code. The test to apply: **if I delete the entire pipeline file in a pull request, does that pull request become mergeable?** If yes, everything you have is advisory in the only case that matters. If the answer is "no, it wedges", you have real authority, and the wedge is the desired behaviour rather than a bug to be worked around. ## Property 3 — silence and error are denials - The enforcer emits a decision for **every** change, not only for changes matching a path filter, so "the trigger did not match" cannot become "no result". - An evaluation error reports as a failing state with a distinct message, never as an absent result and never as a pass. Distinguish three outcomes explicitly: allowed, denied, could-not-evaluate. - Verify what your platform does with a **skipped** result. Some treat it as satisfying a requirement so that path-filtered pipelines do not wedge every pull request; on such a platform a job that stops matching its conditions is a silent bypass, and you must not rely on the requirement alone. - Treat the decision's **name** as an interface. It is the string the merge rule matches on, so renaming it is a change to enforcement and belongs with the enforcement configuration, not in a refactor. ## What this costs, and say it before you are asked An unskippable gate is an availability dependency on the path to merge. When the enforcer is unreachable it should fail closed, which means every team is blocked by your outage — so you owe them an uptime posture proportionate to that, a clear signal that it is your fault and not their code, and a documented escape path that leaves a record. It is also a centralisation trade: the fast local loop must genuinely reproduce the authoritative decision, or people will learn to push and pray, and your feedback quality collapses even though your enforcement is technically sound. ## The reviewer's habit that goes alongside None of this removes the need to read diffs. As the maintainer reviewing a pull request, the triage question is whether the diff touches the evaluation path: the job, its matching conditions, or any rule data the check reads. Those hunks are enforcement changes regardless of which branch they appear in, and they should be obvious enough to notice at a glance rather than something you have to hunt for. ## The answer that fails Saying "mark the check required and forbid people from editing the pipeline" fails on both halves. Required alone does not survive a platform that counts skipped as passed or a rule file lowered in the same commit; and forbidding pipeline edits stops teams doing legitimate work and pushes them into worse patterns. The strong answer separates *where the decision comes from* from *where the code lives*, and makes the absence of a decision the loudest possible outcome.

  • A team insists on keeping the rule in their repo so they can run it before pushing. How do you square that?
    Give them the copy — you want a fast local loop, and denying it just moves the failure to a slower place. Make clear that the vendored copy produces feedback, not a verdict: the enforcer resolves its own copy and reports which version decided. When the two disagree, the developer sees "you ran an older rule" rather than an argument about who is right.
  • Your enforcer is unreachable during an incident. Should the gate fail closed or open?
    Closed by default: an unreachable enforcer is not an approval, and a gate that fails open converts itself into a suggestion at exactly the moment things are going wrong. What you owe in exchange is uptime proportionate to being on the merge path, an unambiguous signal that the block is your outage rather than their code, and an escape path that leaves a record instead of a shrug.
  • How would you verify, on a live repository, that your gate really is unskippable?
    Test it as an attacker would, in a throwaway pull request: delete the job, rename it, narrow its trigger so it no longer matches, and lower any threshold the check reads. Each of those should leave the pull request unmergeable. If any of the four goes green, you have found the hole, and doing this once per quarter is cheaper than discovering it from a change that already merged.

saying these in an interview costs you the question

  • Thinks marking a check required is sufficient on its own
  • Proposes simply forbidding teams from editing pipelines
  • Leaves the authoritative rule inside the gated repository
  • Lets an unreachable enforcer count as approval
  • Ignores that a skipped result may satisfy a requirement
  • Provides no local way to reproduce the decision

context