The evolution gap

The missing framework for how systems actually change.

We’ve mastered CI/CD, GitOps, Infrastructure-as-Code, and deployment automation.
But there is still one part of modern systems that engineering treats like it’s 2005:

The external systems your application relies on — and how they evolve over time. 1 evolution gap

These systems fall into three broad categories:

1. External state surfaces

Databases, collections, indexes, constraints, TTLs.

2. Messaging & orchestration surfaces

Queues, topics, streams, schema registries.

3. Platform & policy surfaces

Buckets, storage rules, IAM roles, permissions, feature/config toggles.

2 ext systems categories

All of them evolve.
Your application evolves.
But their evolution is almost never kept in sync.

And that misalignment has a name: the Evolution Gap — the silent distance between what your applications expect and what your systems actually contain.

The real problem: undisciplined system evolution

Most companies manage external system changes through ad-hoc, manual, and informal processes:

  • “Run this script before deploying.”
  • “Update this schema; I already applied it in prod.”
  • “Create this topic in staging, I’ll do prod later.”
  • “Toggle this config once the new version is live.”
  • “Don’t forget to add this permission.”

It works — until it doesn’t.

And when it fails, it rarely fails loudly.
It fails silently.

A 20-second example

A new service version changes a Kafka event schema (Schema Registry):
adds customerTier (BASIC/VIP). Downstream routing depends on it.

It works perfectly in dev.
It works in staging (schema registered; consumers updated).
It even works in prod-blue during deployment testing.

But in prod-green, the schema update (and the config it depends on) never happened.

3 silent failure

Symptoms:

  • No crashes
  • No alerts
  • Consumers read the missing field as the default (BASIC)
  • VIP traffic is silently routed down the wrong path
  • Environments diverge across prod-blue and prod-green

Three days later someone asks:

“Why are VIP customers getting BASIC treatment in half of prod?”

Observability doesn’t help — there is no explicit failure.
Schema compatibility can prevent some breakages — but it doesn’t orchestrate evolution across environments.

This wasn’t an operational failure. It was a silent evolution failure.

How drift happens

External system changes are rarely:

  • versioned or auditable
  • idempotent or reversible
  • aligned with application versions
  • repeatable across environments

Instead, they live as scattered, invisible instructions:

  • “Run this before merging.”
  • “Apply this after deploying.”
  • “Don’t forget to update the topic.”
  • “Someone already changed that in prod.”

The result is drift
a mismatch between what the code expects
and what the real system contains.

Drift is the operational fingerprint of the Evolution Gap.

Drift produces three predictable classes of failures:

4 drift cascade

1. Behavioral inconsistency

Nondeterministic behavior, intermittent failures, fallback paths triggering unexpectedly.

2. State corruption & divergence

Half-applied changes, mismatched schemas, broken rollbacks, multi-environment divergence.

3. Operational & compliance risk

IAM inconsistencies, untracked changes, unverifiable audit trails.

The larger the organization, the faster drift compounds.

Why this matters now

Over the last decade, architecture has changed faster than our practices for evolving the systems behind it.

Modern applications now depend on:

  • dozens of managed cloud services,
  • multiple independent data stores,
  • continuously evolving policies and permissions,
  • fragmented execution environments across dev, staging, and prod.

Each dependency introduces an evolution vector.
Each evolution vector introduces drift.
And drift compounds.

We version everything around the system — code, infrastructure, pipelines, artifacts —
but we still do not version the evolution of the systems themselves.

This asymmetry is no longer sustainable.

As architectures become more distributed and more service-oriented,
the number of cross-system changes grows faster than any team can manage manually.

System evolution has been the last unmanaged part of software delivery.
Its impact is finally too significant to ignore.

A needed discipline: Change-as-Code

Change-as-Code is the idea that every external system evolution should be:

  • defined as code
  • versioned in Git
  • executed automatically
  • fully auditable
  • deterministic and idempotent
  • aligned with the application version that requires it

No manual steps.
No tribal knowledge.
No invisible side effects.
No drift.

Just controlled, observable, deterministic evolution.

Change-as-Code is not a tool.
It’s a discipline — the missing counterpart to Infrastructure-as-Code.

5 CaC principles

Where Flamingock fits

There is a growing recognition that system evolution must become a first-class discipline,
not an informal collection of scripts, dashboards, and tribal processes.

Existing approaches fall short for structural reasons:

  • CI/CD automates deployments, not evolution.
  • IaC tools manage static infrastructure resources, but lack the granular sequencing required for application evolution.
  • Manual operations lack determinism, auditability, and synchronization with application versions.
  • Schema or resource-specific tooling exists — but only for isolated domains, not the full landscape of external systems.

A new class of tools is emerging around the principles described here:
tools designed to ensure applications and their external systems evolve in lockstep — safely, predictably, and observably.

Flamingock is one such tool, built around Change-as-Code —
but the point of this article is the discipline, not the implementation.

This series focuses on the underlying concepts:
the patterns, failure modes, and mental models required to evolve complex systems without drift, surprises, or hidden state.

Final thought

Modern failures aren’t caused by speed —
but by unsynchronized evolution.

⭐ Support the Change-as-Code movement

We are building Flamingock, an open-source implementation of the principles explored in this series.
If this resonates, consider supporting the project with a ⭐ on GitHub