Send this to both teams and have them fill in their own column without seeing the other. That separation is the method, not a formality: asking the two sides together produces agreement, which is what you already have. A blank is a legitimate answer and it is worth as much as a filled one, because it names something nobody owns.
| Property | Side A says | Side B says | Remove |
|---|---|---|---|
| Property | Side A | Side B | Status | Severity | What a mismatch produces |
|---|---|---|---|---|---|
| Units for every numeric field | bar | tenths of a bar | disagree | S5 | A plausible number that is wrong by a factor. No error, ever. |
| Byte or word order for multi-byte values | big endian | little endian | disagree | S5 | A plausible number rather than an exception, which is worse. |
| Who owns the agreement itself | the platform team | the automation team | disagree | S5 | Nobody. Both sides defend, neither improves, investigations stop here. |
| Who retries, how often, how far apart | 3 times, 1 s apart | we do not retry, the caller does | disagree | S4 | Duplicate work under load, and only under load. |
| Behaviour when the other side is absent | return the last value | raise | disagree | S4 | A default consumed as a reading, silently. |
| Which fields are optional | all required | not answered | unanswered | S5 | One side omits, the other reads a default and proceeds confidently. |
| Behaviour on partial success | not answered | not answered | unanswered | S5 | The action happened, the acknowledgement did not, and the retry repeats it. |
| Ordering guarantee | not answered | not answered | unanswered | S4 | Works until volume, then reorders and corrupts derived state. |
| Behaviour when the other side is slow | not answered | not answered | unanswered | S3 | Backpressure that propagates the wrong way. |
The thirteen properties, ordered by how they fail
What crosses a boundary, ranked not by importance but by silence. The rows at the top return a well-formed wrong answer and survive to production; the rows at the bottom throw on the first message and are found the same afternoon. Most documentation covers the bottom of this list and almost none of the top.
| Property | Severity | What a mismatch produces |
|---|---|---|
| Units for every numeric field | S5 | A plausible number wrong by a factor. No error, ever. |
| Byte or word order | S5 | A plausible number rather than an exception, which is worse. |
| Which fields are optional | S5 | One side omits, the other reads a default and proceeds. |
| Behaviour on partial success | S5 | The action happened, the acknowledgement did not, the retry repeats it. |
| Who owns the agreement | S5 | Nobody. Both sides defend, neither improves. |
| Timeout on each side | S4 | An outer timeout below the inner budget: retries never complete. |
| Who retries, how often | S4 | Duplicate work under load, and only under load. |
| Behaviour when the other side is absent | S4 | A default consumed as a reading, silently. |
| Ordering guarantee | S4 | Works until volume, then corrupts derived state. |
| Ranges and out-of-range handling | S3 | Clipping or wraparound at edges nobody tested. |
| Encoding, precision, dtype | S3 | Throws on the first message. Found in a day. |
| Behaviour when the other side is slow | S3 | Backpressure propagating the wrong way. |
| Fields exchanged | S2 | Found immediately, because nothing parses. |
Severity five means the mismatch produces a plausible value and no error. Severity two means nothing parses and somebody fixes it before lunch. Interface documentation is usually written in the opposite order to this table.
A worked example
A boundary between a platform team and an automation team on a floor system, filled in separately by each. The calculator opens with this example loaded, so the numbers below are the ones on the page.
Nine of thirteen properties came back answered by both sides. Four agree exactly, which includes the field list, the ranges and the encoding, and those are the rows that appear in the interface document. Five disagree, and all five are on rows that fail silently: units, byte order, ownership, retry responsibility, and behaviour when the other side is absent.
The units row alone is the whole integration. One side says bar, the other says tenths of a bar. Neither is wrong within their own scope, nothing raises, and every reading is off by a factor of ten in a way that looks like a badly calibrated sensor. Add the byte order disagreement on top and the numbers stop being interpretable at all, still without a single exception.
The row worth acting on first is not technical. Asked who owns the agreement, one side said the platform team and the other said the automation team, which means nobody does. That is why the other four disagreements have survived: each side has been correct within its own boundary the entire time, and no party had the standing to reconcile them.
Four rows came back blank from at least one side, including partial-success behaviour and ordering. Those are not agreement. Nobody has decided, so the behaviour will be whatever each implementation happened to do, which is the same position as a disagreement with the added disadvantage that nobody knows it exists.
How it is scored
Comparison is loose on purpose: case, spacing and trailing punctuation are normalised away, because two people writing the same answer will not write it identically. A row counts as answered only when both sides filled it, and a blank from either side is reported as unanswered rather than as agreement.
Severity is fixed per property and reflects how the mismatch fails rather than how consequential the field is. Disagreements are ordered by severity, then unanswered rows follow in the same order, because an unanswered severity-five row deserves attention before an answered severity-two one.
A loose string comparison cannot tell a real agreement from two people writing the same wrong thing, and it will flag a disagreement when both sides mean the same thing in different words. Read the diff rather than the count. The tool is a structured way to run the conversation, not a verdict, and its actual output is the fifteen minutes each team spends discovering what they assumed.
The five signs a failure lives in a seam are in signs the failure is in the seams, and the boundary this most often sits on in PLC to model. To count the boundaries first, use the seam counter.
Questions
Because asking the two sides together produces agreement, and agreement is what you already have. The integration is failing precisely because both parties believe they understand the boundary and their beliefs differ. Filling it in apart is the only way to surface that, and it takes each team about fifteen minutes.
Units, ranges, which fields are optional, encoding and precision, ordering guarantees, the timeout on each side, who retries and how often, what happens on partial success, what happens when the other side is slow or absent, and who owns the agreement. The field list is the part everybody documents and close to the least likely to cause a production failure.
Because of how they fail rather than how wrong they are. A units disagreement produces a plausible number with no error and survives to production. An encoding disagreement throws on the first message and is found in an afternoon. The loud failures are cheap; the ones that return a well-formed wrong answer are the expensive ones, so severity is ordered by silence.
No, it is an unanswered question, and on a high-severity row it is nearly as bad as a disagreement. Nobody has decided, which means the behaviour will be whatever each implementation happened to do, and that is indistinguishable from the two sides having decided differently.
That is usually the finding, and it outranks every technical row. A boundary with nobody accountable for the agreement is defended from both directions and improved by neither, which is why both investigations end politely at the line with two correct partial answers. It is also the cheapest thing on the list to fix.