Do SOLID principles still matter when AI writes the first draft?
Casey Holt
August 27, 2026
The first draft used to be where juniors learned to over-apply SOLID. Now the draft arrives in eight seconds with an IUserRepository, a factory, and a folder the prompt did not ask for. The question I keep getting is whether the letters still matter if a model will emit them for free. The short answer is yes, more than they did, because the cost of typing ceremony went to zero and the cost of deleting it did not.
I have already written about which SOLID letters still save you and which ones just add files. This is the agent-shaped version of that argument. The principles did not change. The default draft did. Your job moved further toward refusal.
What the model has read
Training data is full of Clean Architecture sample repos, interview-prep blogs, and enterprise Java that solved staffing with types. When you say “add a user endpoint,” the prior is: interface, implementation, DTO, mapper, service, controller, a test that mocks the service. That prior compiles. It also arrives when you needed a function and a query.
The model is not wrong about SOLID in the abstract. It is statistically generous. Generous design is how you get inversion of control for a script that runs twice. I used to catch that when the author was tired. I now catch it when the author is fast. Speed hides the same pile.
If you ask the agent to “make it SOLID,” you will get more files. That prompt is a trap. If you ask it to “keep the HTTP handler thin and put Stripe behind a function I can fake,” you will get something closer to the D I still want. The letters in the prompt matter less than the seam you name.

What still matters in review
Substitution still matters, because the draft will fake it. Agents love a subclass or a wrapper that implements an interface and then no-ops a method “for now.” That is a Liskov bug with a polite comment. I reject those on sight. If it cannot honor the contract, it is not the type. Write a new type. The model will not volunteer that. It will volunteer the wrapper because wrappers look like design.
Edges still matter, because the draft will import the vendor. The first pass often talks to Stripe, S3, or the clock from the handler. That is convenient and untestable. I still want a port at the network. I do not want a port for every helper. The agent cannot tell the difference unless you say “only invert I/O.”
Responsibility still matters, because the draft will mix reasons. A generated “UserService” will validate, persist, send email, and write an audit row. That compiled in 2014 too. The difference is you can get it in one paste. Split at the reasons that already fail separately — email is allowed to fail when persist is not — not at every verb.
Open/closed and fat interface splits matter less as defaults. The model will offer strategies for two branches and four one-method interfaces for one implementation. I delete those first. I have a higher delete rate on agent PRs than on human PRs, and it is almost always these two letters plus a folder named domain.
The new failure mode is plausible architecture
A junior used to write a long function. You could see the mess. An agent writes a tidy mess. The names are consistent. The folders match a conference talk. The tests are green because they mock the world the code invented. Reviewers who skim for “does this look professional” will merge it. That is the 2026 risk. SOLID-looking is not SOLID-working.
I changed how I review generated first drafts. I do not start at style. I start at: what is the one change this makes cheaper, and what vendor or clock does it touch? If I cannot answer in a minute, the architecture is a fog the model painted. I ask the author — human or not — to collapse it until I can. A draft that needs a guided tour is not a first draft. It is an unfinished design with tests.
I also run the tests with the mocks removed once. Not always. Often enough. A suite that only passes when every port is a lie is a compliment, not a net. Agents write compliments. You have to ask for an ugly integration check. They will do it if you insist. They will not volunteer it. Volunteers write more interfaces.
Prompts that reduce the pile
I keep a short list in the repo, next to the test command. Do not add an interface for one implementation. Do not add a factory for one product. Do not introduce a folder called abstractions. Invert I/O only. Prefer a function over a service class. If you add a type, name the change it makes cheaper.
That list is ruder than a style guide and more useful than “follow SOLID.” When I skip it, I get the sample repo again. When I include it, I still get extra files, just fewer. The residual extras are a delete pass, not a redesign.
I do not prompt “ignore SOLID.” That produces a 200-line handler with a nested retry and a log in the middle. The letters are not the enemy. The unearned application is the enemy. A model has no scar to tell them apart. You do. That is why the principles still matter: they are a vocabulary for the refusal, not a recipe for the draft.

Teaching changed more than the design did
I used to make people write the extra types so they would feel the cost. That exercise is obsolete. The cost of writing is gone. The cost of owning is not. I now make people delete. Take a generated SOLID stack and remove types until a test still proves the seam. The ones that remain are the ones that mattered. The ones that vanish were a prior.
Juniors who only accept the draft will learn a museum of patterns and no judgment. Juniors who can say “I kept the Stripe port and I deleted the IUserLister” are doing the job. That sentence is the new homework. It is also the sentence I want in standup when an agent wrote the PR.
Seniors are not off the hook. If you merge the museum because you are tired of review, you taught the team that plausible is enough. The model will keep giving you plausible. You set the ceiling.
A concrete pass I run
Open the generated tree. Count implementations per interface. If the ratio is 1:1 and the consumer is one module, delete the interface and keep the concrete type unless the type is an edge. Count folders created in the PR. If a folder has one file, inline it. Search for Factory and Provider. If there is one product, delete the factory. Search for abstract and Base. If the subclass is a no-op, you have a Liskov smell. Then add one test that hits the real edge or a recorded fixture — not another mock of a port you just invented.
That pass takes fifteen minutes and usually removes a third of the diff. The remaining third is the change you wanted. The middle third is the argument you still have to have as a human. I will take that argument. I will not take a merge of the whole paste because the names were tidy.
So do they still matter
They matter as a filter on a cheap draft, not as a generator of a first draft. Use S and L and D-at-the-edge to decide what to keep. Use O and I as reasons to delete until a real boundary shows up. Do not ask the model to perform SOLID. Ask it to perform a change, then you apply the letters as a knife.
If the principles were only a way to type more classes, they would be dead. They were never only that. They were a way to remember how systems fail. Agents do not remember your failures. They remember the internet’s sample repos. Someone still has to stand between those two memories. In 2026 that someone is you, and the letters are how you talk about the cut.
I am not going back to writing every interface by hand to prove I care about design. I am also not going to let a model’s prior become the architecture because it was free. Free first drafts are how expensive second years start. Keep the knife. Use it on the paste. That is the whole update SOLID needed this year: same failures, cheaper typing, stricter delete.