← All Essays

The Agentic Engineer

The era of the individual coder is ending. The engineers who survive aren't writing faster — they're building the factories that write for them.

Syntax is a commodity now. Architecture is the only moat left standing between you and the unemployment line.

When Vibe Coding Hits the Wall

In 2025, a certain kind of engineer found religion. They described features in plain English, watched the AI generate a diff, and shipped it. No architecture review, no edge case inventory, no thought given to what happens when two concurrent requests hit that new endpoint. They called it “vibe coding.” It felt productive. It felt almost unfair — all that leverage, none of the drudgery.

By 2026, Hacker News became a museum of cautionary tales. A startup’s checkout flow starts randomly dropping orders. An auth system quietly grants elevated permissions when two race conditions collide just right. A data pipeline that “totally works” in staging eats duplicate records in production for three weeks before anyone notices. The post-mortems share a common thread: generated code that nobody truly understood, piled on top of more generated code that nobody truly understood, running in a system that nobody had designed.

Vibe coding doesn’t fail because AI writes bad code. It fails because no one specified what “correct” looks like. The AI fills in gaps. It makes plausible choices. It picks the most-common-in-training-data implementation of every ambiguous requirement. And it does this a hundred times across a codebase without any awareness that those choices need to be consistent, coherent, or aligned with constraints that live outside the chat window. The result is code that passes every test you thought to write and fails every requirement you forgot to state.

The engineers who are struggling aren’t being replaced by AI. They’re being replaced by the engineers who realized that writing code was never the job. The job was always modeling a problem precisely enough that its solution could be specified and verified. The AI just made that distinction impossible to ignore.

The Software Factory

The manufacturing industry solved this problem forty years ago. In the 1980s, the “dark factory” was a thought experiment: a facility with no lights, because there are no humans. Robots do the building. Robots do the testing. The facility runs at night, in silence, producing output that would take ten times the human workforce to match. The engineers don’t disappear. They design the factory. Then they go home.

Software is arriving at that inflection point now. The code isn’t written by an engineer at a keyboard — it’s produced by a pipeline. One agent takes the spec and generates the implementation. Another writes the tests. Another runs the tests, identifies failures, and feeds the diagnostics back upstream. Another handles dependency resolution. Another watches for security advisories and patches. The pipeline compresses into hours work that used to take a sprint. It does it without getting tired, without getting bored, without arguing about semicolon conventions.

What this means for the engineer is a job description that reads nothing like what they studied for. You are not writing the software. You are writing the spec that the software factory runs against. You are designing the workflow that routes work between agents. You are setting the quality gates that output cannot clear without meeting. You are, in the most literal sense, building the factory — and the factory builds the software.

That is a harder job than writing code. It requires you to hold the entire system in your head, anticipate failure modes that haven’t happened yet, and make architectural decisions whose consequences won’t surface until the system is under load. An engineer who can do this is not a commodity. An engineer who cannot do this — no matter how fast they type — is.

Verification Velocity

The bottleneck has moved. For most of software engineering history, implementation was the constraint. You needed someone who could translate a requirement into working code — and that person’s hours were finite and expensive. The faster you could write code, the faster things shipped.

AI broke that constraint. Implementation is no longer the bottleneck. Verification is.

A senior engineer running a fleet of coding agents isn’t spending their day writing functions. They’re reviewing outputs. Plan → Execute → Verify, in loops that run faster than a human sprint used to. The planning stage requires clarity about what you actually want — not a feature description, but a specification precise enough that a non-human executor can disambiguate edge cases without asking. The execution stage runs largely without you. The verification stage is where your judgment is worth money: reading a 400-line diff and knowing, without running it, where the logic is wrong. Recognizing that the agent solved the stated problem but missed the unstated constraint. Knowing which test passing means nothing because the test was written by the same agent that wrote the code it’s testing.

