“The limits of my language mean the limits of my world.”
— Ludwig Wittgenstein
I’m deep in the architecture of a new iteration of an AI agent right now, and I keep running into the same thing: the design takes a different shape depending on what I name its parts.
Not the documentation, the architecture itself: which components exist at all, where the boundaries between them fall, which one owns a piece of state and which only gets to read it. I rename something, and a few decisions later the whole design has quietly rearranged itself around the new word.
“There are only two hard things in Computer Science: cache invalidation and naming things.”
— Phil Karlton
Everyone has heard the quote, but why, why is naming hard?
It’s hard because the name isn’t the coat of paint you apply once the work is done. The name is the design. Naming is where the thinking happens.
When you try to give a component a precise name, the ambiguity you’ve been comfortably carrying has nowhere left to hide. Here’s one I hit this week: is this thing an escalation or a handover? It turns out, the naming here matters. An escalation means the agent keeps ownership and pulls in help: there’s a queue, there’s urgency, someone owes an answer. A handover means the agent transfers ownership and stands down. Different states, different failure modes, different promises to the customer. My fuzzy design could have been either, which means it was neither, which means it wasn’t a design yet. The name forced the decision.
The cost of skipping this compounds, because every decision you make after a naming decision inherits the name as a constraint. Call something a Queue and six weeks later someone adds retry logic to it, because that’s what you do with queues. But the thing was really a ledger, and now every retry writes the same entry twice. You don’t pay for a vague name once. You pay interest on it every time a later decision builds on a foundation that was never solid.
None of this is new. Domain-driven design has said for twenty years that the fight to name things in the domain’s own language is the modeling itself. Peter Naur said the deeper version in 1985:
“Programming properly should be regarded as an activity by which the programmers form or achieve a certain kind of insight, a theory, of the matters at hand.”
Names are the language the theory is written in. But notice that in this whole tradition, a name only ever acts on people. It sharpens the designer, it aligns the team, and the system improves downstream of the humans improving.
LLMs amplify this, by a lot.
If you design systems with a coding agent, you already feel it. Names shaping human understanding is a slow, forgiving process. What the model does with your names is neither slow nor forgiving.
When I hand a design to a coding agent, it reads my names as the spec. Not a hint toward the spec. The spec. To a model trained on millions of codebases, a name is a retrieval key: it points at every system that ever used that word.
A colleague who gets a vague name will either ask you about it or pick an interpretation and move on. Either way the gap is still there, and sooner or later someone will pay for it. An agent just takes what your word usually means across every codebase it has seen, builds that, and hands it back in seconds. The code compiles, the tests pass, it looks like progress, and three turns later you’re both building on a decision nobody made.
A bad name with a human costs you time now and compromised decisions later, as the name hardens into a constraint on everything built after it. A bad name with an agent costs you direction.
This is measurable now. A recent study from June 2026 ran 46,535 controlled code-generation experiments across 19 cue types, variable naming among them:
“Incidental prompt cues, meaning contextual words or metadata outside the task specification, can steer which algorithm the model selects, even when all outputs pass the same tests.”
They observed swings of up to 100 percentage points in which algorithm family got built. Even cues designed as meaningless placebos, team names and project codenames, shifted the distribution by 26 points on average. Your words carry cargo whether you loaded any or not.
The same mechanism works in your favor when the name is right. Name a component Orchestrator and the agent reaches for what real orchestrators are built with: sagas, retries, compensation logic. Name it Gateway and the code stays at the boundary and keeps business logic out. You never wrote any of that down. The word brought it in.
So picking a name is also picking how much you want the model to assume. A standard word (Orchestrator, Ledger) comes loaded with everything the model has seen built under it, most of it what you want, some of it not. An invented word comes loaded with nothing, so you have to spell out every behavior yourself. Both can work. What doesn’t work is the middle: a standard word used to mean something slightly different. The model builds the standard meaning, not yours.
When I can’t find a name that fits, I stop writing and go looking for the decision I haven’t made yet. So far there has always been one. It’s the cheapest warning I get all day, and it fires before the model has built half a feature on top of the ambiguity.
A name is an instruction now. Every name you choose is a bet on which thousand systems you invite into yours.
Choose your ghosts on purpose.

