Published on

The ambiguity of communication

Authors

"But I told you"

Imagine two senior software engineers, Sarah and Sam, sitting in a call.

Both have been in the industry for years.

Both know their craft.

Sarah has been at the company for years - she knows every corner of the system, every decision, every failed experiment that led to where things are today.

Sam has just joined. Experienced engineer, but new to this particular system.

Sarah is doing the onboarding.

The topic is complex - an event-driven, distributed architecture with multiple bounded contexts and asynchronous message flows.

Discussion
Sarah, the Senior Engineer: Ok, so here's the deal. We have three main BCs - BDG, KLP and the Fulfillment core. Each is a separate deployable, communicating via EDA. We use Kafka as the broker and we follow CE spec for all events on the wire.
Sam, the Senior Engineer: Ok.
Sarah, the Senior Engineer: The tricky part is the WORF layer. We do CQRS inside each BC - so Commands go in, Events come out, read side is eventually consistent. We had idempotency issues before so now every handler in BDG has an outbox and a deduplication table. Consumer groups are partitioned by WORF root id so ordering is preserved inside a single stream.
Sam, the Senior Engineer: Right, right.
Sarah, the Senior Engineer: The MTR Saga orchestrates across all three - it listens on BDGSettled, does a compensating transaction if KLPRejected arrives before the SLA window closes. We track state in the saga store, which is basically a WORF projection. The whole thing is idempotent because we slap ETags on entity level and use optimistic concurrency on every write against the FLX schema.
Sam, the Senior Engineer: Sounds solid.
Sarah, the Senior Engineer: One more thing - the BFF in front of KLP does token exchange via the GXR provider, so don't go calling KLP directly from the UI. Route it through the AGW, it handles the RBAC policies and rate limiting for us.
Sam, the Senior Engineer: Got it.
Sarah, the Senior Engineer: Good. Any questions?
Sam, the Senior Engineer: No, I think I got it.
Sarah, the Senior Engineer: Great. Did you get it?
Sam, the Senior Engineer: Yeah, yeah.

How do you think, dear Reader, did Sam get it?

He didn't even know what question to ask.

A few days later, Sam sat down alone to implement his first change.

No one around.

Just him, the codebase, and a mental model assembled from thirty minutes of acronyms.

He touched the wrong layer entirely.

When Sarah found out, she said: "But I told you - BDG doesn't own that, it goes through the MTR Saga."

She was right.

She did tell him.

Alone, isolated from the heads that held the real context, Sam had only the words - not the understanding behind them.

Sarah had no idea.

She was too fluent in the language of the system to notice that each sentence she spoke was an acronym stacked on an assumption, with no shared ground beneath.

Because she was only at the Telling level.

"Does it make sense so far?"

A week later, Sarah noticed something after hearing back from a colleague that Sam had been asking very basic questions in team chat for days.

Questions that the onboarding was supposed to answer.

So she tried something slightly different.

Discussion
Sarah, the Senior Engineer: Do you know what the system does?
Sam, the Senior Engineer: Not really, I only had a brief look at the docs before joining.
Sarah, the Senior Engineer: Ok, let me start with the high level. We have three main areas - Payments, Orders, and Fulfillment. Each of them is a separate service. Does that make sense so far?
Sam, the Senior Engineer: Yes, three separate services. Got it.
Sarah, the Senior Engineer: They talk to each other using events, through a message broker - Kafka. So instead of direct HTTP calls, they publish and consume events. Following so far?
Sam, the Senior Engineer: Yes, I know Kafka. Events instead of direct calls.
Sarah, the Senior Engineer: Good. Inside each service we do CQRS - does that ring a bell?
Sam, the Senior Engineer: Command Query Responsibility Segregation, yes - separate models for reading and writing.
Sarah, the Senior Engineer: Exactly. And on top of that, to coordinate across all three services - we have a Saga. It's the thing that knows the overall flow and handles failures. Make sense?
Sam, the Senior Engineer: I think so. The Saga is like a coordinator?
Sarah, the Senior Engineer: Yes, exactly - we can think of it as an integrator of various contexts. And it listens on specific events and reacts. If something fails, it can trigger compensating actions to undo what was already done. Clear?
Sam, the Senior Engineer: Ok, I think I follow. But I am not entirely sure about the "compensating actions" part. What does that look like in practice?
Sarah, the Senior Engineer: Good question. So imagine payment succeeded but fulfillment failed - we need to refund. The saga listens for FulfillmentFailed, then issues a RefundPayment command. Does that help?
Sam, the Senior Engineer: Yes! That makes sense now. So the saga basically reacts to what goes wrong.

This time, Sam walked away with something real.

Not everything, but enough to ask the right questions.

Sarah was now at the Explaining level - checking if the signal was getting through, adjusting based on what came back.

Still, there was something missing.

She was the one drawing the picture.

Sam was receiving it.

"Can you tell me what you understood?"

Another session.

This time Sarah decided to approach it differently.

