Back to blog
Doors

The reads door: one entrance for every “understand the code” question

Explore an area, trace a flow across dynamic-dispatch hops grep can’t follow, or get a change’s blast radius — through a single door. You name the symbols; the graph hands back their source, already Read. Six tools, one entrance, and the agent never has to pick.

explore node search callers callees impact

An agent working in an unfamiliar codebase spends most of its budget on one thing: figuring out what the code does. Grep for a name, read the file, follow an import, read that file, grep again. Each hop is a tool call and a few thousand tokens of source pasted into the context, and most of it gets read once and never used. That loop is where sessions go slow and expensive.

SpecShip collapses that whole loop into a single door. Type /specship:explore, describe what you want to understand, and the graph answers — no grep, no Read, no file-hopping. This is the post about that door and the six tools behind it.

One door, not six commands

The temptation with a code-intelligence tool is to expose a command per capability: one for callers, one for callees, one for impact, one for tracing, one for search. That's honest to the internals and useless to the agent — now it has to choose the right tool before it even understands the problem, and choosing wrong means a wasted round-trip.

So the reads door takes intent, not tool names. You say what you're trying to understand; the door picks the behaviour from the shape of the request:

an area
“how does X work” → explore that region
a flow
“how does X reach Y” → trace the path between them
a change
“what breaks if I touch X” → the blast radius

Same door, three questions. The agent never has to know which underlying tool serves which — it describes the goal and walks through.

The default: “how does X work”

Most reads are this one, and they resolve through specship_explore — the primary tool of the door. You hand it a bag of symbol names (include qualified Class.method forms when you have them), and it returns the verbatim source of those symbols, grouped by file, plus any call path it can synthesize between them. One capped call, Read-equivalent.

The rule that makes it work is a discipline the door enforces on the agent:

Treat the returned source as already Read. Explore hands back the real code, so re-Reading the same file is pure waste. If a giant “god file” truncates the output, the answer isn’t to Read it — it’s to call explore again with a tighter bag of symbols. The door steers there deliberately, because the instant an agent falls back to Read, the whole economy collapses.

When you need one symbol in full — its complete body, its signature, and its caller/callee trail — that's specship_node, the door's secondary tool. Its quiet superpower is overloads: ask for an ambiguous name and it returns every matching definition's body in a single call, so the agent never Reads a file just to find the right one.

Trace a flow — across the hops grep can’t follow

“How does updating an element re-render the canvas?” isn't a search — it's a path. You call specship_explore and name the symbols that span the flow, both ends (mutateElement renderScene), and it surfaces the call path among them.

The part grep structurally cannot do: SpecShip rides dynamic-dispatch hops. Callbacks, EventEmitter wiring, a React setState→render, a JSX child mounting — these are edges no text search will ever find, because the call target is computed at runtime, not written next to the caller. SpecShip synthesizes those edges into the graph, so a trace connects end-to-end even where the source has a gap. If you only have half a name to start from, specship_search locates the symbol first, then you hand it to explore.

Grep finds the lines that mention a name. The reads door finds the path a value actually travels — including the three hops where the code never mentions the next function at all.

Blast radius — “what breaks if I change this”

Before you touch a symbol, you want the dependents. specship_impact returns the transitive set — everything that would feel the change, however many hops away. When you want just one hop in either direction, specship_callers (who calls this) and specship_callees (what this calls) answer instantly. It's the difference between “is this safe to rename?” and a half-hour of manual dependency archaeology.

The tools behind the door

explore
primary — a bag of symbols → their source, grouped by file, plus the synthesized flow. Usually the only call you need.
node
one symbol in full — body, signature, trail; every overload in a single call.
search
locate a symbol by (partial) name when you don’t have the exact one.
callers / callees
one hop in or out — who calls this, what this calls.
impact
the transitive blast radius of changing a symbol.

A flow worth trying, on your first run

Open the door with no argument and it does something small but deliberate: it prints a concrete question worth asking in your repo — a real flow it has verified actually connects, like How does GET /api/orders reach OrderService.create? — so your very first move can be watching the agent answer a genuine cross-file question by exploring the index instead of reading files. It bows out on its own once you've started using retrieval this session; it's a nudge, not a nag.

the reads door, three ways
# understand an area
/specship:explore AuthService.login rate-limit enforce

# trace a flow (name both ends)
/specship:explore mutateElement renderScene

# blast radius
/specship:explore impact of SessionToken.rotate

Why it’s a door and not a menu

The index is kept fresh automatically — edit a file, and once it settles the graph already reflects it (force it with specship sync if you're impatient). So the door is always answering from current code, and it's answering the one question the agent actually has: what does this do, and what touches it? It gathers that in one to a few fast calls with zero Reads, where the grep-and-read version would be dozens of turns over an ever-growing pile of pasted source.

That's the whole point of a door. You don't stand in front of it choosing between six handles. You say where you're going, and it opens.

#doors#retrieval#explore#impact
SE
Selva E.
Building SpecShip · graph, specs & harness
Works on the parsing, storage, and spec layers of SpecShip. Spends an unreasonable amount of time thinking about edges.