Skip to main content
← /writing
  • #engineering-leadership
  • #agentic-sdlc
  • #ai-strategy

The Bottleneck Is Never the Stack: What Held and What Moved

In May I named the argument underneath a year of writing. Five months later, I'd keep the argument and narrow several claims. Here is what changed, what survived, and what I still can't prove.

Vinny Carpenter17 min read3.2k words

never the stack · audio edition

The Bottleneck Is Never the Stack: What Held and What Moved

22:30

On May 13 I published The Bottleneck Is Never the Stack, an essay that tried to name the argument underneath a year of writing. It had three pillars and a section called "Where I am less sure." I said I was most confident in the spec pillar, because every example I'd tried had held up.

Eleven days later I published the first counterexample. Claude Code had handed me a refactor with a clean diff and passing tests, and I killed it after reading it twice. It solved the problem I'd written down, which turned out to be a different problem from the one we had.

The May 13 essay still leads my Start Here page and gave the book its title. Five months later, it deserves an update.

Better tools alone don't produce reliable delivery. As implementation gets cheaper, the constraint can move among framing, specification, trusted context, verification, and operability. The work is to find what limits a useful, reliable change today, fix it, and keep the lesson where the next run can use it.

Five things have moved. Most of the corrections came from something that went wrong in my own work.

Two panels compare five positions. In May: the bottleneck is clarity of intent, every example of the spec had held up, organizations need fewer generators and more evaluators, principles outlast personalities, and the bargain is a plan affected people can interrogate. Now: the constraint can move as the work improves, the spec is necessary, revisable, and insufficient on its own, evaluation means funding repeatable checks and the people who own them, principles are carried in defaults and habits people can challenge, and the bargain means making the decisions about work, learning, and saved time explicit.

The line holds as a warning

By stack I mean the tools under the work, from the language and the cloud to the model and the agent around it. This year took one away.

On Friday, June 12, Anthropic said a U.S. export-control directive required it to switch off Fable 5 and Mythos 5 for every customer. I'd been running Fable for four days. My usage chart shows the bars ending that evening, and the next two days ran on Opus 4.8.

The work kept going. My specs, standards, and tests read the same on Saturday as they had on Friday. They gave me a way to continue and a standard for checking the replacement. Switching models isn't enough until you've verified how the replacement behaves on your work.

I've since made portability a design goal in AgentMachinist, which runs one delivery workflow through Claude Code, Codex, Pi, or OpenCode behind thin adapters. The engineering system should last and the agent should be replaceable. I don't have comparative results yet.

Never is a strong word, and my own summer argued with it. I built System Headroom inside Apple's App Sandbox and lost most of my arguments with it. I rebuilt a web app as native software because cross-platform frameworks fought the integrations I wanted. In June I wrote "rarely the stack," which was the more careful word.

Those are real technical constraints. The stack decides what's possible, expensive, or allowed. It can also disappear on a Friday.

I'm keeping the line as a warning against mistaking a tooling decision for an operating model. The claim I can defend is narrower, that better tools alone have never explained reliable delivery in the organizations I've led. DORA's 2026 report on AI returns argues that those returns come from the organizational system around the tools. The work still depends on how we frame it, what context we trust, how we check it, and who can operate it. A literal technical bottleneck deserves fixing too.

The constraint moves

The May sentence named a place. It said the bottleneck is clarity of intent, as if the constraint had one address. Five months of my own posts say otherwise.

On May 24 I called it the frame, after the refactor that solved the wrong problem. Three weeks later I wrote that it had moved from generation to verification, after a checker caught a claim I had read six times. By August it was trusted context, then operability.

Read back to back, those posts could look like a writer renaming his thesis every few weeks. Eliyahu Goldratt's 1984 novel The Goal describes the pattern, in which relieving a system's constraint can expose another. His five focusing steps send you back to the first and warn against letting inertia become the next constraint. In May I stopped at the one I'd found.

The goal here is useful changes that meet the intended need and can be operated reliably. Five places to look have shown up so far, listed in the order work usually reaches them.

Framing means we're solving the right problem. The spec records the intent precisely enough to check. Trusted context means we know which organizational answers deserve authority. Verification means we have evidence beyond the author's claim. Operability means someone can restore the service when production disagrees.

Five places to look: framing, spec, trusted context, verification, and operability. Framing means we're solving the right problem, named second on May 24. Spec means the intent is recorded precisely enough to check, named first on May 13. Trusted context means we know which organizational answers deserve authority, named fourth on August 15. Verification means we have evidence beyond the author's claim, named third on June 14. Operability means someone can restore the service when production disagrees, named fifth on August 24.

These links overlap. Trusted context shapes the frame and the spec. Verification and production reveal gaps in both. A failure is useful only if the lesson finds its way back into the next run.

I found them in a different order, the order in which they hurt, and I'd be surprised if five is the final count. I now ask which link is limiting the work in front of me. Once it's improved, I look again.

A spec is necessary and not sufficient

The spec is still the most valuable thing I write. It has also come up short three times since May, and each time narrowed what I'm willing to claim for it.

The first was the refactor from the opening. What I'd written down was precise and described the wrong problem, so the tests confirmed my misunderstanding with complete consistency. A spec can't check its own frame.

The second was a gap in my argument. Nobody Pages the Agent started when I noticed that almost everything I'd written stopped at deployment. A spec that covers the happy path helps you build a service. It tells the person holding the pager little about how the service fails or how to bring it back. Ownership, service objectives, failure modes, and a rollback someone has run now belong in the spec.

The third is a limit on my favorite line from May, that the code is exhaust. In July I wrote about one engineer porting roughly half a million lines of Bun from Zig to Rust. Bun's postmortem reports roughly 60,000 tests and 1.39 million assertions passing before merge. It also reports 19 known regressions, since fixed. An exceptional test suite carried a great deal of intent across the rewrite, and still missed things.

In enterprise legacy systems, behavior lives in exception queues, hardcoded rules, and dependencies that nobody documented. The code and the running system may be the only complete record available. Some of that behavior was intended. Some was an accident somebody downstream learned to depend on.

Before I call that code exhaust, I need evidence that the behavior worth preserving has been captured elsewhere and can be checked. Executable contracts make replacement safer without making every implementation disposable.

Thoughtworks has been cooler on this pillar than I have. It placed spec-driven development at Assess on its Technology Radar in November 2025, the ring for techniques worth exploring. Birgitta Böckeler, a Distinguished Engineer there, watched a tool turn a small bug fix into four user stories and 16 acceptance criteria. Her worry is that heavy specification up front repeats an old mistake from model-driven development.

My practice agrees with her more than my slogan did. In her taxonomy, calling the code exhaust sounds like spec-as-source, where people edit only the spec. What I do is spec-anchored, where specs and standards stay with the code and change with it. I still test the running preview and audit a sample of merged pull requests by hand.

People can't fully say what they mean until they see it running, and working software is how we find out. Cheap implementation makes that loop faster. I can build the wrong thing in an afternoon, learn what I meant, and put the lesson where the next run will read it. The spec is where the correction gets stored, so a spec that never changes isn't doing that job.

Evaluation needs its own capacity

In May I asked whether evaluation capacity was separate from specification clarity, or the same skill at a different height. I now treat evaluation as its own capacity constraint. A clear spec doesn't supply the time, expertise, or infrastructure to check what gets built.

My clearest evidence is small. I built a verifier that reviews every post on this site before it ships. The first useful thing it did was catch a memory requirement I had stated as a simple property of a model. I'd read that sentence six times. I was the reviewer, and by then I was recognizing the sentence instead of reading it.

The May essay said organizations need fewer generators and more evaluators. Adding reviewers alone can recreate the rushed review at higher volume. What worked for me was encoding the repeated checks in a review that runs every time. A person still writes the standard, reviews exceptions, and decides whether the standard is good enough. My coding pipeline keeps two human approvals and a hand audit of one in 10 merged pull requests.

The verifier is fallible too, particularly when both passes use the same kind of model. A passing review means the checks we chose ran and passed, and it leaves open whether we chose the right ones.

DORA's report identifies a verification tax during adoption. In the Stack Overflow survey released October 6, 48% of respondents to the trust question said they trust output they can easily verify. Fewer than 7% trust it for many tasks, including important work decisions. That supports investing in evaluation, but it doesn't establish its independence from specification quality or measure how well the checks work.

One finding cuts against me. In April, Faros reported two years of telemetry from 22,000 developers. Task throughput per developer rose 34%, bugs per developer rose 54%, and unreviewed merges rose 31%. Mature, high-performing teams saw the same deterioration.

Faros sells measurement and compares its customers' low and high adoption periods. Bugs per developer also isn't bugs per change; volume can contribute. I hold the result loosely, and I can't dismiss it.

Its later analysis of deeper adoption found some delivery recovery alongside persistent review and operational burdens. Incidents per pull request were up 14.5% while monthly incidents were up 125%, so per-change risk stabilized and volume drove the total. The rise in unreviewed merges grew from 31% to 76%. Substantial agentic review was associated with faster first reviews and lower change failure rates. Faros explicitly calls those findings correlational.

"Stronger systems" is too vague a prescription. Review requirements that hold under pressure, error budgets that change release decisions, and evidence of operability are concrete enough to evaluate. I believe they help, and I haven't measured the combination at enterprise scale.

Machine judgment is getting cheaper too. I'm building a feedback triage pipeline on Jev, a model that returns typed decisions and probabilities and writes no prose. If it performs well on my queue, it could shrink the share of evaluation I do by hand. The remaining work includes choosing which errors are acceptable, noticing which criterion is missing, and owning the result when the check was wrong.

Principles last when people can inherit and revise them

The third pillar said principles outlast personalities. I still believe it. Principles last when people can inherit them as defaults, understand why they exist, and challenge them when the work changes.

I learned that from a control I thought was finished. When we moved to pipeline-first delivery, we removed engineers' standing access to production and built a break-glass process for emergencies. It worked, and I considered it done. Then we reviewed the requests and found emergency access handling routine cleanup, because no pipeline path existed for that work. The control worked as designed, and each approval still told engineers this was how the job got done.

