01 / Introduction
Better code starts with better context.
We’re launching AxiomCode Graph v0.1.0, our graph builder for AI software engineering.1 It turns any codebase into a knowledge graph grounded in formal methods: a queryable map of the relationships behind a change, the methods it calls, the code that calls it, and the paths through which its effects can travel.
Coding agents are taking on bigger work: whole features, migrations, and fixes that span a codebase, often running unattended. Everything they do starts with one question: what does this code touch? Today they answer it with grep, turn after turn of searching and reading, working from name matches that only approximate how the code connects. The deeper the link, the easier it is to miss.
We think agents deserve a better starting point: the program’s real structure, derived with formal methods instead of guessed from names (grep). AxiomCode Graph resolves types, follows values through assignments, returns, and callbacks, and reads the configuration that wires code together, so every call already points to the code it truly reaches. Your agents spend less time exploring and understanding code and more time on the task itself, so the work they hand back is more complete, higher quality, and has fewer bugs.
Today, AxiomCode Graph v0.1.0 launches with support for five programming languages (Java, TypeScript, and Python, with JavaScript and C# in beta) and three configuration formats (XML, YAML, and Gradle), so links defined in config files show up in the graph too.
The difference shows up where it counts. On real Java bugs, the best SOTA CST-based graph builder missed bug-revealing tests nearly 7× as often as AxiomCode, and the other three missed them 9× to 15× as often.
02 / How it works
From syntax to meaning.
Leading code graph tools are built on concrete syntax trees (CSTs), and for good reason: CSTs are fast to build, keep exact source positions, and don’t need the project to compile. AxiomCode starts there too. But a CST records how code is written, not what it means. It has no types, no overloads, and no dispatch, so CST-based tools have to approximate which code a call reaches.
AxiomCode goes further. It turns each tree into relational facts, then uses formal methods and declarative queries to resolve types across the whole codebase. Type flow tracks the concrete type behind every call, so a call reaches the one implementation it uses, not every class that shares its interface. Value flow follows data through assignments, parameters, returns, and callbacks, so indirect calls still connect.
The result is a graph that knows which code runs, not just which code matches, ready for agents and engineers to query.
Parse
Source code becomes
structured facts.
Derive
Explicit rules connect
the relationships.
Query
A graph gives each task
a connected starting point.
One foundation, several ways to work.
- 01Understand how it works
- Ask how a feature runs and get the call flow in order, with the code for each step.
- 02Know what a change reaches
- Find callers and dependencies, even through interfaces, overrides, callbacks, and dependency injection, each labelled with how certain it is.
- 03Review and plan changes safely
- See what a diff touched, what must change with it, and whether code is safe to delete.
- 04Run the right tests
- See which tests reach an edit, with the call chain that proves it.
- 05Find where a bug lives
- Go from a symptom or a stack trace to the connected code paths.
03 / Why accuracy matters
A typed graph is a more accurate graph.
We measured every call against the compiler’s own answer: bytecode for Java and the type checker for TypeScript, across five open-source projects per language. AxiomCode linked 96.5% of calls to their exact target in Java and 88.8% in TypeScript, leading the best SOTA CST-based graph builder by more than 17 points in both.
The gap comes from types. A CST-based graph has to approximate which implementation a call reaches, and every approximation can drop a real link. A typed graph resolves it, so each link it gets right is one more path an agent can follow.
Call resolution accuracy
Java & TypeScript · Five projects per language
Java, other four tools: range 67.5% to 78.9%, mean 74.2%, median 75.2%. TypeScript, other four tools: range 49.8% to 71.6%, mean 63.0%, median 65.3%.
Share of one-target groups with the expected link (%)
Counts and project datasets
| Tool | Javaof 33,257 | TypeScriptof 9,829 |
|---|---|---|
| AxiomCode | 32,092† | 8,731† |
| GitNexus | 26,240 | 6,400 |
| CodeGraph | 26,115 | 6,425 |
| Graphify | 22,439 | 4,894 |
| Code-Review-Graph | 23,925 | 7,040 |
JavaBytecode ground truth
maven-core · netty-transport · spring-boot · apache-ant · rxjava
TypeScriptType checker ground truth
kysely · typedoc · fp-ts · ioredis · excalidraw
Each language uses its own five-project dataset. Connecting lines pair the same tool’s results across languages. The “vs. mean” figures compare a tool with the unweighted mean of the other four tools, excluding AxiomCode.
† Coverage is not resolution precision. AxiomCode’s totals include projects where its output resembles broad candidate enumeration. Recovering the expected link does not, by itself, show that extra candidates were ruled out.
The candidate-envelope reference (CHA) scores 100% by construction. It is not a resolver and is kept outside the tool comparison.
That accuracy carries through to real tasks. Choosing the tests a change affects means following calls several levels deep, and one missed link can lose every test beyond it. That is where a typed graph pays off most, as the Defects4J results show below.
About this call-graph benchmark
Unit and ground truth. Tier B counts a caller and callee-name group with exactly one possible target. Java uses bytecode ground truth; TypeScript uses type-checker ground truth. Pooled groups with two different targets sharing a name are excluded from this measure.
Five-project totals. Counts and percentages use the supplied “all five” column for each language. Percentages are based on pooled counts, not an average of project percentages. Results describe these selected projects; they are not an estimate for all Java or TypeScript codebases.
Coverage and precision. The † mark is retained on both AxiomCode totals because they include envelope-class project results: broad candidate enumeration can recover expected links without resolving targets precisely. The source defines this flag using the class-hierarchy-analysis (CHA) envelope’s fan share and strict precision. These marked totals do not establish a resolution lead.
Comparison rows. The chart shows the five tools’ default results. The CHA envelope covers all one-target groups by construction, so its 100% is explained as a reference rather than ranked as a tool.
04 / Test impact
Choosing the right tests.
On a held-out set of 748 real bugs from Defects4J, the standard benchmark of Java bugs, scored once after our evaluation rules were frozen, AxiomCode kept every bug-revealing test for 94.9% of bugs. The best SOTA CST-based graph builder kept them all for 61.5%. Put another way, AxiomCode missed a bug-revealing test on 38 of the 748 bugs; the best of the others on 288, and the weakest on 584.
To choose tests, AxiomCode walks back from the changed code, through every caller, to the tests that reach it. Defects4J’s own selection gets its answer by running the test suite. Working from source alone, AxiomCode selected a median of 0.98× as many tests as Defects4J’s run, and reached an F1 of 72.4% against it, the highest of every static tool measured, where the next is 54.3%.
Test selection benchmark
Defects4J 748 held-out bugs
Bugs with all triggering tests included
Share of held-out bugs (%)
Coverage means all triggering tests were included for a bug. Suite share measures tests, not tokens; neither metric measures end-to-end code correctness.
Every tool was scored through the same walk. The only difference was the graph.
How we evaluated
Dataset. 748 held-out Defects4J bugs across 16 Java projects. A separate set of 80 development bugs was used during benchmark rule development; the benchmark rules were frozen before the held-out set was scored once. The report’s combined 828-bug table is not used for the headline results.
Equal evaluation path. Each tool’s emitted call edges went through the same benchmark resolver and dispatch step. This compares graph output under that shared procedure, not each product’s native impact command or an end-to-end coding agent.
Two metrics. Full triggering-test coverage is the share of cases where every triggering test was selected. Test selection is the mean share of each bug’s full test suite selected. Neither metric measures token cost or test runtime.
F1. The harmonic mean of precision and recall against Defects4J’s own selection: 73.7% precision and 71.2% recall give 72.4% across the 748 held-out bugs. It puts a test wrongly selected and a test wrongly skipped in one number, which is why safe is reported beside it — those two costs are not equal, and running the whole suite scores 64.5% here while missing nothing.
References. The dynamic reference comes from Defects4J observing which test classes loaded changed code during execution. The full-suite reference selects all tests. They are comparison points, not competing static graph tools.
Beyond known triggers. AxiomCode’s mean triggering-test recall is 95.5%; its relevant-test recall is 71.2%, and relevant-class coverage is 80.5%. These are different measures from the 94.9% bug-level result.
Scope. These results are from our evaluation on this dataset and setup. Every tool’s version and AxiomCode’s exact commit are recorded with the published results. The report does not include timing or token measurements; those are not inferred here.
05 / Real changes
What it looks like on a single change.
In Closure-157, AxiomCode selected 5,917 of 6,862 tests from source; Defects4J, running the suite, observed 5,919. Both kept all 12 bug-revealing tests, each reached through a chain of 6 to 10 calls. Below are two more cases, where it falls short, and why.
Held-out bug · Closure-157
The same selection Defects4J observed, with every trigger included.
Tests selected
Share of the full test suite · 6,862 tests
5,917 AxiomCode
5,919 Defects4J
AxiomCode selected about as many tests as Defects4J observed
Triggering tests included
Share of the 12 tests known to expose the bug
12 / 12 AxiomCode
12 / 12 Defects4J
AxiomCode included every known triggering test
From source alone, AxiomCode selected 5,917 of 6,862 tests; Defects4J, running the suite, observed 5,919. Both included all 12 tests known to expose this bug. One held-out example, not an average across projects.
Why. AxiomCode followed each call from the 12 tests to the changed code, 6 to 10 calls deep, including a call through an interface it resolved to the exact method that changed, so every chain stayed connected.
Source: held-out table of the published Defects4J results (release d4j-2026-09-24). Defects4J’s selection is the set of tests it observed load a changed class when it ran the suite.
06 / Where this goes
Where this goes.
A graph you can trust is the foundation for agents that can check their own work. Next, we’re narrowing down which implementation a call actually reaches when several are possible, and measuring how the graph changes real agent workflows, from test selection to bug localization and safe change planning.
Typed graphs work. AxiomCode missed a bug-revealing test on 38 of 748 bugs, where CST-based builders missed on 288 to 584: seven to fifteen times less often. That is the gap between matching names and following the program’s real structure, and it is the starting point we think every agent deserves when it asks what a change touches.
07 / Build with us
Build with us.
AxiomCode Graph v0.1.0 is available today, with its source on GitHub.1 Run it on your code, inspect every edge, and tell us where it can improve. The better the graph gets, the more agents can safely take on, and we want to build that with you.
- AxiomCode Graph is available under the FSL-1.1-ALv2 license at github.com/AxiomCodeAI/axiomcodegraph
