Pattern · seen in 1 breakdown across 1 company

Violation Ratchet

Definition

When establishing a new architectural invariant across a large, actively evolving codebase — no cross-database joins, no cross-store transactions, no direct use of a deprecated base class — a one-time cleanup loses to the codebase's own velocity: uninvolved engineers introduce new violations faster than a dedicated team removes old ones. The ratchet converts the chase into a monotonic burn-down. First, build detection for the invariant: static analysis, runtime analyzers that raise on violation, and sampled production telemetry that confirms real traffic obeys (and exposes code paths tests never execute). Second, enumerate every existing violation into an explicit allowlist. Third, fail the build on any violation not in the allowlist — new offenses become impossible to merge — while the allowlist itself only ever shrinks as items are fixed and removed.

The mechanism's virtues are social as much as technical: the allowlist is a visible, finite work queue that teams can own in slices; progress is legible to leadership; and the invariant's enforcement doesn't depend on every engineer knowing the migration exists — the pipeline knows. The costs: detection must be trustworthy at merge time (false positives train people to bypass the gate), production sampling adds telemetry expense (GitLab parsed 1 in 10,000 queries), and the ratchet only defends invariants you can detect mechanically — judgment-shaped rules can't ride it. This is an engineering-process pattern enforced through CI rather than a runtime mechanism; it earns its place in a systems library because large-scale architectural transitions fail without it.

When it applies

01A multi-quarter architectural transition (decomposition, deprecation, boundary enforcement) proceeds while the codebase evolves under engineers not involved in the transition
02The invariant is mechanically detectable — by static analysis, runtime assertion in test/dev, or query/telemetry inspection
03Progress visibility matters: the transition spans many owning teams who need a finite, attributable list rather than a moving target

Tradeoffs

Detection quality is load-bearing: false positives at merge time erode trust in the gate and breed workarounds that outlive the migration
The allowlist can fossilize — without deadlines or ownership per entry, the ratchet holds the line but the burn-down stalls at a permanent plateau
Only mechanically detectable invariants qualify; rules requiring judgment must be enforced by review culture, which the ratchet can't replace

The same move, 1 ways

Every row is a production system that bet on this pattern — the note says how, in that system's own terms.

GitLab
GitLab Blog (Engineering)
2022
GitLab borrowed this from how it rolls out new code-style rules. First, add automatic checks that catch the problem you are stamping out; here, any query or transaction that touches both databases. Next, record every case that already exists as a known exception. Then make any new case fail the build, so the count can only go down, never up. That one-way behavior is what GitLab named a ratchet. Read the breakdown →

Problems this pattern answers

The walls where its breakdowns live — each opens the cross-company comparison.