We fixed it by building the missing paths. What I took from it is that a default teaches whether or not you meant the lesson. A decision is only worth preserving alongside a way to find out it's wrong. A default needs an owner, a stated reason, and a path for changing it.

Platforms carry those decisions in features. Incentives, decision rights, apprenticeship, and operating habits also carry principles into the work.

Agents make the platform part concrete. The test I use is whether an agent that joined tomorrow could deploy a service correctly without asking anyone. The colleague who remembers an exception has to make that knowledge discoverable. When the agent acts, the platform should record whose authority it used and be able to stop it without locking out the person. Those are leadership principles written as platform features, one of the most durable forms I've seen.

The bargain is a budget

In May I asked builders to stop saying "workforce optimization" and make the real plan legible enough for affected people to argue with. I still want that. Three budget decisions underneath it now need names: when we redesign the work, how we fund learning, and who gets the saved hour.

The first is order. Redesign the work before the org chart, meaning the workflows, decision rights, ownership, and evaluation loops. Let staffing decisions follow what you learn. DORA's report makes the same call from the finance side and advises against headcount reduction as a strategy.

The second is the apprenticeship. Entry-level work always produced two things, the artifact and an engineer who got better by making it. Agents can deliver the first without the second. The system that develops people who can evaluate needs a line in the plan. Stack Overflow's most common stated avoidance reason combined losing skills with training AI to replace you. It doesn't isolate apprenticeship, but the concern is real.

The third is the saved hour. When I audited my own, the time AI gave back had gone into more apps, a book, and deeper work on the job I already had. None of it went to rest, and I'm not sure I chose that. An organization that absorbs every saved hour as more output has made the same decision without saying so.

The people affected need a say in those choices. Put the learning plan and the proposed use of saved capacity in front of them, name who owns the decisions, and give them a route to challenge the allocation. A bargain needs a way to be negotiated.

Metering made the cost harder to hide. GitHub began moving Copilot to usage-based billing on June 1; existing annual Pro and Pro+ plans stay on request-based billing until they expire. My 26 days of Claude Code amounted to $2,556 at API rates against a $200 subscription, an equivalent usage cost rather than my bill. A vague request now carries visible tokens and rework. Trading a salary for a subscription stops looking like simple arithmetic.

The audience problem I flagged in May is still open. I write these essays for people who run engineering organizations. The people absorbing the consequences mostly aren't reading them, and a budget they never see is still a decision made without them.

Where I am less sure

I'm more confident that evaluation deserves its own capacity plan. I'm confident in the spec pillar in its narrower form. I trust the mechanism behind the platform pillar and I'm short on evidence for it. On the bargain, I trust the three decisions and I've made little progress on reaching the people affected.

The largest weakness is the evidence. Most of it comes from my own repositories and pipeline, where I hold the whole mental model. I still don't have a published enterprise before-and-after series, such as deployment frequency or recovery time. This is an operating hypothesis. The anecdotes are good, and they're still anecdotes.

I owe four follow-ups: whether Bun's Rust port holds its defect rate over a year, what my pipeline's telemetry shows, how one workflow performs across five coding agents, and how Jev's probabilities behave on my feedback queue. None of those results are in. Each one could move a pillar.

Two positions changed and should be on the record. In The Frame Is the Bottleneck, I told leaders to retire the personal-agent fantasy. On October 1 I wrote about five personal agents I use. The maintenance problem I worried about is real, and hosted vendors now carry more of it for consumers. I'd still keep personal agents out of the center of an enterprise strategy.

The May 24 essay also proposed throughput per framer. I meant systemic leverage, but the phrasing invites individual ranking. I withdraw it. I'd measure team flow, rework, and accepted outcomes instead. A measure that rewards people for needing less help teaches them to stop asking for it.

The nearer test is whether the controls I recommend improve outcomes. At comparable change volume and risk, do they reduce escaped defects and rework without simply moving the delay somewhere else? If a check adds waiting and catches little, I should change or remove it. If clearer context has no effect on repeated failures, I should question whether context was the constraint.

I'd also revise the larger argument if machine evaluators reliably handled consequential cases for which nobody had written a criterion. I haven't seen evidence that settles that question.

Walk one change backward

You can start on your own team with one change. Take the last thing an agent helped you ship and walk it backward. Who framed the problem, and who checked the frame? Where was the intent recorded? What context did the agent get, and who vouched for it? What checked the result besides its author? Who could restore the service tonight?

The first question nobody can answer gives you a place to investigate. Look for where work waits, returns for rework, or creates failures someone else has to absorb. Improve that link, then check whether useful, reliable delivery improved. Ask again after the change, because the constraint may have moved.

In May, the claim I was surest of lasted 11 days. If you find the next weak link before I do, write to me at vin@vinny.dev.

// found this useful? share it

Post on X Share to LinkedIn
Vinny Carpenter

Written by Vinny Carpenter

VP Engineering · 30+ years building software

I lead engineering teams building cloud-native platforms at a Fortune 100 company. I write about engineering leadership, AI-assisted development, platform strategy, and the hard lessons that come from shipping at scale.

keep reading