# Graph Schema for Nodes and Edges: Unified Code-Graph-RAG Model Across 13 Languages

> Explore the unified graph schema for nodes and edges in Code-Graph-RAG. Normalize AST elements from 13 languages into a language-agnostic knowledge graph.

- Repository: [Vitali Avagyan/code-graph-rag](https://github.com/vitali87/code-graph-rag)
- Tags: architecture
- Published: 2026-08-13

---

**The graph schema for nodes and edges in Code-Graph-RAG defines a language-agnostic knowledge graph using protobuf definitions that normalize AST elements from 13 programming languages into unified node types (Class, Function, Module) and directed relationships (CONTAINS, DEFINES, CALLS).**

Code-Graph-RAG (vitali87/code-graph-rag) parses heterogeneous repositories into a single, queryable graph structure. The graph schema for nodes and edges is formally specified in `codec/schema.proto` and documented in [`docs/architecture/graph-schema.md`](https://github.com/vitali87/code-graph-rag/blob/main/docs/architecture/graph-schema.md), enabling consistent representation whether your codebase contains Python, Rust, or TypeScript.

## Core Node Types in the Schema

The schema defines entity nodes through the protobuf `Node` message, with each node carrying a label that determines its property set. According to the schema documentation (lines 13‑30)【L13-L30】, the following node types capture architectural and implementation details.

### Project and Package Hierarchy

**Project** nodes serve as the root container with a simple `{name: string}` property set. **Package**, **Folder**, and **File** nodes form the filesystem hierarchy, carrying `path`, `absolute_path`, and `name` properties. **Module** nodes extend this with `qualified_name`, `flow_covered` flags, and line number references (`start_line`, `end_line`).

### Code Entities: Classes, Functions, and Methods

**Class**, **Function**, and **Method** nodes share a common property shape including `qualified_name`, `modifiers`, `decorators`, `docstring`, and positional metadata. **Function** nodes add an `is_macro` boolean for languages like Rust, while **Method** nodes include `is_property` and `overrides_external` flags. **Interface**, **Enum**, **Type**, and **Union** nodes follow the same structural pattern as **Class** nodes.

### External and Synthetic Nodes

**ExternalPackage** and **ExternalModule** nodes represent third-party dependencies with minimal name-only descriptors. **Resource** nodes model I/O objects such as files, environment variables, and sockets using `{qualified_name, name, kind}`. Analysis outputs generate **Pattern**, **CodeSmell**, and **SecurityIssue** nodes containing `message`, `snippet`, and line range data.

## Edge Types and Relationships

Directed edges in the graph use the protobuf `Relationship` message with an enumerated `RelationshipType` (lines 40‑64)【L40-L64】. These edges create a semantic web linking the node types above.

### Containment and Definition Relationships

Containment edges establish the structural hierarchy:

- **CONTAINS_PACKAGE**, **CONTAINS_FOLDER**, **CONTAINS_FILE**, **CONTAINS_MODULE** — Link Project/Package/Folder nodes to their children
- **DEFINES** — Connects Module/Function/Method/Class nodes to the Class, Function, Method, Enum, Interface, Type, Union, or Module entities they declare
- **DEFINES_METHOD** — Specific relationship from Class/Interface/Enum/Type/Union to Method nodes

Module-specific relationships include **IMPORTS** (Module to Module/ExternalModule), **EXPORTS** (Module to Class/Function), **EXPORTS_MODULE** (Module to ModuleInterface), and **IMPLEMENTS_MODULE** (Module to ModuleImplementation).

### Inheritance and Implementation

Object-oriented and functional inheritance patterns use:

- **INHERITS** — Connects Class/Interface/Function to Class/Interface/Function/ExternalModule
- **IMPLEMENTS** — Links Class/Enum to Interface/Class/Enum/ExternalModule
- **OVERRIDES** — Explicit link from Method/Function to the Method it overrides
- **IMPLEMENTS** (ModuleImplementation to ModuleInterface) — For module system patterns

### Runtime and Data Flow

Dynamic and static analysis relationships include:

- **CALLS** — Module/Function/Method to Function/Method/Enum/Type
- **REFERENCES** — Module/Function/Method to Function/Method/Class
- **INSTANTIATES** — Module/Function/Method to Class
- **READS_FROM** / **WRITES_TO** — Connects code entities to Resource nodes
- **FLOWS_TO** — Dataflow edges between Module/Function/Method/Resource nodes
- **IMPLEMENTS_PATTERN**, **HAS_SMELL**, **HAS_VULNERABILITY** — Link modules to findings nodes

## Language-Specific AST Mappings

The unified graph schema for nodes and edges relies on Tree-sitter parsers to map language-specific AST nodes to the generic types above. The schema documentation (lines 116‑131)【L116-L131】 defines these mappings for 13 languages:

- **C**: `enum_specifier`, `function_definition`, `struct_specifier`, `union_specifier`
- **C#**: `class_declaration`, `constructor_declaration`, `property_declaration`
- **C++**: `class_specifier`, `function_definition`, `lambda_expression`
- **Dart**: `class_definition`, `enum_declaration`, `extension_declaration`
- **Go**: `function_declaration`, `method_declaration`, `type_spec`
- **Java**: `class_declaration`, `interface_declaration`, `method_declaration`
- **JavaScript**: `class`, `function_declaration`, `arrow_function`
- **Lua**: `function_declaration`, `function_definition`
- **PHP**: `class_declaration`, `function_definition`, `trait_declaration`
- **Python**: `class_definition`, `function_definition`
- **Rust**: `function_item`, `macro_definition`, `struct_item`
- **TypeScript/TSX**: `class_declaration`, `interface_declaration`, `enum_declaration`, `arrow_function`
- **Scala**: `class_definition`, `object_definition`, `trait_definition`

These mappings ensure that a Python `class_definition` and a Java `class_declaration` both instantiate the generic **Class** node with identical property schemas.

## Implementing the Schema in Python

The protobuf definitions compile into [`codec/schema_pb2.py`](https://github.com/vitali87/code-graph-rag/blob/main/codec/schema_pb2.py), which provides Python classes for graph construction. The [`codebase_rag/services/protobuf_service.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/services/protobuf_service.py) file handles serialization of `GraphCodeIndex` instances, while [`codebase_rag/tests/test_protobuf_end_to_end.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/tests/test_protobuf_end_to_end.py) demonstrates round-trip persistence.

```python
import codec.schema_pb2 as pb

# Initialize the graph container

graph = pb.GraphCodeIndex()

# Create a Function node

func = pb.Function(
    qualified_name="my_pkg.utils.compute",
    name="compute",
    modifiers=["async"],
    path="my_pkg/utils.py",
    absolute_path="/repo/my_pkg/utils.py",
    start_line=10,
    end_line=20,
)

# Append as a generic Node wrapper

graph.nodes.append(pb.Node(function=func))

# Create a CALLS relationship

calls = pb.Relationship(
    type=pb.Relationship.RelationshipType.CALLS,
    source_id="my_pkg.main.run",
    target_id="my_pkg.utils.compute",
    source_label="Function",
    target_label="Function",
    properties=pb.Struct(),
)

graph.relationships.append(calls)

```

This Python API allows services to build, persist, and query the graph schema for nodes and edges without handling language-specific parsing logic directly.

## Summary

- **The graph schema for nodes and edges in Code-Graph-RAG is language-agnostic**, defined in `codec/schema.proto` and documented in [`docs/architecture/graph-schema.md`](https://github.com/vitali87/code-graph-rag/blob/main/docs/architecture/graph-schema.md).
- **Node types** include Project, Package, File, Module, Class, Function, Method, and synthetic Resource/Pattern nodes, each with standardized property sets.
- **Relationships** span containment (CONTAINS_*), definition (DEFINES), inheritance (INHERITS, IMPLEMENTS), and runtime behavior (CALLS, FLOWS_TO).
- **Thirteen languages** map to this unified model through Tree-sitter AST mappings defined in the schema documentation.
- **Python implementations** use generated protobuf bindings in [`codec/schema_pb2.py`](https://github.com/vitali87/code-graph-rag/blob/main/codec/schema_pb2.py) to construct `GraphCodeIndex` objects programmatically.

## Frequently Asked Questions

### What file defines the graph schema for nodes and edges in Code-Graph-RAG?

The canonical definition resides in `codec/schema.proto`, which declares the `Node`, `Relationship`, and `GraphCodeIndex` messages. Human-readable documentation appears in [`docs/architecture/graph-schema.md`](https://github.com/vitali87/code-graph-rag/blob/main/docs/architecture/graph-schema.md) (lines 5‑131)【L5-L131】, detailing node labels, edge types, and language mappings.

### How does the schema handle different programming languages uniformly?

Tree-sitter parsers extract language-specific AST nodes—such as Python's `class_definition` or Java's `class_declaration`—and map them to generic schema types like **Class** or **Function**. This mapping ensures that all 13 supported languages populate the same node and edge structures with consistent property fields.

### What properties are available on Function and Method nodes?

Both node types include `qualified_name`, `name`, `modifiers`, `decorators`, `path`, `absolute_path`, `start_line`, `end_line`, `docstring`, and `is_exported`. Function nodes add an optional `is_macro` boolean, while Method nodes include `is_property` and `overrides_external` flags to capture language-specific behaviors like Python properties or Java overrides.

### Can the graph schema represent security vulnerabilities and code smells?

Yes. The schema includes **Pattern**, **CodeSmell**, and **SecurityIssue** node types that capture static analysis findings. These nodes contain `message`, `start_line`, `end_line`, `path`, and optional `snippet` properties, linked to modules via **IMPLEMENTS_PATTERN**, **HAS_SMELL**, and **HAS_VULNERABILITY** edges.