She opened a shared canvas - a blank excalidraw board - and put it in front of both of them.

Discussion
Sarah, the Senior Engineer: Ok, I want to try something today. I'll explain the system, but instead of me doing all the talking, I want you to draw what you hear. Does that work?
Sam, the Senior Engineer: Sure, though I might get things wrong.
Sarah, the Senior Engineer: That's exactly the point. We start with three services. I'll give you names, you draw boxes.
Sam, the Senior Engineer: (draws three boxes, labels them: Payments, Orders, Fulfillment)
Sarah, the Senior Engineer: Good. Now - they don't call each other directly. They publish events to a broker, and other services consume from it. How would you draw that?
Sam, the Senior Engineer: (draws a central box labeled "Kafka", arrows going from each service into it, and arrows going back out) Like this?
Sarah, the Senior Engineer: Almost. The arrows going in represent publishing. What do the ones going out represent?
Sam, the Senior Engineer: Consuming... but then which services consume from which? I don't know that yet.
Sarah, the Senior Engineer: Exactly - that's the interesting part. Let me tell you about the main flow, and you draw what you understand. Payments publishes PaymentInitiated. Fulfillment listens. If it succeeds, it publishes FulfillmentConfirmed. If not, FulfillmentFailed.
Sam, the Senior Engineer: (draws and narrates) So Payments puts this event into Kafka... Fulfillment picks it up... and then publishes one of two outcomes. (pauses) But who reacts to FulfillmentFailed?
Sarah, the Senior Engineer: That's the Saga. Where would you put that on the board?
Sam, the Senior Engineer: (draws another box, labeled "Saga") Is it another service?
Sarah, the Senior Engineer: Yes. And based on what you know now - what do you think the Saga does when it sees FulfillmentFailed?
Sam, the Senior Engineer: It needs to undo the payment somehow. So maybe it publishes a command back to Payments? Like RefundPayment?
Sarah, the Senior Engineer: Exactly. Now look at your drawing. What does it tell you?
Sam, the Senior Engineer: (stares at the board) That the Saga is... the only thing that sees the whole picture. The other services don't know about each other.
Sarah, the Senior Engineer: Yes. That's exactly why it exists.
Sam, the Senior Engineer: Ok, let me try to use my own words to check if I got it right, according to your understanding. We have three services - Payments, Fulfillment, and the Saga. They don't call each other. Instead, they publish events to Kafka and consume from it. Payments starts the flow by publishing PaymentInitiated. Fulfillment picks it up and either confirms or reports failure. The Saga listens to those outcomes and is the only one that knows the whole story - so if something fails, it's the Saga that decides what to undo and how. Is that roughly it?
Sarah, the Senior Engineer: That's exactly it. And now you also know why we don't call services directly.
Sam, the Senior Engineer: Because if they called each other, they'd each need to know what the other does. And then you'd have no Saga - you'd have chaos.
Sarah, the Senior Engineer: (smiles) Now you got it.

Sam drew it.

Sam discovered it.

Sarah guided him there, but the understanding belonged to Sam now.

Because they were collaborating on the Aligning level.

What is TEA?

Three conversations.

Same topic.

Very different outcomes.

What distinguished them was not the information - it was the direction of the communication and who was responsible for creating the conditions for growing the understanding.

Let's bring some definitions, because they might be useful.

Telling - a definition

One-way conveyance of information. The sender speaks, the receiver listens. Feedback is not actively sought nor incorporated. Understanding is assumed, not verified.

 

Explaining - a definition

Two-way conveyance of information. The sender speaks and actively probes - "does this make sense?", "are you following?". Feedback is collected and used to adjust the message. Understanding is checked but still sender-driven.

 

Aligning - a definition

Collaborative construction of shared understanding. The sender invites the receiver to articulate, draw, rephrase - to externalize their internal model. Gaps and mismatches are surfaced and resolved together. Understanding is co-created.

Together, they form TEA - Telling, Explaining, Aligning.

Three levels of communication intensity when it comes to conveying abstract ideas and collaborating with others.

Not a ladder to climb once and stay at the top.

A range to move through, consciously, depending on what the situation demands.

Why does it matter?

"Communication always fails, except by accident" - as Wiio's laws remind us.

And as we explored in Keep it visible, smartass - words are volatile, invisible by nature.

Spoken words are impermanent.

They dissipate.

The mental model built in the sender's head and the one assembled in the receiver's head might share a few words, but diverge significantly in meaning.

And neither side knows it.

Because it is invisible.

Conclusion 🔍

Communication always fails, except by accident

The first conversation between Sarah and Sam - pure Telling - is the most common mode of illusionary knowledge transfer in software teams.

Architecture reviews, onboarding sessions, design discussions, incident post-mortems.

Someone talks.

Others nod.

And everyone leaves with a slightly different map of the same territory.

Then the codebase pays for it.

Telling is not wrong

Let's be fair to Telling.

It has its place.

