Rubric
Contents — domains, guide and mocks

Choosing Claude Code’s built-in tools

CCAR-F 2.510 min read · checked 21 September 2026

Task statementSelect and apply built-in tools (Read, Write, Edit, Bash, Grep, Glob) effectively

Which built-in tool answers this question?

What do you need?
  • Files matching a name pattern
    Globe.g. **/*.test.tsx
  • Where some text appears
    Grepfunction names, errors, imports
  • What one file says
    Readthen follow what it imports
  • Change or run something
    Edit · Write · Bashtargeted edit, new file, command
Glob looks at names and paths; Grep looks inside files. Read and Edit work on one file you already know about.

The six tools and their jobs

ToolDoesReach for it whenPermission prompt?
GlobFinds files by path pattern, newest first, up to 100 resultsYou know the shape of the file name: src/**/*.ts, *.{json,yaml}No
GrepSearches file contents with ripgrep regex; skips gitignored filesYou know text that should be inside: a function name, an error stringNo
ReadReturns a file with line numbers; also images, PDFs, notebooksYou have a specific file to understandNo, inside the project
EditReplaces an exact, unique string in a fileA targeted change to an existing fileYes
WriteCreates a file or overwrites it entirelyA new file, or a rewrite of a small oneYes
BashRuns a shell commandTests, builds, git, anything no dedicated tool coversYes

