Codebase Exploration
Understand before you touch. The cost of exploration is minutes; the cost of editing on a wrong mental model is a broken subsystem discovered later and blamed on you.
Step 1: Structure sweep (2 minutes)
- List the repo root. Read
READMEand the manifest (package.json/Cargo.toml/pyproject.toml/go.mod) — note language, package manager, and declared scripts. - Read the lockfile's top-level entries enough to know the major frameworks in play. The lockfile is ground truth for versions; your memory of the ecosystem is not.
- Check
.github/workflows/(or CI config). CI encodes the REAL build/test/lint commands — more reliably than the README, which drifts.
Step 2: Find the entry points
Locate how the code actually starts: main/index/app files, the manifest's
scripts/bin entries, Dockerfile CMD, or the daemon/service definition. For a library,
locate the public surface (exports, lib.rs, __init__.py). You cannot place a change
correctly until you know what calls what from the top.
Step 3: Map configuration and environment
Find .env.example, config files, and feature flags. Note which behavior is config-driven —
a "bug" is often a config difference, and an edit is sometimes the wrong fix for what a config
change does properly.
Step 4: Establish the test baseline BEFORE the first edit
- Find where tests live and what runs them (from CI, Step 1.3).
- Run the suite — or the fastest relevant subset — before changing anything, and record the result in your notes.
- Rule: a pre-existing failure discovered AFTER your edits will be attributed to you, and you'll waste time debugging code you didn't break. The baseline is your alibi and your safety net. If the suite can't run (missing env), record that fact instead.
Step 5: Targeted exploration of the task area
- Grep for the concrete anchors the task gives you: the route path, the error message text, the symbol name, the table name. Error strings are the highest-yield anchor — they're unique and land you at the exact site.
- Trace ONE representative flow end-to-end (request → handler → service → storage, or input → parse → transform → output). One full vertical slice teaches more than reading four layers horizontally.
- Reading-depth rule: read COMPLETELY any file you will edit; read the signatures and call sites of anything you will call; skim only what you merely pass through. Never edit a file you have not read in this session — no exceptions, however obvious the edit looks.
- Signature rule: never assume an internal API's signature or behavior when you could verify it — grep for an existing call site (how it's used HERE beats how it's "usually" used) or read the definition. Two existing call sites that disagree with your assumption are a finding, not an inconvenience.
Step 6: Confirm the mental model before the first edit
Make one falsifiable prediction and check it:
- "Hitting
/healthreturns{status: 'ok'}" → curl it. - "This function is only called from the scheduler" → grep proves 1 caller or reveals 3.
- "Deleting a user cascades to sessions" → find the FK or the test that encodes it.
If the prediction fails, your model is wrong — loop back to Step 5 before editing. If you can't formulate any prediction, you haven't understood enough to edit.
Worked example
Task: "Fix: CSV export drops the last row" in an unmapped Node repo.
- Sweep:
package.json→ pnpm, vitest, express; CI runspnpm test && pnpm lint. - Entry:
src/server.tsmounts routes fromsrc/routes/. - Baseline:
pnpm test→ 84 pass, 2 fail inbilling.test.ts— recorded as PRE-EXISTING before any edit. - Anchor grep: "text/csv" →
src/routes/export.ts→ callsserializeRowsinsrc/lib/csv.ts. Read both files fully. - Prediction: "
serializeRowsdrops the final row when input lacks trailing newline handling" → 3-line REPL check with a 2-row array → confirmed (returns 1 data line). - Now — and only now — edit
csv.ts, add the regression test, re-run: 85 pass, same 2 pre-existing failures.
Done when
You can state without hedging: where the change goes, what calls it and what it calls, the exact command that verifies it, and the recorded baseline test result — and every file you're about to edit has been read in full this session.


