Reference graph

At indexing time the AST walker captures CALLS / IMPORTS / INHERITS edges (and optionally MENTIONS in markdown, via a YAML toggle) into the node_references SQLite table. get_references(target, direction=…) answers the graph shapes, and get_symbol(target, depth="tree") the structural one:

  • direction="callers" — every site that calls this method, project-wide (your code + every dep).

  • direction="callees" — every method this one calls.

  • direction="inherits" — the inheritance graph above this class.

  • direction="impact" — the transitive reverse dependencies of a symbol (everything a change to it could affect), walked backward up to reference_graph.impact.max_depth hops.

  • direction="governed_by" — the recorded architectural decisions governing a symbol (inbound GOVERNS edges from the decision graph).

  • get_symbol(…, depth="tree") — the structural DocumentNode tree for the module, the same shape used for structural rendering.

Cross-package edges resolve through a rule-based resolver (ReferenceResolver in python/pydocs_mcp/extraction/strategies/reference_resolver.py, composed by application/indexing_service.py at index time): it matches an edge’s target name against indexed qualified names, preferring exact matches and falling back to suffix matches under strictness controls, with guards to avoid combinatorial blow-ups on deeply nested attribute chains. Unresolved targets are still stored (with a null to_node_id) so a later index pass can resolve them.

Capture is on by default and tuned via YAML (reference_graph.capture.{enabled,kinds}); MENTIONS is opt-in.