Two details decide many answers. Grep’s default output mode is files_with_matches — just paths — which is often all you need to decide what to read next; content adds matching lines with line numbers, and count gives totals. Its glob and type filters narrow a search to, say, **/*.tsx or Python files. Glob, by contrast, never looks inside a file: searching for a function name with Glob can only match file names.

Explore incrementally: search, then read

The costly mistake with an unfamiliar codebase is reading lots of files “to get context”. Every file read lands in the context window, most of it irrelevant, and the details that matter get diluted. Anthropic’s context-engineering guidance describes the better pattern, and names Claude Code as an example: keep lightweight references such as file paths, and pull content in just in time with tools like glob and grep. Each step tells you where to look next.

Tracing a feature through unfamiliar code

  1. Grep for an entry pointroute, command name or error text
  2. Read that filenote what it imports and calls
  3. Grep for each namefind definitions and every caller
  4. Read only what mattersthen make the change

repeat until the flow is understood

Search narrows, reading confirms. Only the files on the path you are tracing ever enter the context window.

Changing files: Edit, and when to fall back

Edit is the precise tool: give it an old_string and a new_string, and it replaces that text. Three rules make it safe. The file must have been read in the conversation first — and a read cut short by a partial-view notice does not count (newer models can skip this in some cases). The old_string must match exactly: one character of whitespace or indentation is enough to miss. And it must appear exactly once, unless you set replace_all: true to change every occurrence.

Why did this Edit fail?

  • Passes: File was read in this conversationa full read, not a partial view
  • Passes: old_string matches character for characterindentation included
  • Fails: old_string appears exactly onceappears 3 times in the file
  • Check: Every occurrence should changeonly then use replace_all: true
The usual culprit is the last two rows: the target text is not unique. Add surrounding lines until it is, or use replace_all only if every copy should change.

When the text is not unique, first give Edit more context — the lines around the one occurrence you mean. If no stretch of text reliably pins it down, fall back to reading the whole file and writing the corrected version with Write. That trades precision for certainty, so keep it for small files or genuinely tangled cases: rewriting a large file risks silently dropping content you did not mean to touch.

An Edit that fails, and two ways outtext
Edit  config.ts
  old_string: timeout: 30
  → error: old_string appears 3 times

Edit  config.ts                    # 1. add context to pin one occurrence
  old_string: payments: {\n    timeout: 30
  new_string: payments: {\n    timeout: 60

# 2. If no unique context exists: Read the whole file, then Write it back
#    with the one change. Check the diff before moving on.

Traps the wrong answers are built from

Tempting but wrongDo this instead
Reading every file up front to “build context”Grep for an entry point, Read it, and follow imports and names outward.
Using Glob to find where a function is calledUse Grep; Glob matches file paths, not contents.
Retrying the same Edit after a non-unique match errorAdd surrounding context, use replace_all if every copy should change, or Read then Write.
Rewriting a whole large file with Write for a one-line changeUse Edit for targeted changes; keep Write for new files or small rewrites.
Tracing a function only through its wrapper moduleList the wrapper’s exported names and Grep for each across the codebase.

You should now be able to

  • Choose Grep for content search and Glob for path patterns.
  • Use Read for a specific file and Write for new files or full rewrites.
  • Make targeted changes with Edit, and recover when old_string is not unique.
  • Explore an unfamiliar codebase incrementally: search, read, follow imports, search again.
  • Trace a function across wrapper modules by searching for each exported name.

Practice questions

Original questions written for this lesson, in the exam’s style. Answer first, then open the reasoning — every option is explained, including why the wrong ones are tempting.

  1. Question 1

    A developer asks Claude Code to find every place a deprecated function, legacyAuth, is called in a large monorepo so the calls can be replaced.

    Which tool should Claude use first?

    1. AGlob with the pattern **/*legacyAuth*.
    2. BGrep for legacyAuth across the repository.
    3. CRead each file in the src directory in turn.
    4. DEdit with replace_all: true on the main entry file.
    Show answer and reasoning
    1. AIncorrect. Glob matches file names; the calls are inside files that are not named after the function.
    2. BCorrect. Grep searches file contents and returns the files — or lines — where the name appears.
    3. CIncorrect. It loads thousands of irrelevant lines and is the slowest way to find a name.
    4. DIncorrect. Editing before finding the call sites changes one file and misses the rest.
  2. Question 2

    Claude tries to change retries: 3 to retries: 5 for the payments client only, but Edit fails: the string appears four times in config.ts, once per client.

    What should Claude do next?

    1. ARetry the same Edit; the error is often temporary.
    2. BSet replace_all: true so the Edit goes through.
    3. CInclude the payments block’s surrounding lines in old_string.
    4. DDelete config.ts and ask the user to recreate it.
    Show answer and reasoning
    1. AIncorrect. The text is genuinely not unique; retrying cannot change that.
    2. BIncorrect. It would change all four clients, three of them unintentionally.
    3. CCorrect. More context makes the match unique to the one occurrence that should change.
    4. DIncorrect. Destructive and unnecessary; the edit can be made precisely.
  3. Question 3

    Claude Code joins an unfamiliar codebase and is asked how a password-reset email gets sent. There are around 3,000 files.

    Which two steps reflect an effective approach? (Select 2.)

    1. AGrep for a distinctive string such as the reset email’s subject line.
    2. BRead the hit, then follow its imports and Grep for the functions it calls.
    3. CRead all files under src/ first so nothing is missed.
    4. DUse Glob with **/* to list every file before deciding.
    5. EWrite a new email module, since tracing the old one is slow.
    Show answer and reasoning
    1. ACorrect. It finds an entry point directly, without loading unrelated code.
    2. BCorrect. Tracing outward from the entry point builds understanding incrementally, one relevant file at a time.
    3. CIncorrect. It floods the context with irrelevant code and dilutes the parts that matter.
    4. DIncorrect. A full listing of 3,000 paths says little about where the logic lives.
    5. EIncorrect. It answers a question no one asked and duplicates existing code.
  4. Question 4

    A team wants to find all test files for React components. Tests are named like Button.test.tsx and live next to their components throughout src/.

    What is the most direct call?

    1. AGrep for describe( in all .tsx files.
    2. BRead src/index.tsx and follow its imports.
    3. CBash with ls src and inspect the output.
    4. DGlob with the pattern src/**/*.test.tsx.
    Show answer and reasoning
    1. AIncorrect. It matches test-like content rather than the naming pattern, and can hit files that are not tests.
    2. BIncorrect. Tests are rarely imported by the application entry point.
    3. CIncorrect. It lists one directory level; test files are spread throughout the tree.
    4. DCorrect. The files share a naming pattern, which is exactly what Glob matches at any depth.

Sources

Drafted with AI assistance and checked against the sources above; expert review is in progress. Spotted an error? Tell us and it gets fixed, dated and listed on how this is written.