Semantica Causal Chain Recording: A Complete Guide to Decision Graph Traversal

Semantica captures causal relationships between AI decisions and provides bidirectional chain retrieval through a layered architecture of graph recording, analysis, and MCP tooling.

The semantica-agi/semantica repository implements sophisticated causal chain recording capabilities that enable developers to trace how decisions influence one another in temporal decision graphs. This system records causal links at decision creation time and exposes powerful traversal APIs for upstream (causes) and downstream (effects) analysis.


How Semantica Records Causal Relationships

When a decision is stored, Semantica encodes causal connections directly into the graph structure. The handle_record_decision function in semantica_mcp/mcp/tools/decisions.py creates nodes with typed relationships that persist the causal context.

In semantica_mcp/mcp/tools/decisions.py (lines 22-40), the recording process establishes three relationship types:

  • CAUSED – Direct causal dependencies
  • INFLUENCED – Partial or contributing factors
  • PRECEDENT_FOR – Temporal or logical precedence
from semantica_mcp.mcp.tools.decisions import handle_record_decision

record_resp = handle_record_decision({
    "category": "finance",
    "scenario": "loan approval",
    "reasoning": "credit score > 700",
    "outcome": "approved",
    "confidence": 0.92,
    "entities": ["customer_123"],
    "decision_maker": "risk_engine"
})
decision_id = record_resp["decision_id"]

This encoding enables subsequent graph traversal without requiring external metadata or post-processing.


Retrieving Causal Chains: The Core Architecture

Semantica's causal chain retrieval operates through three coordinated layers that handle validation, traversal, and backend abstraction.

Layer 1: CausalChainAnalyzer Engine

The CausalChainAnalyzer class in semantica/context/causal_analyzer.py (lines 91-150) serves as the primary traversal engine. Its get_causal_chain method normalizes parameters, validates constraints, and converts raw graph records into typed Decision objects.

Key responsibilities include:

  • Direction handling – "upstream" or "downstream" traversal
  • Depth clamping – Default 5, maximum 100 to prevent resource exhaustion
  • Backend delegation – Uses native get_causal_chain when available, falls back to custom Cypher queries
  • Temporal filtering – trace_at_time method enables historical chain reconstruction

Layer 2: MCP Frontend Handler

The handle_get_causal_chain function in semantica_mcp/mcp/tools/decisions.py (lines 26-44) provides the external API interface. It implements robust fallback logic for varying backend signatures:

from semantica_mcp.mcp.tools.decisions import handle_get_causal_chain

chain_resp = handle_get_causal_chain({
    "decision_id": decision_id,
    "direction": "downstream",
    "max_depth": 4
})
print(chain_resp["chain"])   # → List of Decision objects influenced by the loan approval

The handler automatically attempts three signature variants:

  1. direction + max_depth (full featured)
  2. depth only (simplified backend)
  3. Positional-only decision_id (minimal backend)

This introspection ensures compatibility across diverse graph store implementations.

Layer 3: Graph Store Integration

Any GraphStore implementation—Neo4j, Weaviate, Qdrant—can expose a native get_causal_chain method. When present, the analyzer delegates directly for optimal performance. The pattern is illustrated in semantica/vector_store/vector_store_provenance.py (lines 1-20), showing how backends provide traversal-optimized APIs.


Temporal Causal Chain Analysis

Beyond standard traversal, Semantica supports historical snapshot queries through the trace_at_time method. This enables forensic analysis of decision states at arbitrary points in the past.

from semantica.context.causal_analyzer import CausalChainAnalyzer

analyzer = CausalChainAnalyzer(graph_store=graph_store)
historical_chain = analyzer.trace_at_time(
    event_id=decision_id,
    at_time="2024-01-01T00:00:00Z",
    direction="upstream",
    max_depth=5
)

This temporal capability is essential for audit trails, compliance reporting, and debugging non-deterministic decision sequences.


Rich Result Objects and Metadata

Each node in a retrieved causal chain is materialized as a Decision model defined in semantica/kg/temporal_model.py. These objects include:

Field Description
causal_distance Graph hops from the query root
confidence Decision certainty at recording time
timestamp ISO 8601 creation time
reasoning Human-readable decision rationale
outcome The decision result

The normalization performed by CausalChainAnalyzer ensures consistent structure regardless of underlying storage format.


Validation and Safety Mechanisms

The test suite in tests/test_mcp_decisions_causal_chain.py verifies extensive safety behaviors:

  • Depth clamping – Requests exceeding 100 are silently reduced
  • Direction validation – Rejects unknown direction strings
  • Backend error handling – Graceful degradation when stores are unavailable
  • Signature adaptation – Confirms fallback logic for all three backend variants

These protections prevent resource exhaustion and ensure predictable behavior across deployment configurations.


Summary

  • Recording layer – handle_record_decision persists decisions with CAUSED, INFLUENCED, and PRECEDENT_FOR relationships in semantica_mcp/mcp/tools/decisions.py
  • Analysis engine – CausalChainAnalyzer in semantica/context/causal_analyzer.py provides get_causal_chain and trace_at_time with bidirectional, depth-limited traversal
  • MCP interface – handle_get_causal_chain exposes the functionality through a robust, signature-adaptive API
  • Backend flexibility – Native delegation or fallback Cypher queries support any GraphStore implementation
  • Temporal queries – Historical chain reconstruction at arbitrary timestamps enables audit and debugging workflows

Frequently Asked Questions

What relationship types does Semantica use for causal recording?

Semantica records three causal relationship types when creating decision nodes: CAUSED for direct dependencies, INFLUENCED for partial or contributing factors, and PRECEDENT_FOR for temporal or logical precedence relationships. These are established during handle_record_decision execution.

How does Semantica handle different graph store backends?

The CausalChainAnalyzer detects backend capabilities through introspection. If a GraphStore exposes get_causal_chain, it delegates directly. Otherwise, it falls back to custom Cypher queries. The MCP handler implements additional fallback logic for varying method signatures, ensuring compatibility across Neo4j, Weaviate, Qdrant, and custom implementations.

Can I query causal chains as they existed at a specific point in time?

Yes. The trace_at_time method in CausalChainAnalyzer accepts an at_time ISO 8601 timestamp and returns the causal chain limited to facts recorded before that moment. This enables historical analysis, compliance auditing, and debugging of decision sequences that evolved over time.

What prevents runaway graph traversals in causal chain queries?

Two mechanisms enforce bounds: a default depth of 5 and a hard maximum of 100. The CausalChainAnalyzer clamps user-provided values to these limits. The MCP handler validates the direction parameter (accepting only "upstream" or "downstream"), and the test suite verifies that excessive depth requests are safely reduced rather than rejected.

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 →