fix(audit): enforce zero dangling relationships across all language fixtures#665
Conversation
There was a problem hiding this comment.
Code Review
This pull request resolves issue #652 by preventing the emission of dangling or phantom graph edges (such as IMPORTS, INHERITS, IMPLEMENTS, and CALLS edges) across multiple languages. It achieves this by deferring the emission of these relationships until all files are parsed and registered, verifying them against the complete module and class registries. Additionally, it generalizes CppFunctionLocation to FunctionLocation to track function definitions across all languages, avoids emitting CALLS edges for builtins, and cleans up JS/TS ESM extensions. The review feedback suggests refining the variant type-checking logic in call_processor.py to always verify node types from the registry, even when the variant matches the primary callee, thereby preventing potential schema violations.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Greptile SummaryThis PR enforces zero dangling relationships across the fixture suite. The main changes are:
Confidence Score: 5/5Safe to merge with low risk. No blocking or non-blocking issues were identified in the reviewed changes. The main graph-edge changes defer emission until registries are complete and include targeted tests for imports, inheritance, external bases, builtin calls, and fixture audits. No files require special attention.
What T-Rex did
Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Parser as Language parsers
participant Def as DefinitionProcessor
participant Imports as ImportProcessor
participant Graph as GraphUpdater
participant DB as Ingestor/Memgraph
Parser->>Def: Register modules, classes, functions
Parser->>Def: Queue deferred inherits/implements/module impls
Parser->>Imports: Record import mappings/deferred import edges
Graph->>Def: Resolve deferred inheritance after registry is complete
Def->>DB: Emit verified INHERITS/IMPLEMENTS edges
Graph->>Imports: Flush imports with known module qns
Imports->>DB: Emit verified IMPORTS or ExternalModule edges
Imports-->>Graph: Drop unverifiable internal targets
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Parser as Language parsers
participant Def as DefinitionProcessor
participant Imports as ImportProcessor
participant Graph as GraphUpdater
participant DB as Ingestor/Memgraph
Parser->>Def: Register modules, classes, functions
Parser->>Def: Queue deferred inherits/implements/module impls
Parser->>Imports: Record import mappings/deferred import edges
Graph->>Def: Resolve deferred inheritance after registry is complete
Def->>DB: Emit verified INHERITS/IMPLEMENTS edges
Graph->>Imports: Flush imports with known module qns
Imports->>DB: Emit verified IMPORTS or ExternalModule edges
Imports-->>Graph: Drop unverifiable internal targets
Reviews (3): Last reviewed commit: "fix(review): strip JS extensions only on..." | Re-trigger Greptile |
|
@greptile review |
… emitting test id
…IMPLEMENTS phantom
…s register, skip unresolvable parents
…efer C++20 module impl links
…ses and JS global classes
…ilter variant fan-out
… variant type checks
|
@greptile review |
66746e7 to
7a25b77
Compare
|
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
|




Summary
Iteration 3 of the dangling-edge campaign (#652): eliminates every remaining dangling relationship across ALL language fixtures and flips the conftest audit gate so every fixture test now enforces zero dangling edges permanently.
An edge with a phantom endpoint is silently dropped by Memgraph's MERGE, so everything fixed here was information the live database never actually contained.
Numbers
Root fixes (each red -> green in history)
builtin.*qn (console.log, JSON.stringify, Function.prototype.bind) has no node, so no CALLS edge is emitted at all, mirroring the C++ builtin-operator rule. First-party callbacks handed to builtins stay reachable through the argument-flow path.DeferredInherit), so cross-file bases no longer depend on parse order and self-edges are guarded on both resolution branches.typing.Protocol,::-qualifiedstd::fmt::Display, or a JS global likeError) keeps its edge by targeting the same ExternalModule node the import pass mints; the INHERITS/IMPLEMENTS schema targets are extended withExternalModule(the fix(graph): inconsistent schema for external modules using is_external boolean instead of dedicated label #498 precedent). This also restores Protocol detection for dead-code analysis and incremental protocol dispatch, both of which the live database had silently lost. A module-anchored guess that resolves nowhere still emits nothing: knowledge and guesses are not the same.CYPHER_ALL_MODULE_QNS), index-file aliases (__init__/index/mod/init), and a unique whole-segment suffix match. Broken imports drop; package-anchored stdlib guesses re-resolve as absolute Python imports; explicit.js/.tsextensions strip during JS path resolution; C++20 module declarations never emit self-imports and implementation units link only to interfaces that exist.cpp_function_locationsbecamefunction_locations; Pass 3 reuses the qn/label Pass 2 registered instead of re-deriving, fixing TS declaration merging (members registered underLogger@13while callers were attributed toLogger) and a Rust nested-fn phantom FROM endpoint. Rust keeps its ownership-aware call filter on the recorded path.Test-expectation corrections are limited to assertions that encoded phantom edges (undefined Java generic bases, a Go package-dir import target, builtin-call counts, JS fixtures whose imported files never existed); each carries an explanatory comment.
Verification
uv run pytest codebase_rag/tests -n auto: 4618 passed, 14 skippeduv run ty check: at the 352-diagnostic baseline (no new)Closes the fixture-level goal of #652.