Summary
Graph construction can turn an unresolved bare import target into a self-loop when the target matches a legacy alias for the importing file.
Examples seen with Graphify 0.9.20:
- Python stdlib:
src/contracting/stdlib/builtins.py containing import builtins
- Python package:
playground/services/contracting.py containing from contracting import constants
- Rust parent module imports such as
use crate::fixture::{...} inside tests in fixture.rs
- Rust external paths containing the current basename, such as
...::poseidon::{...} in poseidon.rs
The AST extraction initially emits a bare target such as builtins, contracting, or poseidon. During build_from_json(), the legacy-ID alias index can resolve that target to the importing file node, yielding an imports or imports_from edge whose source and target are identical.
Expected behavior
A file-level import or re-export that resolves to its own source should not be materialized. It carries no connectivity at file-node granularity and is reported as unhealthy by graphify diagnose multigraph.
Other meaningful self-edges, especially recursive calls, should remain intact.
Proposed fix
After endpoint resolution in build_from_json(), discard only self-loops whose relation is one of:
imports
imports_from
re_exports
A regression suite should cover the Python and Rust cases above and verify that recursive call self-loops are preserved.
Validation
The proposed patch removes all seven observed import self-loops across two real repositories. Their rebuilt diagnostics report zero self-loops, dangling endpoints, missing endpoints, or endpoint-collapse groups. The full Graphify test suite passes: 3,478 passed, 3 skipped.
Summary
Graph construction can turn an unresolved bare import target into a self-loop when the target matches a legacy alias for the importing file.
Examples seen with Graphify 0.9.20:
src/contracting/stdlib/builtins.pycontainingimport builtinsplayground/services/contracting.pycontainingfrom contracting import constantsuse crate::fixture::{...}inside tests infixture.rs...::poseidon::{...}inposeidon.rsThe AST extraction initially emits a bare target such as
builtins,contracting, orposeidon. Duringbuild_from_json(), the legacy-ID alias index can resolve that target to the importing file node, yielding animportsorimports_fromedge whose source and target are identical.Expected behavior
A file-level import or re-export that resolves to its own source should not be materialized. It carries no connectivity at file-node granularity and is reported as unhealthy by
graphify diagnose multigraph.Other meaningful self-edges, especially recursive
calls, should remain intact.Proposed fix
After endpoint resolution in
build_from_json(), discard only self-loops whose relation is one of:importsimports_fromre_exportsA regression suite should cover the Python and Rust cases above and verify that recursive call self-loops are preserved.
Validation
The proposed patch removes all seven observed import self-loops across two real repositories. Their rebuilt diagnostics report zero self-loops, dangling endpoints, missing endpoints, or endpoint-collapse groups. The full Graphify test suite passes: 3,478 passed, 3 skipped.