CCLearn

Your first real task: ask a question about code you did not write

verified against Claude Code 2.1.261 · 2026-09-0913 min

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 claude determines 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 fromFile accessCLAUDE.md loaded at launchUse when
Repository rootEvery fileRoot only; subdirectory files load on demand when Claude reads thereThe question spans packages or subsystems
A subdirectoryThat subtree only, until you grant moreThat directory's plus every ancestor'sThe 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):

text
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 ofAsk
"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:

text
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 database

If 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).

text
use a subagent to investigate how our auth system handles token refresh

The 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.

ToolEdge that changes your answer
GlobDoesn't respect .gitignore by default, so it finds gitignored files alongside tracked ones; results are sorted by modification time and capped at 100 files
GrepRespects .gitignore, so gitignored files are skipped — to search one, Claude passes its path directly
GrepBuilt on ripgrep, using ripgrep's regex syntax rather than POSIX grep: interface{} in Go takes the pattern interface\{\}
ReadReturns the contents with line numbers
ReadA 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
ReadReads 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 ofAsk
"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

  1. 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 answer

    File access, and which CLAUDE.md files load into context at startup. From the root Claude can read and edit every file and loads the root CLAUDE.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's CLAUDE.md plus every ancestor's. There is a third, if you want it: the same cd decides which project settings apply.

    Neither start is a lock-in — --add-dir <path> at launch or /add-dir mid-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.

  2. You ask "find every place LegacyClient is 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 answer

    Too low: Grep respects .gitignore, so a use sitting in an ignored path — dist/, vendor/, a generated client — is skipped and never counted. Too high: Glob does not respect .gitignore by 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 Glob cap — 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: a PARTIAL view read that only saw the first page of a long file, or a pattern in the wrong syntax, since Grep is ripgrep rather than POSIX grep and interface{} in Go takes interface\{\}. The follow-up the lesson hands you is to ask which search was run and whether it skipped gitignored files.

  3. 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 answer

    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.

Sources