Claude Code is a terminal program, not a chat window. You type instructions; it reads your codebase, edits files, runs commands, and reports back. The key shift: you are no longer writing code. You are directing an agent that writes code, and your job is to evaluate what it produces.
What Claude Code actually does
An agent with access to your filesystem and terminal
When you run claude in your terminal inside a project directory, you're starting an agent session. The agent can:
Read and edit files — it sees your entire codebase, not just what you paste into a chat. It opens files, modifies them, creates new ones.
Run shell commands — it can execute python3, pip install, git commit, and anything else in your terminal.
Make decisions across a task — unlike a single-turn chat, it keeps working until the task is done, choosing its next action based on what it just did.
Read and edit files — it sees your entire codebase, not just what you paste into a chat. It opens files, modifies them, creates new ones.
Run shell commands — it can execute python3, pip install, git commit, and anything else in your terminal.
Make decisions across a task — unlike a single-turn chat, it keeps working until the task is done, choosing its next action based on what it just did.
What a session looks like
# You: in your project folder in VS Code terminal $ claude # You type a task ➜ Read the clients.csv and write a function that formats each row as a client briefing. Save it to summariser.py. # Claude Code responds, then acts: # - reads clients.csv # - writes summariser.py # - runs it to check for errors # - reports what it did # Your job: read summariser.py line by line before moving on.
The core loop: Claude Code writes → you read every line → ask about anything unclear → only then accept and move on. This is not optional discipline. It is the entire point of Phase 3.
Installation
Requires Node.js · runs in any terminal
Claude Code is a Node.js package, not a Python library. It runs in your terminal — the same one you've been using.
Setup (one-time)
# Install Node.js first if not already installed $ brew install node # Install Claude Code globally $ npm install -g @anthropic-ai/claude-code # Verify $ claude --version # Start a session (inside your project folder) $ cd ~/mollerbeck/briefing-summariser $ claude
Always start inside a Git repo. Commit your current state before every Claude Code session. The Git history is your undo button — once Claude Code edits files, you need a clean prior state to revert to.
Modes
How you control the scope of what Claude Code does
Claude Code has two primary modes. Knowing when to use each is one of the core operating skills.
Plan Mode
Claude describes what it will do before doing it
You review and approve the plan first
Use for anything touching more than 2–3 files
Use for architectural decisions
Default mode for new tasks
Edit Mode
Claude acts immediately without a planning step
Faster, less overhead
Use for small, targeted changes to a known file
Use when the scope is already fully clear
Higher risk on large tasks — scope can expand unexpectedly
When to default to Plan Mode
If you would hesitate before making a change manually — because it touches multiple files, or you're not sure of the knock-on effects — Plan Mode first. The overhead is small. The cost of a runaway Edit session is not.
Context management
The hidden constraint on every session
Claude Code has a context window — a limit on how much it can hold in memory at once. System tools alone consume ~16,800 tokens before you type anything. A long session fills the window, and quality degrades before it hits the hard limit.
Context discipline
✓Check /context regularly to see how full the window is
✓Start fresh sessions for new tasks rather than running one session indefinitely
✓Compaction (/compact) summarises the session history to free space — use when approaching the limit on a task that isn't done yet
✓Keep CLAUDE.md under 500 lines — it loads every session and costs tokens before any task begins
Steering is the skill. Claude Code does what you tell it. If your instruction is vague, the output will be technically plausible and wrong in ways you won't notice until later. The AGENTS.md file, skills, and memory are the three instruments for giving Claude Code durable context rather than re-explaining it every session.
CLAUDE.md — the project brain
Loaded automatically at the start of every session
CLAUDE.md is a plain text file in your project directory. Claude Code reads it before doing anything else. It's how you encode project-level context that would otherwise require re-explaining each session.
There are two versions:
There are two versions:
Global CLAUDE.md
Lives at ~/.claude/CLAUDE.md
Loaded for every project, every session
Put: reasoning preferences, output format rules, personal conventions
Think: how you want Claude to think, always
Local CLAUDE.md
Lives at .claude/CLAUDE.md in project root
Loaded only for that project
Put: stack details, known gotchas, file structure, what done looks like
Think: the briefing a new developer would need to work in this codebase
Example local CLAUDE.md for the briefing summariser
# MøllerBeck · Client Briefing Summariser ## Project overview Reads clients.csv and produces formatted client briefing reports. Python script. No web server. No database. File in, text out. ## Stack - Python 3.11 - Standard library only (csv, pathlib) — no external packages ## File structure clients.csv — input data summariser.py — main script output/ — generated briefing files ## Done looks like Running `python3 summariser.py` produces one .txt file per client in the output/ folder. No errors. No empty files. ## Known issues - CSV sometimes has trailing spaces in header names. Strip them. - Some employee counts are missing. Handle gracefully, don't crash.
Add rules when Claude repeats the same mistake 2–3 times. That's the signal something belongs in CLAUDE.md. Don't try to anticipate everything upfront — you don't know what Claude will get wrong until it does.
Skills — recurring workflows
Lazy-loaded instructions for tasks you repeat
A skill is a markdown file that describes a specific multi-step workflow. Unlike CLAUDE.md, skills are not loaded by default — they cost about 60 tokens of front matter until invoked. This matters because context is finite.
When to create a skill: when you've done something with Claude Code three or more times and you're giving the same contextual instructions each time. Extract those instructions into a skill file.
When to create a skill: when you've done something with Claude Code three or more times and you're giving the same contextual instructions each time. Extract those instructions into a skill file.
CLAUDE.md (always loaded)
Reasoning preferences
Output format rules
Project-wide conventions
Persistent gotchas
Skills (invoked when needed)
Step-by-step recurring workflows
"How to add a new client field"
"How to generate the monthly report"
"How to deploy a new version"
The right mental model
CLAUDE.md is the standing brief — context that applies to every session. A skill is a procedure manual — detailed instructions for a specific task, pulled from the shelf only when that task is underway. Don't build task procedures into CLAUDE.md or you'll have to refactor them out later.
Progressive Disclosure
Give context at the right depth, at the right moment
A common steering error is front-loading everything — giving Claude Code the full specification of a system before starting a simple task. This wastes context and introduces noise.
The principle: give Claude Code the minimum context needed to do the next step correctly. Add depth as the task requires it.
The principle: give Claude Code the minimum context needed to do the next step correctly. Add depth as the task requires it.
1
High-level intent first — "Build a function that reads clients.csv and returns a list of client dicts." Not the full data model, not the output format — just the immediate task.
2
Add constraints when they're relevant — "The employee count field is sometimes missing. Handle that case by setting it to 'unknown'." Disclose this when it would affect the code, not before.
3
Correct errors as they appear — if Claude Code's output doesn't match what you need, add that constraint to CLAUDE.md so you don't have to repeat it.
Automatic Memory
How Claude Code builds its own notes
Claude Code can maintain a memory.md file — a scratch file it writes to during sessions to track decisions, open questions, and state. This is Claude Code's file, not your instruction set. Don't add your own rules to it; put those in CLAUDE.md.
The value: a long-running project benefits from Claude Code being able to refer back to decisions made in previous sessions. Memory is the mechanism for that persistence.
The value: a long-running project benefits from Claude Code being able to refer back to decisions made in previous sessions. Memory is the mechanism for that persistence.
Distinction: memory.md is Claude's scratch pad — it writes to it. CLAUDE.md is your instruction set — you write it. They serve different purposes and should not be conflated.
Large tasks without a plan fail in predictable ways. Claude Code runs out of context before the task is done, or makes assumptions in step 3 that invalidate work done in step 8. The planning tools here are how you break large problems into pieces that fit inside a single context window.
PRDs — defining done
The document that makes a task evaluable
A PRD (Product Requirements Document) in this context is not a formal document — it's a concise spec that answers three questions before Claude Code writes a line of code:
What a good PRD contains
✓What it does — the single-sentence purpose
✓What done looks like — specific, testable. "Running python3 summariser.py with clients.csv produces one .txt file per client with no errors."
✓What it explicitly doesn't do — scope boundaries prevent Claude Code from solving adjacent problems you didn't ask for
✓Constraints — stack, external dependencies, edge cases to handle
Why this matters in Phase 3
You are now evaluating Claude Code's output rather than writing code yourself. You can only evaluate against a standard you defined before the work began. A PRD is that standard. Without it, "is this right?" has no stable answer.
Multi-Phase Plans
Splitting large features across multiple context windows
Some tasks are too large for one Claude Code session. Context fills, quality drops, and errors start compounding. The solution is to structure the task as a series of phases, each with its own PRD and its own session.
The structure: each phase produces a concrete artifact — a file, a test result, a passing spec — that becomes the input to the next phase. Phases don't share context; they share outputs.
The structure: each phase produces a concrete artifact — a file, a test result, a passing spec — that becomes the input to the next phase. Phases don't share context; they share outputs.
Example: multi-phase plan for the intake form
## Phase 1 — Data model Goal: define the fields the intake form collects. Done: intake_fields.py exists with a validated field list. Output to next phase: intake_fields.py ## Phase 2 — HTML form Goal: build the HTML form using fields from Phase 1. Input: intake_fields.py Done: form.html renders correctly in a browser with no JS errors. Output to next phase: form.html ## Phase 3 — Backend Goal: Flask route that accepts form POST, validates, formats email. Input: form.html, intake_fields.py Done: submitting the form sends a correctly formatted email.
Start each phase in a fresh session. Fresh context catches errors the previous session's biases would miss. Pass only the output artifacts, not the full conversation history.
Tracer Bullets
End-to-end thin slices before full implementation
A tracer bullet is a minimal end-to-end implementation — not production-ready, but technically correct along the full path. Build it first to validate assumptions before writing all the real code.
In software, the term comes from the military: tracer rounds show you where the gun is actually pointing before you fire the full barrage.
In software, the term comes from the military: tracer rounds show you where the gun is actually pointing before you fire the full barrage.
Without tracer bullet
Build the full form UI
Build the full backend validation
Build the full email formatting
Discover at the end that the email API doesn't work as expected
Rework all three layers
With tracer bullet
One field, one backend route, one email — working end to end
Discover immediately whether the email API works
Confirm the architecture is correct
Build out remaining fields and logic on a validated foundation
No structural rework
The Plan → Execute → Clear loop
The operating rhythm for any non-trivial task
This is the session-level loop that keeps quality high and context clean:
P
Plan — use Plan Mode to get Claude Code's proposed approach before it writes anything. Review the plan. Correct misunderstandings now, not after 200 lines of wrong code.
E
Execute — once the plan is right, let Claude Code build. Read every file it produces. If you can't explain a section, ask before moving on.
C
Clear — when the task is done (or the context is filling), commit the work to Git, then start a fresh session for the next task. Don't let sessions drag across unrelated work.
Code Claude Code writes is cheap. What is not cheap is discovering the code was wrong three tasks later. Feedback loops are structural mechanisms that surface errors immediately — before they compound. The three below are the ones worth building into your workflow from Phase 3 onward.
Red-Green-Refactor
Test-driven development adapted for AI-generated code
Red-Green-Refactor is a discipline borrowed from test-driven development, and it's unusually well-suited to working with Claude Code:
R
Red — write a test that defines what the code should do. Run it. It fails (red) because the code doesn't exist yet. This step forces you to specify done before Claude Code starts.
G
Green — ask Claude Code to write code that makes the test pass. Run the test. It should pass (green). If it doesn't, the error is concrete and immediate.
R
Refactor — with passing tests as a safety net, ask Claude Code to clean up the code. Tests keep running throughout; if any go red, something broke.
Why this matters when Claude Code is writing
Without tests, Claude Code's output passes only the test you can do visually — which means it passes if it looks reasonable. Reasonable-looking code can be wrong in ways that only show up when specific inputs arrive. Tests catch those cases before they reach production or a client.
Do Work Skills
Steering agents to use feedback loops structurally
A Do Work skill is a skill file that tells Claude Code how to execute a class of task — including the verification steps. Rather than just asking it to "add a new field to the intake form," a Do Work skill instructs it to: add the field, write a test for it, run the test, confirm it passes, then report back.
The practical effect: the feedback loop becomes part of the task definition, not something you have to remember to ask for separately.
The practical effect: the feedback loop becomes part of the task definition, not something you have to remember to ask for separately.
Minimal Do Work skill structure
# Add Client Field Skill ## When to use When adding a new field to the client intake form. ## Steps 1. Add the field to intake_fields.py 2. Add the corresponding HTML input to form.html 3. Add validation logic to the backend route 4. Write a test in test_intake.py that verifies the field is accepted with valid input and rejected with invalid input 5. Run: python3 -m pytest test_intake.py 6. Report: show the test output before marking done ## Done looks like All tests pass. No new failures introduced.
Pre-commit hooks
Catching broken formatting before it enters Git history
Claude Code sometimes produces formatting inconsistencies — trailing spaces, wrong quote style, inconsistent indentation — that don't affect whether the code runs but create noise in diffs and make review harder.
A pre-commit hook is a script that runs automatically before every git commit. If the check fails, the commit is blocked. This catches formatting issues at the boundary where they matter most.
A pre-commit hook is a script that runs automatically before every git commit. If the check fails, the commit is blocked. This catches formatting issues at the boundary where they matter most.
Simple Python pre-commit config (.pre-commit-config.yaml)
# Install: pip install pre-commit --break-system-packages # Then: pre-commit install repos: - repo: https://github.com/psf/black rev: 23.12.0 hooks: - id: black - repo: https://github.com/pycqa/flake8 rev: 7.0.0 hooks: - id: flake8
Phase 3 sequence: Claude Code writes → you read → tests pass → pre-commit runs → Git commit. Never commit code you haven't read.
An agent is just Claude Code acting with more autonomy. In your early Phase 3 work, you stay in the loop on every decision. As you get comfortable, you can give Claude Code longer runways — eventually running tasks while you're not present (AFK). The key variable is how much you trust the task definition and your ability to verify the output.
HITL vs AFK
Human-in-the-loop vs away-from-keyboard execution
These are two modes of agent operation that differ on how much autonomy you grant:
HITL — Human in the Loop
You watch the session as it runs
Claude Code pauses at decision points and asks you
You can intervene, correct, redirect in real time
Higher cost (your attention), lower risk
Right mode for: new tasks, ambiguous specs, anything touching production
AFK — Away From Keyboard
Claude Code runs a task to completion without you present
You review the output when it's done
Requires: a precise spec, a sandboxed environment, tests
Higher leverage (your time freed), higher risk if spec is wrong
Right mode for: well-understood tasks with clear success criteria
AFK without sandboxing is reckless. An AFK agent that can write to production databases, send emails, or delete files without your oversight can cause irreversible damage. Don't run AFK against anything you can't fully roll back.
Sandboxing
Limiting what an agent can touch
A sandbox is a constrained environment — the agent can operate freely within it, but cannot reach outside it. For Claude Code, sandboxing typically means:
What sandboxing looks like in practice
✓Working on a branch, not main — Git gives you a clean rollback
✓Using test credentials, not production API keys
✓Running against a test database, not the live one
✓Restricting file permissions so the agent can only write to specific directories
The principle: an agent should never be able to cause permanent harm faster than you can detect and reverse it. Sandboxing enforces this structurally rather than relying on the agent behaving as expected.
Backlogs and GitHub Issues
How to queue work for longer-running agents
For tasks you want to hand off to Claude Code to complete while you're not present, a backlog is how you queue and specify the work. GitHub Issues is a natural format — each issue is a discrete task with a title, description, and acceptance criteria.
The workflow: you write issues (tasks) in plain language with clear done criteria. An AFK Claude Code agent reads the backlog, picks up issues, works through them, and marks them done. You review on return.
This is Phase 4 territory — bring it up when you've completed the three Phase 3 projects and you're ready for unattended execution.
The workflow: you write issues (tasks) in plain language with clear done criteria. An AFK Claude Code agent reads the backlog, picks up issues, works through them, and marks them done. You review on return.
This is Phase 4 territory — bring it up when you've completed the three Phase 3 projects and you're ready for unattended execution.
At some point you'll want to know what Claude Code is actually doing inside a session — not just the final output. This is the observability problem. There are four technical approaches, each with different tradeoffs. You don't need to implement any of these now — but understanding the landscape matters for Phase 4 tool choices.
Four approaches to observing Claude Code sessions
Based on Nick Saraev's architecture analysis
These are the live options as of early 2026, in order of increasing complexity:
Option A
Claude Code Hooks
Official API. PostToolUse, Stop, SessionEnd hooks POST events to your server as they happen. Stable, works today. Downside: hooks fire per-event and you have to reassemble the session yourself. Claude Code-specific — doesn't work with other agents.
→ Stable starting point
Option B
JSONL Transcript Tailing
Claude Code writes session transcripts to ~/.claude/projects/**/*.jsonl. A daemon watches the directory and uploads deltas. Agent-agnostic (Cursor, Codex, Aider all write logs). Downside: schema is undocumented and can change; polling, not streaming.
→ Best for multi-agent coverage
Option C
MCP Server / Proxy
Intercept model calls at the source. Truly agent-agnostic — captures token counts and tool calls regardless of which agent is calling. Invasive to set up; can't capture metadata that lives outside the model calls (todos, subagent structure, hook output).
→ Highest fidelity, highest setup cost
Option D
OpenTelemetry
Claude Code already emits OTel spans. Plug into standard observability infrastructure. Gives you metrics and spans — not full transcripts. Can't reconstruct "what did Claude say" from OTel alone; useful as a complementary signal.
→ Bonus signal, not primary
Nick's recommendation: A + B together, with D as a bonus signal. Option A handles live events; Option B is the backstop that catches everything even when hooks aren't configured, and survives across agent restarts. Skip Option C unless you have a specific reason — it's invasive and not something you install casually.
What observability is actually for
The practical reason to care about this at all
In Phase 3, you're in the loop on every session — you can observe directly. Observability infrastructure becomes relevant when you're running AFK agents at scale (Phase 4+) and you need to:
Use cases
✓Detect when an agent is stuck in a loop or making repeated failed attempts
✓Measure token cost per task to understand what's expensive
✓Debug why a session produced unexpected output (audit trail)
✓Build a manager agent that spectates running sub-agents and intervenes when needed
Phase 3 vs Phase 4 relevance
In Phase 3, your presence is the observability layer. You watch sessions, you read every file, you catch errors in real time. The infrastructure above becomes relevant when you're no longer in the room. Build it when you're ready to run agents unattended, not before.
The human layer is not a safety feature you add at the end — it's an architectural decision you make at the beginning. Every action Claude Code takes sits somewhere on a spectrum from fully automatic to fully manual. The discipline is knowing where to draw the line, and building that line into the task definition rather than relying on judgment in the moment.
The approval fatigue problem
Why asking about everything is equivalent to asking about nothing
Anthropic's own research on Claude Code usage found that users approve approximately 93% of permission prompts in default mode. At that rate, interactive confirmation provides almost no meaningful oversight — it becomes a reflex, not a decision.
This is the approval fatigue problem. When everything requires confirmation, humans stop reading the prompts. The result is worse than either extreme: you get the friction of manual oversight without the protection.
This is the approval fatigue problem. When everything requires confirmation, humans stop reading the prompts. The result is worse than either extreme: you get the friction of manual oversight without the protection.
The right mental model
You don't watch a junior developer type every line. You review their plan before they start, check the diff when they're done, and interrupt only when something looks wrong. Good HITL design applies the same logic: auto-allow obvious actions, gate at genuine decision points, escalate when uncertain.
Bad HITL asks
"May I read this file?" (always yes)
"May I run the test suite?" (always yes)
"May I install this dependency?" (usually yes)
Result: you click through automatically. No real oversight.
Good HITL asks
"I found 3 approaches. Which do you prefer?"
"This will modify the database schema. Proceed?"
"I'm about to send an email to a client. Confirm?"
Result: genuine decision points where your input changes outcomes.
Permission modes
Claude Code's seven-tier trust spectrum
Claude Code has a graduated permission system — not a binary on/off. The modes form a spectrum from most restrictive to least, and you set the appropriate level per task, not per session type.
Most restrictive
Plan mode
Describes what it will do but cannot execute. No files read, no commands run. Use for reviewing a proposed approach before committing to it.
→ Default for new, unfamiliar tasks
Standard
Default mode
Prompts for confirmation before each tool call. Every file edit, every shell command requires your explicit approval. High friction, maximum visibility.
→ Right for Phase 3 while building confidence
Intermediate
acceptEdits
File edits are auto-approved; shell commands still require confirmation. Good balance when you trust the editing but want to gate command execution.
→ Useful once you know the codebase well
Classifier-based
Auto mode
A separate safety classifier evaluates each proposed action in real time. Auto-approves low-risk operations (in-project reads, edits, build commands); escalates network calls, out-of-project writes, and schema modifications. Research preview as of March 2026.
→ Phase 4 territory; requires understanding the classifier's logic
Least restrictive
bypassPermissions
No confirmation gates. Claude Code runs entirely uninterrupted. Only appropriate in a fully sandboxed environment where every action is reversible.
→ AFK agents only, never against production
The default rule: start one tier more restrictive than you think you need. The cost of an extra confirmation prompt is a second of your attention. The cost of an auto-approved action you shouldn't have allowed is potentially hours of debugging or data loss.
What to always gate, what to never gate
Building the decision into the task spec, not the moment
The practical approach is to classify action types before a session starts — not to decide in the moment whether each prompt is worth reading. These categories are stable enough to encode in CLAUDE.md.
Always gate — never auto-approve
Sending external communications (email, Slack, API POST to external service)
Database schema changes
Writes outside the project directory
Deleting files
Deploying to production
Any network call to an external endpoint
Safe to auto-approve
Reading files within the project directory
Running the test suite
Linting and formatting
Running build commands
Writing to files within the project directory
Installing dependencies (within a known project)
Encoding this in CLAUDE.md
## Permission rules # Always ask — never proceed without explicit confirmation - Any command that sends data outside this machine (curl, POST, email) - Any deletion of files - Any write outside the project directory - Any change to a database schema # Proceed without asking - Reading any file in this project - Running tests (pytest, python3 -m pytest) - Running linters (flake8, black) - Writing to files within /Users/jakob/mollerbeck/[project-name]/
Blast radius — the framing that matters
How reversible is this action if Claude Code gets it wrong?
Anthropic uses the term "blast radius" internally to describe the scope of damage an agent action could cause if it goes wrong. It's the right frame for HITL decisions: not "is this action risky in principle?" but "if this goes wrong, how hard is the recovery?"
Small blast radius — auto-approve
Fully reversible via Git (file edits, new files)
No external effects (runs on your machine only)
Test environments, not production data
Recovery: git checkout or git revert
Large blast radius — always gate
Irreversible (deleted data, sent emails)
External effects (API calls, database writes)
Production systems, real client data
Recovery: difficult, expensive, or impossible
The practical test
Before setting a permission level for any action category, ask: "If Claude Code gets this wrong, what does recovery look like?" If the answer is git revert, auto-approve is fine. If the answer is "I have to call the client and explain," it needs a gate.
HITL for AFK tasks
Designing the loop when you're not present
When Claude Code runs unattended, the human layer doesn't disappear — it shifts. Instead of approving actions in real time, you design the constraints before the session starts and review the output when it's done. The three instruments:
1
Pre-task spec — define done precisely before starting. "All tests pass, no new files outside the project directory, no external API calls." Claude Code can only be as well-constrained as the spec you wrote.
2
Stop hooks — scripts that run before Claude Code ends a session. Can block completion if specified conditions aren't met — for example, blocking the session from ending if the test suite isn't passing.
3
Subagent review — after an AFK session completes, pass only the diff (not the full conversation) to a fresh Claude Code instance for independent review. Fresh context catches what the working session's biases would miss.
The threshold for AFK: don't run a task unattended until you've run it three times with HITL and it went correctly each time. Autonomy should be earned through observed track record, not assumed from a well-written spec.
How your HITL posture evolves
Anthropic's empirical finding on Claude Code usage patterns
Anthropic's analysis of real-world Claude Code sessions found a consistent pattern: users who were new auto-approved about 20% of actions. Users with 750+ sessions auto-approved about 40%. The shift wasn't toward recklessness — it was toward better classification. Experienced users build an accurate internal model of which actions are genuinely safe and stop wasting attention on them.
The implication: in Phase 3, err toward more gates. Not because Claude Code is untrustworthy, but because you haven't yet built the pattern recognition to know which actions are low-stakes. That recognition develops over sessions, not from reading about it.
The implication: in Phase 3, err toward more gates. Not because Claude Code is untrustworthy, but because you haven't yet built the pattern recognition to know which actions are low-stakes. That recognition develops over sessions, not from reading about it.
Phase 3 HITL defaults
✓Default mode for all sessions — every action requires confirmation
✓Read every confirmation prompt before clicking through — this is where pattern recognition develops
✓When you notice you've approved the same action 10 times without thinking, add it to the auto-approve list in CLAUDE.md
✓Never bypass permissions for anything touching external services — the blast radius is always large there