Claude Code across the software development life cycle

· 3 min read

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.