All notes

A code graph is not repository memory

What code graphs can tell an agent, what real repository questions demand, and why useful memory needs a semantic layer.

  • Code graphs are useful for definitions, references, dependencies, and impact analysis.
  • Most agent questions are about ownership, intent, authority, and current behavior rather than structure alone.
  • A capable scout already builds a task-specific map by searching and reading the repository.
  • RepoMemory combines deterministic evidence with reusable summaries and metadata, then sends the agent back to the source.
On this page

After I wrote about giving coding agents a map, I kept looking at other projects trying to solve the same problem as RepoMemory.

Many of them start with a graph. They parse a repository, turn files and symbols into nodes, connect definitions to references, and let an agent walk those relationships without sending the code to a hosted service.

That approach is appealing. It is deterministic, private, and often fast. It also seems like a natural fit for code, which already contains imports, calls, types, packages, and other visible relationships.

I tried versions of that idea during my own work on RepoMemory. What I found was that a graph could describe the shape of a repository, but it did not reliably answer the questions I was actually asking.

What graphs do well

A code graph is useful when the question already matches the structure it has captured.

It can help answer questions such as:

  • Where is this symbol defined?
  • Which files reference this function?
  • What imports this package?
  • Which modules sit downstream from this schema?
  • What code may be affected if this interface changes?

Those are valuable questions. A graph can answer them quickly and consistently, especially in a strongly typed codebase where important relationships are easy to extract.

This kind of graph also gives an agent a better way to expand from a strong starting point. Once an exact symbol match identifies one file, nearby symbols and dependent files may reveal the rest of the implementation surface.

RepoMemory still uses a narrow form of that idea. Symbol relationships can add useful neighbors to a candidate set. The problem begins when the graph is asked to become the whole retrieval system.

The questions agents really ask

Most of my work with coding agents does not begin with a clean symbol question. It begins with intent.

I ask things like:

  • Where does this behavior actually belong?
  • Which implementation is current rather than abandoned?
  • What contract is this code trying to preserve?
  • Which similarly named file is authoritative?
  • Why does the running application behave differently from the API response?
  • What else should be checked before changing this setting?

A graph may contain some of the relationships needed to investigate those questions. It does not naturally contain the answers.

The most connected file is not always the most relevant file. A small configuration module with one string match may control the behavior while a large service with dozens of connections merely consumes it. A test may explain a contract more clearly than the implementation. A deployment script may be the reason the running system disagrees with the source that looks authoritative.

Relevance depends on the task. Topology alone cannot supply it.

Code is not only a call graph

Real repositories also contain relationships that are difficult to recover from static structure.

Runtime configuration, dependency injection, string-based routes, generated code, shell scripts, SQL, documentation, container definitions, feature flags, and deployment state all affect behavior. Some languages make call paths easy to extract. Others rely heavily on reflection, macros, conventions, or runtime registration.

A graph can ignore those edges and remain incomplete, or attempt to represent all of them and become noisy. Either way, another system still has to decide which relationships matter for the question in front of the agent.

That decision is the hard part.

The scout is already a strong baseline

There is another reason a graph-only system has to clear a high bar. A capable coding agent already knows how to explore.

Codex can search for an error message, inspect a directory, follow imports, read tests, compare configuration, and revise its search when the first result is wrong. A scout agent effectively builds a temporary map around the current task.

That map is not as cheap to recreate as a stored graph, but it is adaptive. It can follow a weak clue into documentation, notice that a path is obsolete, or switch from application code to deployment configuration when the evidence points there.

In my testing, a graph without summaries or useful metadata did not consistently perform better than letting Codex and its scout inspect the repository directly. It often moved the search work into an indexing step without adding enough meaning to improve the final starting context.

The useful target is not to replace the scout. It is to let the scout begin much further into the investigation.

The missing semantic layer

RepoMemory became more useful when I added summaries and metadata about what files are for.

A path and a set of edges can tell me that a file exists and what it touches. A summary can say that the file owns note publication rules. Metadata can identify its responsibilities, entry points, related surfaces, or whether it is a test, configuration file, script, user interface, or API route.

That information helps bridge the vocabulary of the task and the vocabulary of the repository. The user may ask about publication scheduling even though no important file contains that exact phrase. The repository may call the concept visibility, future dating, or publication state.

RepoMemory combines several kinds of evidence rather than asking one method to do everything:

TEXT
exact paths and identifiers
          |
          v
text, symbols, and search index
          |
          v
narrow structural neighbors
          |
          v
summaries and metadata
          |
          v
optional ranking when the result is ambiguous
          |
          v
agent reads and verifies the source

The deterministic evidence should win when it is decisive. The semantic layer helps when the request is about purpose or ownership. The agent still checks the current source before making a claim or changing the repository.

A real RepoMemory status capture. The summary and freshness counts are part of the context an agent can use before it reads the source.

A graph is evidence, not memory

I no longer see graphs and AI-generated repository context as competing ideas. They operate at different levels.

A graph provides useful structural evidence. Text search and symbols provide strong direct evidence. Summaries and metadata add purpose. A ranker can help when several plausible files remain. The coding agent brings the task-specific judgment and verifies the result against the source.

The graph belongs inside that system, but it is not the system.

For the kind of repository questions I ask, memory has to preserve more than connections. It has to preserve enough meaning to help the next agent understand why a file may matter, while remaining humble enough to send that agent back to the code.

Adding that semantic layer creates a separate cost question. In a future note, I will look at how I divide the work between deterministic retrieval, cheaper models, and frontier agents.