TL;DR
Software development is a complex and often expensive process. So the question was how the workflow could be improved by using AI. The result is described in detail in the sections below; the figures achieved come first. In each case the averages of the following three scenarios are compared:
- The last three sprints (1 sprint = 2 weeks of development work) before AI tools were approved for software development (= classic software development process)
- The last three sprints before implementation of the new, AI-supported process began (= classic software development process with developers supported by AI tools, but without integration into the process)
- The first three sprints after full implementation of the process described here (= new development process with the AI tools integrated into it)
The values in the table below each refer to reference state 1 — that is, to the development process as it is still practised in many companies. Scenario 1 therefore equals 100 % for every KPI: values above 100 % mean an increase over the reference state, values below 100 % a decrease.
| KPI (scenario 1 = 100 %) | Scenario 2 | Scenario 3 |
|---|---|---|
| Story points delivered per sprint | 184 % | 434 % |
| New bugs per sprint | 104 % | 35 % |
| Average time to fix a bug | 90 % | 20 % |
The results are striking. Simply approving coding agents and letting the developers use them raised productivity considerably. Once the process around them is deliberately structured, standardised and optimised on top of that, another, even larger jump follows.
The starting point
The setup already in place: GitHub as the platform — repository, pull requests, reviews, CI — and the Atlassian stack, with Jira for tickets and Confluence for documentation. A fairly common tool set, used in this or a similar form by many teams.
The first design decision follows from it: the process docks onto that landscape instead of replacing it. Tickets stay in Jira, documentation stays in Confluence, code review stays a pull request. No new tools — what changes is who does the work inside them.
Repository preparation — one-off
Code states what is. Specs state what should be. For a human that distinction is a nicety; for an agent it is the decisive one. An agent that derives its requirements from the implementation promotes every bug to a requirement and every historical workaround to an architecture decision. It reproduces the current state very reliably, including everywhere the current state is wrong.
The one-off preparation therefore consists of translating the existing codebase into specs, with the help of the documentation already there and of human review — so that the intended state can be determined from the spec files at any time, and not from the memory of whoever has been around long enough.
Domain specs and technical specs
The translation has two halves, and both are needed.
Domain — the business knowledge: which rules a calculation follows, which states a transaction can take, which cases exist and which are deliberately excluded. A large part of this is written down nowhere, because it lives in heads, tickets and meetings. It is also the part that later decides whether an agent satisfies a requirement or merely writes code that compiles.
Technical — code style, architecture decisions, layer boundaries, error handling, which library is the chosen one for which purpose, and which patterns are deliberately not used. To a human these are conventions absorbed over time. To an agent they are acceptance criteria: they are the reason its output looks like the rest of the repository rather than like generic sample code.
The second source next to the code is the existing Confluence documentation. It gets mined, not adopted. Grown documentation always carries three kinds of content at once: domain rules still in force, decisions long superseded, and plans that were never implemented. Every statement is therefore held against the code. What is confirmed becomes a spec. What contradicts the code becomes a question for product management or a ticket. What is obsolete is recorded as discarded, so that it does not resurface as a requirement on the next pass.
Navigation files and the token budget
The second part of the preparation is a set of .md files for code navigation. An agent that does
not know where something lives searches for it — and searching is the most expensive way to find
out. A navigation layer answers four questions per directory or module up front: what lives here,
what the entry point is, what it depends on, where the tests are. Searching becomes lookup.
That pays off twice. Once on cost, because every run needs fewer tokens. And once on quality, because an agent with a narrow, fitting context works more accurately than one that has read its way through half a directory tree and ends up with a context window holding more incidentals than task.
The outcome of this phase is a repository an agent can work in autonomously and efficiently without running into context problems. This step takes some one-off effort at the start and then carries on continuously, as part of normal day-to-day work.
Ticket review — ongoing
The ongoing process starts with a sorting pass by an agent. Two questions have to be answered for every ticket. Is it ready for implementation — is the problem or the feature described precisely enough? And if so, can the implementation be automated by an agent, does it need human support, or should it be done entirely by a human?
Where the tickets come from stays unchanged: bugs arise as before, from user reports via support or from manual and automated tests; features arise from planning sessions between product management and developers. That is deliberate. The process starts after the ticket exists, so that it can begin running without the organisation having to be rebuilt first.
For bugs:
- Analysis in the code. Often the problem can be found directly: the reported symptom plus the places that could produce it are enough to name the cause. An agent reads the files involved together and comes back not just with a suspicion, but with an analysis that is enough to fix it.
- Reproducing in the browser. If the analysis stays ambiguous, the case has to be reproduced. For web applications, for example, an agent can do that directly in the browser.
A bug that neither shows up in the code nor can be reproduced in the browser is not ready for implementation. It goes back for human handling, and it goes back with the specific question that is missing.
For new features:
- Domain gaps. Does the ticket contradict existing specs? Does it leave a case open that it never mentions? Everything a human would “obviously” fill in is a gap here, and it has to be cleared before implementation.
- Technical problems. Is the requirement implementable in the current tech stack at all, or does it need larger changes — a new library, a schema change, an interface that does not exist yet?
None of this is resolved here. The review’s job is sorting, not deciding. Its output is labels on the ticket:
| Label | What it means, and what happens next |
|---|---|
agent-ready |
Description complete, no open domain or technical questions. Goes into implementation planning. |
agent-assisted |
Implementable, but with decisions that need sign-off. Goes into planning too — with checkpoints at exactly those decisions. |
human-only |
The effort sits in the judgement, not in the code. Goes into ordinary development with agent support. |
needs-info |
Bug not reproducible, requirement contradictory or incomplete. Goes back to support or product management — with the specific question. |
Two lists come out of this: tickets the following stages can work through, and tickets that need information. That second list is not a bad sign. It exists in every project, just invisibly — spread across tickets that go into progress and stall there, because the decisive questions only surface during implementation.
Implementation planning
For the released tickets, an agent plans the implementation. For a bug that plan is short: cause, affected code, the test that shows the fault. For a feature the planning is usually more involved — sequence of steps, affected modules, the specs that have to be extended.
Features that cannot be implemented in one go are split up. The parts that need human feedback in particular are carved out as their own sub-tickets: architecture decisions first among them. That is not a formality — it is the reason the rest can run autonomously. One open architecture question should not block four implementable sub-tickets.
The planning yields tickets that can be implemented entirely autonomously, and tickets that need human support. Both now at sub-ticket granularity rather than whole features — the line between “agent” and “human” runs through the middle of a feature, not between features.
Coding, variant A — the agent alone
For a ticket with a complete plan, implementation runs unattended. The steps, in this order:
- Extend the specs where necessary. Every ticket that introduces new behaviour carries a spec change with it, so that the spec files stay current.
- Set up test shells from the specs. Before implementation, the tests the code will have to satisfy already exist (test-driven development) — for features derived from the specs, for bugs as the test that fails today and prevents the fault from returning. Depending on the setup and the kind of task, those are unit tests, automated E2E tests or, in individual cases, manual tests. The order carries the whole construction: a test written after the code may well end up testing the code. A test written from the spec tests the requirement.
- Implementation of the code — by a dedicated agent.
- Implementation of the tests — by a dedicated agent. The separation matters: an agent writing code and tests in one context writes tests that confirm its own implementation instead of checking it.
- Review agent for the tests. Its question is not whether the test is green, but whether the implemented test actually covers what the specs require.
- Review agent for the code. It examines whether the new code matches the specs, both the domain ones and the technical ones.
The review agents each feed their objections back to the implementing agent. Several rounds are run here, until there are no objections left.
The abort condition
A loop without a limit is the usual mode in which a setup like this fails: two agents can correct each other politely for a very long time. The loop therefore has a configured number of rounds.
If that number is reached while objections remain, the run is aborted — but not silently. The current state of the code is pushed to GitHub and the open points are documented: which objection stayed open, in which round, what was attempted. The ticket then goes to a human with exactly that state.
A branch, its test situation and a list of concrete objections are a considerably better starting point than an empty ticket. The abort is not a failure of the process but its intended exit for the cases it does not carry alone.
Coding, variant B — human with agent
For everything labelled human-only or agent-assisted, the usual workflow stays: a person works,
with agent support. Only one detail about it is interesting, and it is the decisive part of the
whole design.
The steps from variant A are available to that person as skills — implement tests, test review, code review — and can be triggered against their own code at any time.
That makes the two variants one process rather than two worlds. A ticket whose autonomous run hit the round limit does not land in a team that works differently; it lands in the same workflow with the same tools — and a person who builds a feature by hand gets the review the agent would have got.
Finishing a coding task
How a coding task finishes is identical in both variants. The defined CI pipeline (static code analysis, tests and so on) has to pass, and the changes have to be confirmed by a human in a code review. To what extent that manual step can be dropped depends on each company’s philosophy, and on the experience gathered with the process described here as it runs.
What it delivers
The process as a whole delivers faster work, and work of higher quality. The second of those sounds counterintuitive at first, but it has three reasons that can each be checked independently:
- Test coverage rises, because the tests come out of the specs before implementation — and so are not the line item that gets dropped at the end of a ticket for lack of time.
- Agents find mistakes humans miss. They are the unspectacular kind: the forgotten empty case, the unhandled error branch, the copied block with one field left unchanged. A review agent reads the three-hundredth line as carefully as the first.
- People work on the questions that affect the system as a whole — architecture, domain contradictions, prioritisation. The places where a wrong decision is expensive and only becomes visible months later.
The cost side is in the TL;DR above. It is the result of those three points and not the purpose of the design: a process that is only cheaper does not survive, because the first serious regression ends it.
Where the human stays
Five places in the process are designed as handover points to a human:
- Architecture decisions. An agent can prepare them — options, consequences, a recommendation. A human should make them, because they often have long-term consequences and should line up with the general (product) strategy.
- Domain contradictions. When a ticket contradicts a spec, the question is not a technical one. It goes to product management, and the answer changes the spec, not just the code.
- Bugs that cannot be reproduced. What cannot be reproduced cannot be fixed test-first. The work that no agent shortens stays here: talk to the reporter, get the data, read the logs.
- The aborted runs. Every loop that reaches its round limit is a case for a human by construction. That share is the most honest metric the whole setup has: it measures not the agents, but the quality of the specs.
- Code merge. No code goes live without human sign-off.