Coding Is No Longer the Constraint
Getting to the root of a problem always requires going past the surface, and finding the underlying cause. It's the difference between the symptoms exhibited, and the real diagnosis.
I was dealing with an escalation on a project once where the "problems" were described as quality issues and developer velocity issues. The combination of those is particularly nasty because going faster often results in lower quality. We attacked the problem by increasing our automation testing engineers, as well as providing the team with AI coding assistants.
The good news was that velocity went up, but the number of defects wasn't going down, they were actually increasing, and being found late in the game in User Acceptance Testing (UAT).
It was this data that made me dig in, and go even deeper to the problem, "a 5-whys analysis". What we ended up uncovering is that there were two definitions of done, "developer done" which was being completely done against mock APIs, and "UAT done" which was only done in the UAT environment with real representative data. A critical gap was that UAT was an environment that dev and QA didn't have access to. This fact was further compounded by late breaking API contract changes and the fact that all the tests were end-to-end tests, which were thorough, but added considerably to the cycle-time because the full regression suite took hours to re-run.
The perception was that it was a coding and quality problem, but actually it was a test data, contract, and batch size problem. We responded to the perception instead of identifying and optimizing at the constraints.
Once we realized where the true constraints were, we were then able to establish flow, shift left on quality, decrease batch size, and burn down defects with improved velocity.
The Two Complaints
If you ask any business leader what their two biggest complaints are with technology, chances are they'd say: It takes too long, and it costs too much.
I agree.
Being a software developer in a purely digital world is tough. There is no "it's close enough", it either works or it doesn't, zero or one. Every other step in the process up to the point of working code has some room for "close enough". Ideas, research, experience, design, requirements, mockups, we iterate on them until they're good enough to start development. Even in testing, we try to hit every possible edge case and scenario. In UAT we put it through close to real world situations. We subject it to penetration testing, load testing, accessibility testing, every problem, every defect, must be addressed by a developer, in code.
As we all know, the further downstream we find the problem, the more costly it is. We also have known for over 25 years that the practices of automated testing improve velocity and reduce defects. We have known for over 15 years that cloud native, infrastructure as code, and DevOps improve velocity, speed to market and lower cost. That "contract first" lowers the cost of change. With the advent of AI coding assistants like GitHub Copilot and Cursor, combined with powerful foundation models, we now have expert level assistance on algorithms, patterns, practices, and syntax.
For many companies, even those who have "adopted" the practices of automation, DevOps, and AI coding, velocity has remained relatively unchanged. The reason is that coding is not actually the constraint in most systems and per the lean theory of constraints from our friend Eli Goldratt, any improvements made anywhere else but at the constraint, only make the constraint worse.
"I still claim that there are only few constraints... We must put our finger on the core problem, on the root that causes them all."
Eli Goldratt
Now, just to avoid an argument, let's say that coding was the constraint. I say was the constraint, because it is no longer the constraint. The foundational models that came out ~end of 2025 (Anthropic, OpenAI, and Google), and the agentic tools (Codex, Claude Code, Cursor) have now removed coding as the constraint. Greenfield, brownfield, 25-year-old PowerBuilder, 30-year-old COBOL, legacy frameworks, you name it, and the models can now handle it.
As an aside, I find it hilarious when people say "Codex can't do x, Claude Code can't do y" only to find out they've never even used the tools themselves. For the haters out there, get hands-on with the tools for a solid month to understand where the boundaries truly lie.
For the companies that have embraced those foundational norms, they're able to operate at speed and economics that make them moat-evaporating disruption machines. Anthropic was founded in 2021, and currently has a market cap between $300B and $1T. They're using Claude Code + their foundation models and compounding to build the next generation of their products.
For those that still have the "wait states" like ticket queues, and manual review processes, those constraints are about to get really bad.
The new constraints
- Requirements clarity. Refinement time that nobody noticed when coding took weeks.
- Design quality. System design, API contracts, data models. Bad design generates the wrong code faster.
- Code Review, the step immediately after coding is the first place where the constraint is felt. Merge, or Pull Requests pile up waiting to be reviewed, commented on, and approved by a human.
- Deployment, the step right after testing where features waiting for full integration, UAT testing, and other manual gates pile up. For those that use feature flags and continuous delivery this may not emerge as a constraint. If not, then pat yourself on the back.
- Operational Readiness, the Site Reliability Engineering checklist. The things that must be true before we put a new system into production. Most important, but often an after-thought is observability. This also includes the run books, dashboards, alerts, and monitoring for our runtime system.
- Boundary Constraints, hand-offs at each boundary from design to dev, dev to QA, QA to release. Each point "in-between" where work accumulates is a "wait state" and wait == waste.
- Review and approval gates. Manual inspection and review in any and all forms. If we're waiting on a human to inspect, it's going to be too slow to keep pace with agentic.
- The "final boss" constraint: Creativity & ideas. Innovative, differentiated, disruptive opportunities in the market. Going from idea to ready for construction is going to quickly become our biggest constraint in less than 18 months.
The fix
Before we jump to the fix for the new constraints, make sure that these really are the constraints. At the very least do a value stream mapping exercise on your Software Delivery Life Cycle (SDLC). If you really want to get good information, invest in a metrics tool that can give you basic DevOps Readiness Assessment (DORA) metrics on top of your agile project management, source control, and Continuous Integration, CI, Continuous Delivery (CD), and Continuous Testing (CT) tooling.
Pre-conditions
In the pyramid revisited, the foundation is largely the same. There isn't any new box with "AI" on it, because AI is part of the "substrate", just like there's no box for "the internet" or "mobile".
So, first of all, get your foundational house in order. Don't try to just slather AI on top of a click-ops, ticket-driven process, or manual end-to-end testing. The good news is that AI will help you greatly accelerate this process. The foundation models know Terraform, Azure, AWS, GCP, every test framework out there, GitHub Actions, Jenkins, you name it. It's an expert at bash and the command line. Get a clear vision for where you need to go, and get there quickly. Establish clean golden paths that are standards based.
Also, move beyond the Integrated Development Environment (IDE) as your main means for doing AI coding. Get to the command line (CLI), and learn how to establish the "agentic loop" so you can improve your task horizon.
Shift all the way left with Service as Software, everything becomes an agent
Shift-left is not realized nearly as often as it's talked about. We have shifted some things left as we've adopted the frictionless foundation with automation and automated inspections, linting, automated (Unit, Integration, API, e2e, contract) tests, static analysis, code coverage, security analysis, etc. in our CI and pull-request pipelines. That was a good first start. In many cases it allowed us to catch things before they even left the developer's local machine.
The things it couldn't catch were the structural issues. The design patterns, leaky abstractions, architectural choices, SOLID principles, etc. Things that were stylistic, best practices, but still extremely important. Those were the things that were churned on in merge requests. The reason we churned on them so hard was because the first time that a senior engineer was seeing the code was when the PR was submitted, and it took a human reviewing the code to catch that stuff.
Agent Teams for Adversarial Review of Code
Now we have agents, and not just a senior developer, but a senior staff engineer, a quality engineer, security specialist, compliance specialist, lead architect, available to do the first round of review as an agent. Not only that, but I can run all of those agents pre-wired with the company's best practices, standards, policies, and guidelines, before the code even leaves the developer's machine. That's before the PR is even submitted. It's already going to have the tar beaten out of it across as many dimensions as you want, and not just in the context of the PR itself, but also the current state of the repository. Each agent in the adversarial agent team compiles their findings, and then feeds back to the developer agent to build out a plan for remediation. Lather, rinse, repeat, until everything is resolved. Then put it through the rest of your normal CI / CD / CT process for all final verification checks, and a final review by a human to review all of the massive body of artifacts that are built up for that PR. And that's JUST for Coding. We can apply the same pattern of review throughout our process.
Applying the agentic pattern at the other constraints
- Test coverage and edge case agents who analyze the current code and test coverage. Additionally these agents can ensure that every defect gets a failing test with the reproduction steps so that we're able to constantly fix-forward without regressing.
- Artifact and change review agent. Instead of manual inspection of artifacts, we can create an intelligent, interrogatable layer on top of things like audit, traceability, code and test coverage reports, security and static scans, documentation and checklist completions. Reviewers can ask intelligent questions of the body of information through a chat interface, and responses provide synthesized information with links back to the source material.
- Full integrations at the seams with clean contracts. Given that the boundaries between disciplines and teams is often where things fall through the cracks and information is lost, we can utilize MCP, CLI, and API integrations to more effectively manage areas of hand-off. Changes flow more seamlessly, and are proactively detected rather than reactively dealt with. For example, a visual design change in Figma can be automatically be evaluated against the codebase, test cases, and detect regressions across all dimensions (usability, accessibility, performance, etc.) as a "what-if" scenario.
- True operational readiness, and continuous improvement for SRE teams. Objective analysis of the full workload package can be evaluated against SRE readiness checklists before transferring ownership. Gaps can be closed quickly with agent teams. Additionally, any new issues uncovered during operations, can quickly be converted into automation or pinpoint fixes to prevent toil accumulation.
Targeting at the constraint with metrics
Metrics are essentially the instrumentation of our value stream. It's also important to make sure that we are using metrics to identify constraints and improve our process not to enshrine metrics as something to be gamed. What I mean by that is, once a metric is tied to compensation or performance, it is guaranteed to be gamed. Also watch out for policies that made sense at one time, but then no longer make sense with respect to metrics. For example, a metric that all pull requests must improve code coverage works great if you have low coverage, but once you achieve a high level of coverage you'll have the agent creating getter and setter tests just to gain an increase.
Metrics should help point you at the "smells" in the process. The area where something is going on that you need to improve. Once it's eliminated, start hunting for the next constraint. The big ones here are wait, cycle-time, and batch size accumulation.
The constraint moved
There is always a constraint. Remove one and another emerges. Theory of constraints does not let you off the hook, ever.
For decades the constraint sat in the back half of product delivery. Build. Test. Deploy. Operate. Those problem spaces are mature now. The agentic substrate this post has been about is the last big push on that half of the lifecycle, and the one that finally takes the whole thing off the critical path.
The new constraint sits at the front. Figuring out what to build, who it is for, why it matters, how we know. Code is cheap now.
The constraint emerging at the front is research and understanding, but keep going. Past research, past synthesis, past segmentation, the constraint that does not compress is creativity. The act of seeing something nobody else has seen yet. The bet on what is worth making at all.
The substrate cannot do that for you. AI can simulate it, but it's not truly creative.
The org that wires every layer of the substrate around that human act becomes a pure innovation engine. Everyone else becomes a faster version of what they already were, which is not the same thing.
Author's note: I get a lot of my inspiration from conversations with friends and peers. Thank you to Brandon Varilone for the stimulating conversation on coding no longer being the constraint, and to Chris Reed for the forward-looking vision of creativity as the new differentiator.