Module 2 · Tools, Knowledge, Memory & Research Design · scripted
Jumping-Off Points: Naming for the Searching Agent
When the task doesn't map onto a tree
We like trees. A tree gives the agent a designed entry point — start at the root, read the table of contents, descend — and the structure itself encodes a process for looking through the information. But often the situation isn't so obliging. Tasks frequently arrive with no clear mapping onto any tree we could reasonably build: a large codebase where nobody can say in advance which files a change will touch; a web of research notes that interconnect rather than nest; an organization's accumulated documents, where the task "update our consent procedure" doesn't correspond to any single branch. The information is a graph with no front door, and the agent must manufacture its own way in. How do we handle these situations — where finding the starting point is itself part of the task? That is this lesson: a set of principles for designing information, and tasks, for the agent that has to search its way to a beginning.
Two ways in
The mechanic on the right is worth stating plainly, because everything in this lesson follows from it: task words → guessed names → text search → jumping-off points → explore outward. The searches are cheap and lexical — text matching over names and contents, not understanding. Which means the whole scheme lives or dies on one question: do the names in the information correlate with the words in the task?
Watch an off-the-shelf agent bootstrap
This is not a hypothetical design. It is exactly what the coding agents you can buy today — Claude Code, Codex and their kin — do in the first seconds of any task. Watch the opening moves:
The invoice page times out when it loads. I think it's a database problem. Fix it.
⟨tool_use⟩
search_files(pattern = "database")⟨tool_result⟩
47 matches across 12 files:
src/legacy/database_helper.py (19), src/db/session.py (6),
src/db/queries.py (8), docs/database_setup.md (5), …⟨tool_use⟩
search_files(pattern = "invoice")⟨tool_result⟩
src/billing/invoices.py (31), src/billing/invoice_views.py (14),
src/legacy/database_helper.py (2), templates/invoice.html (7)⟨tool_use⟩
read_file(path = "src/billing/invoice_views.py")And the queries get smarter as the corpus reveals its dialect. An agent told to "fix the layout of the settings screen" that can see React in the project doesn't search for "screen" — it searches the way React projects name things:
Example 2 · Inferring the dialect
The agent blends TWO vocabularies: the task's words and the corpus's visible conventions. Both are naming systems — and both are under YOUR control.
Names are addresses, not labels
A name is not just a label for the human who opens the file. It is
the address by which task language finds the thing. Those are
different jobs, and they can disagree: a module named persistence/
is accurately labeled — but if every task that touches it says
"database," the address is wrong. The searching agent will fly right
past it, or land somewhere worse.
The test of a name
Name things with the words tasks will use. When you cannot predict the task vocabulary, you are guessing — so listen for it: the way your team actually phrases requests is the vocabulary your names need to speak.
One concept, one name
Search returns what matches — and only what matches. If the same
concept lives under db, database, store, and dao, then every
query returns a shard of the truth, and the agent has no way to
know the shards are siblings. It will explore the shard it found and
believe it has seen the whole.
Synonyms fragment the view
The agent now "knows" how this system does persistence. It is wrong — and nothing it found will tell it so.
The rule: one concept, one name, everywhere. A dull consistent name beats a clever varied one, because consistency is what makes search results COMPLETE.
This is the conventions file again, with a sharper reason to keep
it. A convention like "we always call it db" isn't just for
readers — it is what guarantees that whoever searches the corpus,
human or agent, gets the whole picture in one query.
A hit carries no authority — and becomes training data
Here is the trap in the middle of this lesson. Text search ranks by match, not by correctness. And corpora accumulate: the old way of doing things rarely gets deleted — it gets left. So the query "database" matches the deprecated helper from four years ago exactly as well as the current code. Often better — old code tends to be more literally named.
What happens next is the dangerous part, and you already know the mechanism from teaching by example: the agent doesn't just read its first hit. It imitates it. Whatever pattern search surfaces becomes the worked example in the agent's context — the in-context training set for everything it writes next.
Add a query that fetches unpaid invoices from the database.
⟨tool_use⟩
search_files(pattern = "database")⟨tool_result⟩
src/legacy/database_helper.py — 19 matches, e.g.
"conn = raw_connection(DATABASE_URL)"
"cursor.execute('SELECT * FROM invoices …')"I found the database access pattern. Following the existing style, I'll add a function using raw_connection and a cursor…
Two designs follow from this trap — one for the information, one below for the marks it must carry. The first is blunt: don't leave two ways of doing the same thing alive and unlabeled. Delete what you can. What you cannot delete, you must mark — which raises the question of where the mark has to live.
Marks must live where the search lands
A wiki page that says "the old database helper is deprecated" does nothing. The searching agent never routes through the wiki — it lands directly on the hit, reads outward from there, and starts work. For an authority mark to function, it must be lexically attached to the thing search finds: in its name, its path, or its opening lines.
Marks that travel with the hit
The searching agent gets the hit and ONLY the hit. Whatever it must know about the hit has to arrive WITH it.
Note the best version does two jobs: it warns, and it forwards —
"use db/session.py instead" turns a dead end into a redirect. The
wrong entry point becomes a signpost to the right one.
Plant signposts — small trees floating in the graph
You cannot impose a global tree on a living codebase or a knowledge
graph. But you can scatter local roots: small, name-dense
landmark files — an INDEX.md per region, a README per subsystem,
a start-here map. These are search magnets. Precisely because they
are dense with task vocabulary — a good index mentions everything
it points to — they outcompete random middle-of-the-corpus files
for the first hit. And once found, each one acts as a local table of
contents: the agent falls back into the tree-reading behavior we
wanted all along.
A signpost is a search magnet
src/billing/README.md
The design goal in one sentence: make the first thing search finds be a signpost, not a random page.
Or hand the entry point over in the task
Everything so far designs the information. The dual is to design the task: if you already know the names, say them. Every name you provide converts a search gamble into simple navigation — the task prompt can carry a table of contents even when the corpus has none.
Two versions of the same task
Three filenames. They replace the entire bootstrapping phase — every search, every wrong hit, every token of exploring the legacy code — and they close the trap from Example 3 before it opens.
Cheap insurance, and it compounds: the guidance costs you one sentence, and it saves the priciest and most error-prone stretch of the whole trajectory — the part where the agent knows the least.
The grep test
All of these principles compress into one design check you can run in five minutes, on any corpus, before any agent touches it. It is the same move as stress-testing a skill's catalog line — pointed at your whole information space.
The grep test
Every failure has a fix from this lesson: rename toward task vocabulary · collapse synonyms · delete or mark the dead · plant a signpost · seed the task.
Run the grep test on an information space you actually own — your codebase, your notes, your lab's shared drive. Three real tasks, their words, the searches. Bring the single worst hit you found: the leftover, the shadowed synonym, the missing signpost — and say which fix you'd apply and why.