# AI-native SDLC: Project Handoff

> **What this is:** a handoff for using Claude Code (VS Code extension or CLI) in this repository. It is based on Claude Academy's *The AI-native SDLC Playbook* and our team session deck. It covers what we're fixing, the working agreement, and copy-ready templates for every file the playbook expects.
>
> **Where to put it:** `docs/ai-sdlc/HANDOFF.md` in the project repo.
>
> **Owner:** Balaji K · **Version:** 1.0 · October 2026

---

## 0. How to use this file in VS Code

1. Install the **Claude Code** extension from the VS Code Marketplace and sign in with the company Claude subscription.
2. Copy this file to `docs/ai-sdlc/HANDOFF.md` and commit it.
3. Open the Claude Code panel and paste:

   > Read `docs/ai-sdlc/HANDOFF.md`. Use **plan mode**. Propose a plan to set up Section 5 (Repo scaffold) for this repository. Adapt the commands, paths and conventions to what this codebase actually uses. Do not create or change any files until I approve the plan.

4. Review the plan, approve it, then review every file Claude creates **before** you commit (see Rule 1).
5. Delete the scaffold sections you don't need. The working agreement (Section 2) is mandatory.

> **Windows note:** the hook scripts are bash and need `jq`. Run Claude Code from Git Bash or WSL, or ask Claude to port the hooks to PowerShell.

---

## 1. Why we're doing this: bottlenecks we've seen

**With Claude today:**

| Problem | What we've seen | Fix (playbook play) |
|---|---|---|
| Ownership | Developers don't take ownership of the code Claude writes | Rule 1 + PR gate with code-owner approval |
| Unreviewed commits | Claude's changes are committed before a developer has read the diff | `git commit` / `git push` are set to **ask** (Section 5.3); branch protection |
| Understanding | The team can't explain the code Claude produced | Explain-back step in every PR (Rule 3) |
| Prod triage | Prod issues are sent back to Claude, but prod has no Claude access | "How to debug in prod" section in PR + runbooks (Rule 4) |
| Plans lost | `plan.md` isn't reviewed properly or kept | Plans committed under `intent/` and reviewed like code (Rule 2) |
| `.md` files lost | intent/spec/plan files aren't stored | Artifact chain in Git (Section 3) |
| Skill misuse | `SKILL.md` written per functional module of existing code | Module knowledge → nested `CLAUDE.md`; skills only for reusable policy (Rule 6) |
| Idle time | Story pasted in, plan approved, then the developer watches Claude work | Auto mode + parallel worktrees (Rule 5) |
| No multitasking | One task at a time | 2–3 sessions in Git worktrees |

**Traditional SDLC bottlenecks we still have:** ticket handoffs (PDM → Dev → QA → Ops) that lose context · PRs waiting for reviewers · testing at the end · releases waiting on meetings and manual runbooks · docs written late or never · reactive prod support.

---

## 2. Working agreement (mandatory)

**Rule 1: The developer owns every line.** Claude is a tool, not an author. Nothing reaches a shared branch until the developer has read the full diff and can defend it in review. The developer is accountable for any defect, not Claude.

**Rule 2: Plan before code; keep the plan.** Every non-trivial change starts in **plan mode**. The developer interrogates the plan: *What could break? What's the riskiest step? Which options were rejected?* Iterate until someone new to the task could carry it out. Commit it as `plan.md` before implementation starts. If the implementation diverges, update `plan.md` in the same commit.

**Rule 3: Explain-back before PR.** Before opening a PR, the developer explains the change in their own words in the PR description: what changed, why, and how it works. If you can't explain it, you don't merge it. Ask Claude to walk you through the diff file by file until you can.

**Rule 4: Prod-ready without Claude.** Every PR that touches runtime behaviour includes a short **How to debug this in production** section: logs to check, key log messages, feature flags, how to roll back. Recurring issues go into `docs/runbooks/`. In prod we triage without Claude.

**Rule 5: Don't watch, orchestrate.** After the plan is approved, switch to auto mode for routine work (tight spec, small blast radius, good tests) and pick up a second task in another worktree. Start with 2–3 parallel sessions; add more only while review quality holds.

**Rule 6: Right file for the right knowledge.**

| Knowledge | Where it goes |
|---|---|
| Repo-wide commands, conventions, architecture, repeat mistakes | Root `CLAUDE.md` (under one page) |
| How one functional module works (existing human-written code) | `CLAUDE.md` **inside that module's folder** (loaded only when working there) |
| Reusable policy that applies across modules (security, API rules, coding standards) | `.claude/skills/<name>/SKILL.md` |
| Rules that must be **enforced**, not just suggested | Hooks + permissions (`.claude/settings.json`) |
| Review policy | `REVIEW.md` |

