What you will take away
- AI removes setup and boilerplate work, not architectural judgement.
- Review, testing and observability gain more from AI than code generation does.
- The teams that benefit already had strong CI, tests and code review in place.
What AI changed first, and why it was not the code
The headline promise of AI in software was that it would write the application for you. That is not what happened in practice. What changed first was everything around the code: scaffolding a new service, wiring a repository to a pipeline, translating a schema into typed models, writing the fifteenth integration test that looks like the previous fourteen. Those tasks are mechanical, well represented in public code, and expensive in engineer hours.
On the projects we run, the measurable gain lands in the first two weeks of a build. Environment setup, base architecture and the first pass of CRUD endpoints come together in a fraction of the time they used to. What does not compress is the part that decides whether the product works: understanding the business rules, choosing where state lives, and deciding what happens when a downstream service is unavailable.
AI gives you a running skeleton in an afternoon. It does not tell you whether the skeleton is the right shape for your business.
Where large language models genuinely help
The most reliable wins come from tasks where the model has full context and a human checks the output immediately. That means work inside a single file or a single pull request, not sweeping changes across a codebase.
- First-pass code review that flags null handling, missing error paths and unchecked inputs before a human reviewer opens the diff.
- Test generation for existing functions, especially edge cases around boundaries, empty collections and time zones.
- Migration work - moving a component library, upgrading a framework major version, or converting a service from one client library to another.
- Documentation generated from the code and regenerated when the code changes, so it stops going stale.
- Log and trace summarisation during an incident, where the sheer volume is the actual problem.
What these have in common is a tight feedback loop. The model proposes, a test or a reviewer verifies, and a wrong answer costs seconds. The moment that loop stretches - a model refactoring an entire module unattended - the economics reverse, because reviewing a large machine-written change is slower than writing it yourself.
Security and quality: prediction rather than generation
The quieter and more valuable shift is in analysis. Static analysis trained on large volumes of real code now flags risky patterns with far less noise than the rule-based scanners it replaces: a query built by string concatenation, a token written to a log in plain text, a permission check that exists on one route and not on its sibling.
We treat those findings the way we treat a linter. They run in CI, they block a merge when the severity is high, and they are tuned per repository so the team does not learn to ignore them. A scanner nobody reads is worse than no scanner, because it creates the impression of coverage.
Performance work has moved the same way. Models that simulate realistic traffic patterns surface the query that degrades at ten thousand rows but not at ten - the class of problem that never appears in a manual test and always appears in production three months after launch.
What has not changed
Requirements are still the hardest part of software, and no model can tell you that the finance team calls a refund something different from what the warehouse calls it. Data modelling is still the decision you cannot cheaply reverse. Accountability is still human: when a payment double-posts, the answer cannot be that the tool wrote it.
There is also a discipline cost. AI raises the volume of code a team produces, which raises the volume of code a team must review, test and eventually maintain. Teams without solid CI, meaningful test coverage and real code review do not get faster with AI. They get into trouble faster.
How we apply this on client projects
Our rule is that AI may touch anything a test can verify, and a human owns everything a test cannot. Generated code is reviewed like any other contribution and never merged unreviewed. Tooling that touches a client repository runs against code we are licensed to work on, and no client source leaves the environments agreed in the contract.
The result for the client is not a novelty feature. It is a shorter path from signed scope to a running staging environment, more test coverage per sprint than the same budget bought two years ago, and fewer of the defect classes that used to be found by users.