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 columnsPropertyDict— 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 functionis_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
Spanof 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:
Spanof the binding expressionbind_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
- Edge-site properties are
PropertyDictdictionaries attached to edges, stored in the optionalsitefield of the protobufEdgemessage. - The base
siteproperty contains aSpanwith precise file, line, and column information. - Specialized variants (
call_site,definition_site,import_site,reference_site,bind_site) extend this for specific relationship types. - Core types are defined in
codebase_rag/constants/structural.pyand encoded viacodec/schema_pb2.py. - Construction happens in
codebase_rag/graph_loader.pyandcodebase_rag/schema_builder.py; consumption incodebase_rag/graph_updater.pyandcodebase_rag/editor_links.py.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →