Ground Truth

The Seam Is Nobody's Job: Why Failures Live Between Systems That Each Work Correctly

Mostafa DhouibMostafa Dhouib·7 min read
The short answer

Three systems, each owned, each correct by its own contract, each reporting success. The failure lives in the relationship between two of them, and relationships are not assigned to anyone. That is why these defects survive code review, pass every component test, and are found by a customer rather than by a team.

The Seam Is Nobody's Job: Why Failures Live Between Systems That Each Work Correctly

The short answer. Take any failure that was expensive and hard to find, and there is a good chance every component involved behaved correctly. The site collected the intent. The processor moved the money. The records are consistent with everything they were told. Nothing errored, nothing alerted, and the money is gone. The defect lives in the relationship between two components rather than inside either, and relationships do not appear on an org chart, in a repository, or in a test suite. Components have owners. Seams do not, which is precisely why the hardest failures concentrate there and why finding them is a different activity from debugging.

There is a pattern behind a surprising share of expensive incidents, and it is not a technical pattern. It is an ownership one.

Every component has somebody responsible for it. Somebody owns the front end, somebody owns the service, somebody owns the integration with the processor, and the processor owns itself. Each of them can demonstrate, convincingly and correctly, that their part did what it was supposed to do.

And the system as a whole did something wrong.

What a seam actually is

A seam is an assumption held on both sides of a boundary that nobody wrote down and nobody verified matches.

Each side has a mental model of the other. The front end believes a successful response means the work is done. The service believes the caller will retry on failure. The processor believes you will listen to its notifications rather than trusting the redirect. Nobody is wrong about their own component. They are wrong about the other one, and no component test can detect a mismatch that exists entirely between two correct implementations.

The front end believesa success response means the work is done
The service believesthe caller will retry on failure
The processor believesyou will listen to its notificationsrather than trusting the redirect
No error is raisedboth sides are correct by contractthe system produces a wrong outcome through a sequence of right operations
No owner existseach side owns its halfand the half nobody owns is the one that failed
No test covers itcomponent tests check own expectationswhich are the expectations that are wrong, and the integration tests cover the happy path
The payment succeeds at the processor, the browser never comes back, and the customer has been charged and does not exist as far as your system is concerned. Detecting that requires somebody to compare two systems that each believe they are correct, which is nobody's assigned task.
FigureNobody is wrong about their own component. Each side is wrong about the other one, and no component test can detect a mismatch that exists entirely between two correct implementations. A seam is an assumption held on both sides of a boundary that nobody wrote down and nobody verified matches.

Three properties make seam failures distinctive.

No error. Both sides behave correctly by their own contract, so there is nothing to raise. The system produces a wrong outcome through a sequence of right operations.

No owner. Asked who is responsible for the behaviour of the boundary, the honest answer is nobody. Each side owns its half, and the half nobody owns is the one that failed.

No test. Component tests verify a component against its own expectations. Integration tests usually verify the happy path, because the failure modes at a seam are the ones nobody thought of, and nobody thought of them for the same reason they are not in the code.

The canonical shape

The clearest example is taking a payment on an existing site.

Three systems. Your site, the processor, your records. A customer pays. The payment succeeds at the processor. The browser never comes back, because the tab closed, the connection dropped, or the redirect failed.

Your site did its job. The processor did its job and will say so if asked. Your records are internally consistent. The customer has been charged and does not exist as far as your system is concerned.

Everything works. The money is gone. And the reason it goes undetected is that detecting it requires somebody to compare two systems that each believe they are correct, which is nobody's assigned task.

Four questions that find them

Seams are discoverable by inspection, which is the good news, and they are only discoverable if somebody goes looking.

What does each side assume about the other? Written down, both sides, independently. The value is in the asking separately: conferring produces agreement, which is what you already have and the reason the boundary is failing.

What happens when one side is absent? Not failing, absent. A silent dependency is usually handled worse than a failing one, because a failure raises something and absence produces a default consumed as a reading.

Who hears about it first when this boundary breaks? If the answer is a customer, the boundary has no monitoring. If the answer is a different team, it has no owner.

What is the authoritative source when the two disagree? Most seams have no answer to this. Deciding it is usually the single most useful thing you can do for a boundary, because it turns a dispute into a procedure.

The defences

Name an owner for the boundary. Not for either component, for the relationship. Somebody whose job includes the question of whether the two agree.

