Skip to content
8 min read

How does the AI software development lifecycle really work?

The AI software development lifecycle changes estimation, review, QA, and on-call by shifting control from code production to evidence and risk.

How does the AI software development lifecycle really work?
Table of Contents

Agents make code production cheap, but they do not make software delivery cheap. The scarce work moves to defining intent, checking evidence, limiting blast radius, and learning from production. A team that keeps its old lifecycle and merely adds an agent to the coding phase will create larger queues, harder reviews, and more surprises for whoever carries the pager.

The AI software development lifecycle needs a different control system. Estimate the path to a safely observed outcome, give agents bounded tasks with testable acceptance criteria, review risk instead of typing, and treat production signals as part of the change. The agent can perform much of the mechanical work. A named person still owns the decision to ship and the consequences after release.

This distinction matters because code volume is a terrible proxy for progress. DORA's research describes AI as an amplifier of the organization around it. That matches what I see in practice: clean interfaces, fast tests, and disciplined deployment get faster; vague requirements, shared databases, and slow review become expensive at machine speed.

Estimation moves from effort to uncertainty

Estimate the unknowns and the delivery path, not how long an agent will spend generating code. Generation may take minutes while clarification, review, migration, rollout, and observation still take days. Story points tied to typing effort lose most of their signal when an agent can produce several plausible implementations before lunch.

Start by separating work into four classes. A bounded change has a known interface, local tests, and an easy rollback. An investigative change must answer a technical question before anyone can promise a result. A cross-system change needs coordination across contracts or data owners. A high-consequence change can affect money, identity, privacy, or service availability. Agents compress the first class most. They help explore the second. They rarely remove the waiting and coordination in the last two.

For each item, estimate a delivery window with this simple model:

delivery window = queue + clarification + implementation + review + verification + rollout + observation

Do not turn that line into fake precision. Use ranges and name the dominant uncertainty. A small endpoint change might have ten minutes of implementation and a day of waiting for a test environment. A data migration might have a quick generated script but require a week to rehearse, sample results, and prepare recovery. The useful estimate tells a founder what could move the date and what decision would reduce that uncertainty.

Replace velocity forecasts with throughput by change class, median review time, time waiting for a decision, and change failure rate. Keep human and agent work in the same delivery data. Splitting out "AI tickets" invites a vanity comparison that ignores whether the change survived production. The business bought an outcome, not a fast patch.

Capacity planning must include the people who validate work. Count reviewer hours by domain, availability of QA environments, migration windows, and the number of simultaneous rollouts the on-call team can observe. If implementation capacity doubles while those limits stay fixed, planned scope should not double. Put the excess agent time into reducing the constraint: create missing fixtures, shorten a test suite, document an interface, or automate release evidence. This turns a vague productivity promise into a queueing decision a CTO can inspect. Report the range and its assumptions together. A date copied without its assumptions becomes a promise, even when the original estimate was explicitly conditional.

A sensible planning commitment sounds like this: "We expect the bounded API change this week. The authorization redesign remains a range until Thursday's policy decision and a load test settle the two open risks." That answer is less tidy than a point total and far more honest.

Specifications become the main engineering surface

An agent needs a constrained change contract, because a conversational request leaves too many decisions implicit. Experienced engineers infer local conventions, ask when a requirement conflicts with the system, and notice when a task crosses an ownership boundary. An agent often resolves ambiguity by choosing the most probable path. Probability is not product intent.

A good contract states the user-visible behavior, boundaries, invariants, acceptance tests, forbidden areas, rollout plan, and evidence required for review. It also says when the agent must stop. That last rule prevents a local fix from turning into an unsolicited refactor of authentication, schema, or deployment code.

This compact file is enough for many bounded changes:

change: reject-expired-invitations
owner: identity-team
scope:
  allowed: [services/invitations, tests/invitations]
  forbidden: [services/billing, db/migrations]
invariants:
  - accepted invitations keep their current session behavior
  - expired tokens never create a user
acceptance:
  - unit tests cover expiry boundary in UTC
  - integration test returns 410 for an expired token
rollout:
  flag: invitation_expiry_v2
  first_stage: internal_accounts
stop_when:
  - schema change is required
  - session behavior differs from the invariant
