Edge-Site Properties in the Code-Graph-RAG Graph Schema

Edge-site properties in Code-Graph-RAG are metadata dictionaries attached to relationship edges that store the precise source-code location (file, line, column) where a code relationship originates.

The Code-Graph-RAG graph model enriches edges with location-aware metadata, enabling precise traceability from graph relationships back to the exact lines of code that generated them. This article documents the complete set of edge-site properties defined in the schema, their structure, and how they are constructed and consumed across the codebase.


What Are Edge-Site Properties?

In graph terminology, an edge represents a relationship between two nodes (e.g., a function calling another function). An edge-site property is a dictionary attached to that edge describing where in the source code that relationship was observed.

The schema defines these properties using two core types in codebase_rag/constants/structural.py:

  • Span — A concrete location range with file path, start/end lines, and columns
  • PropertyDict — A flexible string-to-value map that serializes site data into the graph

These types feed into the protobuf Edge message defined in codec/schema_pb2.py, which stores the optional site field on every edge.


Complete List of Edge-Site Properties

The Code-Graph-RAG schema defines several specialized site properties for different edge types. Each extends or specializes the base site property with domain-specific fields.

site — The Base Property

The foundational edge-site property. Present on any edge that requires location information. Contains at minimum a Span serialized as a dictionary.

Field Type Description
file str Absolute or repository-relative file path
start_line int 1-indexed start line
start_col int 0-indexed start column
end_line int 1-indexed end line
end_col int 0-indexed end column

call_site — For CALLS Edges

Specific to edges where one callable invokes another. Records the exact expression location of the call.

Constructed in codebase_rag/graph_loader.py when processing call expressions from language-specific parsers. Includes the base Span plus optional fields:

  • callee_name — The resolved name of the called function
  • is_implicit — Boolean flag for implicit calls (e.g., operator overloading)

definition_site — For DEF and DEF_TYPE Edges

Marks where a symbol is originally defined. Used for function definitions, class definitions, type aliases, and variable declarations.

Populated by the symbol resolver in codebase_rag/schema_builder.py. Contains:

  • Full Span of the definition statement
  • symbol_type — Enum indicating function, class, variable, etc.
  • scope_qualifier — Namespace or module path for disambiguation

import_site — For IMPORT Edges

Captures details of import statements. Set in codebase_rag/editor_links.py during import resolution.

Extends base site with:

Field Description
imported_name The raw name being imported
local_alias Alias used locally, if any
is_from_import Boolean for from X import Y vs import X
source_module Resolved module path of the origin

reference_site — For REFERENCE Edges

Tracks non-call usages of a symbol—variable reads, attribute access, or type annotations.

Filled in codebase_rag/graph_updater.py during reference analysis. Contains the Span plus reference_type to distinguish read vs. write vs. annotation contexts.

bind_site — For BIND Edges

Used where a name is bound to a value: assignments, pattern matching, destructuring, or parameter bindings.

Created in codebase_rag/graph_loader.py during AST traversal. Records:

  • Span of the binding expression
  • bind_type — assignment, parameter, catch clause, etc.
  • is_rebinding — Boolean if shadowing an existing name

How Edge-Site Properties Are Constructed

The pipeline for adding site metadata follows a consistent pattern across edge types.

Step 1: Parse Source Location

Language-specific parsers extract raw location data from AST nodes. The Span constructor normalizes this into the schema's standard format.

from codebase_rag.constants.structural import Span

def node_to_span(ast_node, file_path: str) -> Span:
    return Span(
        file=file_path,
        start_line=ast_node.lineno,
        start_col=ast_node.col_offset,
        end_line=ast_node.end_lineno,
        end_col=ast_node.end_col_offset,
    )

Step 2: Build Property Dictionary

The Span serializes to a plain dictionary for storage in the PropertyDict type.

site_data = span.to_dict()  # Returns dict matching PropertyDict schema

Specialized edge types add their domain fields to this base dictionary.

Step 3: Attach to Edge

The add_edge helper in codebase_rag/graph_loader.py accepts the site data and encodes it into the protobuf Edge message.

from codebase_rag.graph_loader import add_edge

# Example: creating a CALL edge with full site information

caller_node = ("my_module", "src/services.py", 42)
callee_node = ("utils_module", "src/utils.py", 15)

call_site = Span(
    file="src/services.py",
    start_line=42,
    start_col=8,
    end_line=42,
    end_col=25,
).to_dict()

call_site["callee_name"] = "validate_input"
call_site["is_implicit"] = False

add_edge(
    parent=caller_node,
    child=callee_node,
    rel_type="CALLS",
    site=call_site,
)

Step 4: Persist via Protobuf

The codec/schema_pb2.py file defines the wire format. The Edge message includes:

message Edge {
  string parent_id = 1;
  string child_id = 2;
  string rel_type = 3;
  optional PropertyDict site = 4;
}

Where PropertyDict maps to the Python dictionary structure used throughout the loader.


Retrieving and Querying Edge-Site Data

Site properties enable precise code navigation queries. The graph API provides accessors that expose this metadata.

Basic Site Inspection


# Fetch an edge and inspect its site

edge = graph.get_edge(parent_id, child_id, rel_type="IMPORTS")

if edge.HasField("site"):
    site = edge.site
    print(f"Imported at {site['file']}:{site['start_line']}")
    if "local_alias" in site:
        print(f"  Aliased as: {site['local_alias']}")

Querying by Location

The codebase_rag/graph_updater.py module uses site properties to implement location-based queries:

def find_edges_in_range(graph, file: str, start_line: int, end_line: int):
    """Return all edges whose site falls within the given line range."""
    results = []
    for edge in graph.edges:
        if not edge.HasField("site"):
            continue
        site = edge.site
        if site["file"] == file and start_line <= site["start_line"] <= end_line:
            results.append(edge)
    return results

Editor Integration

The codebase_rag/editor_links.py module consumes import_site properties to generate IDE-compatible location links, enabling "Go to Import" functionality.


Edge-Site Property Reference Table

Property Edge Types Populated By Key Additional Fields
site Any (generic) graph_loader.py file, start_line, start_col, end_line, end_col
call_site CALLS graph_loader.py callee_name, is_implicit
definition_site DEF, DEF_TYPE schema_builder.py symbol_type, scope_qualifier
import_site IMPORTS editor_links.py imported_name, local_alias, is_from_import, source_module
reference_site REFERENCES graph_updater.py reference_type (read/write/annotation)
bind_site BINDS graph_loader.py bind_type, is_rebinding

Summary


Frequently Asked Questions

What is the difference between site and call_site in Code-Graph-RAG?

The site property is the generic base container for any location metadata on an edge. call_site is a specialized variant used exclusively for CALLS edges that adds call-specific fields like callee_name and is_implicit. Internally, call_site is stored as the site field—the specialization is a semantic convention in the loader code, not a separate protobuf field.

How does Code-Graph-RAG handle edges without location information?

Edges where location is irrelevant or unavailable simply omit the site field. The protobuf definition marks site as optional, and graph consumers check HasField("site") before accessing location data. This design keeps the graph compact for structural relationships like containment hierarchies where source location adds no semantic value.

Can edge-site properties be updated after initial graph construction?

Yes. The codebase_rag/graph_updater.py module provides methods to refresh site data when source files change. The updater compares stored Span information against re-parsed AST locations and merges changes while preserving edge identity. This incremental update capability is essential for IDE integrations that must stay synchronized with live code edits.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →