Technology · Discipline

Code graph and static dependency analysis

The code graph under my memory service is extracted with a parser into partitioned edge tables; dependency traces are bounded database traversals with no model involved, and the explainer may narrate only proven edges.

tree-sitter parserPostgreSQL edge tablesBounded SQL traversal
Blast radius of one symbol · edges from the parser
the symbol one hop two hops
Breadth-first in SQL only edges that exist in the source
0model calls in a dependency trace
  • 6edge kinds extracted from source by the parser
  • 3languages with edge extractors: Rust, Python and TypeScript
  • 294,033of the index's 294,362 code chunks covered by the graph
  • ~19,000files in the monorepo the graph is built over

Edges from a parser, not from a model

In FAFOHive, my agents had to know the blast radius of a symbol before changing it, and a language model asked for call paths invents some.

Structure must come from a parser and a database; a model may only put that structure into words.

tree-sitter extracts calls, imports, implements, references, definitions and re-exports from source, and they land in partitioned PostgreSQL edge tables. An edge whose endpoint is not indexed yet stays pending, and a resolver promotes it only once both endpoints are indexed. Graph generations let me rebuild an index without serving a half-built graph, and each request is pinned to one generation.

Pending
source symbol · indexedkind · file and line · generationtarget · not indexed yet
Active
source symbolpromoted by the resolvertarget symbol
A pending edge is held back from every answer.

Two tools over one graph

trace_symbol_dependencies is plain traversal: a bounded breadth-first search in SQL with a Redis fast path, returning edges and nodes with file and line. explain_code_path walks the same graph between two points and only then hands the proven path to a model to describe.

trace_symbol_dependenciesone to three hops, capped at fifty edges by default
explain_code_pathup to five hops; the model receives the path after it is proven
Hop limits and an edge cap keep a trace cheap enough to call before every change.

A standing rule before every change

I also made the graph part of how agents work. Their operating doctrine requires a sequence before any change, told in A code explainer that is not allowed to invent.

Search past decisions
Find the reference implementation
Locate the local counterpart
Trace incoming dependencies two hops deep
Explain sparingly
Save the decision once it holds
Each step returns paths, lines or edges that the next step consumes.