Case Study 1: Nineteen Violations
"We asked twice, with a good argument, and were declined twice, reasonably. Then we stopped asking and started counting."
Executive Summary
Kestrel's data team introduced data contracts for three upstream services. Two teams adopted within a quarter. The third — the inventory service — declined, politely and with a legitimate reason: a heavy roadmap and no capacity for "documentation for another team's benefit."
The data team did not escalate. They wrote the contract anyway, marked status: observed, enforced
it at the consumer, and logged every violation for eight months.
Then they brought the log to a conversation: nineteen violations, six of which had caused incidents, and four of which had consumed the inventory team's own time — because each investigation had pulled them in to answer questions.
The inventory team adopted the contract that quarter, and the reason they gave was the fourth point.
This case study is §17.7's social half. It is here because the technical work in this chapter is the easy part, and because the approach that worked is not the one most teams try.
Skills applied: observed contracts (§17.8); consumer-side enforcement (§17.5 point 3); the social failure modes (§17.7); evidence as an argument.
Background
The relationship. The inventory service is owned by a four-person team supporting warehouse
operations. It writes stock levels, reservations, and adjustments, and it is the source for
fct_inventory_snapshot.
Why the data team wanted a contract. In the preceding year, inventory-related changes had caused four data incidents:
| What changed | How it was found | |
|---|---|---|
| Feb | reserved began including in-transit stock |
an analyst noticed inventory looked high |
| May | a new adjustment_type value, cycle_count |
rows fell into an ELSE bucket |
| Aug | on_hand could go negative during a race |
a CHECK constraint failed downstream |
| Nov | updated_at moved from application to trigger |
the extract's watermark behavior changed |
Every one was a good change. The February change was a bug fix. The August negative values were a correct representation of an oversell. The November trigger change was the fix Chapter 13 §13.4's second lie recommends.
The first ask, in January. A well-written proposal: here is what a contract is, here is what we would need, here is why it helps you.
The response, and it deserves to be quoted rather than paraphrased:
"We understand the value and we cannot take this on this quarter. We have two people on the WMS migration and one on call. Writing and maintaining a document that describes our system for another team's benefit is not something we can prioritize, and we would rather say no than say yes and not do it."
That is a good answer. It is honest, it explains the constraint, and it declines cleanly rather than agreeing and defaulting.
The second ask, in March, after the May incident had been anticipated in a design review. Same answer, slightly warmer.
The Problem
The data team's options at this point, and each has an obvious problem:
Escalate. Take it to a shared manager. This wins the argument and loses the relationship, and a contract maintained resentfully is a contract that goes stale (§17.7's first failure mode). It also spends political capital that the data team would need later.
Give up. Accept four incidents a year as the cost of doing business. Tempting, and it means the data team absorbs a cost caused elsewhere, indefinitely.
Build defensively and say nothing. Consumer-side validation, absorb the failures, stop asking. Better than giving up and it leaves the underlying problem in place.
What they did was the third option plus one addition: they wrote it down.
📐 Design Decision — Escalate, absorb, or gather evidence?
The team's reasoning, recorded at the time:
Against escalating: the inventory team's refusal was reasonable and well-argued. Escalating a reasonable refusal converts a peer into an adversary, and the resulting contract would be maintained under duress — which is §17.7's failure mode 1 and produces a stale document that consumers rely on, which is worse than no document.
Against absorbing quietly: it makes the cost invisible. The data team would spend the same effort every year and nobody would know, including their own management.
For gathering evidence, which they chose: it is compatible with both other options — you can still escalate later, with better material — and it converts an argument about principle into an argument about facts. "We would like a contract" is a preference. "Nineteen changes broke us, six caused incidents, four cost you time" is a finding.
What it costs: eight months of absorbing failures they could have escalated to avoid, and the discipline to log something every time rather than only when it hurt. That second cost is the real one — the log is only persuasive if it is complete, and completeness requires recording the boring violations too.
The Analysis — Building the Log
The contract, written from observation:
contract: kestrel.inventory
version: 1.0.0
status: observed # ← NOT agreed. This describes behaviour.
owner:
team: warehouse-systems
note: "No agreement exists. Maintained by data-engineering from observation.
Reviewed with warehouse-systems: never. Last verified 2025-03-14."
semantics:
on_hand: "Units physically present. OBSERVED to go negative during
oversell races -- see violation 2025-08-11."
reserved: "OBSERVED to include in-transit stock since 2025-02. Prior to
that it did not. No announcement."
adjustment_type:
observed_values: [receipt, shipment, damage, shrink, correction,
cycle_count] # cycle_count appeared 2025-05-02
observed_guarantees:
freshness_p99_seconds: 210 # measured 2025-02-01..2025-03-01
volume_per_day: {typical: 141000, min: 118000, max: 172000}
The validation, at the consumer, running on every load:
VIOLATIONS = []
def check_contract(df, contract):
for field, spec in contract["semantics"].items():
if "observed_values" in spec:
unknown = set(df[field].unique()) - set(spec["observed_values"])
if unknown:
record_violation(
kind="unknown_enum_value",
field=field, detail=sorted(unknown),
contract_version=contract["version"])
# ... type checks, required-field checks, volume band, freshness
The violation record, and the fields were chosen with the eventual conversation in mind:
- id: 2025-05-02-001
detected_at: 2025-05-02T06:14:00Z
kind: unknown_enum_value
field: adjustment_type
detail: "new value 'cycle_count'"
our_impact: "412 rows fell into the ELSE branch and were counted as
'correction'. Inventory adjustment reporting wrong for 3 days."
our_cost_hours: 6
their_cost_hours: 2 # ← the field that mattered
incident: true
their_change_was_reasonable: true # ← and so did this one
🔎 Read the Plan — Two fields that made the log persuasive
Most "they broke us" logs are lists of grievances, and they read as such. Two fields turned this one into something a peer team could engage with.
their_cost_hours. Every time the data team investigated, they asked the inventory team questions — did something change on the 2nd? what doescycle_countmean? is negativeon_handintended? Each investigation consumed an hour or two of the producer's time, and the producer had never connected those interruptions to their own changes. From their side it looked like the data team occasionally asked questions.Four of nineteen violations cost the inventory team time. That was the number that moved the conversation, and it would not have existed if the log recorded only the consumer's pain.
their_change_was_reasonable. Markedtrueon seventeen of nineteen. Recording that explicitly did two things: it kept the log honest, and it removed the conversation's defensive shape before it started. The data team could open with "almost every one of these was a good change, and that is the point — good changes broke us because nothing recorded the dependency."A log of the other team's mistakes is an accusation. A log of good changes with unintended costs is a shared problem. The difference is one field.
The Decision — The Conversation
November, eight months after the second refusal. The data team asked for thirty minutes.
What they brought:
| Violations detected | 19 |
| Of which caused a data incident | 6 |
| Of which the change was reasonable | 17 |
| Data-engineering hours | 84 |
| Warehouse-systems hours | 11 |
| Incidents where the answer required asking warehouse-systems | 9 |
What they asked for, and it is deliberately smaller than the January ask:
- Review the observed contract once. Not write one — read the one that exists and correct what is wrong. Estimated: 90 minutes.
- Add the data team to the review of any change touching four named fields. Not approval — visibility.
- Nothing else.
The inventory team agreed to both, in the meeting.
Their stated reason was the 11 hours. From their side, the data team's questions had been occasional interruptions with no pattern. Seeing them grouped by their own changes, with the causal link made explicit, reframed it as a cost they were already paying and could reduce.
The 90-minute review corrected six things in the observed contract, including one the data team
had recorded backwards — reserved had always included in-transit stock, and what changed in
February was a bug fix that made it do so correctly. The observed contract had been wrong for
eight months, which is a fair argument against observed contracts and is also the strongest possible
argument for getting it reviewed.
What Happened
The contract moved to status: agreed in January, a year after the first ask.
In the eighteen months since:
- Violations: 3, all caught in the producer's own review because the data team was in it. None reached production.
- The warehouse-systems team asked for a contract for a different consumer — the WMS integration team — having found the format useful for a problem of their own.
- The four named fields grew to nine, at the producer's suggestion, because they found the review step cheap.
Two honest caveats the team recorded:
It took a year. A faster route existed — escalation — and would have produced a worse outcome, and that is a judgment rather than a certainty. A team under more pressure might reasonably choose differently.
The observed contract was wrong about a material fact for eight months, and the data team's validation had been enforcing a misunderstanding. An observed contract is a hypothesis about the producer's behavior, and hypotheses should be labeled as such. They now review observed contracts quarterly whether or not the producer participates, specifically to catch this.
Lessons
-
A reasonable refusal escalated becomes a resentful contract, which goes stale, which is worse than no contract.
-
Write the contract anyway, marked
observed. It requires nobody's agreement and it is where the evidence accumulates. -
Log every violation, including the boring ones. The log is only persuasive if it is complete.
-
Record the producer's cost, not only yours. Four of nineteen violations cost the producer time, and they had never connected those interruptions to their own changes. That was the number that moved it.
-
Record that their change was reasonable. Seventeen of nineteen. It keeps the log honest and removes the conversation's defensive shape before it starts.
-
Ask for less the second time. Ninety minutes of review and inclusion in a review, rather than "write and maintain a contract."
-
An observed contract is a hypothesis. Kestrel's was materially wrong for eight months. Review it on a schedule whether or not the producer participates.
-
Evidence converts an argument about principle into an argument about facts. "We would like a contract" is a preference; "nineteen changes, six incidents, eleven of your hours" is a finding.
Questions for Discussion
-
The inventory team's refusal is quoted in full because it is a good answer. What makes it good, and what would a bad refusal have looked like? Does the difference change your response?
-
The data team absorbed eight months of failures they could have escalated to avoid. Was that the right call? What would change your answer — the incident severity, the team's size, the manager?
-
their_cost_hourswas the field that moved the conversation. What is the equivalent field in other cross-team frictions you have seen? Is it always "their cost"? -
The observed contract was wrong about
reservedfor eight months and the validation enforced the misunderstanding. Estimate the damage that could have done. What would limit it? -
The second ask was deliberately smaller. Is that a negotiation tactic or genuine scoping? Does the distinction matter?
-
The producer later asked for a contract for a different consumer. What does that suggest about how practices spread between teams, and can it be engineered?
-
This case study's approach took a year. Write the version of the plan for a team that has three months before a compliance deadline forces the issue.