Coding agents have created a new infrastructure problem.
Before an agent can change a codebase, it first needs to understand it. It searches for symbols, reads files, follows imports, inspects interfaces and tries to reconstruct the relationships between different parts of the system.
Then, in the next session, another agent often repeats much of the same work.
It is therefore unsurprising that "memory for coding agents" has become an increasingly popular product category. Many tools now parse repositories, extract symbols, generate summaries and store the resulting information for later retrieval.
This is useful work.
But it is not the same as creating an architectural model of a software system.
That distinction is the reason I started building Enola.
What coding-agent memory usually means
Most codebase-memory systems follow some variation of the same pipeline:
- Parse the repository.
- Extract files, functions, classes and other symbols.
- Generate summaries or embeddings.
- Store the extracted information.
- Retrieve relevant fragments when an agent asks a question.
Tree-sitter is frequently used in this process because it provides a practical and language-independent way to construct syntax trees.
There is nothing wrong with this approach. It is significantly better than blindly splitting source files into arbitrary text chunks.
The problem begins when a syntax tree, symbol index or retrieval database is described as an architecture map.
A syntax tree describes the grammatical structure of source code. A symbol index describes which constructs exist and where they are located. A retrieval system helps find previously indexed information.
Architecture requires another layer.
Architecture is made of relationships
A list of functions is not an architecture. A list of classes is not an architecture. Even a complete inventory of every symbol in a repository is not yet an architecture.
The architectural value comes from the relationships between those elements.
- Which function calls which other function?
- Which implementation satisfies which interface?
- Which component is injected into which service?
- Which HTTP route reaches which handler?
- Which handler invokes which application service?
- Which repository accesses which storage model?
- Which frontend client communicates with which backend endpoint?
- Which dependency crosses a repository or service boundary?
These relationships must then be usable for more than visualisation. A structural model should support questions such as:
- What depends on this symbol?
- What is the complete transitive blast radius of changing it?
- What path connects these two components?
- Which strongly connected components indicate dependency cycles?
- Which modules violate an intended architectural boundary?
- How does a request travel through several layers of the system?
- How are separate repositories connected?
Answering these questions reliably requires an explicit graph, not merely a collection of retrieved text fragments.
Parsing is the beginning, not the result
Parsing source code is necessary, but it is only the first stage.
Different languages and frameworks express similar architectural concepts in very different ways. A Go interface, a Java interface and a TypeScript interface do not have identical syntax. Dependency injection can be represented through constructors, frameworks, annotations, generated code or configuration. HTTP routes can be declared explicitly, registered through a router or inferred through a framework's directory structure.
To build an architectural model, these language-specific details need to be normalised into a shared vocabulary.
Enola represents architectural entities — repositories, modules, packages, services, interfaces, functions, methods, routes, storage components — and connects them using explicit relationships: calls, imports, implements, instantiates, injects, contains, and depends_on.
This is where an extracted code inventory starts becoming a structural representation of the system.
Deterministic context instead of repeated reconstruction
Large language models are capable of inferring architectural relationships from source code. But there are limitations.
The model must first receive the correct files. It must notice all relevant relationships. It must keep enough context available. It must avoid losing details while moving through a large repository. And it must repeat much of this investigation whenever the context is reset.
The result can be impressive, but it is still probabilistic.
Enola takes a different approach. It builds the structural model before the agent asks its question. The agent does not need to infer every dependency from raw source files. It can query an existing graph and receive the nodes, edges, paths and evidence relevant to the task.
This does not remove the need for reasoning. It changes what the model needs to reason about.
Why this matters more across repositories
The difference between retrieval and architecture becomes particularly visible when working across repository boundaries.
Inside one small repository, an agent can often grep its way to a reasonable answer. Modern systems are rarely limited to one small repository.
A user action may begin in a web application, pass through a generated API client, reach an HTTP route in another repository, invoke several services and eventually access a database or publish an event.
A text-retrieval system may retrieve some of these pieces. An architectural graph can represent the complete path.
This makes questions such as the following possible:
- Which backend route does this frontend client call?
- Which repositories depend on this shared contract?
- What is the path from this UI action to persistent storage?
- Which components are affected if this API changes?
- Where does a dependency cross a service boundary?
These are not simply search questions. They are graph questions.
Architecture is more than static source structure
It is also important to define the boundary honestly.
No static source-code model represents the complete architecture of a running organisation. Source code alone may not reveal production traffic patterns, runtime frequency, organisational ownership, undocumented architectural intent, externally configured infrastructure, operational failure modes, or every relationship created through reflection and dynamic behaviour.
Enola is not intended to invent information that cannot be supported by evidence. It builds a structural architecture graph from the code and relationships it can extract. Deterministic findings can be treated differently from heuristic observations, and architectural conclusions can retain links to the evidence behind them.
The goal is not to pretend that a static analyser knows everything about the system. The goal is to create the strongest possible deterministic foundation before asking an AI model to interpret it.
A different layer of infrastructure
I no longer think of Enola primarily as coding-agent memory.
Memory is about retaining information from previous interactions. Enola is closer to structural intelligence for software systems: a language-neutral, queryable representation of code and architecture that agents can use as infrastructure.
The MCP server is one way of exposing that infrastructure to agents. The graph is the underlying product.
This difference matters because coding agents will continue becoming more capable. They will write more code, perform larger refactorings and operate across increasingly complicated systems.
But better reasoning models do not eliminate the need for reliable facts.
The more responsibility we give agents, the more important it becomes that their understanding of the system is based on deterministic structure rather than a sequence of partially successful searches.
That is the problem Enola is trying to solve. Not helping an agent remember a few more files. Giving it a real structural model of the software it is changing.
FAQ
What is the difference between codebase memory and an architecture map?
Codebase memory systems parse repositories, extract symbols, generate summaries or embeddings, and retrieve relevant fragments when an agent asks a question. An architecture map goes further: it builds an explicit graph of the relationships between those symbols — which function calls which, which module imports which, which route reaches which handler — and supports structural queries like dependency traversal, impact analysis, and shortest-path between components.
Why is a syntax tree not enough for understanding software architecture?
A syntax tree describes the grammatical structure of source code within a single file. It tells you what constructs exist and how they are nested, but it does not capture cross-file relationships like call edges, interface implementations, dependency injection, or HTTP route-to-handler mappings. Architecture is defined by these relationships, not by the syntax of individual files.
How does enola differ from RAG-based codebase tools?
RAG-based tools retrieve text fragments that are semantically similar to a query. Enola builds a deterministic, typed, directed graph from the actual code — nodes represent modules, symbols, routes, and storage, while edges represent calls, imports, implements, injects, and other relationships. This graph supports structural queries (traversal, shortest path, impact analysis) that text retrieval cannot answer reliably.
Can enola work across multiple repositories?
Yes. Enola links multiple repository snapshots into a single traversable graph using HTTP route matching, import references, and shared symbol detection. Once linked, all tools — including traverse, find_path, and impact_analysis — follow edges across repository boundaries.
Does enola use AI to understand code architecture?
No. Enola uses deterministic parsers — Go's native AST package, tree-sitter grammars, and YAML/JSON scanners — to extract facts from source code. Graph algorithms like Tarjan's (for cycle detection) and pattern matching (for architectural layers) produce the structural analysis. Run it twice on the same commit and you get the same result. The goal is to give AI agents a reliable factual foundation rather than asking them to re-derive the structure probabilistically.
enola is open source under Apache 2.0 — free, local, no data leaves your machine.
curl -fsSL https://raw.githubusercontent.com/enola-labs/enola/main/install.sh | sh