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

> Explore Semantica's causal chain recording for AI decisions. Understand bidirectional chain retrieval and decision graph traversal with our complete guide.

- Repository: [Semantica /semantica](https://github.com/semantica-agi/semantica)
- Tags: how-to-guide
- Published: 2026-09-06

---

**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`](https://github.com/semantica-agi/semantica/blob/main/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`](https://github.com/semantica-agi/semantica/blob/main/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

```python
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`](https://github.com/semantica-agi/semantica/blob/main/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`](https://github.com/semantica-agi/semantica/blob/main/semantica_mcp/mcp/tools/decisions.py) (lines 26-44) provides the external API interface. It implements robust **fallback logic** for varying backend signatures:

```python
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`](https://github.com/semantica-agi/semantica/blob/main/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.

```python
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`](https://github.com/semantica-agi/semantica/blob/main/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`](https://github.com/semantica-agi/semantica/blob/main/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`](https://github.com/semantica-agi/semantica/blob/main/semantica_mcp/mcp/tools/decisions.py)
- **Analysis engine** – `CausalChainAnalyzer` in [`semantica/context/causal_analyzer.py`](https://github.com/semantica-agi/semantica/blob/main/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.