Why this lesson matters
In Level 1 you saw that Claude Code is an agent: it does things in your project instead of only talking about them. This lesson opens the bonnet. Once you can see the cycle it runs, the tools it picks up and the limited space it works in, its behaviour stops being mysterious. You will know why it reads five files before touching one, why some actions ask permission and others don't, and why a long session gets sloppy.
Nothing to install yet. Read the traces here closely; from Level 3 onward you will watch the same thing happen on your own machine.
The loop: gather, act, verify
Give Claude Code a task and it works through three phases:
- Gather context: find and read what is relevant.
- Take action: change a file or run a command.
- Verify results: check that the action did what was intended.
Then it repeats until the job is done. The phases blend together. A question about your code may only need the first one; a bug fix usually goes round several times.
It is how a careful mechanic works: look, adjust one thing, test, look again. Each step is chosen from what the previous step revealed, which is why you can't predict the exact sequence in advance.
You are part of the loop too. You can interrupt at any point (Esc stops it) and steer it somewhere else.
The six tools you will see most
The model on its own can only produce text. Tools are what let it act. Each tool call returns a result, and that result feeds the next decision.
| Tool | What it does | Changes anything? |
|---|---|---|
Glob |
Finds files by name pattern, e.g. **/*.py |
No |
Grep |
Searches file contents for text or a regex | No |
Read |
Reads a file's contents | No |
Edit |
Makes a targeted change inside an existing file | Yes |
Write |
Creates a file, or overwrites one completely | Yes |
Bash |
Runs a shell command: tests, git, installs, anything | It depends on the command |
There are more tools (web search and fetch, among others, and a PowerShell tool on Windows), but these six carry most everyday work.
One task, traced step by step
Imagine a small Python project where a test fails. You type:
The test for apply_discount is failing. Find out why and fix it.
A realistic trace looks roughly like this (simplified, and the exact display varies by version):
# --- GATHER ---
Bash(pytest) # run the tests to see the actual failure
-> FAILED tests/test_cart.py::test_apply_discount
assert 90.0 == 80.0
Grep("def apply_discount") # where is that function defined?
-> src/cart.py:14
Read(src/cart.py) # read the real code, don't guess
Read(tests/test_cart.py) # read what the test expects
# --- ACT ---
Edit(src/cart.py) # change one line: the percentage maths
- return price - percent
+ return price * (1 - percent / 100)
# --- VERIFY ---
Bash(pytest) # run the same tests again
-> 6 passed
Three things to notice:
Bashappears in two phases. The first run gathers information; the second verifies. The tool is the same; the purpose differs.- It read before it edited. An agent that edits without reading is guessing.
- The test is what closes the loop. Without a check it can run, "looks done" is the only signal it has, and you become the verification step. Giving Claude something that returns pass or fail is the single most useful habit in this course.
Had the tests still failed, the loop would simply go round again: read the new error, adjust, re-run.
Read-only tools versus tools that change things
Split the six into two groups:
- Look, don't touch:
Read,Grep,Glob. The worst realistic outcome is wasted time and used-up context. - Change things:
Edit,Write,Bash. These alter your files or your system.
This split is why the permission system treats them differently. When you are approving actions yourself, Claude Code does not ask before reading or searching inside your project folder, but it does ask before file edits and shell commands. (Paths outside the project prompt even for reads. Permission modes get their own lesson later.)
Gotcha:
Bashis the wildcard.lsandgit statusare harmless, and Claude Code runs a built-in set of read-only commands like these without prompting. Butrm -rf build/,git pushor a database migration also go throughBash. Judge the command, not the tool name.
Gotcha: undo has limits. Claude Code snapshots a file before it edits it, so
EditandWritechanges can be rewound. Changes made by aBashcommand are not captured, and neither is anything that touched a remote system such as a database or a deployment. So reading costs you almost nothing, edits are recoverable, and shell commands deserve a careful look before you approve them.
The context window: a desk, not a warehouse
Everything the model can "see" at one moment sits in its context window, measured in tokens (roughly, pieces of words). Think of it as a desk: large, but finite, and everything in play has to be on it.
What lands on the desk:
- system instructions you never see
- your project's
CLAUDE.mdand Claude's own saved notes (both covered later) - every message you send and every reply
- the full contents of every file
Readreturns - the output of every
Bashcommand, including that 400-line stack trace
The size depends on the model. Current models run windows from about 200,000 up to 1 million tokens, but the number matters less than the behaviour: it fills quickly, and quality drops as it fills. With a crowded desk, Claude starts "forgetting" earlier instructions and making more mistakes. One debugging session can burn tens of thousands of tokens on file contents and command output alone.
When the window nears its limit, Claude Code makes room automatically: it clears older tool outputs first, then summarises the conversation if needed. That keeps you working, but detailed instructions from early on can get lost in the summary.
Two practical consequences for now:
# Fills the desk: it may read hundreds of files
investigate the codebase
# Stays tidy: it reads what the job needs
look at src/cart.py and its tests and explain how discounts are calculated
And once you are set up, /context shows what is using the space. Managing it properly is a later lesson.
Exercise (pen and paper)
You ask: "Rename the function get_total to calculate_total everywhere and make sure nothing breaks."
- Write the tool calls you would expect, in order, labelled gather, act or verify.
- Mark each as read-only or changing.
- Circle the two that would add the most to the context window.
A reasonable answer: Grep for get_total (gather), Read on each file that matches (gather), Edit on each (act), Bash to run the tests (verify). The Read calls and the test output are the big context consumers.
Key takeaways
- Claude Code repeats a loop of gather context, take action, verify results, choosing each step from the last result.
Read,GrepandGlobonly look.Edit,WriteandBashchange things, which is why they are the ones that ask for approval.Bashis as safe or as dangerous as the command it runs, and its effects are not covered by the file snapshots.- A check Claude can run (tests, a build) is what lets the loop finish on its own.
- The context window holds the conversation, file contents and command output. It fills fast, and a full one produces worse work.