The AI-native SDLC playbook
Specs, context, verification, review and release when agents write most of the code.
Series Claude Academy: Learn the products Part 6 of 7
A walkthrough of the Claude Academy course The AI-native SDLC playbook (Learn the products track, 14 lessons, about 1 hour of reading). Each lesson is summarised with my own tables and examples; take the course for the full lessons. All the courses are listed in the Claude Academy course index.
Note: My own summary of the course, not the course itself; verify details against the lessons and current docs.
Full single-page version: https://claude.com/blog/the-ai-native-sdlc-playbook
Prerequisites / Audience
- Engineering, platform, and security leads whose organization already uses Claude Code, but whose approval gates, reviews, and handoffs still move at human speed.
- Written for large and regulated enterprises, where review queues can’t be allowed to build up and code can’t ship under-reviewed.
- To run the plays you need day-to-day Claude Code comfort, plus a Git repo and CI pipeline you’re allowed to change. Each play lists its own prerequisites, and several have none.
Objectives
- Identify what changes at each of the 6 SDLC stages and choose a first play from the dependency graph.
- Explain how
intent.mdbecomes a requirements and design spec in one session. - Decide whether knowledge belongs in CLAUDE.md, a skill, or a hook.
- Explain continuous evals, Claude reviewing every PR, and which code humans still review.
- Explain hooks as approval gates, and how a metric leaving its control band becomes a new
intent.md.
The artifact chain: intent.md → spec.md → plan.md → code + tests → PR (REVIEW.md) → deploy gates → metrics → new intent.md
Every play follows the same structure: What changes · Getting started (prereqs and infra) · How to execute · What it looks like · Governance · How to measure (leading and lagging indicators). The running example is an insurer’s claims status self-service portal (portal/, claims-api/, legacy claims-core at 50 rps).
Introduction — What changes and where to start
| Stage | Traditional | AI-native |
|---|---|---|
| Plan | Committee requirements, workshops, sign-offs | Claude synthesizes pain points into intent.md (human-readable, machine-actionable) |
| Design | Analysts write the spec, designers parse it | Requirements and design in one session, guided by standards encoded as skills, versioned in Git |
| Build | Handwritten code and tests, docs come last | AI-generated code and tests. Knowledge kept in CLAUDE.md and skills |
| Test | QA gates at stage boundaries | Continuous evals woven through implementation |
| Deploy | Humans review every line, inconsistent governance | Layered agentic review. Humans focus on regulated and critical code. Hooks as approval gates |
| Maintain | Humans watch production | Agents monitor. A breached control band becomes a new intent.md |
- Humans stay accountable for every judgment call.
- Plays with no prerequisites (good first picks): Capture as intent.md · Plan mode as default · The CLAUDE.md · Skills as institutional knowledge · Give Claude a feedback loop · Hooks as approval gates.
Stage 1: Plan — Capture as intent.md
- An idea, ticket, or alert becomes a proto-spec: what is wanted, why, and under which constraints, in the originator’s own words.
- Infrastructure: Claude access for non-engineers (claude.ai or Cowork), an agreed template (which can be a skill), and a version-controlled
intent/folder in the product repo. Use a dedicated repo only if intent spans many repos. A GitHub connector lets non-Git users commit through Claude. - Steps: describe the problem → brainstorm (Claude asks analyst questions: scope, users, constraints, success) → write intent.md from the template → originator corrects it → commit → product owner reviews and accepts (merge) or rejects (close).
# Intent: claims status self-service
Author: J. Ortiz (claims operations). Status: draft.
## Problem
## Proposed outcome
## Affected users and systems
## Constraints (e.g. No new PII in the portal session. Existing auth only.)
## Open questions
- Measure: time from first conversation to committed intent (weeks → hours). The survival rate (share accepted into Design). Edits to intent.md after the first spec.md commit.
Stage 2: Design — Requirements and design
- Claude turns the accepted intent into spec.md, constrained by the org’s skills (brand, security, compliance, UX), with areas of concern flagged. The product owner reviews it but doesn’t write it. For front-end work, mock it up in Claude Design and export to Claude Code.
- Progression: run it by hand → make it an org slash command → trigger it automatically on the intent merge with a non-interactive job that opens spec.md as a PR.
- Prompt pattern: “Read the attached intent.md and produce a requirements and design spec… Apply the skills available to you… Describe clearly any areas of concern, especially where you cannot satisfy contradicting policies.”
- spec.md contents: skills applied, numbered requirements (R1–R4), design, a constraint→how-met table, open questions carried forward, and areas of concern with owners (e.g. the
portal-uxandbrand-voiceskills conflict over showing a date, resolved as “Estimated date”; an untested rate limit). - Resolve concerns with their policy owners before engineering sees the spec. A human decides whether it goes to build, with a tech lead for higher-risk work.
- Measure: time from intent commit to spec commit. Spec commits made after the first plan.md commit (rework).
Stage 3: Build
Plan mode as the default starting point
- Start in plan mode with intent.md and spec.md. Ask for files, order of work, and tests. Interrogate the plan: what could break, what’s riskiest, which alternatives were rejected.
- Iterate until an engineer who never saw the conversation could implement it from the plan. Commit it as plan.md, citing R-numbers and spec concerns. Keep plan.md in sync if the implementation deviates (a hook can enforce this).
- Auto mode becomes the default for routine work once the guardrails mature. The review shifts from watching edits to reviewing artifacts, and it enables parallel work with worktrees.
- Legacy source of truth (choose per artifact): (1) the repo is the truth and legacy tools link to it, (2) the legacy system (Jira, ServiceNow) is the truth and Claude reads and writes it via MCP, or (3) linkage as the minimum bar: artifacts cite record IDs and records cite commit SHAs.
- Measure: share of changes merged from the first pass. Rework cycles. Whether the merged diff matches plan.md.
The CLAUDE.md
- Context a new joiner would need: commands, conventions, architecture, and the mistakes the team keeps making.
- Steps:
/init→ cut it to day-one essentials → commit at the repo root → “when Claude makes a mistake twice, add the correction” → keep it under a page.
# Claims portal
## Commands - Test: make test (unit), make itest (integration, needs docker)
## Conventions - Every endpoint needs a test in claims-api/tests.
## Architecture - Only claims-api talks to claims-core. Cache reads; never poll it.
## Things Claude gets wrong
- Do not log request or response bodies in claims-api; they can hold PII.
- Measure: repeated mistakes. Time to first merged PR for new team members.
Skills as institutional knowledge
- Write a skill for knowledge that must be applied consistently. Start from one policy that’s enforced inconsistently today and has a named owner. Put it in
.claude/skills/<name>/or distribute it via a plugin. Test that it triggers with varied phrasings. The policy owner signs off on changes.
---
name: secure-api-review
description: Apply the API security standard. Use whenever creating or modifying an external-facing endpoint, reviewing API code, or generating an OpenAPI spec.
---
1. Authentication: every endpoint requires the gateway JWT; no anonymous routes outside /health.
2. Input validation against the OpenAPI schema; reject unknown fields.
3. Audit event on every state-changing endpoint.
4. Fields tagged pii never appear in logs or error messages.
Run scripts/check-endpoints.sh and include its output in your summary.
- A skill is an advisory control. A hook is the deterministic one. “The skill makes violations rare and the hook makes them close to impossible.” Back the hook with a required PR check, because an
Edit|Writehook doesn’t fire when a shell command rewrites the file. - Build-phase hooks should be fast and scoped to the changed file. Uses: block protected paths, format and lint after edits, keep credentials out of the diff.
"hooks": { "PostToolUse": [ { "matcher": "Edit|Write",
"hooks": [ { "type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/api-policy.sh", "args": [] } ] } ] }
- The script reads
.tool_input.file_path, runs only forclaims-api/routes/*.py, and exits 2 with the violation on stderr so Claude fixes it. (A post-edit hook can’t undo the edit.)"args": []runs the script directly rather than through a shell. - Approval-prompt hooks belong in Deploy, not Build, because a prompt during build puts a human on the critical path of every parallel session.
Parallel sessions and subagents
- Parallel session = a separate Claude Code instance in its own worktree (
claude --worktree feature-auth). Subagent = a scoped helper within one session that has its own context window and tool limits. - Split work by non-overlapping files using plan.md. Start with 2–3 sessions and only add more while review keeps up.
---
name: verifier
description: Runs the app and checks the change works before the session reports done
tools: Bash, Read
---
Start the app with make run. Exercise the changed behavior and the two nearest neighboring flows.
Report what you ran, what you saw, and any mismatch with plan.md. Do not fix anything; report only.
- Measure: concurrent sessions per engineer (from the OpenTelemetry export). Merged changes per week alongside the rework rate.
Stage 4: Test
Give Claude a feedback loop
- Always give Claude a way to verify its own work: tests, a build, or a screenshot diff. (This differs from a verifier subagent, which is a one-time fresh-context final check.)
- Steps: wrap checks in single commands (
make test, which exits non-zero on failure) → list them in CLAUDE.md with examples of healthy output → set quantifiable targets → for bugs, write the failing test first, commit it, then fix without editing the test → for UI, use a browser or screenshot MCP tool and iterate against the mock (2–3 rounds) → make verification part of “done” → protect the loop with a hook that blocks test-file edits during fixes.
## Verifying your work
- Build: make build (must finish with "Build succeeded")
- Test: make test (all green; never skip or delete a failing test)
- Lint: make lint (zero warnings)
Run all three before reporting any task complete, and paste the output.
If a test fails, fix the code, not the test.
- Measure: first-pass CI success rate. Review time per PR. Change failure rate.
Continuous evals in CI
- Evals are the AI-native stage-gate QA. They rerun whenever the agent’s configuration changes (model, CLAUDE.md, skills, hooks). The suite is live: retire cases that no longer discriminate and add new ones from monitoring.
- Steps: collect 20–50 real tasks with accepted outcomes → write each as prompt + checks → run in CI on a schedule and on config changes → gate config PRs on the pass rate → every production incident becomes an eval.
{ "name": "status-no-pii-in-logs", "from": "9d04e7a",
"prompt": "Add debug logging to the claim status endpoint ... Run the tests before you finish.",
"may_change": ["claims-api/routes", "claims-api/tests"],
"checks": [ { "name": "tests pass", "run": "make test" },
{ "name": "no pii in logs", "run": "scripts/check-endpoints.sh claims-api/routes/status.py" },
{ "name": "no response body in logs", "run": "python3 $EVALS/log_bodies.py" } ] }
- Runner pattern:
on: pull_request: paths: ['CLAUDE.md', '.claude/**', 'evals/**']plus a nightly cron. For each eval: create a worktree atfrom→ removeevals/→ copy in the branch’s CLAUDE.md and.claude/→claude -p ... --allowedTools ... --output-format json→check.shgrades from a pre-run copy and fails any change outsidemay_change. - ⚠️ Don’t use
--barehere, because it skips the very CLAUDE.md, skills, and hooks under test. - Worked example: a PR trims the “don’t log bodies” line from CLAUDE.md. The skill and hook still pass (no field is tagged pii), but
log_bodies.pycatches the free-textnext_stepleaking a name and phone number. The merge check fails and the line is restored. - Test behavior, not code shape: the check runs the endpoint and inspects the logs.
Stage 5: Deploy
AI in the PR review loop
- Claude reviews every PR and addresses comments on its own PRs. Humans judge intent and risk.
- Options: managed Code Review (enabled by the org Owner) or
claude-code-actionin your CI (routing via Bedrock, Vertex, or Foundry if needed). Branch protection requires code-owner approval. - The tech lead writes REVIEW.md at the repo root:
## Passes - Bugs - Security (injection, auth gaps, PII in logs) - Compliance (spec.md, plan.md, design principles)
## What Important means here Break behavior, leak data, or breach policy. Style = nit.
## Cap the nits At most five per review; summarize the rest as a count.
## Do not report src/gen/ and anything CI already enforces.
- Findings never approve or block on their own. To gate merges, read the machine-readable severity tally from the check run.
@claudeon a review comment (via the action) makes Claude fix it and push. Teams can build a “babysit to merge” slash command that sweeps unresolved comments and failing checks.- Repeated findings go into CLAUDE.md. Tune monthly by rating findings and capping nits.
- Governance: separation of duties holds because the agent that wrote the code can’t approve it, and the PR is the audit record.
Hooks as approval gates
- Hooks can allow, ask, or deny. When the approver is someone else (e.g. a release manager), the hook checks for their recorded approval.
- Leadership, change management, and compliance list the gates that must survive. The platform engineer turns each into a hook. Team hooks go in
.claude/settings.json. Non-negotiable hooks go in managed settings. Every block must state its reason and the route to approval. - Release gate example (
matcher: "mcp__deploy-.*__release"):
| Env | Decision |
|---|---|
| dev | allow |
| staging | allow if GITHUB_REF=refs/heads/main (the pipeline), else ask |
| prod | allow only if ticket CHG-n is approved for this exact version (checked via the change-system CLI), else deny with the route |
| other | deny “No release rule…” |
- An
askreason is shown to the person. Adenyreason is shown to Claude so it can relay it. In non-interactive runs,askbecomes deny. The gate only works if the agent can’t write to the records it reads. - Managed settings for a regulated enterprise (MDM or admin console):
| Setting | Control |
|---|---|
permissions.deny (Read(.env*), WebFetch, Bash(curl *)) / allow (make test…) |
Keep secrets out of context. Pre-approve the safe inner loop to avoid prompt fatigue |
disableBypassPermissionsMode + allowManagedPermissionRulesOnly |
Nobody can widen the rules |
sandbox (failIfUnavailable, allowUnsandboxedCommands:false, network.allowedDomains) |
OS-level egress control. Refuses to start without a sandbox |
sandbox.credentials |
Deny ~/.ssh and ~/.aws/credentials. Strip GITHUB_TOKEN |
allowManagedHooksOnly |
Only managed hooks run (so define the gate there) |
disableSideloadFlags + strictKnownMarketplaces |
Extensions come only from the approved marketplace |
allowManagedMcpServersOnly |
The tool surface is a platform-owned allowlist |
requiredMinimumVersion |
Run only builds the org has assessed |
CI/CD integration and deployment
- Progression: read-only judgment steps first (
claude -pto triage failed builds or draft changelogs) → write steps that arrive as PRs (no route to main) → sandboxed containers with short-lived scoped tokens and no standing prod credentials → deployment exposed as MCP tools → autonomy tiered by environment → rollback is the most rehearsed path. - One MCP server per environment (
deploy-dev,deploy-staging,deploy-prod), because allow rules name the server and tool, not the arguments. Each exposesrelease,status, androllback.
claude -p "Release version $SHA to staging, then call status. If the 5xx rate on any endpoint is over 1%, roll back. ..." \
--allowedTools "mcp__deploy-staging__release,mcp__deploy-staging__status,mcp__deploy-staging__rollback" \
--permission-mode dontAsk
- In prod,
releaseis off the allowlist, so only the hook’sallowlets it through and the gate fails closed.rollbackstays allowed because it’s a pre-approved runbook. - Principle: the agent may act up to the production gate and cannot pass it.
- Measure: share of failures triaged without paging a human. DORA metrics.
Stage 6: Maintain — Closing the loop on metrics
- A deterministic detection script (no model involved) watches a metric and invokes Claude headlessly when its control band is breached. Claude diagnoses, acts only through gated routes, and writes a new intent.md.
- Control band: mean and σ over 30 days of hourly readings. Chance alone puts readings above 1σ about 1 in 6 times, above 2σ about 1 in 44, and above 3σ about 1 in 740 (roughly once a month at 720 readings a month). The Western Electric rules catch drift: 4 of the last 5 readings above 1σ, or 8 in a row above the mean.
metric: ci_test_failure_rate # or status_5xx_rate
baseline: rolling_30d
rules: western_electric
tiers:
1sigma: { action: log }
2sigma: { action: diagnose, tools: "Read,Grep,Bash(gh run view *)" } # drift counts as 2σ
3sigma: { action: propose, routes: [pull_request, runbook:rollback-deploy] }
- Triggers: a scheduled workflow, a monitoring webhook, or cron. Claude runs stateless via
claude -por the Agent SDK in a sandbox. - Worked example: a release sets the panel’s cache to 0 → claims-core rate-limits → 5xx hits 1.9% against a 0.2% mean (3σ) → the agent runs the rollback-deploy runbook, then writes intent.md (problem, evidence, constraints, action taken, open questions) → triage → the fix ships with a new eval,
status-panel-keeps-its-cache. - Triage: fix now, schedule, or dismiss. Dismissals tune the bands.
- Claude Tag (public beta, Slack): Claude joins incident channels under its own identity as a first responder, verifies recovery via MCP, and writes post-mortems to a versioned lessons file. Small fixes arrive as PRs and larger work becomes intent.md.
Closing — resources
Docs to roll out, in order: org setup decision map → settings and precedence (managed-only keys) → server-managed settings → permissions → sandboxing → hooks → skills → plugins and private marketplaces → managed MCP → enterprise deployment (Bedrock, Vertex, Foundry) → network config → monitoring (OpenTelemetry) and analytics → Compliance API → security model.
Quick-Review Flashcards
- Q: What does intent.md contain? → A: Problem, proposed outcome, affected users and systems, constraints, and open questions, with author and status.
- Q: Who writes spec.md, and who approves it? → A: Claude writes it, constrained by org skills and flagging concerns. The product owner reviews it and decides.
- Q: When is a plan good enough? → A: When an engineer who never saw the conversation could implement from it. Commit it as plan.md.
- Q: What are the three source-of-truth options with legacy tools? → A: The repo is the truth, the legacy system is the truth (synced via MCP), or linkage (IDs and SHAs) as the minimum bar.
- Q: What’s the CLAUDE.md rule of thumb? → A: A mistake made twice becomes a correction. Keep the file under a page.
- Q: Skill vs. hook as a control? → A: A skill is advisory and makes violations rare. A hook is deterministic and makes them nearly impossible. Back both with a PR check.
- Q: When should evals run? → A: On a schedule and on any change to CLAUDE.md,
.claude/**, or evals. Every incident adds an eval. - Q: Why not use
--barein the eval runner? → A: It skips the CLAUDE.md, skills, and hooks being tested. - Q: What goes in REVIEW.md? → A: The passes (bugs, security, compliance), what counts as Important, a nit cap, and exclusions.
- Q: Why one MCP server per environment? → A: Allow rules match the server and tool, not the arguments, so separate servers are what let you tier permissions.
- Q: What do the control-band tiers do? → A: 1σ logs, 2σ (or drift) runs a read-only diagnosis, 3σ allows a proposed PR or a pre-approved runbook only.
- Q: What’s the governing deploy principle? → A: The agent may act up to the production gate and cannot pass it.
Practice Ideas
- Draft an
intent.mdtemplate skill and run one real idea through it to a committedintent/file. - Turn one accepted intent into
spec.mdusing the “flag areas of concern” prompt, then intoplan.mdin plan mode. - Pick one inconsistently enforced policy. Write it as a skill plus a PostToolUse hook (exit 2) plus a required PR check.
- Build a 5-case eval suite (
from,prompt,may_change,checks) and a GitHub workflow that runs it onCLAUDE.md/.claude/**changes. - Write a
REVIEW.mdand enable Code Review orclaude-code-actionon a test repo. - Implement a PreToolUse release gate with allow, ask, and deny tiers for dev, staging, and prod MCP tools.
- Write a detection script with mean, σ, and Western Electric rules over a metric you already collect, plus a
bands.yaml.