What Is the ContextGraph Class in Semantica? Core Architecture Explained

The ContextGraph class is Semantica's single source of truth for all contextual knowledge, serving as an in-memory graph store that unifies entity management, temporal validity tracking, decision recording, and advanced knowledge graph analytics behind a thread-safe API.

The ContextGraph class sits at the heart of the semantica-agi/semantica repository, powering the framework's knowledge graph and decision-tracking ecosystem. This article examines its architecture, responsibilities, and implementation based on the source code in semantica/context/context_graph.py.


Core Responsibilities of the ContextGraph Class

The ContextGraph class fulfills ten distinct responsibilities that together enable Semantica's cognitive architecture.

In-Memory Graph Storage

At its foundation, ContextGraph maintains nodes (ContextNode) and edges (ContextEdge) in efficient data structures:

  • self.nodes — dictionary mapping node IDs to ContextNode objects
  • self.edges — dictionary mapping edge IDs to ContextEdge objects
  • self._adjacency — adjacency list for fast traversal

These structures enable O(1) lookups and efficient BFS-based graph traversals.

Unified Mutation API

The class exposes high-level methods for graph construction:

  • add_node()
  • add_edge()
  • add_nodes()
  • add_edges()

All mutations are guarded by self._lock, a re-entrant lock guaranteeing thread safety for concurrent access.


Temporal Validity and Time-Aware Queries

The ContextGraph class handles temporal knowledge through timestamp-aware nodes and edges. Every entity can carry valid_from and valid_until properties.

Helper functions in semantica/context/context_graph.py normalize temporal inputs:

  • _parse_iso_dt() — parses ISO datetime strings
  • normalize_temporal_input() — converts various inputs to canonical tz-naive UTC ISO format

This enables queries like "all programming languages valid after 2023" or decisions that expired.


Querying and Neighbor Discovery

Rich traversal methods support complex graph queries:

Method Purpose
query() General-purpose filtered search
get_neighbors() BFS traversal with hop limits
get_neighbor_distances() Distance-weighted results
neighbors Property-based quick access

Parameters include:

  • hops — BFS depth limit
  • min_weight — confidence threshold
  • edge_type — relationship filtering
  • skip / limit — pagination

Decision Management and Causal Analysis

The ContextGraph class embeds decision intelligence through specialized capabilities:

Causal Edge Types The private constant _CAUSAL_EDGE_TYPES defines relationship semantics for decision tracing.

Key Methods:

  • record_decision() — persists a decision with category, scenario, reasoning, outcome, confidence, and linked entities
  • find_precedents() — retrieves similar historical decisions
  • analyze_decision_influence() — traces causal chains through the graph

This transforms the knowledge graph into a decision support system where past choices inform future reasoning.


Advanced Knowledge Graph Analytics

When advanced_analytics=True is passed to the constructor, ContextGraph instantiates optional components (lines 45–55 in context_graph.py):

  • CentralityCalculator — PageRank, betweenness, closeness metrics
  • CommunityDetector — graph clustering (Louvain, label propagation)
  • NodeEmbedder — vector representations of nodes
  • PathFinder — shortest paths, bidirectional search
  • SimilarityCalculator — structural and embedding-based similarity

Exposed methods include:

  • get_node_centrality()
  • find_similar_nodes()
  • analyze_graph_with_kg()

These require the optional KG package but enable production-grade graph intelligence without external databases.


Persistence and Version Control

The ContextGraph class supports knowledge-as-code workflows:

  • export_node_markdown() — serializes nodes to canonical Markdown with YAML front-matter
  • apply_node_markdown() — applies updates with atomic revision checking

The expected_revision parameter prevents concurrent modification conflicts, enabling Git-based versioning of knowledge artifacts.


Indexing and Performance Optimization

For query acceleration, ContextGraph maintains:

  • self.node_type_index — maps type labels to node ID sets
  • self.edge_type_index — maps relationship types to edge ID sets

These indexes synchronize automatically during mutations and power efficient label-based filtering. Decision-specific indexes support fast precedent retrieval.


Extensibility and Lifecycle Management

Two advanced features enhance operability:

Mutation Callbacks The mutation_callback constructor parameter accepts a callable invoked on every graph change—useful for audit trails, event streaming, or reactive updates.

Retraction and Tombstoning Separate maps handle safe removal:

  • self._retractions — logical deletions (preserving ID space)
  • self._tombstones — permanently removed entities

Implemented in coordination with semantica/context/erasure.py, this allows time-travel queries and regulatory compliance without data destruction.


Practical Code Examples

Initialize with Advanced Analytics

from semantica.context import ContextGraph

graph = ContextGraph(
    advanced_analytics=True,
    centrality_analysis=True,
    community_detection=True,
    node_embeddings=True,
)

Build a Basic Knowledge Graph

graph.add_node("Python", "language", content="Programming language")
graph.add_node("Programming", "concept")
graph.add_edge("Python", "Programming", edge_type="related_to")

Query with Constraints

neighbors = graph.get_neighbors(
    "Python",
    hops=2,
    min_weight=0.5,
    include_distance_metadata=True,
)

Record and Analyze Decisions

decision_id = graph.record_decision(
    category="loan_approval",
    scenario="First-time homebuyer",
    reasoning="Good credit score",
    outcome="approved",
    confidence=0.95,
    entities=["customer_123", "property_456"],
)

precedents = graph.find_precedents(decision_id, limit=5)

Version-Controlled Node Updates

md = graph.export_node_markdown("Python")

# Modify and apply with revision safety

updated_md = md.replace("language", "language\nvalid_from: 2024-01-01")
graph.apply_node_markdown(
    "Python",
    updated_md,
    expected_revision=graph.export_node_markdown("Python")[:32],
)

Key Source Files

File Role
semantica/context/context_graph.py Main ContextGraph implementation (lines 1–2000+)
semantica/context/erasure.py Retraction and tombstoning utilities
semantica/context/markdown.py Markdown serialization and parsing

ContextNode and ContextEdge dataclasses are defined within context_graph.py (approximately lines 18–30 and 61–74).


Summary

  • ContextGraph is the central data structure for Semantica's knowledge ecosystem, implemented in semantica/context/context_graph.py
  • Provides thread-safe graph mutations through re-entrant locking
  • Supports temporal validity with ISO datetime normalization
  • Enables decision tracking via causal edges and precedent analysis
  • Optionally integrates advanced analytics: centrality, community detection, embeddings, pathfinding
  • Exports to Markdown for version-controlled knowledge management
  • Uses type indexes for performant queries and tombstoning for safe deletion

Frequently Asked Questions

What is the difference between ContextGraph and a standard graph database?

ContextGraph is an embedded, in-memory structure optimized for Semantica's cognitive workflows—decision recording, temporal queries, and Markdown persistence. Unlike Neo4j or similar databases, it requires no external service, supports atomic revision tokens for version control, and includes built-in causal analysis primitives for decision intelligence.

How does ContextGraph ensure thread safety?

All mutations acquire self._lock, a threading.RLock (re-entrant lock). This allows nested acquisitions by the same thread while preventing concurrent modifications. The lock wraps add_node, add_edge, and all bulk operations, as visible in the method implementations within context_graph.py.

Can ContextGraph scale to large datasets?

ContextGraph is designed for working-set scenarios where hot knowledge resides in memory. Its adjacency lists and type indexes provide O(1) lookups for indexed fields and O(V + E) BFS traversals. For datasets exceeding RAM, Semantica integrates with external vector stores—the ContextGraph serves as the coherent, queryable layer while heavy embeddings persist elsewhere.

What happens when a node is deleted?

Deletions use logical retraction by default: the node enters self._retractions with an invalidation timestamp but remains queryable for historical analysis. Physical removal (tombstoning) moves entries to self._tombstones, freeing the ID for reuse while preserving audit trails. Both patterns are implemented in coordination with semantica/context/erasure.py.

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 →