Anagnorisis

A computer-science look at the recognitions you cannot be taught, only earn: the patterns and tools whose purpose stays invisible until scale or time forces it. Idempotency, eventual consistency, the index, the interface, and the exact moment each one finally makes sense. Plus why AI is quietly removing the loop that produces that understanding.

Aristotle had a word for the moment a character finally recognizes the truth that was there the whole time, the hinge the whole story turns on. He called it anagnorisis. You cannot hand it to someone in the first act. If you could, there would be no story.

Software engineering runs on a whole category of knowledge that works exactly this way. Not the syntax, not the frameworks, those you can teach in a week. The part you cannot teach is why the patterns and the tools exist. A developer can learn what an interface is in an afternoon and learn why it exists only years later, when something forces the recognition. And that something almost always arrives on one of two clocks: scale and time.

The recognitions that arrive at scale

These are the ones that hit when a system that worked fine in development meets real load, real data, real concurrency. You were told about them. You did not believe them until the graph turned red.

Idempotency. You learn why it exists the day a network blip retries a request and a customer is charged twice. At any real scale, delivery is at-least-once, never exactly-once. The retry is not a bug, it is the default behavior of every queue and every flaky connection, and a handler that is not idempotent is a data-corruption incident waiting for its duplicate.

Eventual consistency. You learn why the day you add a read replica to take pressure off the primary, and a user updates their profile and immediately sees the old one. CAP was an abstract triangle in school. Now it is a support ticket, and you understand in your gut that you cannot have consistency, availability, and partition tolerance at the same time, so you had better choose on purpose.

The index, and the N+1 query. You learn why the day the table crosses ten million rows and the query that was instant on your laptop times out in production, because a sequential scan is fine over ten thousand rows and fatal over ten million. Or the day you watch your ORM's lazy loading quietly fire ten thousand queries to render a single page, and you finally understand what the people muttering about N+1 were protecting you from.

Big O. You learn why algorithmic complexity was never a classroom abstraction the day the first real load test on a greenfield app comes back saying it can serve maybe ten percent of the target user base before it tips over. The nested loop that looked harmless over a hundred records is quadratic over a hundred thousand, and no amount of bigger hardware buys back a bad curve. Big O was a grade in school. The load test is where it becomes a budget you cannot expand your way out of.

Caching and cache invalidation. You learn why "there are only two hard things in computer science" is a joke about invalidation the day a stale cache serves a wrong price after a write. And you learn the second half of it, the thundering herd, the day a single hot key expires and every request that was being served from it stampedes the database at once.

Timeouts, circuit breakers, backpressure. You learn why they exist the day one slow downstream dependency holds every request open until your thread pool is exhausted, and the retries you added to be safe turn into a retry storm that finishes the job the outage started. The resilience patterns are not academic until you have watched a single slow service take down five healthy ones.

None of these are hard to explain. Every one of them is impossible to believe until you have watched it happen to something you own.

The recognitions that arrive over time

The other clock is slower. These are the ones you cannot feel in a load test, only by living with a decision long enough for it to come back around.

Interfaces and dependency injection. You learn why the day you have to swap a vendor, or write a real test, or migrate a platform, and you find the class that constructs its own database connection cannot be tested, cannot be pointed somewhere new, cannot be reasoned about on its own. The indirection you called ceremony turns out to be the only reason the swap is possible at all.

Modularity and loose coupling. You learn why the year you inherit the module that reached directly into three others and discover it has to be moved as one welded lump or not moved at all. Coupling is invisible while everything ships together. It only presents the bill when you try to take one piece out.

Backward compatibility and schema versioning. You learn why the first time a deploy breaks because, for ninety seconds during the rollout, the old code and the new code are both live and half the fleet is reading a column that does not exist yet. Nobody warns you that "deploy" means "run two versions at once" until it has cost you an outage.

Readability over cleverness. You learn why the day you open a file too clever to follow and realize you wrote it, and the smartest line in it is the one you now cannot touch without fear. Code is read far more than it is written, and the reader, eighteen months from now, is usually you with no memory of the trick.

Consistency over novelty. You learn why a boring, consistent codebase beats an exciting one the year you inherit the project that chased every trend: three HTTP clients, two ORMs, five ways to manage state, each one the framework someone was excited about the quarter they added it, and none of them ever removed. Novelty is a tax the next maintainer pays, and often the next maintainer is you, nursing a dependency the rest of the world abandoned two versions ago. The senior reflex to reach for the convention already in the codebase, even when a newer tool is marginally better, is not conservatism. It is scar tissue from maintaining the alternative.

Time teaches a different lesson than scale, but it teaches it the same way: by making you live inside the consequence of a decision long enough to feel its full weight.

Why none of it can be front-loaded

A junior looks at an interface with one implementation and sees overhead. They are not wrong to ask why. They are missing an answer they cannot yet have, because the answer is on the far side of an experience. You can put "program to an interface" on a slide. They will nod, repeat it back on a test, and still write the concrete dependency, because conviction of this kind is not transmitted by instruction. It is installed by consequence. The slide is information. The 3am page is belief.

That is the whole problem with treating these lessons as curriculum you can simply deliver. The patterns are teachable. The recognitions are not. They have to be earned on the two clocks, and there is no fast-forward button.

What AI quietly removes

Here is what should worry anyone planning past this quarter. The recognition requires the consequence, the consequence requires the mistake, and AI is quietly removing the mistake.

When the model writes the idempotent handler, the indexed query, the decoupled module, the junior never ships the version that double-charges, never watches the unindexed query fall over, never inherits the welded lump. The output is better in the moment and the learning loop is severed underneath it. What you grow instead is an engineer fluent in the vocabulary, who can say idempotent and eventual consistency and backpressure in a prompt, and who has never once felt why any of them is true. They can describe the pattern and cannot recognize its absence, which is the only skill that actually matters when the AI gets it confidently wrong.

This is the Atom Eve problem from the first piece in this series: she rebuilds a city from memory, every building looks right, people move back in, and it starts failing because she shaped the appearance without understanding what holds it up. She did not know what she did not know. AI-assisted code without the recognitions behind it is the same. It compiles. It passes review. The load-bearing failure is invisible until the load arrives.

And it compounds into a pipeline problem. Cut the junior roles because the model can do what juniors did, and you stop running anyone through the two clocks. In ten years the organizations that did it have no one who feels why the index matters, no one who recognizes an anti-pattern being generated at scale, no one who knows in their hands what holds the system up. That is the question the first piece left open: where do the senior engineers of the next decade come from, once you have automated away the years that made them?

The recognitions are the curriculum

You cannot shortcut the recognition, but you can stop treating the experience that produces it as waste, and you can deliberately put the consequence-bearing work in front of the people ready to be changed by it. That is the workforce half of The Stenographic Mediator: use a fine-grained view of the work to route the migration, the scaling problem, the architecture call that has to live with its own past choices, to the developer who will earn the recognition from it. Not as a kindness. As the only known way to manufacture a senior.

The patterns and the tools were never the knowledge. They are the vocabulary for the knowledge. The knowledge is the set of recognitions underneath them, each one paid for in scale or in time, each one impossible to believe until it happened to something you owned. AI can generate the pattern. It cannot generate the moment you understand why the pattern had to exist, because that moment is bought with having gotten it wrong and lived there. Protect the loop that produces it, or in a decade we will have a generation that can name every pattern and feel none of them, shipping systems that look right and do not stand.


William Dunn is the founder of Quasarke, a software development consultancy, and has spent a decade building company architectures. This is part of a series on communicating with AI as a practitioner.