Your first real task: ask a question about code you did not write
By the end you can
- Start the session in the directory that matches the question, and say what that choice decides
- Ask a codebase question the way you would ask a senior engineer, with no prompting technique
- Scope an investigation so it does not read hundreds of files before you get to the real question
- Predict where the search tools have blind spots — gitignored files, the Glob cap, a partial read
- Require an answer you can check — the file, the line, the command and what it returned
You have a repository you did not write, a ticket that assumes you understand it, and nobody free to ask. This is what Claude Code is best at on day one, and it is not a coding task at all — it is a question. Lesson 1.3 taught you to read what a session is doing; this gives it something worth doing. First thing to unlearn: you do not have to prepare context for a question.
Claude Code reads your project files as needed. You don't have to manually add context. — Quickstart
Nothing you are required to paste, no architecture summary you owe it first. You ask; it reads. Lesson 2.2 covers the cases where handing over a file or an image is still the better move; everything below is about aiming the reading it does on its own.
Where you start the session decides what it can see
Before you type anything you have made one decision — the directory you ran
claude in — and it is bigger than it looks:
Where you launch
claudedetermines which files Claude can read and edit without an additional permission grant, which CLAUDE.md files load into context at startup, and which project settings apply. — Work in large codebases
Three things, decided at once, by a cd:
| Start from | File access | CLAUDE.md loaded at launch | Use when |
|---|---|---|---|
| Repository root | Every file | Root only; subdirectory files load on demand when Claude reads there | The question spans packages or subsystems |
| A subdirectory | That subtree only, until you grant more | That directory's plus every ancestor's | The question is confined to one package |
The default is what you would guess — "By default, Claude has access to files in
the directory where you launched it" (Permissions)
— extendable with --add-dir <path> at launch or /add-dir mid-session. For a
first question about an unfamiliar repo, start at the root: you do not yet know
which subtree holds the answer. What a session reaches from there is more than
the files: the docs list your git state among them — "current branch,
uncommitted changes, and recent commit history"
(How Claude Code works)
— so why is this written this way is often answerable from history rather than
from the code.
Ask the question you would ask a senior engineer
There is no technique here. The docs are blunt about it — "No special prompting required: ask questions directly" — and their examples read like a conversation with a colleague, not a search query (Best practices):
How does logging work?
How do I make a new API endpoint?
What does `async move { ... }` do on line 134 of `foo.rs`?
What edge cases does `CustomerOnboardingFlowImpl` handle?The third names one line of one file; the first a whole subsystem. Both are legitimate — specificity is not a virtue in itself, it is how you spend a smaller budget when you already know where to look. One rewrite is worth learning, though, because it hands over the thing that answers the question:
| Instead of | Ask |
|---|---|
| "why does ExecutionFactory have such a weird api?" | "look through ExecutionFactory's git history and summarize how its api came to be" |
Same question; the second names the source. The docs call this pointing to sources. It is the cheapest upgrade available to anything you ask.
Broad, then narrow
"Start with broad questions, then narrow down to specific areas" (Common workflows) — and narrow by tracing a path, not by naming another topic:
give me an overview of this codebase
find the files that handle user authentication
how do these authentication files work together?
trace the login process from front-end to databaseIf that opening line looks like the vagueness the next section warns about — it is, and it is fine: "Vague prompts can be useful when you're exploring and can afford to course-correct" (Best practices). Can afford to is the load-bearing half. Cheap and redirectable in a fresh window; the same vagueness ninety minutes in is the trap below.
The infinite exploration, and the two ways out
The docs name this as a failure pattern, not a style preference:
The infinite exploration. You ask Claude to "investigate" something without scoping it. Claude reads hundreds of files, filling the context. — Best practices
Why it hurts is a separate fact: the window "holds your entire conversation, including every message, every file Claude reads, and every command output", and one exploration "might generate and consume tens of thousands of tokens" (Best practices). Every file read stays. The cost is not the minute you waited — it is that the question you came for now gets asked into a window full of code neither of you needed.
Two documented fixes, and neither is "ask more politely":
Fix: Scope investigations narrowly or use subagents so the exploration doesn't consume your main context. — Best practices
Scope it. Give the question a target — a feature, a file, an execution path, a symbol. "Trace the login process from front-end to database" bounds itself; "look at the auth stuff" does not.
Delegate it. The reading can happen somewhere that is not your window: "Exploring a large codebase fills your context with file reads. Delegate the exploration so only the findings come back" (Common workflows).
use a subagent to investigate how our auth system handles token refreshThe subagent reads in its own window and reports a summary. Level 8 covers defining agents and what they inherit; today it is just the second escape.
What the search tools can and cannot see
An answer is only as good as the search that found it. Lesson 1.3 taught you to read tool-call lines; here is what those names imply about what you are told.
| Tool | Edge that changes your answer |
|---|---|
Glob | Doesn't respect .gitignore by default, so it finds gitignored files alongside tracked ones; results are sorted by modification time and capped at 100 files |
Grep | Respects .gitignore, so gitignored files are skipped — to search one, Claude passes its path directly |
Grep | Built on ripgrep, using ripgrep's regex syntax rather than POSIX grep: interface{} in Go takes the pattern interface\{\} |
Read | Returns the contents with line numbers |
Read | A whole-file read over the token limit returns the first page with a PARTIAL view notice saying how much arrived and how to read more |
Read | Reads files, not directories — Claude lists a directory with a shell command such as ls |
Read the first two rows together, because they disagree, and that disagreement
is why "find every place X is used" comes back both too long and too short in
one session. Glob sees your dist/, your vendor/, your generated clients;
Grep does not. Neither is wrong — they answer different questions, and only you
know which one you meant. The cap matters the same way: when 100 files is not
all of them, "Claude sees a truncation flag in the result and can narrow the
pattern" (Tools reference).
Note who that sentence says sees the flag: Claude. So treat a result that stops
at exactly 100 files as a count you have not been given, and when a count
decides something, ask for the count rather than the list. Grep's count mode
prints a per-file count and a total across matching files, and that total covers
every match even when the listed entries are truncated — a guarantee that
arrived in v2.1.208; before that the total summed the listed entries alone,
so a truncated count came back short in the same direction as the list it came
from (Tools reference). Learn
that as a shape of failure rather than as a version note: "how many, and did
anything get cut off" is the form of the question that survives whatever the tool
happens to do. PARTIAL view is the quiet row for the same reason — a confident
answer about a 4,000-line file can rest entirely on its first page, and the
prose need not mention which page it read. Asking which lines it came from does.
Make the answer checkable
An explanation of code you have never read is unfalsifiable by definition: you have nothing to check it against except the confidence it was written with. Fix that in the question, not afterwards.
Have Claude show evidence rather than asserting success: the test output, the command it ran and what it returned, or a screenshot of the result. — Best practices
That is written about verifying work, and it transfers. Because Read returns
line numbers, a citable answer is always available — you have to ask for one.
| Instead of | Ask |
|---|---|
| "How does auth work here?" | "How does auth work here? Cite the file and line for each claim." |
| "Does anything else call this?" | "Show me the search you ran and its output, then interpret it." |
| "Is this dead code?" | "Find every caller of X. Say which search you used and whether it skipped gitignored files." |
Then spend thirty seconds opening one citation. Not all of them — one. A citation that resolves tells you the reading was real; one that does not tells you far more, far earlier, than re-reading the explanation would.
What you actually do next
Open a repository you have never read. Start claude at its root. Ask for the
overview, pick the one thing that surprised you, and trace it — by path, not by
topic — until you get a file and a line number. Then open that line yourself.
Ask with a target, watch what it reads, demand a claim you can check: that is
the loop the rest of the course is built on, and it changes no files.
Checkpoint
-
You need to understand one package inside a large monorepo. Name two things that change depending on whether you start the session at the repository root or inside that package.
Show answerAnswer
File access, and which
CLAUDE.mdfiles load into context at startup. From the root Claude can read and edit every file and loads the rootCLAUDE.md, with subdirectory ones loading on demand when it reads there; started inside the package it reaches that subtree only, until you grant more, and loads that directory'sCLAUDE.mdplus every ancestor's. There is a third, if you want it: the samecddecides which project settings apply.Neither start is a lock-in —
--add-dir <path>at launch or/add-dirmid-session extends the access. The table points a question confined to one package at that package's directory, but the lesson's advice for a repo you have never read pulls the other way: start at the root, because you do not yet know which subtree holds the answer. -
You ask "find every place
LegacyClientis used" and get four results. Give two documented reasons that number could be wrong — one that would make it too low, one too high.Show answerAnswer
Too low:
Greprespects.gitignore, so a use sitting in an ignored path —dist/,vendor/, a generated client — is skipped and never counted. Too high:Globdoes not respect.gitignoreby default, so it finds those same files alongside the tracked ones, and four hits can be one real call site plus its compiled and generated copies. That is the disagreement the lesson pulls out of the first two table rows, and why this exact question comes back too long and too short in one session: neither tool is wrong, they answer different questions, and only you know which one you meant.The reflex answer that does not apply here is the
Globcap — a result that stops at exactly 100 files is a count you were not given, and four is not 100. Two others would push the number low: aPARTIAL viewread that only saw the first page of a long file, or a pattern in the wrong syntax, sinceGrepis ripgrep rather than POSIX grep andinterface{}in Go takesinterface\{\}. The follow-up the lesson hands you is to ask which search was run and whether it skipped gitignored files. -
A colleague opens a session in an unfamiliar repo with "investigate this codebase and tell me how it works," asks their real question ten minutes later, and gets a worse answer than they expected. What happened, and which of the two documented fixes applies if the investigation genuinely did need to be that large?
Show answerAnswer
They hit the infinite exploration, which the docs name as a failure pattern: the opening line has no target, so nothing tells the agent when to stop, and Claude reads hundreds of files, filling the context. The damage is not the ten minutes. The window holds the entire conversation — every message, every file read, every command output — and one exploration can consume tens of thousands of tokens, so the real question ten minutes later gets asked into a window full of code neither of them needed.
If the reading genuinely had to happen, the fix is to delegate it, not to scope it: a subagent explores in its own window and only the findings come back. Scoping is the other documented fix, but by hypothesis there is nothing to cut. And do not read the moral as "vague prompts are bad" — "give me an overview of this codebase" is the lesson's own opening move, and vagueness is useful while you are exploring and can afford to course-correct. The difference is a target you can narrow toward.