A team hands you a pull request with twenty thousand lines in it and promises another ten thousand within the hour. You have no idea what to do with that, and neither does anyone else. The standard framing is that the bottleneck moved from writing code to reviewing it, and that framing is close enough to be useful and wrong enough to send you looking for the wrong tools.
The bottleneck did not move. It has always been in the same place: whether the thing is understood by a human being. Writing code slowly used to smuggle understanding in for free. You built the mental model in instalments while you typed, and by the time the diff existed you had already paid for comprehension. Now generation is fast, comprehension takes exactly as long as it ever did, and the invoice arrives all at once.
Why visualizing the code does not fix code review
The first instinct is to draw it. Code maps, dependency graphs, call webs, anything that turns twenty thousand lines into a picture. It helps a little and solves nothing, because visualizing methods, fields and classes gives you the same quantity of information in a different format. Some people find a web of dependencies easier to scan than a diff, and that is a real if modest win. What is missing is a level of abstraction above the code.
Think about how you design something in the first place. You do not open the editor and start typing, because code is too dense and too precise for that stage. You reach for coarser blocks, whatever your vocabulary is, and you work at that level until the shape is right. When someone else implements it and you come back to review, what you are really asking is whether the model you designed is the model that ended up in the code, and whether the relationships between those blocks survived the trip.
Doing that by hand meant reading the code and rebuilding the block diagram in your head, or on a sheet of paper when your working memory ran out. That worked when it happened once a month. It does not work when it happens twice a week.
So the tool that is actually missing is not a prettier renderer. It is something that extracts the design-level building blocks back out of the code, so you can check the big picture first and only then descend, block by block, into whether each one behaves.
How AI coding centralizes knowledge in one developer
There is a second effect that gets much less attention than review throughput, and it is more dangerous. Working with an agent is a solo activity. The interface is a terminal, one person drives it, and the tempo is high enough that there is nowhere for a second person to plug in. If someone is halfway through a session with an agent, you cannot join.
That pushes teams back toward one feature, one developer. That person accumulates the knowledge, becomes the sole expert on that part of the system, and had better not resign. Meanwhile the volume of code makes honest review less likely than before, so the usual backstop against knowledge silos quietly stops working.
If collaboration has to happen, it has to happen earlier: during domain exploration and design, before anyone opens a terminal. Which is a slightly funny outcome, because the most technical toy in a decade ends up re-teaching the oldest lesson in domain-driven design, that understanding the domain is the part that matters.
Where AI genuinely helps an architect
Reading the current state of a system is the biggest win, and it is not close. If you work with a dozen teams, you do not know what is in the code anymore. Features land constantly. When somebody asks you to design something that crosses three contexts, your options used to be checking out the repository and reading for a day, or interrupting three people to ask how their piece works and breaking their flow in the process. Now you ask a model to read that code and tell you how it works, and the number of interruptions collapses. You have moved knowledge transfer from synchronous to asynchronous, and you get maybe eighty percent of what you needed without costing anybody an afternoon.
The second win is producing artifacts nobody ever had time for. Architecture decision records are the canonical example. Everybody agreed for years that they should be written, and in practice only the biggest decisions ever got one. Now the meeting itself can produce the drafts, and the scope widens beyond architecture: which library was picked and why, where the aggregate boundary went, which business rule was dropped and on whose authority. Then the people who were in the room review the draft instead of reconstructing the discussion from memory.
What you gain from that is the thing that always evaporated: not the decision, but the context around it and the arguments that lost. Even teams that maintained documentation heroically documented how the system is, never how it came to be that way. And once the record exists, you can query it mid-meeting: have we discussed this before, what were the options, what killed the one we are about to propose again?
How to run a meeting so a model can use the transcript
Two practical habits make an enormous difference here, and both of them are good for humans too. The first is a spoken summary at the end. A transcript of a real design discussion is not an article you can summarize; it is a braid of interrupted threads where a decision gets made, then reversed because a new fact appeared, then remade in a different form. Models are excellent at summarizing well-structured prose and much weaker at recovering the temporal structure of an argument. If you close the meeting by stating the final decisions out loud, you give the extraction a clean anchor: weight the ending, then fill in supporting detail from earlier.
The second habit is agreeing on the categories you want to extract. Decisions, rules, assumptions, open questions, dilemmas, scenarios. Models categorize well when the boxes are well defined, and poorly when you hand them an undifferentiated wall of speech and hope. The categories differ by team, because teams genuinely think in different units, and figuring out yours is a job of thinking about how you think.
One warning from practice. If a colourful phrase gets repeated on a call, expect it to come back as a key architectural term in the generated decision record, spelled exactly as you said it. That may be perfectly fine if everyone reading it shares the joke. Read before you commit.
Why spec-driven development is not the answer either
The pitch is appealing: the specification becomes the primary artifact, the code becomes disposable, and when something needs to change you edit the spec and regenerate.
Follow the logic and it collapses. If a specification is precise enough that you can mechanically turn it into a working system and trust the result, then it is a programming language. And once it is a programming language you do not want a probabilistic model in the middle, you want a compiler, because the trust comes from determinism. We know how compilers behave. That is the whole reason we rely on them.
The other problem is the loop. A spec was always a starting point, not an oracle. You wrote some code, learned something, ran it, learned more, tested it, learned more again, and arrived somewhere better than the spec described. That feedback cycle is where the knowledge came from. Clicking approve, approve, approve until an agent stops, then either shrugging "looks good to me" or throwing the whole thing away and writing it by hand, is not a substitute for it.
Nobody has a good answer for this yet. If code generation keeps improving, we need to invent new feedback loops to replace the one that writing code used to provide.
Does code quality still matter if only an agent reads it?
The claim making the rounds is that clean code is obsolete: models write it, models read it, so who cares what it looks like. Follow that chain one step further and it falls apart. Why does the agent read the code? To produce a synthesis of what the system does, which is exactly what you asked for at the start of the design process. So the code is an input, and it lands in the context window of your next prompt.
If the code carries no meaning, if names are vague and the structure is arbitrary, the model still answers. It just answers worse. That worse answer gets written back into the code, degrading the input for the next question, which degrades the next answer.
That reframes code quality rather than abolishing it. Alongside developer experience there is now something like agent experience: what information does this code carry for whoever consumes it? A human wants less information, but synthesized and well ordered. A model can take more.
Which makes an old idea suddenly worth the effort. Put an Order.md next to Order, describing the domain concept, its definition, its invariants and the vocabulary around it. Annotate a class with what kind of building block it is and which concept it represents.
# The annotation is metadata for whoever reads this next, human or not.
# It states the design intent that the code alone cannot carry.
module Booking
# @building_block aggregate_root
# @context Booking
# @concept Stay
# @invariant A confirmed stay cannot overlap another confirmed stay
# for the same room.
# @glossary A "stay" is the period a guest occupies a room. It is not
# the same concept as a "reservation", which is the commercial
# agreement and lives in the Sales context.
class Stay
def confirm!(clock)
raise AlreadyConfirmed if confirmed?
@status = :confirmed
@confirmed_at = clock.now
end
end
end
This was worth doing before any of the current tooling existed. Keeping one structure of information beats keeping two, and every team that put the domain description on a wiki discovered that navigating two structures at once is miserable. It also enabled automation: a check that flags the description when the public API of the class changed underneath it. The difference now is that the payoff is roughly ten times larger, because everything downstream consumes it.
The bet worth making: Ontology over models
Look at which companies have actually succeeded with this technology, and set aside the labs that build the models themselves. The clearest operational success story is a company known for two things: ontologies, and an engineer who goes and sits with the customer.
The ontology is a structured model of how the business works, entities and processes and the relationships between them, queryable deterministically rather than by vector similarity. Embedding similarity is effective and it is not the only way to search, and for a lot of questions it is the wrong one. The engineering pattern is the other half: rather than building a product for a client from the outside, someone goes in, extracts the real processes, gathers the data, helps build that operational model, and only then puts agents on top of it.
Now apply the same thing to our own domain, which is building software.
An ontology of the development process would hold decisions, linked to the meetings where they were made, linked to the people who were in those meetings, linked to the commits those people authored, linked to the modules and use cases and building blocks in the repository, linked to the test scenarios that traverse those blocks, linked to the change history.
With that graph you can answer questions that are currently unanswerable. Who else should have a say here, because they spoke about this on a related call or touched code that is coupled to it? That is a deterministic traversal, not a guess based on textual resemblance.
You can also generate the intermediate artifacts automatically, decision records and scenarios and use case contracts, and only then generate code from them. The model's input stops being a paragraph of prose and becomes a chain of structured artifacts.
And then you can close the loop.
What to invest your learning time in
Not the models. They will keep getting better whether you follow the release notes or not, and a technique tuned to one of them expires quickly.
Invest in the input. Gathering knowledge, categorizing it, building the ontology, and then designing agents on top of that structure. However good the model is, it only performs when its input is good.
There is a neat corollary in how business rules map to design. Once you can categorize a rule, it tells you which construct to reach for. Calculation rules become a strategy or a policy. Consistency rules become an aggregate. Coordination and process rules become an application service or a process policy. So write your rules down with obsessive precision, categorize them, and let the categories drive the building blocks, the building blocks drive the structure, and the structure drive the processes. That chain does not need a large budget. It needs discipline, and possibly nothing more than a document.
Why the same tool makes some teams faster and others slower
The survey data looks contradictory until you break it apart. Averages suggest productivity drops when teams adopt these tools, which makes business people ask why they should pay for something that slows people down. Open up the distribution and you find a large group reporting no change or a slowdown, and a smaller group reporting they are several times faster.
The explanation is that automation amplifies whatever process it is applied to. This is exactly what happened when continuous delivery arrived: teams with a bad deployment process automated it and started deploying badly, faster. If your process is broken, an agent produces broken output at speed. If your process is sound, if you care about quality attributes, architecture and knowledge management, the same tool compounds that.
There is also a familiar organizational shape forming. The interesting work is coming out of small teams and small companies, exactly as it did with extreme programming, test-driven development and microservices. The difference is the adoption curve. Agile took years to reach large organizations; this took about a year. Which means practices developed by two-person teams, where whole categories of problem are invisible, are being rolled out at enterprise scale right now.
So yes, expect a chunk of the industry to adopt this the way it adopted agile: a faster horse, bolted onto an unchanged culture and unchanged processes, delivering point improvements and a few genuine slowdowns.
When does the bubble burst?
Nobody knows, and anyone who does is shorting it rather than blogging about it. But the more useful question is what kind of bubble this is.
There are bad bubbles, the purely speculative kind, where the pop leaves nothing behind. And there are good ones. The dot-com bubble is remembered for websites about pets, but the money went into fibre, and when it burst the world was left with an enormous amount of unused capacity. That dark fibre is why streaming became possible at all.
Right now the largest sums are not going into thin wrappers around a prompt. They are going into infrastructure, into data centres the size of a city block, built to train larger models. Which suggests that whatever gets built on that foundation is still ahead of us, and that most of the companies currently dominating the conversation will be remembered the way we remember Kodak and Xerox.
The payoff may not even be business software. It may be models good enough to put inside robots, which would change where physical manufacturing happens far more than it changes how we write code. We have had that hope before, with 3D printing, and it did not arrive. This time the bet is a great deal larger.
FAQ
Does 'clean code' still matter when an agent writes it?
Yes, and arguably more. The code you generate becomes context for your next prompt, so unclear structure and vague names degrade the next answer, which then degrades the code again. You may read the code less often, but you will constantly read summaries derived from it, and those are only as good as the source.
Is spec-driven development a replacement for writing code?
Not in its strong form. A specification precise enough to be mechanically executable is a programming language, and at that point you want a deterministic compiler rather than a probabilistic model. The weaker form is fine and always was: the spec is a starting point for iteration, not the finished artifact.
How do you review twenty thousand lines of generated code?
You do not, at least not line by line. You extract the design-level building blocks and check the big picture first, then descend into the blocks that matter. The gap in current tooling is exactly this extraction step, which is why teams are building it themselves rather than buying it.
What should an SDLC ontology actually contain?
At minimum: decisions and their rationale, the meetings and people they came from, repository structure down to modules and use cases, test scenarios and which building blocks they exercise, and the change history that ties it together. The exact shape differs per organization, and most of the value comes from the relationships rather than the individual records.
Why do productivity surveys disagree about AI tooling?
Because they average two populations. Teams with sound processes get compounding gains, teams with broken processes get faster production of the same problems, and the mean of those two lands near zero. Read the distribution, not the headline.
Happy architecting!
