Fig. 01 — Latest note

Teaching Claude to read my codebase

De lectione · on reading, not pasting

What changed when I stopped pasting snippets and started letting it wander the whole repo — and the small rituals that made the difference.

May 2026· 6 min read· 1,115 words ClaudeCode

For about a year I used Claude the way most people first do: I copied a function out of my editor, pasted it into the chat, asked my question, and pasted the answer back. It worked, in the way that bailing a boat with a coffee mug works. You stay afloat. You also never stop bailing.

The trouble with a snippet is that it arrives with its context amputated. The function you pasted calls three others you didn’t. It assumes a shape of data defined in a file you’ve forgotten. It is polite about all of this and answers anyway — confidently, plausibly, and just often enough wrongly that you learn to distrust it. The fix wasn’t a better prompt. It was giving up the snippet entirely.

The snippet trap

Every paste is a small act of editing. You decide what’s relevant before you’ve asked the question — which means you’ve already answered it, badly. I’d paste the function with the bug and leave out the test that would have explained the bug. I was, without noticing, curating away the very context that made the problem legible.

What I wanted was the opposite posture: let it read the way a new colleague reads. Not the one file I think is the problem, but the directory around it, the imports, the README nobody updated, the test that quietly documents what “correct” means. A codebase is an argument, and a snippet is a sentence torn out of it.1

Give it the whole map

The shift was mechanical and almost embarrassingly simple: instead of pasting, I let it open files. Point it at the repository, let it list the directory, let it follow an import the way you’d follow a footnote. The first time it read three files I hadn’t mentioned to answer a question I had, something clicked. It wasn’t guessing at the shape of my code anymore. It was reading it.

There’s a real cost to this, and it’s worth naming. Letting a model wander a repo spends tokens — context is finite, and a large tree will not fit at once.2 So the skill that mattered shifted, too. It used to be “how do I phrase this.” Now it’s “what is the smallest set of files that makes this question answerable,” which, conveniently, is also the question a good engineer asks themselves.

Stop describing your code to the model. Let it read the code, and spend your words describing the problem instead.

— the one rule, if there's only one

A small ritual: a reading list

The single highest-leverage thing I added wasn’t a better prompt — it was about thirty lines of code. A small helper that, given a question, hands back the few files worth reading: not the whole repo, not one pasted function, but the short list in between.

RepoReader.java
// RepoReader.java — hand the model a map, not a paste.
package studio.ray.claude;

import java.nio.file.Path;
import java.util.List;
import java.util.stream.Stream;

/** Picks the handful of files worth reading for a question. */
public final class RepoReader {

    private static final int MAX_FILES = 40;

    public List<Path> shortlist(Path root, String question) {
        try (Stream<Path> tree = walk(root)) {
            return tree.filter(RepoReader::isSource)
                       .filter(p -> mentions(p, question))
                       .limit(MAX_FILES)
                       .toList();
        }
    }

    private static boolean isSource(Path p) {
        String name = p.getFileName().toString();
        return name.endsWith(".java") && !name.contains("Test");
    }
}

It’s nothing clever — a walk, two filters, a limit. But it moved the decision of what’s relevant out of my head and into something I could version and test. The model stopped guessing at my repo because it was finally pointed at the right corner of it.

Read the diff, not the file

The second ritual is about output, not input. When it proposes a change, I ask for the change as a diff — the few lines that move, not the whole file rewritten. A rewritten file hides its decisions; you can’t see what it chose to leave alone. A diff is honest. It shows you the surgery and nothing else, and a small honest thing is easier to trust than a large plausible one.

A review diff, a handful of lines changed
Fig. 02

A good suggestion is mostly the code it didn’t touch. The diff makes that visible; a rewrite hides it.

This also keeps me in the loop in the right way. I’m not approving prose about code; I’m approving code. The reviewing muscle is the same one I’d use on a teammate’s pull request, and it turns out that’s exactly the muscle worth keeping warm.

Where it still fails

I want to be honest about the seams. It’s still happy to be confidently wrong about anything not on the page in front of it — an environment variable, a deploy quirk, a decision we made in a meeting and never wrote down. It cannot read the room, only the repo. And the more I let it do, the more I have to consciously stay the engineer of record, because the gravity of a fluent answer is real and it pulls you toward accept.

So the practice isn’t “hand it the wheel.” It’s closer to working with a fast, well-read junior who has read everything and remembers nothing about why. Give them the map. Ask for diffs. Keep your hand near the wheel. That’s the whole method, and most of it is just the habits of working well with another person, applied to a tool that finally rewards them.

If you take one thing from this: the model was never the bottleneck. My willingness to let it read was. The day I stopped curating and started pointing, the work got quieter — and a little bit better.

Footnotes
  1. A phrase I stole, loosely, from how editors talk about quoting. The smallest honest unit of a codebase is rarely a single function.
  2. Context windows are large now, but not infinite — and a repo will happily exceed any of them. Choosing what to load is the work.
Ray Wen
Codes, designs, and writes to think. Believes in small tools and slow, deliberate work — the kind you can sit with for hours.
More notes ↗ ray@ray.computer # slow to reply, quick to read

Comments