In the last post, I wrote about a specific issue: Snyk checks not running in GitHub merge queues, and how that breaks security validation at the point of integration.
It’s easy to look at that and think:
“That’s just a tooling gap.”
But it’s not.
It’s a symptom of something deeper.
The problem with “shift left”
We’ve spent years pushing quality earlier in the lifecycle.
run checks in PRs
catch issues before merge
give developers fast feedback
All good things.
But somewhere along the way, “shift left” quietly became:
“If we validated it early, we’ve validated it enough.”
And that’s where it breaks down.
Because systems behave differently in different circumstances:
in isolation (PR)
in combination (merge)
in environment (deploy)
under real conditions (runtime)
GitHub merge queues make this explicit. They require checks to run again on the combined state (merge_group) because the thing you are about to merge is not the same thing you validated in the PR.
The Snyk issue is just one example of that.
The real issue is this:
quality can regress between stages unless you enforce it where it actually matters
Which brings us to the real problem
We don’t have a detection problem.
We have a quality persistence problem.
A team identifies something undesirable:
flaky tests
recurring vulnerabilities
unreliable deployments
missing runbooks
weak alerting
manual rollback steps
People do the right thing. They investigate. They improve. They get the metric moving in the right direction.
For a while, everything looks better.
Then, slowly:
flaky tests creep back in
vulnerabilities reappear
pipelines degrade
incidents repeat
Not because teams don’t care - because nothing made the improvement stick.
Quality persistence is the idea that:
once you’ve improved something, the system helps prevent it from regressing
The key shift: from fixing → preserving
Most teams optimise for:
find → fix → move on
Quality persistence requires:
fix → encode → enforce → persist
What this looks like in practice
1. Turn improvements into constraints
“We reduced flaky tests” ❌
“Build fails if flakiness exceeds X%” ✅
2. Encode quality into pipelines
vulnerabilities → fail the build
test coverage → enforced threshold
deployment safety → gated
Quality becomes part of the delivery mechanism, not a side concern.
3. Close PIR loops properly
Most PIRs end with:
“We should improve X”
Quality persistence asks:
“How do we make it difficult (or impossible) for X to regress?”
⚙️ Examples
Flaky tests
→ detect + fail pipeline if reintroducedSecurity vulnerabilities
→ block merge (including merge queue, not just PR)Manual deployments
→ remove the manual path entirelyIncident learnings
→ convert into automated checks or signals