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.
Decision Recording with Causal Links
In semantica_mcp/mcp/tools/decisions.py (lines 22-40), the recording process establishes three relationship types:
CAUSED– Direct causal dependenciesINFLUENCED– Partial or contributing factorsPRECEDENT_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_chainwhen available, falls back to custom Cypher queries - Temporal filtering –
trace_at_timemethod 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:
direction+max_depth(full featured)depthonly (simplified backend)- 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_decisionpersists decisions withCAUSED,INFLUENCED, andPRECEDENT_FORrelationships insemantica_mcp/mcp/tools/decisions.py - Analysis engine –
CausalChainAnalyzerinsemantica/context/causal_analyzer.pyprovidesget_causal_chainandtrace_at_timewith bidirectional, depth-limited traversal - MCP interface –
handle_get_causal_chainexposes the functionality through a robust, signature-adaptive API - Backend flexibility – Native delegation or fallback Cypher queries support any
GraphStoreimplementation - 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →