Claude Code across the software development life cycle
A phase-by-phase guide to pairing with Claude Code across the SDLC: requirements, planning, design, development, testing, CI/CD, and operations — with real prompts and diagrams.
claude-codeaiagenticsdlcautomation
Claude Code is Anthropic's agentic coding tool that runs in your terminal and can pair with you at every step of the software development life cycle. This guide maps the seven phases — from requirements to operations — to the concrete prompts, configuration, and diagrams an expert developer actually uses.
The SDLC in seven phases
Every phase has a job for the agent. At each step you decide what to hand off and what to review yourself. Here is the loop, then each phase in detail.
flowchart LR
R[1. Requirements] --> P[2. Planning]
P --> D[3. Design]
D --> I[4. Development]
I --> T[5. Testing]
T --> C[6. CI / CD]
C --> O[7. Operations]
O -. feedback loop .-> R
1. Requirements
Claude turns raw notes into a structured backlog and, more importantly, calls out what is ambiguous before it becomes a bug. Give it the source material and a strict output shape:
Turn notes/requirements.md into a structured backlog:
- Rewrite each functional requirement as "As a <role>, I want <goal>,
so that <value>".
- List non-functional requirements (security, performance, availability)
as separate items.
- Flag anything ambiguous or missing as an open question.
- Output a markdown table: ID | Requirement | Priority | Acceptance criteria.
2. Planning and estimation
Break epics into day-sized tasks ordered by dependency. The agent is good at sequencing because it sees the coupling between files and services:
Break this epic into tasks no larger than one day, ordered by dependency.
For each task give: title, affected files, effort (S/M/L), and definition
of done. Start with the riskiest task.
Epic: migrate order checkout from REST to async messaging.
For big changes, start in plan mode so Claude proposes the approach and task list before touching files. Review and adjust the plan, then let it execute. The plan becomes your gantt:
gantt
title Sprint plan for checkout migration
dateFormat YYYY-MM-DD
section Design
ADR & event schema :a1, 2026-10-08, 2d
section Build
Order service producer :a2, after a1, 3d
Consumer + DLQ :a3, after a2, 3d
section Test
Contract tests :a4, after a3, 2d
section Ship
Canary + rollout :a5, after a4, 2d
3. Architecture and design
Ask Claude to produce a system diagram, then push back on it. It will happily critique coupling, single points of failure, and consistency trade-offs:
flowchart TD
subgraph Client["Client"]
A[Web App]
end
subgraph Edge["Edge"]
B[API Gateway]
end
subgraph Core["Core services"]
C[Order Service]
D[Payment Service]
end
subgraph Data["Data"]
E[(Order DB)]
F[(Payment DB)]
end
A --> B
B --> C
B --> D
C --> E
D --> F
C -. async events .-> D
Capture the outcome as an Architecture Decision Record so the next session — human or agent — starts with the same context:
# ADR-007: Move checkout to async messaging
## Status
Proposed
## Context
Checkout currently calls the payment service synchronously over REST.
Under peak load this couples availability and pushes latency past SLO.
## Decision
Publish an OrderPlaced event to the broker; the payment service consumes
it and publishes PaymentCaptured. Use an outbox pattern for reliability.
## Consequences
- Lower coupling and better tail latency.
- New failure modes need a dead-letter queue and idempotent consumers.
4. Development
A production-grade CLAUDE.md is the single biggest lever for consistent output. It encodes build commands, architecture, security rules, and style so every session starts from your standards:
# CLAUDE.md
## Build & test
- `dotnet build` — build the solution (src/Orders.sln)
- `dotnet test` — run the xUnit suite
- `dotnet format` — apply code style from .editorconfig
- `dotnet ef migrations add <Name>` — add an EF Core migration
## Architecture
- `src/Orders.Api` — HTTP API (ASP.NET Core minimal APIs)
- `src/Orders.Application` — use cases, no I/O
- `src/Orders.Infrastructure` — EF Core, Azure Service Bus
- `src/Orders.Domain` — entities and value objects, no dependencies
- `tests/Orders.UnitTests` — one xUnit project per layer
## Security rules (never break these)
- Never log or commit secrets, tokens, or appsettings.Production.json
- Use parameterized queries; never concatenate SQL strings
- Do not add a package without mentioning it in the summary
## Testing
- New code ships with unit tests (xUnit + FluentAssertions)
- Mock external calls (HTTP, DB) — no network in unit tests
- Integration tests use Testcontainers
## Style
- Enable nullable reference types in every project
- Prefer records for DTOs and primary constructors for services
- Comments only explain "why", never "what"
Repeatable routines become skills. Write the procedure once and trigger it by name:
---
name: write-tests
description: Add unit tests for a changed class following project conventions.
---
1. Read the diff and find every public method that changed.
2. Write an xUnit test (with FluentAssertions) for the happy path plus one edge case each.
3. Mock dependencies with NSubstitute — no real I/O.
4. Run `dotnet test` and fix anything red before reporting.
Heavy, isolated jobs go to subagents with a narrow tool set, keeping the main session focused and cheap:
---
name: code-reviewer
description: Expert reviewer for pull requests.
tools: Read, Grep, Bash
model: sonnet
---
Review the diff for correctness, performance, and security.
Return findings ordered by severity (blocker, major, minor).
Frequently used prompts become slash commands, and $ARGUMENTS makes them composable across the codebase:
---
description: Generate unit tests for a given file.
---
Read the file at $ARGUMENTS and its dependencies. Write an xUnit
test at `tests/` covering the public methods, the happy path, and
one failure case. Run `dotnet test` and fix anything red.
5. Testing
Run test-driven development as a tight loop: you write the failing test, Claude implements the minimal fix, and the suite is the contract. Iterate until green, then refactor:
flowchart LR
W[Write failing test] --> R[Claude implements]
R --> G{Suite green?}
G -- No --> F[Claude fixes]
F --> G
G -- Yes --> RF[Refactor & review]
RF --> W
Act as the implementer. I have written this failing xUnit test:
<test code>
Implement the minimal change that makes it pass. Do not add features
the test does not require. Run `dotnet test` and confirm green.
Before merging, hand the diff to a review subagent. It checks correctness, security, and conventions without burning your own attention.
6. CI/CD and release
Claude Code belongs in the pipeline. A merge only happens after lint, tests, a security scan, and an automated review — then deploy with a smoke test and a rollback path:
flowchart LR
PR[Pull request] --> L[Lint & typecheck]
L --> T[Unit tests]
T --> S[Security scan]
S --> R[Claude Code review]
R --> M[Merge]
M --> D[Deploy]
D --> P[Smoke tests]
P --> V{Pass?}
V -- No --> RB[Rollback]
V -- Yes --> O[Release]
name: Claude Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- run: dotnet restore
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt: >
Review the changes in this pull request. Summarize the
behaviour change, flag correctness and security issues,
and post inline comments on the files.
Headless mode makes the agent scriptable, so release checklists and one-off migrations run from the terminal or a workflow step:
claude -p "Run the release checklist and report failures" \
--output-format stream-json \
--permission-mode acceptEdits
Hooks enforce policy at the tool level, blocking dangerous commands before they run:
#!/usr/bin/env bash
# .claude/hooks/guard.sh — block destructive commands
set -euo pipefail
read -r INPUT
if echo "$INPUT" | grep -qE 'rm -rf|git push --force|DROP TABLE'; then
echo "Blocked a potentially destructive command." >&2
exit 2
fi
exit 0
7. Operations and maintenance
On call, connect Claude to the code, the database, and the ticketing system through MCP, then ask it to triage an incident the way a senior engineer would:
flowchart LR
CC[Claude Code] <-->|MCP| GH[GitHub MCP]
CC <-->|MCP| DB[(Database MCP)]
CC <-->|MCP| TK[Ticketing MCP]
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "<token>" }
},
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost:5432/app"]
}
}
}
When the off-the-shelf servers are not enough, build your own with the official SDK. A server exposes typed tools Claude can call:
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
import { z } from 'zod'
const server = new McpServer({ name: 'ticketing', version: '1.0.0' })
server.tool(
'search_tickets',
'Search support tickets by keyword',
{ query: z.string().describe('Search term') },
async ({ query }) => {
const rows = await db.tickets.find({ subject: { $like: `%${query}%` } })
return { content: [{ type: 'text', text: JSON.stringify(rows, null, 2) }] }
},
)
const transport = new StdioServerTransport()
await server.connect(transport)
Wrapping up
Treat Claude Code as a teammate across the whole SDLC: clarify requirements, sequence the plan, review the design, implement and test, gate the merge, and triage in production. The experts who get the most from it are the ones who define the context, codify their standards, and stay in the loop at every decision point.