Why an AI coding agent needs a map

The subject of this series is ripwire, a repository-analysis tool built for coding agents. This opening chapter asks a practical question: why would an agent need a map of a codebase before it starts reading files? The answer is not that ordinary search has become useless. It is that an unfamiliar repository creates a selection problem: the agent must decide what matters, what is connected, how much context to spend, and whether the answer is trustworthy before it can make a safe change.

That selection problem appears before any sophisticated coding begins. An agent may know the task in human terms—“add another cache backend” or “fix the parser error”—without knowing the repository’s vocabulary. It has to discover which names correspond to the task, whether the relevant code is centralized or distributed, and which apparently similar files are tests, generated output, or production paths. The first useful answer is therefore not necessarily a piece of source. It is a defensible way of choosing the next piece of source.

Ripwire’s distinctive response is to treat repository context as an evidence-serving problem. It builds a ranked representation of the source tree, returns only a bounded portion of that representation, and marks the places where its evidence is incomplete. That combination—ranking, limits, and disclosure—is more important than any individual command. It is what makes a small answer potentially useful without pretending that a small answer is automatically complete.

The expensive first question

When a coding agent lands in a repository it does not know, its first task is rarely “find this exact string.” More often it is something like: locate the caching path, understand how a request flows through the service, identify the tests that protect a parser, or determine which part of the system is safe to change. Those questions are structural. They concern relationships among symbols and files, not merely the presence of a word.

A conventional workflow can answer them, but it makes the agent assemble the answer manually. A grep may return definitions, comments, generated fixtures, tests, and unrelated uses in one long list. Reading a file identified by that list may reveal the implementation, but not its callers or the tests that exercise it. Reading several whole files eventually supplies the missing context, at the price of spending attention on lines that never mattered. The result is not necessarily wrong; it is simply expensive and easy to mis-prioritize.

There are three different costs hidden inside that apparently simple workflow. The first is finding: locating the relevant names when the task uses different words from the code. The second is connecting: identifying callers, dependencies, or tests rather than stopping at the first lexical match. The third is stopping: knowing when enough evidence has been gathered. A search tool can help with the first cost while leaving the other two to the agent. A whole-file habit can cover the second by brute force while making the third nearly impossible. Ripwire is designed around all three: rank candidates, attach relationships, and give the answer a declared boundary.

This cost repeats whenever a fresh agent context is created. A parallel engineering workflow may give several agents the same repository and different tasks. Each one begins without the structural understanding the others have already paid to acquire. A map is valuable in precisely that moment because it turns orientation into a reusable intermediate answer: a compact account of which symbols are important and how they relate.

Ripwire’s own evaluations illustrate both the opportunity and the restraint required. On a held-out localization set of 243 instances, its routed task surface reached 60.9% strict file-at-10, compared with 27.6% for the pre-routing baseline. “Strict” here means that all gold files for an instance had to appear in the first ten, not merely one plausible file. That is evidence that routing and ranking can improve where an agent starts. It is not evidence that the agent will solve every task, nor that multi-file changes have ceased to be difficult: the same report gives 73.4% strict accuracy for single-file cases and 18.2% for multi-file cases.

The gap between those two strata is especially instructive. A primary file often contains the words used in an issue or request; sibling files may contain consequences, tests, registrations, or integration changes that share little of that vocabulary. A map can improve the first landing without making the whole dependency problem disappear. The right conclusion is a change in workflow: use the map to form a better first hypothesis, then check the relationships and coverage markers before treating that hypothesis as a plan.

That distinction matters. The useful claim is not “a map solves software engineering.” It is “a map can make the first decision more targeted, and the tool should tell you how much of the problem it actually covered.”

What ripwire promises—and what it does not

Ripwire is a single C++23 executable that analyzes a source tree locally. The project describes it as having no runtime dependencies, no background service, and no need for a network connection during normal builds or runs. Its central output is a ranked symbol map. Around that map are views for task-scoped retrieval, callers and callees, use sites, impact, test obligations, quality signals, documentation recall, and carefully bounded editing.

The promise is narrower than that of a compiler or a language server. Ripwire does not claim to build a complete semantic model of every program it reads. Its call graph begins with source syntax and names. That makes it inexpensive and broadly applicable, but it also means that dynamic dispatch, some callbacks, macro-generated behavior, reflection-like mechanisms, and unsupported language semantics can fall outside the graph. A result can therefore be useful without being conclusive.

It is also narrower than an autonomous coding system. Ripwire does not decide which design a team should adopt, write a complete patch from a task description, or certify that a change is safe merely because a symbol ranked highly. Its role is closer to an instrument panel: expose the parts of the repository that deserve attention, make the evidence behind that exposure inspectable, and provide a route to more precise evidence when the first pass is insufficient. That modest role is a strength because it leaves the final engineering decision attached to the source, the tests, and the people responsible for the change.

This is why the project’s most consequential design choice is not a ranking formula. It is an honesty contract. A count that cannot be proven to be a total is labeled as a floor. A zero means “none found,” not “none exists.” An ambiguous call can be marked as ambiguous rather than silently assigned to one definition. A selector that names nothing refuses with a near-match instead of presenting an arbitrary neighbor. A budget cut reports what was shown and what was withheld. A file missing from the index is distinguished from a file that was indexed but parsed with errors.

These are not disclaimers attached after the analysis. They change how an agent should act. If a task result has a strong relevance separation and no material coverage warning, the agent may use it as a focused starting point. If the result is flat, ambiguous, truncated, or built over an incomplete corpus, the next step should be deliberate: expand a symbol, inspect its uses, measure its impact, provide a compiler-grade index, or read the source directly. The output is designed to make that escalation legible.

The central theme of this series is therefore trustworthy context compression through deterministic, explicitly bounded evidence. “Compression” names the practical pressure: an agent cannot read an entire repository at every turn. “Evidence” prevents compression from becoming arbitrary summarization. “Deterministic” means the same tree should yield the same answer, so a changed result has an interpretable cause. “Explicitly bounded” means that a ceiling, a skipped directory, or a missing language is part of the answer rather than an invisible loss.

A map is a chain of evidence

Ripwire’s operating model can be understood as a five-stage chain:

flowchart LR A["Coding agent lands cold"] --> B["Repository question"] B --> C["Ripwire map"] C --> D["Ranked context"] D --> E{"Enough evidence?"} C --> F["Budget and uncertainty disclosed"] F --> E E -->|"Yes"| G["Read or change the relevant code"] E -->|"No"| H["Expand, inspect source, or use compiler-grade evidence"]

First comes ingest: the tool decides which files belong to the analyzable corpus and extracts definitions and references from them. Next comes the graph: references are connected to candidate definitions, with the resolver preserving uncertainty where syntax cannot settle the target. The rank stage then orders symbols. That order may represent structural importance in the repository or task relevance in a query; those are related but different questions. Serialize turns the result into a compact machine-readable answer. Finally, the CLI and optional MCP interface serve that answer in forms an agent can use.

The sequence is important because each stage constrains the next. A ranker cannot recover a file that ingest excluded. A graph cannot prove a dynamic call target that the source representation does not expose. A serving layer cannot honestly claim that a response is complete if the ranking was cut by a budget. Ripwire’s map is thus not a miniature copy of the repository. It is a chain of decisions about what was seen, how it was connected, how it was ordered, and how much of it was emitted.

That also explains why a map is different from a summary. A summary asks a system to paraphrase what it thinks the repository means. Ripwire’s core map instead preserves compact structural facts: symbol identity, location, rank, relationships, and selected measurements. The agent can then decide which body or file to read. The tool is reducing the search space, not replacing the source with an untraceable narrative.

There is a cost to this design. Ripwire’s output is written for a machine reader: its default XML is deliberately dense, and human-readable prose is not its main interface. The map is also a fixed cost that is wasteful when a person already knows the file and one direct search would answer the question. The project says this plainly: a narrow lookup in a known file may be cheaper without the map. A trustworthy tool must be allowed to recommend “use ordinary search” when its own machinery is unnecessary.

The productive way to read ripwire is therefore neither as an oracle nor as a prettier grep. It is a structured first pass over an unfamiliar system. It helps an agent decide where to look, what relationships may matter, and what evidence is still missing. The next step is to examine the boundary that makes that first pass possible: how a mixed repository is filtered, parsed, and converted into stable symbols before any ranking begins.

References