When context is genuinely shared, when the audience is already aligned, when speed is the constraint - Telling is appropriate and efficient.

But how do you know, dear Reader, that we can stay at the Telling level?

A standup update is Telling.

A well-written ADR is Telling.

Briefing a team that already lived through the same decisions is Telling.

The problem is not Telling itself.

The problem is defaulting to the Telling level when the Explaining or Aligning level is needed - because it feels easier - which might seem faster - or because we assume shared context that isn't there.

Conclusion 🔍

Telling is not wrong. Misapplied Telling is wrong.

The hidden cost of assumed understanding

Notice what Sam said in the first conversation.

"Yeah, yeah."

Not because he understood.

Because he didn't know what he didn't know.

This is Dunning-Kruger applied to receiving information - you cannot ask about the gaps you cannot see.

And Sarah filled the silence with confidence.

Silence is not agreement.

Silence is not understanding.

Silence is what happens when someone doesn't have the vocabulary to ask.

Provide the context.

Provide the vocabulary.

Provide abstract ideas supported by examples.

Visualize the language - put it on the board, write down the words as they appear, draw the boxes as the concepts emerge.

When Sam sees "BDG" and "MTR Saga" written down next to each other with an arrow between them, he has something to point at.

He can say "what is this arrow and what does it mean?" instead of not knowing what he doesn't know.

The board doesn't just capture ideas - it creates the vocabulary that makes questions possible.

The first conversation produced an illusion of alignment.

Both parties left feeling good about it.

The team chat told the truth a week later.

Explaining is not enough either

The second conversation was better.

Sarah asked "does it make sense?" and waited.

Sam even pushed back on the compensating transaction part.

Real signal came through.

But notice who held the pen.

Sarah owned the mental model and was handing pieces of it to Sam.

Sam was receiving, validating, acknowledging.

His understanding was still a pale copy of hers - not a structure he built.

When he would sit down to implement something a week later, he would be working from a received model.

Received models are fragile.

They don't survive contact with new information well.

And they are easy to misremember.

Aligning is the investment

The third conversation was slower.

It required a shared canvas.

It required Sarah to give up control and let Sam drive the drawing.

It required Sam to be wrong in front of her and not feel bad about it.

But something happened at the end of that conversation that didn't happen in the previous two.

Sam made an inference on his own.

"The Saga is the only thing that sees the whole picture. The other services don't know about each other."

Sarah didn't say that.

Sam derived it.

That's the difference.

When someone can derive the conclusion from the structure they built themselves, the understanding is theirs.

It can be extended.

It can survive contact with new information.

It can be taught to the next person.

Conclusion 🔍

Understanding you built yourself is yours. Understanding you received belongs to someone else.

From invisible to visible

All three levels of TEA benefit from making things visible - but the Aligning level depends on it.

You cannot align on an invisible mental model.

The canvas in the third conversation was not a nice-to-have.

It was the mechanism through which alignment became possible.

Sam's drawing was wrong in places.

That was the point.

The assumptions became visible.

It could be corrected.

As Alberto Brandolini wisely noted - don't talk about invisible things.

And as we know from Keep it visible, smartass - making things visible is what surfaces assumptions, gaps and misunderstandings that would otherwise remain hidden forever.

In Telling, nothing is visible.

In Explaining, the sender's model is visible.

In Aligning, the receiver's model becomes visible - and that's where the real work happens.

Which mode to use?

This is not about always doing full Aligning level sessions.

That would be exhausting and inefficient.

TEA is a spectrum, not a prescription.

The question to ask is: "what is the cost of misalignment here?"

If Sam misunderstands a team social event - low cost, Telling level is fine.

If Sam misunderstands why boundaries are organized in a certain way, or what event-driven thinking really means for how things are structured - the cost is high, and it grows with time. Every decision made on top of a misunderstood foundation adds another layer of drift. Weeks later, no single change is cheap anymore.

The less shared context there is, the more abstract the topic, the higher the stakes - the further along the TEA spectrum the investment should go.

"We only have 30 minutes" is often said precisely in the situations where the Aligning level matters most.

And 30 days of work can save 30 minutes of Aligning.

Starting small

You don't need to organize a full collaborative modeling session to practice Aligning.

It starts with a single sentence.

Instead of "did you get it?" - try "can you tell me what you understood?".

Instead of "does this make sense?" - try "can you draw what you heard?".

Instead of assuming the nod means understanding - treat it as a signal to probe further.

We are two boxes and an arrow away from surfacing the first gap.

And the gaps are always there.

In every technical discussion.

In every design session.

In every architecture review.

Invisible, until someone makes them visible.

So next time, dear Reader, when you are about to present something important to a colleague, pause before the closing "any questions?", and try this instead:

Conclusion 🔍

Can you tell me what you understood so far - in your own words?

Then listen.

Not for agreement.

For their model.

Question 🤔

Which level of TEA are you defaulting to?

And what is the cost of that default?

How to change the levels?