v0.12.0
v0.12.0 — graph-correctness sync with upstream
A curated port of 17 upstream commits from DeusData/codebase-memory-mcp
(8d00f4b..97ce23f), scoped to C++, Python and Go indexing correctness, plus one
fork-specific regression found while porting. Every fix below is verified by tests and by
indexing real fixtures with the release binary.
Full test suite: 5626 passed / 0 failed (+11 ported regression guards).
If you index anything larger than 50 files, re-index after upgrading
Several of these fixes change the graph the indexer produces. The parallel pipeline (the
default above 50 files) was dropping edges that the sequential one kept, so existing graphs
are incomplete rather than wrong-but-consistent. delete_project + re-index to pick up the
corrected edges.
Call-graph completeness
- Parallel-path CALLS edges restored — the registry fallback ran only when no LSP
resolution existed, so an LSP resolution whose target wasn't a graph node dropped the edge
outright. Upstream measured ~21% of a Next.js call graph lost this way. Parallel is the
default above 50 files, so the default index was the affected one. (upstream8c39465) - Reason-keyed LSP strategies restored on the default path — a fork-only regression: this
fork had made the per-file O(1) LSP index authoritative and dropped the linear rescan that
reason-keyed strategies join through.lsp_func_ptr,lsp_dll_resolve,lsp_destructor,
lsp_dict_dispatch,lsp_method_ref_ctor{,_synth}andphp_method_dynamicwere all
silently dropped whenever the parallel path ran. Measured on a 61-file project: 1096
edges with the fix, 1036 without. - Python aliased imports —
from m import f as g; g()produced no CALLS edge at all.
Now resolved via a newlsp_import_aliasstrategy. (upstreamd322548) imported.method()no longer collapses to the imported symbol — the aliased
direct-symbol import shortcut fired before suffix handling and bound the call to the
symbol's own node. Upstream measured this degrading Django by ~11K edges (CALLS
74,685→72,175, TESTS 38,032→29,236). (upstream89e1c47+afcce2d)
IMPLEMENTS / INHERITS / OVERRIDE
IMPLEMENTSvsINHERITSis now one decision in both pipelines, keyed off the resolved
base node's label. The parallel path hardcodedINHERITSand demoted every explicit
implementsat scale — upstream measured elasticsearch going from 3 to 11,182IMPLEMENTS.- New
OVERRIDEedges for explicit-inheritance languages (Java, TypeScript, C#, Kotlin,
PHP): a class method is linked to the base method it redefines, for both interfaces and
superclasses. Go keeps its implicit-satisfaction path and is excluded so it isn't
double-covered. (both upstream4a3aac6)
C/C++
- Definitions split across
#ifdef/#elsebraces are recovered. A function whose body
braces open in each branch with one shared close is unparseable in raw form, and was
silently dropped while its callers stayed unresolved. Recovered from the preprocessed pass
and remapped to original lines, with every line verified to belong to the main file so
header-inlined definitions and macro-generated callables fail closed. (upstream65a176e,
99d3919) - Headers get their own
Filenode. Extension stripping applied to File QNs too, so
NodeController.handNodeController.cppcollided and the header ended up with no node.
Also fixes.env/.env.local/.env.productioncollapsing to one node. (upstream
751752b) #includeresolves to the header rather than a same-stem source or module node.
(upstream632fd08)- No more false parse gaps from macro calls —
ALLOC(int, n)-style function-like macro
invocations make the grammar emit an ERROR node, which was reported as aparse_partial
coverage gap even though nothing was missing. Top-level invocations that expand to
definitions stay flagged. (upstreama75f4b6)
Go / Java
- Directory-module collision guard — a class-level env access or
throwsin a
package-per-directory language falls back to the module QN, which collides with the shared
Folder node and conflated every such edge. (upstream6b2cd08)
Reliability
- Wide repositories index completely. A directory with more than 512 immediate
subdirectories silently dropped every subdirectory past the walk-stack cap — the fan-out
just vanished from the index with no error. dotnet/runtime has 855 sibling dirs in one
folder. The stack now grows on demand. (upstream03dc9c9) - Runaway Cypher queries abort instead of hanging. An unbounded
OPTIONAL MATCHor a
whole-graphGROUP BYproduces no rows, so the 100k row ceiling never fired and
query_graphhung indefinitely. Now bounded by a 30s wall-clock deadline with an
actionable error. (upstream6bd11ff) - Second-index crash fixed — a SIGABRT (
freeof a non-libmalloc pointer in
ts_stack_delete) when a sequential index run preceded a parallel one in the same process.
(upstream2f7befb) - Incremental re-index no longer diverges from a full index — the incremental path named
File nodes by relative path while the full pipeline used the basename, so an incremental
re-index renamed the node in place and name-based traversal dead-ended at every touched
file. (upstream2833ef5)
Extraction
- UTF-8 docstring truncation no longer cuts mid-codepoint. (upstream
3ebcf48) body_tokensare populated before the MinHash gate, so short functions still get
semantic-search tokens; token buffer and identifier caps widened. (upstreamb9797ec)
Not included
This is a deliberately scoped sync. The upstream shared-coordination daemon, the MCP
tree-format output migration, ObjectScript and Perl language support, the Windows
launcher/install-transaction work, and the store-integrity cluster were not ported — see
UPSTREAM_SYNC.md
for the full ported/skipped breakdown and the fork-side deviations.
Upstream credit: the original engine and design are by
DeusData/codebase-memory-mcp.