evidence:
  - test commands and results
  - changed files
  - rollback command

The failure it prevents is common. Asked to "handle expired invitations," an agent may add a nullable column, alter token parsing, and update an unrelated session helper because those changes make its local tests pass. The contract forces it to stop at the schema boundary and return the conflict to a person.

Keep these contracts in version control beside the code. They become the durable explanation for why a change exists and which tradeoffs were deliberate. NIST SP 800-218 recommends tracking security requirements, risks, and design decisions throughout development. Agent use makes that advice more useful, not less, because the prompt history alone is a weak audit record: it is noisy, tool-specific, and often detached from the commit that shipped.

Treat prompts as temporary instructions and repository policy as the lasting source of truth. If a rule matters twice, move it out of a personal prompt and into a checked file, test, linter, or permission boundary. Record the agent model and tool version for reproduction, but do not assume rerunning the same prompt will yield the same patch. Reproducibility comes from the contract, inputs, environment, and observed evidence. It does not come from preserving a clever sentence somebody typed into a chat window.

Review shifts from authorship to proof

Reviewers should judge the claim, risk, and evidence before reading every changed line. The traditional pull request assumes code is expensive to write, so a reviewer can use the diff as a rough map of the author's reasoning. An agent can create a polished, internally consistent diff without understanding the business rule it violated. Fluency raises the cost of casual review.

Require every pull request to answer five questions:

  • What observable behavior changes?
  • Which invariant could this break?
  • What evidence shows the intended path and the failure path?
  • How will we limit and reverse the release?
  • What did the agent attempt but leave unresolved?

Then route the change by consequence. Formatting, generated clients, and isolated test additions can use automated approval when ownership rules and checks pass. Authorization, payments, destructive migrations, concurrency, and public contracts need a responsible reviewer even when the diff is tiny. File count and line count do not measure consequence. A one-line permission change can deserve more attention than a generated thousand-line client.

Review the specification and tests before the implementation. If the acceptance test encodes the wrong rule, a beautiful implementation only makes the mistake harder to spot. For sensitive changes, ask a second agent to challenge the contract or generate counterexamples, but never treat agent agreement as independent proof. Models can share the same blind spots, training patterns, and missing context.

Large generated diffs should be rejected for size, not admired for completeness. Ask the agent to split mechanical changes from behavior changes, isolate refactoring, and preserve a sequence a person can inspect. DORA has repeatedly connected small batches with better delivery performance. Its AI research also warns that faster generation can increase batch size and burden downstream delivery. The practical response is a lower diff budget, not a bigger reviewer queue.

The approval record must name the human owner, the change class, the checks run, and any waived check with an expiry. "Reviewed by AI" says nothing about accountability. An agent can summarize and challenge; it cannot carry the pager, explain the risk to a customer, or decide that a business exception is acceptable.

Spot checks are a poor substitute for this record. Sampling one file from a generated change can miss a dangerous default in configuration, a transitive dependency update, or a modified migration path. Build an evidence view that groups behavior changes, dependency changes, generated files, and policy exceptions separately. Make reviewers acknowledge the groups that match their ownership. Security should not have to scan formatting noise to find a new network permission, and a database owner should not discover a locking change after merge.

QA begins before the first generated line

QA should design the test oracle and risk model before implementation starts. When code becomes abundant, test generation also becomes abundant, and quantity hides a basic weakness: an agent can write tests that confirm its own mistaken interpretation. Passing tests prove consistency between code and tests. They do not prove the requirement was right.

Give the acceptance examples to someone other than the implementation agent when the consequence justifies it. Product, QA, or the service owner should define concrete inputs and observable outputs, especially at boundaries: time zones, rounding, retries, duplicate events, partial permissions, stale caches, and unavailable dependencies. These cases expose specification errors before they become code review debates.

Use four test layers with different jobs. Fast unit and property tests explore local behavior. Contract tests protect interfaces between services and external consumers. A small set of journey tests checks business paths in a production-like environment. Runtime checks verify the assumptions that only production traffic can test. More browser scripts will not compensate for a missing contract test, and a high coverage percentage will not tell you whether refunds can be issued twice.