The engineers who thrive in this environment have an almost editorial sensibility. They move through generated code the way a copy editor moves through a draft — not rewriting it from scratch, but finding the places where the meaning diverged from the intent. Their value is in how fast they can verify, how sharp their eye is, how precisely they can diagnose failure and write a corrective spec. Verification velocity isn’t a new metric. It’s just the old metric of engineering judgment, running at much higher throughput.

Designing the Guardrails

An engineer hands an agent the task: “Update the subscription pricing endpoint to apply the new enterprise discount tier.” Clear enough. The agent reads the codebase, finds the pricing service, and begins making changes. It notices the discount logic is also referenced in the billing reconciliation job. Helpful — it updates that too. The billing job joins against a legacy_pricing_overrides table that the agent doesn’t fully understand, so it makes a reasonable assumption about the join condition and rewrites it. The tests pass. The engineer reviews the pricing endpoint changes, which look correct, and ships.

Three days later, the finance team reports that enterprise invoices are generating at the wrong amount for accounts created before a certain date. The agent’s “reasonable assumption” about that join condition was wrong in a way that only surfaces for accounts with records in the legacy table. The fix takes two hours. The forensics take two days. And somewhere in that forensics process, someone discovers that the agent also made six undocumented requests to the Stripe sandbox API during its initial exploration — because it had the credentials, the task was billing-adjacent, and nothing told it not to.

The agent did exactly what an eager junior engineer might do: read the surrounding context, tried to be thorough, made confident inferences where the spec was silent. Nobody designed the boundaries. The agent had access to every table in the database, every credential in the environment, and no machine-readable definition of what “done correctly” looks like. It operated with the degrees of freedom of an engineer who has been at the company for ten years, and the contextual judgment of someone who joined this morning.

Now multiply that by a pipeline running thirty agents in parallel. The blast radius of an unconstrained agent isn’t a bug — it’s a category of incident.

Treat agent access the way a good security engineer treats system access: the minimum required, explicitly granted, auditable after the fact. The Model Context Protocol gives agents a structured interface to data, tools, and services — so that access is explicit, auditable, and constrained. Spec-Driven Development forces requirements into a machine-readable format before a single line of execution, creating a ground truth the agent must satisfy and the verifier can check against. Together, these aren’t workflow preferences. They’re the equivalent of physical safety constraints on industrial equipment: the machine can only move in directions that can’t kill anyone. You design the range of motion before you turn it on.

The engineers who build these harnesses well share a trait with good security engineers: they think about failure before they think about success. They ask what the agent can do wrong with the permissions it has, then narrow the permissions. They ask what happens if the spec is ambiguous, then sharpen the spec. They treat every agent invocation as a potential failure path that needs a defined recovery. The factory runs because someone thought through all the ways it could stop running.

From Coder to Orchestrator

Code is tactics. Architecture is strategy. The engineer who maximizes their value in the next decade is not the one who learns the best prompt for generating React components. It’s the one who can look at a distributed system and trace the causal chain — how a schema change in one microservice ripples into unexpected behavior three services downstream, how a new agent introduced into the pipeline creates a race condition that only surfaces under load, how a context window limit in one model causes silent truncation that corrupts state in another.

That kind of thinking has always been the mark of a senior engineer. What’s changed is who it applies to. “Senior” used to mean years of accumulated syntax knowledge. That knowledge is now free. What remains valuable is the ability to hold a system’s causal graph in your head and reason about it precisely. The engineer who can do that — at the level of AI agents, orchestration pipelines, and multi-model workflows — is the irreplaceable one.

The role has a new shape. You’re specifying requirements with the precision that used to only matter for compiler-facing interfaces. You’re designing workflows with the rigor that used to only matter for distributed systems teams. You’re reviewing outputs with the speed that used to only matter for high-frequency trading desks. You are, in the fullest sense, the adult in the room — not because you’re supervising children, but because the agents you’re running are powerful, fast, and completely indifferent to consequences you haven’t specified.