Data Contracts: Ending the "Someone Changed a Field" Outage
Here's a failure everyone in data engineering recognises. A dashboard breaks. Or worse, it doesn't break — it just starts showing numbers that are subtly wrong. Days later someone traces it to an upstream team who renamed a field, changed a code, or dropped a column in a release nobody outside their team read.
Nobody did anything wrong, exactly. The upstream team owned that system and changed it. They had no idea a pricing model depended on that field, because nobody ever told them.
That's the problem data contracts exist to solve, and it's the reason mature data platforms stay reliable while immature ones lurch from breakage to breakage.
What a data contract is
A data contract is an explicit, versioned agreement between a data producer and its consumers about what will be provided and what guarantees come with it. Concretely:
- Schema — fields, types, nullability
- Semantics — what each field actually means ("policy_status = ACTIVE means bound, in-force, not lapsed")
- Quality guarantees — completeness thresholds, valid ranges, allowed code values
- Delivery guarantees — frequency, freshness, late-arrival behaviour
- Change policy — how breaking changes are announced, and the notice period
- Owner — a named person accountable, not a team mailbox
The critical property: it's machine-checkable. A contract that lives in Confluence is documentation. A contract enforced in the pipeline is a contract.
Why insurance needs this more than most
Insurance data has three characteristics that make undeclared coupling especially dangerous:
Systems are old and shared. The policy admin core feeds everything. A change there ripples into pricing, reserving, reporting, and every model — and nobody has a complete list of consumers.
The numbers are regulated. A silently-wrong figure in a solvency return or a rating decision isn't an inconvenience. And when the regulator asks why, "an upstream team changed a code value and we didn't notice for six weeks" is a governance finding, not an explanation.
The blast radius is invisible. Because ownership is usually undefined (the "who owns the data?" problem), producers genuinely don't know who depends on them. Contracts make the dependency explicit — which is the actual fix.
How to introduce them without a two-year programme
1. Start with your most critical dataset, not all of them. Pick the feed that most decisions depend on — usually policy or claims core extract. One contract, done properly, teaches you more than a framework rollout.
2. Write down what's already true. The first contract shouldn't demand change; it should document the current schema, meanings, and de-facto guarantees. This alone surfaces disagreements — you'll find two teams believe different things about the same field, which is a discovery worth the exercise on its own.
3. Enforce at the boundary. Validate incoming data against the contract at ingestion. Violations should fail loudly and route to the owner. The key discipline: reject bad data rather than silently transforming it. Silent coercion is how a misread column becomes a misstated reserve.
4. Version, and treat breaking changes like an API. Additive changes are fine. Removing or redefining a field is a breaking change requiring a version bump and a notice period. Data producers should think like API owners, because that's what they are.
5. Publish the consumer list. The most valuable side-effect: producers can finally see who depends on them. Most upstream breakage is caused by people who genuinely didn't know.
6. Wire it to quality scores and lineage. Contracts define the promise, quality scores measure whether it's kept, lineage shows where the data went. Together they're an actual data platform; separately they're three projects.
The honest constraint
Data contracts are a social mechanism with a technical implementation. The schema validation is straightforward; getting an upstream team to accept accountability for a contract is the hard part — especially when they're measured on delivering their own system's features, not on downstream stability.
This is where it connects to data ownership. A contract needs a named owner with a mandate. If nobody owns the data, nobody can sign the contract, and you're back to hoping people read release notes.
So the sequencing is: establish ownership, then contracts become possible. Try it in the other order and you'll produce beautiful YAML that nobody feels bound by.
The point
Every organisation with a data platform has a recurring category of incident: something upstream changed and something downstream broke, quietly. Teams treat each instance as bad luck and add another monitoring rule.
It isn't bad luck. It's an undeclared dependency, and the fix is to declare it — explicitly, versioned, machine-checked, with a name attached.
Boring, unglamorous, and the difference between a data platform people trust and one they work around.
We build governed pipelines with contracts, quality gates, and lineage wired in from the start. More at IntelliBooks.
Comments
Post a Comment