Mutation testing and fault injection become more useful in this lifecycle. Mutation testing asks whether the suite fails when behavior changes in small, systematic ways. Fault injection asks whether timeouts, partial failures, and retries behave as designed. Both challenge the oracle instead of rewarding the agent for producing more green checks. Run them selectively on risky modules; a blanket mandate can consume more compute than insight.

Do not let the implementation agent silently repair a failing acceptance test. It may change the test until its code passes and erase the only independent statement of intent. Protect externally authored tests with ownership rules. If the test is wrong, require a visible change and approval from the requirement owner.

QA ends after observation, not at deployment. Every change contract should name the production signal that confirms success and the threshold that triggers rollback or investigation. A flag that deploys cleanly but increases payment retries has failed verification even if every preproduction check stayed green.

Flaky tests become especially damaging when agents can retry until a pipeline turns green. A passing rerun does not erase the failed signal. Track retries as evidence, quarantine only with an owner and deadline, and stop automatic merge when a relevant test changes state across identical commits. Otherwise the agent learns an accidental operating rule: persistence beats diagnosis. Fixing the source of nondeterminism gives every later agent a faster and more trustworthy feedback loop.

Flow limits matter more than agent count

Estimate the savings before cuts
The five-day audit identifies at least $50,000 a year in savings or costs nothing.

Limit work in progress before adding more agents, because generation capacity can overwhelm every downstream gate. Ten parallel agents can open ten plausible pull requests while one senior engineer still has one review afternoon. The queue grows, context decays, branches conflict, and reviewers begin approving from summaries. That is slower delivery wearing the costume of activity.

Set explicit limits for changes awaiting human review, changes in rollout, and risky changes per service. When a lane is full, agents should help close work: reproduce a failure, improve a test, split a diff, update evidence, or prepare rollback. They should not start another feature simply because generation is idle. Idle agent capacity costs little. Saturated human attention costs incidents.

Measure arrival rate and departure rate at each gate. If agents open twelve changes a day and the team safely deploys four, the missing eight are inventory. Track their age, not just their count. An old generated change becomes harder to validate as dependencies and assumptions move. Close or regenerate stale work rather than nursing a large branch through repeated conflicts.

Keep branch life short and integrate continuously. Do not give each agent a week-long branch and hope the merge resolves itself. Shared interfaces, migrations, and generated files create collisions that semantic merge tools cannot settle reliably. A coordinator can assign bounded paths and serialize changes to hot files, but the architecture should reduce those hotspots over time.

The management mistake is rewarding pull requests opened or lines produced. Those metrics train people to feed the queue. Reward accepted outcomes, review latency, escaped defects, recovery time, and the share of agent changes that needed substantial human rework. Even that last measure needs context: high rework may mean poor instructions, the wrong task class, or a weak test setup.

Use service level expectations for the internal flow. A bounded change may need review within one working day, while a high-consequence change waits for its named owner. When the expectation is missed, reduce arrivals or add qualified review capacity; do not ask everyone to click faster. Publish queue age beside deployment results so leaders see that generated work is waiting. This also reveals whether a supposed implementation gain merely moved cost into evenings and interruptions.

On-call owns every agent decision that reaches production

The on-call engineer needs the intent, change evidence, and rollback path at incident speed. They do not need a transcript containing thousands of tokens of exploration. Store the concise change contract, deployment identity, flag state, affected service, expected signals, and exact reversal procedure with the release.

Consider a predictable failure. An agent changes retry behavior in a worker and adds exponential backoff. Unit tests pass, staging traffic is too small to expose the issue, and the change deploys on Friday. In production, jobs now stay alive longer, hold database connections during retries, and push the pool toward exhaustion. Request latency rises in a different service, so the first alert points away from the worker.

The response fails in four stages when the lifecycle is weak:

  1. The responder sees the deployment but cannot tell which behavior changed because the pull request describes files, not intent.
  2. The generated runbook suggests restarting workers, which briefly increases connection churn.
  3. The change has no flag, and the rollback also reverts an unrelated schema dependency from the same large batch.
  4. The team finds the retry change hours later by comparing connection traces with deployment timing.

A safer design records retry count, attempt age, queue age, connection occupancy, and dependency error class. The rollout starts with a small worker group, and the contract declares a connection threshold and a disable switch. The responder can connect the symptom to the change without trusting the agent that wrote it. This is why observability belongs in the definition of done rather than a later operations ticket.

Agents can help during an incident by collecting timelines, comparing recent changes, running approved queries, and drafting hypotheses. Keep write actions behind explicit authorization. Never allow an incident agent to improvise a database mutation or broad rollback because its confidence score looks high. Under pressure, a fast wrong action is worse than a slow hypothesis.

Google's SRE Workbook treats an error budget as a policy for balancing release pace and reliability. Apply the same control to agent throughput. When a service burns its budget, reduce change volume, raise the required evidence, and direct agent capacity toward reliability work. The budget should change permissions in the delivery system, not merely color a dashboard.

Postmortems must feed the agent control system. If an incident exposed an undocumented invariant, add it to the contract template or encode it as a test. If an agent had too much authority, narrow the permission rather than adding a warning paragraph nobody reads during an incident. If evidence failed to connect a deployment to a symptom, change the release metadata. The useful action item changes what the next agent can do or what proof it must return.

Architecture must make mistakes cheap

Give on-call a safer system
Fractional CTO work connects agent changes to rollout limits, observability, and tested recovery paths.

The best architecture for agents has explicit boundaries, fast feedback, and reversible releases. This does not require a migration to microservices. A modular monolith with clear ownership, typed contracts, isolated tests, and one-command local setup is often easier for agents and humans than a distributed system with vague service boundaries.

Agents perform badly when important rules live in oral history. Put invariants near the interface they protect. Use schema constraints for data truths, policy tests for authorization, contract tests for service expectations, and architecture checks for forbidden dependencies. Documentation still matters, but executable boundaries fail closer to the mistake.

Reduce the authority available to the coding environment. Give an implementation agent read access to the repository and only the tools needed for its task. Use short-lived credentials, separate development from production, record tool calls, and require approval for dependency changes, secrets access, migrations, and deployment. The goal is not to distrust every output. It is to keep one wrong inference from becoming a broad action.

Design rollout as part of architecture. Backward-compatible schema changes, flags with named owners, canaries, shadow reads, idempotent jobs, and tested rollback paths let a team discover mistakes with limited damage. A flag without removal criteria becomes permanent complexity, so every flag needs an owner and an expiry condition. A rollback that nobody rehearses is a wish.

Architecture decision records should state constraints in language an agent can apply. "Use the standard pattern" is useless if three patterns exist. Name the accepted dependency direction, transaction boundary, failure behavior, and example implementation. When reviewers repeatedly correct the same generated mistake, fix the repository guidance or guardrail instead of writing the same comment forever.

Repository layout also controls context quality. Give each owned module a short entry point that names its purpose, public interface, invariants, test commands, and operational signals. Keep obsolete examples out of search paths and mark generated code clearly. An agent with a limited context window will choose among the files it can find, so duplicate guidance creates unpredictable decisions. Humans benefit from the same cleanup, which is a good test that the architecture work has substance beyond the current tool.

Team roles move toward decision ownership

Turn agents into delivery capacity
I design Claude Code, Codex, MCP, and multi-agent workflows around your actual release constraints.

A smaller team can ship more with agents only when decision ownership stays explicit. Removing programmers while leaving a maze of product approvals, shared ownership, and manual releases will not produce the promised gain. It concentrates waiting around fewer tired people.

Senior engineers spend less time producing routine code and more time defining boundaries, reviewing risky changes, improving feedback systems, and deciding when evidence is sufficient. Product managers must express acceptance examples instead of handing over broad prose. QA engineers become owners of risk models, test oracles, and production verification. Platform engineers build paved paths that encode how a safe change gets built, checked, released, and reversed.

Junior engineers still have a place, but the apprenticeship must change. If an agent always supplies the answer, a junior can merge code without building a mental model of the system. Give them ownership of bounded services, require explanations of failure modes, rotate them through review and on-call with support, and assess diagnosis rather than prompt fluency. Reading generated code critically is a learned skill.

Do not assign accountability to an "AI owner" and let everyone else ignore the lifecycle. A central group can select tools, set data rules, and maintain shared controls. Each service owner must still decide which tasks agents may perform, which changes require human approval, and what production evidence counts. Local consequence requires local ownership.

Headcount should follow the redesigned workflow, not precede it. I have reduced teams successfully, but only after making work visible, automating delivery, removing ownership gaps, and proving that a smaller group could carry on-call without heroics. Cutting first forces the remaining engineers to use agents as a survival tactic, which produces speed without control.

Change the lifecycle with a measured trial

Adopt the new lifecycle on one service with real traffic, clear ownership, and a tolerable failure radius. A toy repository proves that an agent can generate code. It says nothing about review queues, deployment evidence, customer behavior, or an exhausted responder at 2 a.m.

Run the trial for several delivery cycles and make the operating rules explicit:

  1. Classify incoming work by uncertainty and consequence, then allow agents to implement only the bounded classes at first.
  2. Require a versioned change contract and protect acceptance tests from silent agent edits.
  3. Set review and rollout work limits, with a named human approver for sensitive paths.
  4. Attach production signals and rollback instructions to every release, then exercise one rollback during the trial.
  5. Compare lead time, review time, change failure, recovery time, and responder load with the service's own earlier baseline.

Do not demand an immediate percentage improvement. Early cycles expose missing tests, undocumented setup, slow environments, and unclear ownership. Those are useful findings because they identify why adding more agents would have multiplied trouble. Fix the constraint and repeat.

Keep an exception log. Record when a person overrides an agent policy, why the normal path failed, who accepted the risk, and when the exception expires. Review the log monthly for controls that cause workarounds or gaps that invite them. Governance becomes credible when the safe path is also the fastest ordinary path.

A Team & AI Audit from oleg.is examines this whole delivery system, including team structure, agent tooling, review gates, QA, and production operations, rather than counting licenses or generated lines. That is the right scope for leaders deciding whether a smaller AI-augmented team can carry the product safely.

The lifecycle has changed when faster generation no longer creates a downstream queue, every risky change arrives with independent evidence, and on-call can reverse it without reconstructing the author's intent. Until those conditions hold, the team has an AI coding tool, not an AI operating model.

Frequently Asked Questions

What is an AI software development lifecycle?

It is a software delivery process in which agents perform a substantial share of implementation, testing, analysis, and release preparation. Humans still define intent, approve consequential changes, and own production outcomes.

Do AI coding agents make estimates unnecessary?

No. They reduce implementation time for bounded work, but clarification, review, coordination, rollout, and observation still need estimates. Estimate the delivery path and its uncertainties rather than the typing effort.

Should every AI-generated change get human review?

Not every change needs the same gate. Low-consequence mechanical changes can use automated approval when ownership and checks are clear, while payments, permissions, migrations, concurrency, and public contracts need a responsible human reviewer.

How should teams review code written by AI?

Review the behavior claim, affected invariant, independent tests, rollout, and rollback before inspecting implementation details. Route attention by consequence, and reject generated diffs that are too large to understand safely.

Can an agent write its own tests?

Yes, but those tests are not independent evidence of correct intent. For consequential changes, have product, QA, or another owner define acceptance examples and prevent the implementation agent from silently rewriting them.

Does AI reduce the need for QA engineers?

It reduces some repetitive test writing, not the need for a trustworthy test oracle. QA work moves toward risk analysis, boundary cases, contract tests, fault injection, and verification against production signals.

How many coding agents should one engineer supervise?

There is no useful universal ratio. The limit comes from review capacity, system coupling, task consequence, and the quality of automated feedback; add agents only while completed changes leave the system as fast as they enter.

What metrics show whether an AI engineering team works?

Use lead time, review latency, deployment frequency, change failure rate, recovery time, escaped defects, and responder load. Pull requests opened, lines generated, and agent utilization mostly measure activity and can reward a growing queue.

Should AI agents have production access?

Implementation agents should not receive broad production authority. Incident agents may run approved read queries and collect evidence, but deployments, data mutations, and broad rollbacks need explicit authorization and recorded ownership.

How can a company introduce agents without disrupting delivery?

Choose one owned service with real traffic and a limited failure radius. Run several cycles with change contracts, protected acceptance tests, work limits, staged rollouts, and production measures before expanding the policy.

Related Posts