# C1 — Write a Real CLAUDE.md

> **Summary — what this page covers**
> Point **Claude Code** at the C0 starter, run a quick **gap analysis**, then write a real
> **`CLAUDE.md`** — the project briefing Claude loads on every session. This is your first Day 1 lab:
> you configure Claude to understand BookTracker before you change a single line of code.
>
> **Time:** ~30 minutes · **Format:** hands-on, solo · **You start from:** `checkpoint/c0-base` ·
> **You end at:** `checkpoint/c1-claude-md`

C0 left you with a starter you can build, run, and read — and a notepad of rough edges. In C1 you
turn that understanding into a **map** Claude can use. A good `CLAUDE.md` is **facts and soft
conventions**, not a wall of rules: it describes the project, the stack, the commands, the
architecture, and the handful of conventions that keep the code healthy. **No production code
changes in this lab** — the only file you commit is `CLAUDE.md`.

---

## 1. Prerequisites

This is a **Day 1 (Claude Code)** lab, so beyond the C0 tooling you need:

| Tool | Why | Check |
| --- | --- | --- |
| **Claude Code CLI** | runs the agent against your repo | `claude --version` |
| **A paid Claude plan** | required to use Claude Code | sign in when prompted |

> Day 1 uses Claude Code with a paid Claude plan. (Day 2's labs use the Anthropic API and a separate
> API key — you don't need that here.)

---

## 2. Continue from your C0 work

If you already have your `my-booktracker` branch from C0, just keep using it. Otherwise start a fresh
working branch from the C0 checkpoint:

```bash
# only if you don't already have a working branch
git switch -c lab checkpoint/c0-base
```

Everything in this lab runs from the solution folder, where Claude Code should be launched so it
picks up the right project root:

```bash
cd src/BookTracker
claude
```

---

## 3. Run a gap analysis with Claude Code

Before you write anything, let Claude read the starter and tell you what's wrong with it. From inside
the `claude` session, ask for a structured review — for example:

```text
Review this BookTracker starter. List the risks, gaps, and inconsistencies you find
(security, validation, error handling, observability, what leaks across the API boundary,
and test coverage). Group them and keep it short — don't fix anything yet.
```

Compare Claude's findings against the notes you took in C0. You should see the deliberate gaps
surface: a string-built SQL query in the search repository, a `POST /books` that doesn't validate
input, an endpoint returning an EF entity instead of a DTO, and thin-to-nonexistent observability.
**Don't fix any of these now** — each one becomes a convention you write in the next step.

---

## 4. Scaffold and trim a CLAUDE.md

Let Claude scaffold the file, then **trim it to a map, not a junk drawer**. From the session:

```text
/init
```

`/init` writes a first-draft `CLAUDE.md` by reading the repo. Now edit it down — keep it well under
**~200 lines**. Remember: `CLAUDE.md` is loaded on **every** session, so every line is paid for on
every turn. Earn each one. Your file must include:

1. **A project description** — what BookTracker is.
2. **The stack** — .NET 10 / ASP.NET Core 10 Minimal API, EF Core 10, SQLite, xUnit.
3. **The four commands** — build, test, run, **plus EF migrations**:

   ```bash
   dotnet build                                   # build the solution
   dotnet test                                    # run the xUnit tests
   dotnet run --project BookTracker.Api           # run the API (http://localhost:5255)

   # migrations (EF Core CLI; run from src/BookTracker)
   dotnet ef migrations add <Name> --project BookTracker.Data --startup-project BookTracker.Api
   dotnet ef database update      --project BookTracker.Data --startup-project BookTracker.Api
   ```

4. **Architecture + the deliberate dependency direction** — Core ← Data ← Api ← Tests:

   ```text
   BookTracker.Core   ← BookTracker.Data   ← BookTracker.Api   ← BookTracker.Tests
   ```

5. **At least five conventions** — each one should counter a gap you found in step 3:
   - **Return DTOs, never EF entities** across the API boundary (DTOs live in `BookTracker.Core/Dtos`).
   - **Validate inputs at the endpoint** before they reach the data layer.
   - **Keep endpoints thin** — business logic belongs in Core services.
   - **Parameterized queries / EF LINQ only** — never build SQL by string concatenation.
   - **Async all the way** — use the async EF APIs and thread `CancellationToken` through.
   - **Schema changes go through EF Core migrations** in `BookTracker.Data`.

> **Facts and soft conventions only.** `CLAUDE.md` is *not* the place for hard, deterministic
> guardrails like "never run `rm -rf`" or "never commit secrets." Prompt text can't reliably *enforce*
> anything — those become a `PreToolUse` hook + permissions in **C2**. Keep this file descriptive:
> say what the conventions *are*, not that they're *enforced*.

For reference, here's the shape of a good result (this is the C1 answer key — write your **own**,
don't paste this):

```markdown
# BookTracker

ASP.NET Core 10 Minimal API for tracking books and reading progress, backed by EF Core 10.

## Stack
- C# / .NET 10 · ASP.NET Core 10 Minimal API (no controllers)
- EF Core 10 · SQLite (dev) · xUnit for tests

## Commands
... (the four commands above)

## Architecture
Four projects with a deliberate dependency direction: Core ← Data ← Api ← Tests.
- BookTracker.Core — entities, DTOs, service interfaces, domain logic. Depends on nothing.
- BookTracker.Data — EF Core DbContext, migrations, seed, implementations. → Core.
- BookTracker.Api — Minimal API endpoints, DI, mapping. → Core, Data.
- BookTracker.Tests — xUnit. → all of the above.

## Conventions
- Return DTOs, never EF entities; validate at the endpoint; keep endpoints thin;
  parameterized/LINQ only; async + CancellationToken; migrations in BookTracker.Data.

## Notes
- The starter has intentional gaps — find and fix them, don't copy them.
```

---

## 5. Confirm Claude loads it

`CLAUDE.md` is only useful if it's actually in context. From the session, check the loaded memory:

```text
/memory
```

`CLAUDE.md` should appear in the list of loaded memory files. (It's also picked up automatically on
startup whenever you launch `claude` from `src/BookTracker`.)

---

## 6. Verify nothing broke and commit

You changed no code, so the solution must still be green. From `src/BookTracker`:

```bash
dotnet build BookTracker.sln
dotnet test BookTracker.sln
```

Both should pass exactly as they did in C0. Then commit your one deliverable:

```bash
git add CLAUDE.md
git commit -m "Add project CLAUDE.md"
```

> Want the full reference? The matching checkpoint tag `checkpoint/c1-claude-md` is the answer key —
> diff your file against it rather than copying it in.

---

## ✅ Checkpoint — you're done when:

- [ ] You ran a gap analysis with Claude Code and recognized the planted C0 gaps.
- [ ] `CLAUDE.md` exists, is **< ~200 lines**, and includes the project description, the stack, the
      four commands (build/test/run + EF migrations), the architecture with the Core ← Data ← Api ←
      Tests dependency direction, and **≥5 conventions**.
- [ ] The file contains **no hard-prohibition / guardrail language** (those are C2's job).
- [ ] `/memory` lists `CLAUDE.md` as loaded.
- [ ] The four commands in the file actually work from `src/BookTracker`.
- [ ] `dotnet build` and `dotnet test` are still green (no code changed).

---

## What's next

**Lab 2 (C1 → C2):** you'll turn these conventions into a committed `.claude/` **steering kit** —
moving the path-scoped rules out of `CLAUDE.md` into `.claude/rules/*.md` and adding the first
deterministic guardrails (a `PreToolUse` hook + permissions) that prompt text can't enforce.