**Rule 7: Same mistake twice → fix the instructions.** If Claude repeats a mistake, add the correction to the relevant `CLAUDE.md` in the same PR.

---

## 3. The artifact chain

Each stage ends by committing a file; the next stage starts by reading it. Git history is the audit trail: who asked, what the agent produced, who approved.

```
intent/
└── 2026-10-06-claims-status/      # <date>-<slug>, one folder per change
    ├── intent.md    # Stage 1, Plan: the problem, in the requester's words
    ├── spec.md      # Stage 2, Design: requirements + design, constrained by skills
    └── plan.md      # Stage 3, Build: files, order of work, risks, proof
```

**Linking with Jira:** every artifact carries the Jira key in its header, and the Jira ticket carries the commit link to the artifact folder. Jira is the system of record for status; Git is the system of record for content.

### 3.1 `intent.md` template

```markdown
# Intent: <short title>
Jira: <KEY-123> · Author: <name, team> · Status: draft | accepted | closed

## Problem
<What hurts today, in the requester's words. Include a number if you have one.>

## Proposed outcome
<What should be true when this is done.>

## Affected users and systems
<Who and what this touches.>

## Constraints
<Security, PII, auth, performance, deadlines.>

## Open questions
<What we don't know yet.>
```

### 3.2 `spec.md` prompt (Stage 2)

> Read `intent/<folder>/intent.md` and produce a requirements and design spec for integrating it into our existing codebase. Apply the skills available to you, so it conforms to our security policies, API conventions and UX standards. Write it as `spec.md` in the same folder, ready to hand to engineering. List clearly any areas of concern and any open questions you could not resolve.

**Gate:** the product owner approves `spec.md` (tech lead for higher-risk items) before planning starts.

### 3.3 `plan.md` template

```markdown
# Plan: <title> (from intent.md <date>)
Jira: <KEY-123> · Engineer: <name> · Approved by: <name> on <date>

## Files that change
<path> (new|modified) — <one-line reason>

## Order of work
1. ...
2. ...

## Risks
<What could break; rate limits; migrations; backwards compatibility.>

## Rejected alternatives
<Option — why not.>

## Proof
<Exact tests/commands that prove it works; screenshots for UI.>

## How to debug in production
<Logs, key messages, flags, rollback.>
```

---

## 4. Daily workflow (one change, end to end)

1. **Intent:** turn the PDM story into `intent.md`. Don't paste the story raw: ask Claude to question you on scope, users, constraints and what success looks like, then fill in the template.
2. **Spec:** generate `spec.md`; resolve flagged concerns with the policy owner; get product owner sign-off.
3. **Plan:** in plan mode, ask for files, order of work, tests and risks. Interrogate the plan. Commit `plan.md`.
4. **Implement:** approve the plan → auto mode for routine work. **Start your next task in another worktree.**
5. **Verify:** Claude runs build, tests and lint and pastes the output (feedback loop). For bug fixes, write a failing test first. For UI, use the screenshot loop against the mock.
6. **Own it:** read the full diff. Run `/code-review` locally. Write the explain-back and prod-debug sections.
7. **PR:** open the PR; automated review runs; a code owner approves. The authoring agent never approves.
8. **Close the loop:** repeat mistakes → `CLAUDE.md`; incidents → a new eval and a runbook entry.

---

## 5. Repo scaffold (copy-ready)

### 5.1 Target layout

```
repo/
├── CLAUDE.md                     # day-one context (< 1 page)
├── REVIEW.md                     # PR review policy
├── .mcp.json                     # shared MCP servers (no secrets)
├── intent/                       # intent, spec, plan per change
├── evals/                        # agent eval cases + check.sh
├── docs/
│   ├── ai-sdlc/HANDOFF.md        # this file
│   └── runbooks/                 # prod triage without Claude
├── src/<module>/CLAUDE.md        # per-module knowledge (existing code)
├── .claude/
│   ├── settings.json             # permissions + hooks (team, committed)
│   ├── hooks/
│   │   ├── protect-paths.sh
│   │   ├── production-gate.sh
│   │   └── filter-test-output.sh
│   ├── skills/secure-api-review/SKILL.md
│   └── agents/verifier.md
└── .github/workflows/
    └── claude.yml                # @claude in PRs/issues
```

### 5.2 `CLAUDE.md` (root) starter

Generate a first draft with `/init`, then trim it to this shape:

```markdown
# <Project name>

## Commands
- Build: <cmd>     (must end with "<success text>")
- Test:  <cmd>     (all green; never skip or delete a failing test)
- Lint:  <cmd>     (zero warnings)

## Conventions
- <language/framework versions>
- <non-negotiable rules, e.g. money is decimal, never float>

## Architecture
- <layers/packages and how they talk>

## Working rules
- Start non-trivial work in plan mode; save the plan to intent/<folder>/plan.md.
- Never commit or push; the developer reviews the diff and commits.
- Before reporting done: run build, test and lint and paste the output.
- If a test fails, fix the code, not the test.
- Module details live in the CLAUDE.md inside each module folder.

## Common mistakes
- <added whenever Claude repeats a mistake>

# Compact instructions
When compacting, keep test output, code changes and the current plan.
```

### 5.3 `.claude/settings.json`

```json
{
  "permissions": {
    "allow": [
      "Bash(npm test:*)",
      "Bash(npm run lint:*)",
      "Bash(git status)",
      "Bash(git diff:*)"
    ],
    "ask": [
      "Bash(git commit:*)",
      "Bash(git push:*)"
    ],
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)"
    ]
  },
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          { "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/protect-paths.sh" }
        ]
      },
      {
        "matcher": "Bash",
        "hooks": [
          { "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/production-gate.sh" },
          { "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/filter-test-output.sh" }
        ]
      }
    ]
  }
}
```

> Adjust the `allow` commands to this repo's real build/test tools. The `ask` rules enforce Rule 1: Claude can't commit or push without the developer explicitly approving. Check the hooks are registered with `/hooks`.

### 5.4 `.claude/hooks/protect-paths.sh` (build-time guardrail)

```bash
#!/bin/bash
# Block edits to generated / frozen paths. Exit 2 = block (stderr is shown to Claude).
path=$(jq -r '.tool_input.file_path // empty' < /dev/stdin)
case "$path" in
  *"/generated/"*|*"/legacy/"*|*".lock")
    echo "Blocked: $path is generated or frozen. Change the source or ask the tech lead." >&2
    exit 2 ;;
esac
exit 0
```

### 5.5 `.claude/hooks/production-gate.sh` (approval gate)

```bash
#!/bin/bash
cmd=$(jq -r '.tool_input.command' < /dev/stdin)
if [[ "$cmd" == *deploy* && "$cmd" == *prod* ]]; then
  if [ -z "$RELEASE_APPROVAL" ]; then
    echo "Production deploys need a release authorization (RELEASE_APPROVAL)." >&2
    exit 2
  fi
fi
exit 0
```

### 5.6 `.claude/hooks/filter-test-output.sh` (token saver)

```bash
#!/bin/bash
# Rewrites test commands so only failures reach Claude's context.
input=$(cat)
cmd=$(echo "$input" | jq -r '.tool_input.command')
if [[ "$cmd" =~ ^(npm test|pytest|go test|mvn test|dotnet test) ]]; then
  f="$cmd 2>&1 | grep -A 5 -E '(FAIL|ERROR|error:)' | head -100"
  echo "$input" | jq --arg f "$f" '{hookSpecificOutput:
    {hookEventName:"PreToolUse", permissionDecision:"allow",
     updatedInput:(.tool_input + {command:$f})}}'
else
  echo "{}"
fi
```

Make the hooks executable: `chmod +x .claude/hooks/*.sh`

### 5.7 `.claude/skills/secure-api-review/SKILL.md` (policy skill example)

```markdown
---
name: secure-api-review
description: Use when adding or changing an HTTP API route, controller or handler.
---
# Secure API rules (owner: <security lead>)
- Auth: JWT via the gateway; no anonymous routes except /health.
- Validate every request against the OpenAPI schema; reject unknown fields.
- Audit log every write: actor, action, entity, timestamp.
- Never write PII fields to logs or error responses.
- Run <scripts/check_api.sh> and include its output.
```

### 5.8 Per-module `CLAUDE.md` (for existing, human-written modules)

Put this at `src/<module>/CLAUDE.md`, **not** in a skill:

```markdown
# Module: <name>
Purpose: <one line>. Owner: <name>.
Entry points: <files/classes>. Data: <tables/queues>.
Invariants: <rules that must never break>.
Gotchas: <non-obvious behaviour, known quirks>.
Prod debugging: <log tags, dashboards, runbook link>.
```

### 5.9 `.claude/agents/verifier.md`

```markdown
---
name: verifier
description: Run the app and check a change before it is reported done.
tools: Read, Bash, Grep
model: haiku
---
Run the build and tests. Exercise the changed behaviour and the flows next to it.
Report what you observed, with command output. Do not fix anything.
```

### 5.10 `REVIEW.md`

```markdown
# Review instructions
## Passes
1. Bugs and logic  2. Security  3. Compliance against intent/spec.md and plan.md
## What Important means
Breaks behaviour, leaks data, breaches policy, or blocks a rollback. Everything else is a Nit.
## Limits
At most 5 Nits per review; summarise the rest as a count.
## Do not report
Generated files, lockfiles, anything CI already enforces (lint, formatting).
## Always check
- The PR has explain-back and "How to debug in production" sections.
- The diff still matches plan.md.
- No PII in logs; queries scoped to the caller's tenant.
```

