ADR-0009: KuzuDB Persistent Graph Backend¶
Date: 2026-03-22
Status: accepted
Context¶
The code graph (nodes for modules, classes, functions; edges for calls, imports, inheritance) is built in-memory using NetworkX during each analysis session. This has two limitations:
- No persistence: The graph is lost when the session ends. Re-analyzing a large repo rebuilds the entire graph from scratch, repeating LSP queries and AST parsing.
- No native query language: NetworkX requires imperative Python for graph traversal. Cypher queries would enable the AI agent (and MCP clients) to ask ad-hoc structural questions like "find all classes that inherit from BaseModel and are referenced by more than 3 modules."
Alternatives considered:
- Neo4j: Industry-standard graph database but requires a running server process, Java runtime, and network configuration. Too heavy for a CLI tool.
- SQLite with recursive CTEs: Could model graphs relationally, but graph traversal queries become unwieldy and slow compared to native graph storage.
- Pickle/JSON serialization of NetworkX: Simple persistence but no query language, no incremental updates, and large file sizes for big graphs.
Decision¶
Add KuzuDB as an optional persistent graph backend behind a GraphStorage protocol. NetworkX remains the default in-memory backend.
Key design choices:
GraphStorageprotocol defines the interface (add_node,add_edge,query,to_networkx, etc.) so backends are swappable- NetworkX remains default — zero-config, no extra dependencies, works exactly as before
- KuzuDB provides: embedded graph database (no server), Cypher query support, on-disk persistence, and cross-session graph continuity
- Bidirectional conversion:
to_networkx()andfrom_networkx()methods allow KuzuDB-stored graphs to use NetworkX algorithms (PageRank, community detection, etc.) - Opt-in via configuration:
CODE_CONTEXT_GRAPH_BACKEND=kuzuactivates the KuzuDB backend - ty type checker excluded for
storage.pydue to imprecise kuzu stubs that produce false positives
Consequences¶
Positive:
- Graphs persist across sessions — re-opening a previously analyzed repo loads the graph instantly instead of rebuilding
- Cypher queries enable powerful ad-hoc structural analysis without writing Python traversal code
execute_cypherMCP tool exposes Cypher to external AI assistants- Embedded database (no server process) keeps the CLI tool self-contained
- NetworkX algorithm compatibility preserved via conversion methods
Negative:
- Adds
kuzuas an optional dependency (only installed when the backend is selected) - Conversion to/from NetworkX for algorithms has overhead on very large graphs
- KuzuDB schema must be kept in sync with the
CodeGraphPydantic models; schema migrations are manual - ty type checker exclusion for
storage.pyreduces type safety coverage for that module
Neutral:
- Default behavior is unchanged; existing users see no difference unless they opt in
- Graph database files are stored alongside analysis output, managed by the existing output directory structure