Week 10: Claude Code Fundamentals

Claude Code is an agentic command-line tool that reads, edits and runs code directly in your project, with you staying in control of what actually happens. This week covers getting it installed and running your first session, the permission model that keeps it from doing anything you haven't approved, CLAUDE.md for giving it persistent knowledge about your project, and the read-edit-run-verify loop that's the engine behind everything it does.

Module 4 of 14 Week 10 of 14 ~2 Hours Hands-on Exercise Included

By the end of this week, you'll be able to

  • Install Claude Code and run a first real session in a project
  • Explain the permission model and why reviewing diffs still matters
  • Write a CLAUDE.md that gives a project real, persistent context

1. Install & Your First Session

Claude Code runs in your terminal, inside whatever project directory you launch it from — it can see and act on the files there, unlike claude.ai which never has direct access to your filesystem.

install & launch
npm install -g @anthropic-ai/claude-code

cd your-project
claude
# You're now in an interactive session, in this directory.
# Try something low-risk first:
> explain what this codebase does and how the pieces fit together

That first question is a genuinely good way to start any new session in an unfamiliar codebase — Claude Code reads the relevant files and gives you an oriented summary, which is often faster than you'd get skimming the repo cold yourself.

Same models, different surface

Claude Code is built on exactly the Claude models and API mechanics from Weeks 6–9 (including tool use, which is what lets it read files and run commands) — wrapped in an agent loop purpose-built for working inside a codebase rather than exposed as raw API calls you write yourself.

2. The Permission Model

By default, Claude Code asks before doing anything that changes your system — editing a file, running a shell command — and shows you exactly what it's about to do before you approve it. This is Week 7's tool-use security principle ("your code decides whether the call is allowed") applied to your own filesystem and terminal instead of a custom tool you defined.

what a permission prompt looks like, conceptually
Claude wants to run:
  npm test

Claude wants to edit:
  src/utils/formatDate.ts
  (diff shown here — the exact lines changing)

[Allow] [Allow for this session] [Deny]

You can pre-approve specific commands or tools in project settings so trusted, low-risk actions (like running your test suite) stop requiring a prompt every time, while still requiring explicit approval for anything riskier — deleting files, running commands that touch the network, or changes to sensitive areas of the repo.

The permission prompt is not a rubber stamp

Actually read the diff before approving, the same way you'd review a colleague's pull request. The permission model prevents Claude Code from doing something without your knowledge — it doesn't replace your judgment about whether the specific change is correct.

3. CLAUDE.md — Persistent Project Context

CLAUDE.md is a file at your repo root that Claude Code reads automatically at the start of every session — the file-based, version-controlled evolution of Week 3's system prompt and Week 4's Project instructions, but tied to the codebase itself rather than a chat account.

a real CLAUDE.md, kept short and useful
# Project notes for Claude Code

## Commands
- `npm run test` — run the full test suite
- `npm run lint` — check style; run before considering any change done
- `npm run dev` — local dev server on :3000

## Conventions
- We use named exports only, no default exports
- API routes live in `src/routes/`, one file per resource
- Never commit directly to `main` — always work on a branch

## Gotchas
- The `legacy/` folder is unmaintained; do not "helpfully" refactor it
- Tests require the local Postgres container running (`docker compose up db`)

Keep it concise and focused on what isn't obvious from reading the code itself — build/test commands, conventions a linter won't catch, and traps a newcomer (human or Claude) would otherwise fall into. Update it as the project evolves, the same discipline as keeping a reusable prompt template current from Week 5.

Don't restate what's already obvious from the code

A CLAUDE.md that duplicates your README or re-explains standard framework conventions just adds noise Claude has to read every session. Reserve it for genuinely project-specific context that would otherwise need re-explaining constantly.

4. The Core Loop: Read, Edit, Run, Verify

Every substantial Claude Code task follows the same shape: it reads the relevant files to understand the current state, proposes an edit, and — critically — runs something to verify the edit actually worked, rather than just assuming it did.

the loop, in practice
> add a function to format a date as "3 days ago" style relative time,
  and write a test for it, then make sure it passes

# Claude Code will typically:
# 1. READ  — look at existing utility files & test conventions
# 2. EDIT  — write the function AND a corresponding test
# 3. RUN   — execute the test suite
# 4. VERIFY — if the test fails, read the failure, fix, and re-run
#             until it actually passes (not just "looks right")

This is dramatically more reliable than a one-shot "write me this function" request, because the loop catches its own mistakes against a real, objective check — a test passing or failing — rather than relying on the code merely looking correct on inspection.

Give it something to verify against

A codebase with tests, a linter, and a build step gives Claude Code a real feedback loop to close on its own. A project with none of those forces every check back onto you manually — worth investing in test coverage partly BECAUSE it makes agentic tools like this one more reliable, not just for humans.

5. Hands-on Exercise

Hands-on

Install it, write a real CLAUDE.md, and run one verified task

Get comfortable with the tool on a real (or realistic) codebase.

Part 1 — First session:

  1. Install Claude Code and run it inside a real project you have (or clone a small open-source repo you don't know well).
  2. Ask it to explain the codebase's structure, and ask one follow-up question about a specific file.

Part 2 — Write a real CLAUDE.md:

  1. For that same project, write a CLAUDE.md with at least: the test/build commands, 2-3 real conventions, and one genuine "gotcha" if you know of one.
  2. Start a new session and confirm Claude Code references something from it unprompted (e.g. uses the right test command without you telling it).
Hint

If the project doesn't have a test suite, describing "how to verify a change works" (e.g. "run the app and check X in the browser") in CLAUDE.md still gives Claude Code something concrete to aim for.

Part 3 — One real, verified task:

  1. Give Claude Code a small, real task with an explicit verification step (add a function + test, fix a small bug + confirm with the existing tests).
  2. Watch the permission prompts carefully — read at least one diff in full before approving it.
  3. Confirm the task actually completed with a passing verification, not just a claim that it's done.

6. Knowledge Check

Four quick questions. Expand each to check your answer.

Q1

What's the fundamental difference between claude.ai and Claude Code in terms of what Claude can actually access?

Claude Code runs in your terminal with direct access to the files and commands in your project directory, and can read, edit and run things there. claude.ai never has direct filesystem or shell access — it only works with what you explicitly paste or upload into the chat.

Q2

Why does approving a permission prompt still require you to actually read the diff?

The permission model only guarantees you're notified before something happens — it doesn't judge whether the specific change is correct. That review, the same as reviewing a colleague's pull request, is still your responsibility.

Q3

What kind of content belongs in CLAUDE.md, and what shouldn't be duplicated there?

Genuinely project-specific context that isn't obvious from the code — build/test commands, real conventions, known gotchas. It shouldn't duplicate what a README already explains or restate standard framework conventions, since that just adds noise every session has to read.

Q4

Why does having tests in a project make Claude Code more reliable, not just more convenient?

Tests give the read-edit-run-verify loop a real, objective way to check its own work — a test passing or failing — instead of relying on the code merely looking correct. Without that feedback loop, verification falls entirely back on manual human review of every change.