Every few seasons, the industry falls in love with a new dialect. A framework promises to abstract away the pain. A database promises infinite scale without the operational hangover. The migrations begin, the language wars eat the timeline, and the resumes get rewritten.
Then the years turn, the syntax fades, and the scramble starts again.
Sit in the room long enough and you stop watching the tools. You start watching the physics. Data still has to cross the wire. Memory still has to be managed. The engineer reading your code at 3 AM still needs to know what you meant. These are old problems. People were solving them in C when the machines were uglier and the excuses were thinner.
The modern tech stack is just the current pronunciation of those old solutions. Chase the pronunciation forever and you stay a beginner. Learn the principles and you can speak in any language.
But knowing the principles is not enough anymore. You have to enforce them. The AI assistant in your IDE wants to make you comfortable. It will generate code that looks plausible, runs once, and violates every architectural boundary in the room. So put the machine in the auditor's chair. Strip away the flattery. Make it hunt the parts of the system that are lying.
Here is the stack beneath the stack, and the prompts I use to make AI audit the reality.
1. Separation of Concerns
Isolation buys you freedom. The function pulling a record from the database should not know what color the button is on the display. Keep domains independent and you earn the ability to rebuild the engine without scratching the paint.
Act as a ruthless architectural auditor. Read this module and identify every line
of code that knows something it should not. Where does business logic bleed
into the network layer? Where does the data layer assume UI state?
Do not fix it. Point out the exact lines where isolation is compromised.
2. Abstraction
A good abstraction gives the future a quiet room. You should not need to understand the raw TCP handshake to send a payload. Build interfaces that hide the chaos without lying about what the system can do.
Audit this interface for leaky abstractions. Where is the caller forced to
understand the implementation just to use it safely? What internal chaos
is bleeding through the boundary? Flag any parameters or return types
that betray how the machine works under the hood.
3. Don't Repeat Yourself
Truth should live in one place. If the same core logic exists in three files, the system will fracture when someone only updates two. But do not confuse similar shape with shared purpose. Some code looks alike because it is related. Some code looks alike because reality rhymes.
Find the false twins in this codebase. Identify code that looks identical
syntactically but exists for different business reasons. Tell me which
duplications are safe to abstract into one function, and which must stay
separated to avoid future coupling.
4. Single Responsibility
Give a piece of code one reason to change. If marketing and the database administrator can both trigger a rewrite of the same file, that file is carrying too much weight.
Map the blast radius. If the business pivots the core data model tomorrow,
how many different reasons does this class have to change?
List the distinct responsibilities this module is juggling.
Be brutally honest about what it is pretending not to handle.
5. The Freedom of Statelessness
The less your system has to remember, the cleaner it can move. A pure function takes input, returns output, and forgets you exist. You cannot eliminate all state, but you can quarantine it. Push memory to the edges. Keep the center light.
Hunt the hidden state. Read this logic and tell me where it remembers something
without explicitly declaring it. Find side effects, mutated variables,
and implicit dependencies on system time or external memory. Show me what
is required to make the core logic mathematically pure.
6. Work, Right, Fast
Prove the physics first. Clean the architecture second. Bring in the stopwatch last. Premature optimization is usually ego wearing a lab coat.
Strip all premature optimization from this code. Show me the dumb, slow,
brute-force, mathematically correct version first. Remove the clever bitwise
hacks and pre-caching logic. Give me the baseline a junior engineer
can read, so we can prove it works before we make it dangerous.
7. Fail Fast and Loudly
Honesty is better than politeness. If a system catches a bad input or broken assumption, it should stop the line and tell you exactly where it hurts.
How can I silently corrupt this system? Find the swallowed exceptions,
the unvalidated boundaries, and the soft failures. Tell me exactly what
malicious or malformed payload I can send to make this code write corrupted
data while returning a 200 OK.
8. Composition
Build by assembling. Inheritance chains you to the past. Composition lets you choose the exact behavior you need for the job in front of you.
Untangle this inheritance tree. Rewrite this hierarchy using strict composition.
For every `extends` or inherited class, replace it with an injected dependency.
When you are done, list the historical baggage and rigid constraints we freed
ourselves from.
9. Design for Failure
Treat the happy path as a rare luxury. The network will drop. The disk will fill. The API will vanish without warning. The system's reaction to a timeout is not an edge case. It is the design.