Somewhere there was a moment when the word didn’t exist yet. Someone typed status into a column definition, or tier, or active, needing a name for something that until that second had no name, and picked one that seemed obviously right at the time. That’s the easy part. The word is contained then — it lives in one file, means one thing, and if it turns out to be wrong, changing it costs a migration and an afternoon.

Then the API gets built on top of the table, and the field name goes into the response payload, because giving it a different name in the API than in the schema would be its own small confusion, and confusion is what you’re trying to avoid. Now it’s in two places. The docs describe the field, using the name from the API, because that’s the name a reader can actually go test against. Now it’s in three. Support writes a canned response referencing it, because customers ask about it by the name they see, which is the name in the docs. A dashboard chart gets a label pulled straight from the field. An integration partner’s code has it hardcoded, because they read it off the API and had no reason to invent a synonym.

None of these steps involved a decision to keep the word. Each one just reached for the nearest existing name rather than inventing a new one, which is the locally efficient choice every single time. Reinventing vocabulary at each layer would be its own kind of bad design — you’d want the API to speak in the language of the docs, and the docs to speak in the language of the support macros, precisely so nobody has to hold four translations in their head at once. The alignment is the feature. It’s also exactly what turns a naming choice into a commitment nobody remembers signing.

By the time someone notices the word doesn’t fit — status grew a pending_cancellation value that isn’t really a status, it’s a scheduled transition, and treating it as a status has quietly made the state machine harder to reason about for two years — the word isn’t in one place anymore. It’s in the schema, the API contract with everything that depends on it, the documentation, the support macros, the dashboards someone built without asking, and the sentences customers use when they file a ticket. Renaming the column is still just a migration. Renaming the concept means every one of those surfaces has to change in a coordinated way, or you end up running two words for the same thing indefinitely, which is worse than either word alone.

This is why the fix so rarely happens. Not because anyone disputes that the word is wrong — usually everyone agrees — but because correcting it stopped being a code change somewhere around the third surface and became a coordination problem involving people who don’t report to whoever wants the fix. A support lead doesn’t want to retrain a team on new terminology for a distinction engineering cares about and customers don’t. A partner integration doesn’t want a breaking field rename for a problem that, from their side, doesn’t exist. The word keeps propagating not because it’s still right, but because the propagation itself is the cost of stopping.

The lesson isn’t to freeze names the instant you type them — that’s paralysis, and most first names are fine. It’s to notice the specific moment a name crosses from “internal detail” to “public surface,” because that’s the last cheap moment to fix it. A field that only appears in one service’s internal schema is still just a decision. The same field, the moment it’s echoed in an API response with an external consumer, has started becoming permanent — and every layer it propagates to after that adds another party who has to agree before it can change.