-
Restate the task as a location question.
Before any file read, write one sentence: "To do X, I need to find where Y happens
and what touches it." This defines the exploration target; every subsequent read is
judged against it. If you cannot phrase the target, the task itself is underspecified โ
resolve that first.
-
Breadth-first structural scan (hard cap: ~10 tool calls).
List the top-level directory tree. Read the manifest (package.json / Cargo.toml /
go.mod / pyproject.toml / Makefile) and the README headings only.
Output for yourself: language, build system, test command, and 3-6 candidate
directories relevant to the task. Do not open individual source files yet.
-
Locate entry points.
Find where execution starts for the behavior in question: main, HTTP route tables,
CLI arg parsers, event handlers, exported public API, scheduled jobs.
Grep for the task's key nouns first โ error strings, endpoint paths, flag names,
config keys. Literal strings lifted from the task description are the highest-signal
search keys available: near-zero false positives.
-
Trace ONE representative path end-to-end.
Pick the single most task-relevant flow and follow it from entry point to observable
effect (response written, file persisted, state mutated), reading only files on that
path. Depth-first on one path beats shallow reads of ten files: the traced path
reveals the layering conventions, error-handling style, and data shapes that
generalize to the rest of the codebase.
-
Maintain a known/assumed ledger.
As you trace, keep two explicit lists:
- KNOWN โ facts confirmed by reading code or running commands, each with a
file:line or command receipt.
- ASSUMED โ inferences from names, docs, comments, or convention.
Every ASSUMED item is a liability. Promote it to KNOWN by reading the code, or
carry it into the plan as a named risk. Never let an assumption become load-bearing
silently.
-
Probe dynamically if cheap.
If the project runs or tests in one command, run it once before editing. One observed
runtime behavior โ a log line, a passing suite, a reproduced error โ outweighs ten
inferred ones, and it validates the build/verify loop before you depend on it.
-
Apply the sufficiency test.
Stop exploring when you can answer all four:
- (a) Where exactly will my edit go?
- (b) What calls into it, and what does it call?
- (c) How will I verify the change worked?
- (d) What is the most likely way my change breaks something else?
Four yes answers โ begin editing immediately. Any no โ that question names the
next thing to read; read only that.
-
Declare the model, then act.
Write a 3-6 line summary: architecture in one line, the traced path, the edit site,
the verification plan, and the surviving ASSUMED items. This is your checkpoint โ
if an assumption later proves wrong, you know exactly which belief to revise instead
of restarting exploration.
-
Re-explore only on surprise.
During implementation, return to exploration only when reality contradicts the
ledger (a KNOWN item was wrong, or an ASSUMED item turned out to matter).
Fix that one entry, re-trace the minimal affected path, resume. Do not rescan the
repository.
Task: "POST /orders sometimes returns 500 when a discount code is applied. Fix it."
Unfamiliar Node.js repo, ~40k lines.