### 5.11 `.mcp.json` (shared; secrets come from env vars)

```json
{
  "mcpServers": {
    "github": {
      "type": "http",
      "url": "https://api.githubcopilot.com/mcp/",
      "headers": { "Authorization": "Bearer ${GITHUB_TOKEN}" }
    },
    "db": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@bytebase/dbhub"],
      "env": { "DSN": "${DATABASE_URL_READONLY}" }
    }
  }
}
```

More servers by stage (verify URLs in each vendor's docs before use):

| Stage | Server | Command |
|---|---|---|
| Plan / Design | Atlassian (Jira, Confluence) | `claude mcp add --transport http atlassian https://mcp.atlassian.com/v1/mcp` |
| Test (UI loop) | Playwright | `claude mcp add playwright -- npx @playwright/mcp@latest` |
| Maintain | Sentry | `claude mcp add --transport http sentry https://mcp.sentry.dev/mcp` |

Use `--scope project` to write to `.mcp.json` for the team. Authenticate with `/mcp`. Where a CLI exists (`gh`, `aws`, `gcloud`), prefer it: it adds no tool definitions to context. Always use read-only DB credentials.

### 5.12 GitHub integration

- Quick setup: run `/install-github-app` (needs the `gh` CLI and repo admin). It installs the Claude GitHub App, stores the `ANTHROPIC_API_KEY` or `CLAUDE_CODE_OAUTH_TOKEN` secret, and opens a PR with `claude.yml`.
- Core workflow step:

```yaml
- uses: anthropics/claude-code-action@v1
  with:
    anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
    claude_args: "--max-turns 5"
```

- **Branch protection on `main`:** require a PR, at least one code-owner approval, and passing CI. Claude's findings never auto-approve.
- Before pushing, run `/code-review` locally (`--fix` applies the findings).

---

## 6. Token discipline

| Habit | How |
|---|---|
| Clear between unrelated tasks | `/rename` then `/clear`; `/resume` later. `/clear` costs nothing |
| Compact with focus | `/compact keep the plan and test results` |
| See where tokens go | `/usage` (cache hit rate, usage by MCP/skill/subagent), `/context` |
| Right-size the model | Sonnet by default; Opus for hard design; Haiku for simple subagents (`/model`) |
| Lower effort for simple work | `/effort` |
| Keep CLAUDE.md lean | Under ~200 lines; move workflow detail into skills, which load on demand |
| Disable unused MCP servers | `/mcp` |
| Delegate noisy work | Subagents run tests and read logs; only the summary comes back |
| Be specific | "Add validation to `login()` in `auth.ts`", not "improve the codebase" |
| Stop early | Esc as soon as it drifts; `/rewind` instead of patching forward |

Reference: about $13 per developer per active day and $150–250 per developer per month on average (Claude Code docs, enterprise averages). Measure our own baseline.

---

## 7. Setup checklist

- [ ] Claude Code extension installed; signed in; `gh auth login` done
- [ ] Root `CLAUDE.md` created with `/init`, trimmed, committed
- [ ] Per-module `CLAUDE.md` files for the main existing modules (replacing module skills)
- [ ] `intent/` folder + templates committed
- [ ] `.claude/settings.json` with `ask` on commit/push + hooks; verified with `/hooks`
- [ ] At least one policy skill with a named owner
- [ ] `verifier` subagent
- [ ] `REVIEW.md` + GitHub App + branch protection with code-owner approval
- [ ] `.mcp.json` with GitHub + Jira (read-only DB if needed)
- [ ] PR template with **Explain-back** and **How to debug in production** sections
- [ ] `docs/runbooks/` started
- [ ] First 20–50 eval cases collected (`evals/`)

---

## 8. How we measure it

| Play | Leading | Lagging |
|---|---|---|
| Plan mode | % merged from first implementation | Merged diffs still matching `plan.md` |
| CLAUDE.md | Repeat mistakes it should prevent | Time from joining to first merged PR |
| Feedback loop | First-pass CI success on agent PRs | Review time per PR; change failure rate |
| PR review | Time to first review | Defects caught pre-merge vs prod escapes |
| Parallel work | Concurrent sessions per engineer | Changes merged per week vs rework |
| Prod readiness | % PRs with a prod-debug section | Incidents resolved without escalating |

---

## 9. References

- Claude Academy: *The AI-native SDLC Playbook* (academy.claude.com)
- Claude Code docs: code.claude.com/docs (MCP, hooks, skills, sub-agents, settings, costs, GitHub Actions, code review)
- Team session deck: `AI_Native_SDLC_Playbook.pptx`
