Skip to content

fix(audit): enforce zero dangling relationships across all language fixtures#665

Merged
vitali87 merged 14 commits into
mainfrom
fix/fixture-dangling-sweep
Jul 8, 2026
Merged

fix(audit): enforce zero dangling relationships across all language fixtures#665
vitali87 merged 14 commits into
mainfrom
fix/fixture-dangling-sweep

Conversation

@vitali87

@vitali87 vitali87 commented Jul 8, 2026

Copy link
Copy Markdown
Owner

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)

  1. JS/TS builtin calls: a callee resolving to a synthetic 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.
  2. Deferred non-C++ INHERITS/IMPLEMENTS: parents now resolve after every class is registered (the iteration-2 C++ design, generalized via DeferredInherit), so cross-file bases no longer depend on parse order and self-edges are guarded on both resolution branches.
  3. External bases target ExternalModule nodes: a positively-external base (import-mapped typing.Protocol, ::-qualified std::fmt::Display, or a JS global like Error) keeps its edge by targeting the same ExternalModule node the import pass mints; the INHERITS/IMPLEMENTS schema targets are extended with ExternalModule (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.
  4. Verified IMPORTS emission: all IMPORTS edges (including the CommonJS destructuring fallback, previously a direct-emission bypass) defer to a post-parse flush that verifies internal targets against the real module registry: file modules, inline modules, rehydrated modules on incremental runs (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/.ts extensions strip during JS path resolution; C++20 module declarations never emit self-imports and implementation units link only to interfaces that exist.
  5. Record-and-reuse generalized to every language: cpp_function_locations became function_locations; Pass 3 reuses the qn/label Pass 2 registered instead of re-deriving, fixing TS declaration merging (members registered under Logger@13 while callers were attributed to Logger) and a Rust nested-fn phantom FROM endpoint. Rust keeps its ownership-aware call filter on the recorded path.
  6. Type-filtered variant fan-out: duplicate-qn variants only receive CALLS if registered callable and INSTANTIATES if registered as a class, so a merged TS namespace (a Class duplicate of a Function) no longer takes a label-mismatched edge.

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 skipped
  • souffle mock-ingestor measurement: 0 dangling, 0 orphans
  • uv run ty check: at the 352-diagnostic baseline (no new)

Closes the fixture-level goal of #652.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread codebase_rag/parsers/call_processor.py Outdated
Comment thread codebase_rag/parsers/call_processor.py Outdated
@greptile-apps

greptile-apps Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR enforces zero dangling relationships across the fixture suite. The main changes are:

  • Deferred import edge emission until internal targets can be verified against known module nodes.
  • Deferred non-C++ inheritance and implements edges until class registries are complete.
  • External base classes now target ExternalModule nodes when they are known external symbols.
  • JS/TS builtin calls no longer emit phantom CALLS edges while callback references stay reachable.
  • Function-location recording is generalized across languages so call attribution reuses registered nodes.
  • Fixture tests and audit gates are updated to keep dangling relationship counts at zero.

Confidence Score: 5/5

Safe 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.

T-Rex T-Rex Logs

What T-Rex did

  • The environment proof was reviewed and confirmed the uv version, Python 3.11.6 shims, and absence of accessible cmake paths.
  • A targeted pytest command and an automatic uv setup were attempted, and the pymgclient 1.5.1 build failed because cmake tools were not accessible.
  • Progress was stopped after identifying the setup blocker, and the full test suite and repeated installs were not performed.
  • Two artifacts were uploaded to document the environment check and the pytest setup blocker for reviewer inspection.
  • Next steps depend on resolving cmake accessibility to enable the build and continue testing.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
codebase_rag/parsers/import_processor.py Defers import relationship emission until targets can be verified against known modules, with aliases and language-specific fallback handling.
codebase_rag/parsers/class_ingest/mixin.py Adds deferred parent resolution for non-C++ inheritance/implements and reuses ExternalModule targets for known external bases.
codebase_rag/parsers/call_processor.py Generalizes recorded caller locations and filters builtin/variant call edges to avoid phantom endpoints.
codebase_rag/graph_updater.py Coordinates deferred inheritance, C++ module implementation, and verified import edge flushing after registries are populated.
codebase_rag/types_defs.py Adds generalized deferred import/inheritance/function-location types and extends relationship schemas for ExternalModule targets.
codebase_rag/tests/conftest.py Tightens fixture auditing to enforce zero dangling relationships.
codebase_rag/tests/test_import_edge_verification.py Adds coverage for deferred import edge verification, aliases, and dropped broken imports.
codebase_rag/tests/test_external_base_nodes.py Covers external base nodes used as inheritance/implements targets.
codebase_rag/tests/test_js_builtin_call_no_phantom.py Adds explicit coverage that JS/TS builtin calls do not emit phantom CALLS edges while callback references remain.

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
Loading
%%{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
Loading

Reviews (3): Last reviewed commit: "fix(review): strip JS extensions only on..." | Re-trigger Greptile

Comment thread codebase_rag/parsers/import_processor.py Outdated
@vitali87

vitali87 commented Jul 8, 2026

Copy link
Copy Markdown
Owner Author

@greptile review

vitali87 added 14 commits July 9, 2026 01:32
@vitali87

vitali87 commented Jul 8, 2026

Copy link
Copy Markdown
Owner Author

@greptile review

@vitali87
vitali87 force-pushed the fix/fixture-dangling-sweep branch from 66746e7 to 7a25b77 Compare July 8, 2026 21:36
@vitali87
vitali87 merged commit c01c8ea into main Jul 8, 2026
19 of 20 checks passed
@codecov-commenter

codecov-commenter commented Jul 8, 2026

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 96.66667% with 17 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
codebase_rag/parsers/import_processor.py 94.11% 5 Missing ⚠️
...odebase_rag/tests/test_import_edge_verification.py 97.14% 3 Missing ⚠️
codebase_rag/graph_updater.py 89.47% 2 Missing ⚠️
codebase_rag/parsers/call_processor.py 90.47% 2 Missing ⚠️
codebase_rag/tests/conftest.py 33.33% 2 Missing ⚠️
...e_rag/tests/test_cross_file_inherits_implements.py 95.12% 2 Missing ⚠️
codebase_rag/parsers/class_ingest/relationships.py 87.50% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@sonarqubecloud

sonarqubecloud Bot commented Jul 8, 2026

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
E Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants