Every major shift in computing has been preceded by a shift in interface. Punch cards gave way to command lines; command lines gave way to windows, icons, and pointers; pointers gave way to touch. Each transition changed not just how people used software, but how software was built — because the interface paradigm quietly dictates what kinds of programs are worth writing, and how the people writing them reason about correctness.
Natural language processing is the newest entrant in that lineage, and it is a strange one. It isn't only a new way to point at things — it's a new way to specify intent, and it sits on both sides of the development equation at once. It is the interface end users type into. It is also, increasingly, the interface developers use to describe what a system should do, letting a model produce the implementation. That dual role is why its arrival is reorganizing the entire software lifecycle rather than one corner of it.
Chart by Carlos E. Perez, Intuit Machine · view full size ↗
From scarce code to scarce judgment
For fifty years, the binding constraint on software teams was implementation capacity. Writing correct, working code was slow and specialist work, and because it was expensive, the act of writing it doubled as a forcing function for understanding — a team building a feature by hand was, almost incidentally, working through its edge cases as they typed.
NLP-driven generation breaks that link. When a model can produce a working draft of a function, a service, or a whole feature from a paragraph of description, code stops being scarce. Teams can now generate implementations faster than they can review, absorb, or trust them. The bottleneck doesn't vanish — it relocates, from can we build this to do we understand what we built, and can we stand behind it.
The realignment: when producing code becomes cheap, the scarce resource is no longer implementation. It is judgment — specifying what should happen, validating that it works, and taking responsibility for what ships.
Judgment doesn't get cheaper just because generation got faster. If anything it gets more load-bearing, because there is more generated surface area to specify, validate, and answer for.
The tetrad, applied to a new interface
Adding a natural-language layer to the stack doesn't act as a single force. It pulls in four directions simultaneously — the same structure Marshall McLuhan proposed for how any new medium reworks what came before it. His tetrad of media effects asks one question of each of four quadrants at once, and the field's present turbulence is the sum of all four answers, asked of natural language as computing's newest interface.
Explodes implementation and prototyping capacity. Makes experimentation, refactoring, and exploration cheap. Accelerates iteration from days to hours.
Code abundance becomes trust scarcity. More generation can create more complexity than teams can understand. Production systems flip into confidence-producing systems.
Brings back specification-first thinking. Revives invariants, architecture, and stronger validation methods long set aside as implementation absorbed the budget.
Pushes syntax recall and boilerplate coding into the background. Weakens effort-based planning and line-by-line review as central practices.
Marshall McLuhan's tetrad of media effects (Laws of Media, 1988) — every medium simultaneously enhances, obsolesces, retrieves, and reverses into its opposite when pushed to its limit.
Generation moves to step four
In design and early development, the practical consequence is that generation becomes one step embedded in a larger loop — not the loop itself.
Generate is the fourth step, not the first — everything before it shapes the output; everything after it earns trust in it.
Since manual line-by-line review no longer scales to the volume of generated code, review moves upstream into the constraints that shape generation, and downstream into evidence gathered in production — not a read-through, but an audit trail.
How the standing practices are being rewritten
This is also why long-standing practices are being revised rather than discarded. Each keeps its name and shifts its center of gravity:
| Practice | Old center of gravity | New center of gravity | ||
|---|---|---|---|---|
| Agile | → | Shipping increments | → | Learning from increments |
| Sprint planning | → | Implementation capacity | → | Evaluation & integration capacity |
| Test-driven dev. | → | Writing tests before code | → | Defining correctness before generation |
| Code review | → | Inspecting implementation | → | Inspecting assumptions, risk, evidence |
| Architecture | → | Guiding implementation | → | Constraining cheap-to-produce complexity |
| Documentation | → | Explaining the code | → | Preserving intent & provenance |
| CI/CD | → | Testing human changes | → | Proving generated changes are safe |
The case study: decoupling identity itself
The clearest evidence for how deep this shift runs isn't a new practice — it's an old architectural principle that finally becomes practical. Open-standards communities have argued for decades that five concerns should be loosely coupled rather than welded together: who you are, what's known about you, how that's proven, what you're allowed to do, and where the data actually lives. On paper the separation was always clean. In production it rarely held, because nothing could traverse the seams between the layers cheaply enough to keep them separate — so systems collapsed them into a single vendor-specific identity stack instead.
A standardized identifier — a hyperlink — that names an entity without asserting anything about it. Nothing more than an anchor point.
Credentials — profiles and preferences — built as an entity-relationship graph anchored to that identifier, forming a web equally navigable by a person and a software agent.
Credential verification, pluggable across any of several open-standard protocols — never fused to the identifier itself.
Fine-grained, attribute-based access control that reasons over user, agent, intent, and resource attributes — all represented in the same machine-computable graph, not scattered across config files.
The actual data spaces — databases, knowledge bases, filesystems, APIs — targeted by CRUD operations, swappable underneath without disturbing any layer above.
What was missing wasn't the standards — most of this has existed in open form for years. What was missing was a second class of traverser. The promise of a web "equally navigable by humans and software agents" stayed aspirational as long as only humans could actually read the graph, follow the identifiers, and reason about the attributes; software touching it needed bespoke integration code at every seam, which is exactly what re-welds loosely coupled layers back together under deadline pressure.
An NLP-capable agent can read the same entity-relationship graph a person reads, follow the same standardized identifiers, and reason over the same attributes — without a bespoke adapter per layer. That is what turns loose coupling from a diagram into an operating architecture.
This is the pattern behind §3’s inversion in miniature: an architecture that looked elegant but impractical becomes not just achievable but structurally necessary, because generating five tightly-coupled point solutions is now cheaper than building one loosely-coupled system was — right up until someone has to change an authentication provider, migrate storage, or explain why an agent had access to something it shouldn't have. The specification and governance discipline from §3 is precisely what keeps that graph trustworthy enough for both kinds of readers to rely on it.
The dogfooding gap: demos are not evidence
Software vendors have not historically demonstrated the virtues of what they sell by running it on their own hardest, most representative problems. The industry default is the lightweight canned demo: curated data, a rehearsed path, a scenario sized to finish in twenty minutes without anything breaking. The gap between "this is what we actually use to run our own systems" and "this is what we're showing you" is a dogfooding gap at the point of sale, not just inside engineering.
The asymmetry survives because complexity cuts both ways. The same complexity that would make a real dogfooding showcase persuasive is exactly what makes it hard for a customer to demand one as an evaluation requirement in the first place. Writing "prove you run this on problems as hard as ours" into an RFP requires the buyer to already understand that complexity well enough to tell a genuine demonstration from a staged one — the same specification burden this essay has been describing throughout, just moved to the buying side of the transaction.
None of this requires bad faith on the vendor's part or naivety on the buyer's. It requires only that specifying a real dogfooding showcase is itself hard — harder than specifying feature checkboxes or price — and evaluation processes default to what's easy to specify and easy to score.
The complexity that would make a real demonstration persuasive is the same complexity that keeps a buyer from being able to demand one. That isn't a coincidence — it's the specification burden this essay has been describing, moved from engineering team to purchasing committee.
Seen this way, a canned demo is verification debt exported to the point of sale: it becomes evidence not because it demonstrates correctness under real complexity, but because nobody in the room is positioned to demand the harder proof.
What deployment inherits: three debts
NLP-assisted generation changes what can silently go wrong, in ways that surface at deployment and compound across the maintenance lifecycle. Three liabilities in particular tend to accrue quietly:
Specification debt
The system makes hidden decisions because the requirements were never made explicit. Nobody wrote it down, so the model chose plausibly — and nobody notices until it fails.
Verification debt
Generated artifacts reach production before enough evidence exists that they're correct. Passing a smoke test is not the same as being validated against the spec.
Comprehension debt
Teams depend on systems they can no longer fully explain, modify, or diagnose, because no one ever built a mental model of the parts a human didn't write.
Cartoon by Justin Miller · view full size ↗
AI accelerates all three unless specification discipline, verification rigor, and provenance-preserving documentation are deliberately redesigned to keep pace. Speed without redesigned guardrails just produces debt faster — and debt is exactly what maintenance and support organizations inherit.
What using the system well now means
For the people doing AI-assisted development day to day, none of this is about writing code faster. It's about the discipline that makes fast-written code trustworthy — which is exactly what the people downstream, in support and maintenance, need most. Seven rules fall out of the shift:
- Specify critical behavior before generating code.
- Treat tests as evidence, not proof.
- Review assumptions, not just syntax.
- Constrain complexity — AI makes it cheap to create.
- Preserve provenance: why the code exists, what it's supposed to do.
- Keep humans responsible for high-consequence decisions.
- Optimize for verified capability, not volume of code produced.
Three roles, one developer
This is reflected in what the best developers are becoming — not faster typists, but people who hold three roles at once.
Defines intent, constraints, and invariants before anything is generated.
Demands evidence and actively challenges hidden assumptions, rather than trusting output at face value.
Decides what the organization should and shouldn't let into the system — rationing complexity like any other scarce resource.
The future of software engineering is not about writing more code. It is about creating trustworthy systems in a world where code is cheap.
Frequently Asked Questions
Quick answers to the essay’s core claims — each question links to its entity in the RDF companion.
What does “scarce judgment” mean in an AI-assisted software team?
Why apply McLuhan’s tetrad of media effects to AI coding tools?
Why does “Generate” sit at step four of the engineering loop instead of first?
What are the three debts AI-assisted development can create?
Why is comprehension debt the hardest of the three to notice?
What are the five layers of the loosely coupled identity stack described in this essay?
Why couldn’t this loosely coupled identity architecture work in practice before AI agents existed?
What is the “dogfooding gap” between vendor demos and real product use?
What are the seven new rules for software engineering this essay proposes?
What three roles do the best developers now hold at once?
Who created the chart and the cartoon featured in this essay?
Is this essay itself digitally signed?
Where can I query this essay’s own concepts as structured data?
Glossary
Every concept minted for this essay’s companion RDF, defined in one line.
How To Apply This
The seven rules from §7, indexed here for quick lookup.
- Specify critical behavior before generating code.
- Treat tests as evidence, not proof.
- Review assumptions, not just syntax.
- Constrain complexity — AI makes it cheap to create.
- Preserve provenance: why the code exists, what it’s supposed to do.
- Keep humans responsible for high-consequence decisions.
- Optimize for verified capability, not volume of code produced.