Reconcile. A standing comparison between the two sides, with discrepancies surfaced as findings. This converts an invisible problem into a visible one, which is most of the value. A missing payment that appears in a report is a different problem from one that nobody knows about.

Make one side authoritative and say which. The processor knows whether money moved. Your records are a projection that should agree with it, and when they do not, the processor is right.

Design the absent case explicitly. For every input, decide what happens when it does not arrive, and make that decision visible rather than letting a default stand in.

An undefended boundary
Nobody owns the relationship
both components have owners, so the honest answer about the boundary is nobody
No authoritative side
most seams have no answer to which one is right when the two disagree
The absent case falls to a default
a failure raises something and absence produces a default consumed as a reading
A customer hears about it first
which is the test for whether a boundary has monitoring
A defended boundary
A named owner for the relationship
not for either component, for the question of whether the two agree
One side declared authoritative
the processor knows whether money moved, your records are a projection that should agree with it
A standing reconciliation
a missing payment that appears in a report is a different problem from one nobody knows about
The absent case decided explicitly
for every input, what happens when it does not arrive, made visible rather than left to a default
turn a dispute into a procedure
No organisation can actively own every boundary. Rank them by what a failure costs and accept that the low consequence seams will be discovered rather than prevented, which is considerably better than learning which seams you had from what they cost.
FigureSeam failures are not a sign of a badly run team. Organisations are divided into components because components are what can be owned, staffed and tested, so the more cleanly a system is decomposed the more boundaries it has. The remedy is therefore organisational rather than technical.

Why it is structural rather than careless

This is worth being clear about, because the instinct is to look for who should have caught it.

Organisations are divided into components because components are what can be owned, staffed and tested. That division is useful and it creates seams as a by-product. The more cleanly a system is decomposed, the more boundaries it has and the more places there are for mismatched assumptions.

So seam failures are not a sign of a badly run team. They are a predictable consequence of how teams are organised, which means the remedy is also organisational: somebody has to be responsible for the boundaries, because the default is that nobody is.

The honest limit

Reconciliation makes a seam failure visible and often recoverable. It does not prevent one, and it cannot repair the consequences of some of them. A payment that was never completed cannot be turned into a receipt, and a notification that was never delivered and is no longer available to request is gone rather than recoverable.

There is also a limit to how many boundaries any organisation can actively own. The answer is to rank them by what the failure costs and to accept that the low-consequence seams will be discovered rather than prevented. That is a deliberate position, and it is considerably better than discovering which seams you had by finding out what they cost.

FAQ

Why do expensive failures happen when every component is working correctly? Because the defect lives in an assumption each side holds about the other that nobody wrote down or verified. Both implementations are correct by their own contract, so nothing errors, and the system produces a wrong outcome through a sequence of right operations.

Why does nobody own the space between two systems? Because organisations are divided into components, since components are what can be owned, staffed and tested. Relationships between components do not appear on an org chart or in a repository, so the half nobody owns is exactly the half that fails.

Why don't tests catch seam failures? Component tests verify a component against its own expectations, which are the expectations that are wrong. Integration tests usually cover the happy path, because the failure modes at a boundary are the ones nobody thought of, and they went unthought-of for the same reason they are absent from the code.

How do I find the seams in my own system? Ask four questions at each boundary. What does each side assume about the other, written independently rather than together. What happens when one side is absent rather than failing. Who hears about a break first. And which side is authoritative when the two disagree.

What is the single most useful fix for a seam? Deciding which side is authoritative and writing it down, which turns a dispute into a procedure. After that, a standing reconciliation that surfaces discrepancies as findings, since a problem visible in a report is a completely different problem from one nobody knows about.

Can every seam be defended? No organisation can actively own every boundary. Rank them by what a failure costs, defend those, and accept that low-consequence seams will be discovered rather than prevented. That is a deliberate position and it beats finding out which seams you had by learning what they cost.

Free worksheet
The Seam Register

The five signs that a failure is in the seams, then one register per boundary covering units, ranges, timing, retry ownership and partial-success behaviour. Filled in separately by both sides, which is the whole method.

One email, the resource, and nothing else unless you reply.
Carrying a program like this one?

Tell us the system, the stakes, and the date that matters. You get a straight technical reply from the person who would lead the work, within 24 hours.

Bring us the program