Delegate the Typing, Never the Attention
I built CARL to take a Jira story through implementation and review to a finished pull request. It worked. It also showed me why AI changes how engineers build software without transferring technical ownership to someone else.
July 13, 2026 · 8 min read
Rob Tuckfield, CFP®, AFC® · Business Systems Lead
- AI
- agents
- engineering
AI coding agents are force multipliers. But it is worth being precise about what they multiply: whoever is operating them.
A strong engineer directing agents gets multiplied output. Technical judgment gets multiplied too, and that cuts both ways. Remove that judgment from the loop and the agents will still produce code—often quite good code—but nobody is necessarily making sure the individual decisions add up to a coherent system.
I did not want to take that conclusion on faith. So I built the other side of the argument properly.
Meet CARL
CARL stands for Code Automation and Review Layer, and the name describes his two jobs.
The Code Automation side is an autonomous development pipeline. CARL is connected to Jira: hand him a story and he drives AI coding agents through specification, planning, implementation, review, and rework until they produce a finished pull request.
He can run multiple agents concurrently in isolated git workspaces, route different models to different phases of the work, review the result, feed that review back to the agents, and pause for human approval at defined checkpoints. Anything headed toward production still requires approval from a code owner.
CARL also runs inside the same engineering harness the rest of the team uses: shared skills, coding standards, review practices, and context about our systems. His agents build according to our practices instead of starting from a model’s defaults every time.
CARL began as our implementation of OpenAI’s Symphony, a published specification for orchestrating coding agents from an issue tracker. The original idea was the automation pipeline. The Review Layer came afterward.
Once the orchestration infrastructure existed, automated review was a natural extension. CARL already had GitHub access, agents, and isolated workspaces in which to inspect the code. Using those capabilities to review the team’s pull requests turned out to be the part with the clearest lasting value.
The question I wanted to answer
I built CARL to test a concrete proposition: how far could a business requirement travel through the development lifecycle before it needed an engineer’s direct attention?
The ambitious version was a colleague describing a feature in Jira and CARL carrying it from that description to a reviewed pull request, without an engineer driving the implementation. Business would own the desired outcome, CARL would handle the mechanics, and a code owner would approve the result before anything entered production.
I did not turn that workflow over to non-engineers immediately. I operated CARL myself on a sequence of real features in VAMOS, our internal advisor platform, to find out whether the process was good enough to justify doing so.
Technically, it worked. Operationally, the answer was more interesting.
The interface is not the system
AI has made it remarkably easy to turn an idea into a convincing interface. That is genuinely useful. A working prototype can communicate intent better than a written requirement or static mockup, and non-engineers can now build valuable prototypes and personal tools that would previously have remained ideas.
But the interface is not the application.
Production software also has to model the business correctly, preserve authorization boundaries, maintain data integrity, handle exceptions and historical state, integrate with existing systems, survive failures, and remain understandable to the people responsible for it.
A prototype can demonstrate what someone wants to see. It cannot establish that the system underneath is correct.
That distinction matters because an application can look nearly finished while most of its consequential engineering decisions have not yet been made. CARL was an attempt to see whether a sufficiently capable pipeline and a sufficiently strong set of guardrails could make those decisions safely on someone’s behalf.
What worked
I used CARL to build a finance administration area in VAMOS through a sequence of incremental stories. One established the page and its access controls. Others added aggregate views and progressively deeper ways to inspect the underlying information.
Every story reached a usable state. Every story became a pull request, passed review, and was merged.
The agents were genuinely reliable at well-specified implementation. Given a clear objective, the necessary context, and concrete acceptance criteria, they could build working features consistently. The failures rarely came from a model being incapable of writing the code.
The harness mattered more than the model. Shared system context, repository-level standards, explicit approval gates, and automated review improved the results more than swapping in a newer model. CARL worked because he operated inside an engineering system, not because an agent was independently brilliant.
But working software was not the only thing I was measuring. I also cared about the time required to produce it, the quality of the result, the amount of review it needed, and whether I could trust it without reconstructing every implementation decision afterward.
That is where the automation pipeline started losing ground.
Local correctness is not system correctness
When I drove agents directly, I made architectural, data, and implementation decisions as the work unfolded. I could redirect them immediately when an assumption was wrong or when a locally reasonable choice did not fit the larger system.
With CARL, I moved toward managing by outcome. I still reviewed the code, worked the approval checkpoints, and tested the requested functionality. But more of the implementation happened between those checkpoints, which meant I encountered decisions later and with less context about how the agents had reached them.
One VAMOS story exposed the difference.
VAMOS has a family of backend endpoints serving different compensation views. Some intentionally allow advisors to see generalized information across the firm. Others contain more sensitive data and restrict advisors to their own records unless they are operating in a privileged role.
The new finance feature required adding Finance to those privileged roles. CARL made that change correctly. But it also reused the same self-or-privileged access check across several related endpoints that were intentionally more open.
The result was internally consistent. The authorization helper existed, the endpoints dealt with related data, and the new Finance and Admin experiences worked correctly. It was also wrong for the system: ordinary advisors could no longer access information they were deliberately supposed to see.
I reviewed the changes and tested the new functionality end to end as both Finance and Admin. Those were the roles the feature was built for, and both worked. The regression only appeared under an existing advisor workflow whose endpoints had acquired a new restriction.
It was not a catastrophic failure or a piece of inexplicable generated code. It was a plausible security rule applied too broadly. That is what made it useful.
The final correction was not simply to remove the added security. We had to separate the endpoints according to their actual sensitivity, preserve the restrictions where they belonged, and restore the intentionally broader visibility everywhere else.
That is the systems problem: a feature can work inside the frame of its ticket while making the product less correct somewhere outside it. Someone still has to hold the wider frame.
The comparison that mattered
By the time I had written a story precisely enough for CARL, worked through the approval checkpoints, reviewed the resulting code, tested the feature, and corrected the parts that were merely acceptable rather than good, the autonomous workflow took longer than driving the same coding agents directly.
The output was usually fine. It was rarely disastrous, but it was also rarely the implementation I would have designed with full knowledge of the system. I have since revisited and improved much of the code CARL produced.
That made the practical comparison straightforward. The choice was not between AI and no AI. I use several AI agents in parallel because the pace of our work would make writing everything by hand impractical.
The choice was between agents operating autonomously from a ticket and agents being directed by an engineer who could make technical decisions throughout the work.
The engineer-directed agents were faster. Their output was better. And because I understood why the code had taken its final shape, the result was easier to review and trust.
The part that lasted
CARL’s Review Layer now examines every pull request submitted to VAMOS except his own, including automated dependency updates. He organizes findings into must-fix issues, should-fix issues, and suggestions.
The same review skill runs before a pull request can be opened. Must-fix findings block the process, and should-fix findings have to be resolved or explicitly acknowledged. CARL then performs a fresh review once the pull request exists.
Most engineer-written pull requests do not produce must-fix findings. They commonly produce one or two should-fix items and several suggestions, not all of which ultimately require changes. But the review is meaningful on most pull requests, and CARL has caught real issues—including incompatible changes proposed by automated dependency updates.
That is where the system found its role. Automated review expands the amount of attention the engineering team can apply. It gives every change a consistent first pass and lets human reviewers spend more time on the findings that require judgment.
It supports technical ownership instead of pretending to replace it.
The verdict
The pre-AI shape of the relationship between business and engineering still holds.
Business owns the process, the problem, the desired outcome, and the constraints. AI makes it easier for non-engineers to communicate those ideas through working prototypes instead of static mockups. That is a meaningful improvement.
Engineering still owns the production implementation: the data model, architecture, authorization boundaries, integrations, failure modes, and the accumulated decisions that make a collection of features into a reliable system. Engineering’s job is not merely to produce code. It is to hold the whole system in view while making each local change.
AI has radically changed how that implementation happens. It has changed how quickly one engineer can work and how much one engineer can carry. It has not removed the need for someone with technical judgment to own what the code actually does.
With the tools as they exist today, non-engineers can build valuable prototypes and personal tools. Production software still needs an engineer as its technical owner.
CARL’s autonomous pipeline exists, and it works. We no longer use it to carry Jira tickets through implementation because it lost a fair comparison to an engineer directing the same tools.
CARL still runs as the Review Layer of his own name, applying the system’s attention to every pull request the team submits.
Which brings me back to the multiplier thesis. The agents were capable in both cases. The difference was what they had to multiply.
Delegate the typing. Never the attention.