# How to Trace Decision Chains Using Semantica's ContextGraph

> Learn how to trace decision chains with Semantica's ContextGraph. Our method uses depth-first search and cycle detection to map AI-driven decisions and causal chains.

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

---

**Semantica stores every AI-driven decision as a first-class node in its Context Graph and traces complete causal chains using the `trace_decision_chain` method, which delegates to a depth-first search algorithm with cycle detection.**

In the `semantica-agi/semantica` repository, the **ContextGraph** module provides a deterministic, queryable provenance trail for AI-driven decisions. By treating each decision as a graph node and causal links as typed edges, you can programmatically reconstruct the entire ancestry of any decision to satisfy explainability requirements, audit demands, and regulatory compliance standards.

## How Decisions Are Stored as First-Class Nodes

When you record a decision using `record_decision`, the library creates a graph node of type `Decision` and assigns it a unique identifier. This operation is handled by the **DecisionRecorder** component, which ensures each decision captures metadata including category, scenario, reasoning, outcome, and confidence scores.

The underlying implementation resides in [`semantica/context/decision_recorder.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/decision_recorder.py), where the recorder persists decision nodes with proper schema validation. Once stored, these nodes become addressable entities within the graph, capable of participating in causal relationships and analytical queries.

## Establishing Causal Relationships Between Decisions

To construct traceable chains, you must explicitly define how decisions relate to one another using `add_causal_relationship`. This method, implemented in [`semantica/context/decision_methods.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/decision_methods.py), creates directed edges between decision nodes using relationship types such as **CAUSED**, **INFLUENCED**, or **PRECEDENT_FOR**.

These relationships form the topological structure that the tracing algorithm traverses. Without explicit causal links, decisions remain isolated nodes; with them, you build a directed acyclic graph (or general graph with cycle detection) representing the decision-making process flow.

## The Tracing Algorithm: From Entry Point to CausalAnalyzer

The primary API for tracing is `ContextGraph.trace_decision_chain`, located in [`semantica/context/context_graph.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/context_graph.py) at lines 5589–5608. This public method serves as a thin wrapper that delegates to the internal **`trace_decision_causality`** routine.

The core traversal logic lives in [`semantica/context/causal_analyzer.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/causal_analyzer.py) within the **CausalAnalyzer** component. This analyzer implements a depth-first search (DFS) with cycle detection and chain pruning to ensure tractable output. When invoked, it:

1. Accepts a starting decision node and configuration parameters
2. Follows outgoing and incoming causal edges recursively
3. Builds a list of possible causal chains up to configurable limits
4. Returns structured data including decision IDs, relationship types, and hop metadata

### Configuration Parameters for Chain Traversal

When calling `trace_decision_chain`, you control the search scope using:

- **`max_steps`**: The maximum depth to traverse from the starting decision (prevents infinite recursion in deeply linked chains)
- **`max_chains`**: The maximum number of distinct causal chains to return (limits result set size for performance)

## Practical Implementation: Recording and Tracing Complete Chains

Below is a complete workflow demonstrating how to record decisions, establish causal links, and trace the resulting chain:

```python
from semantica.context import ContextGraph

# Initialize the graph with analytics enabled

graph = ContextGraph(advanced_analytics=True)

# Step 1: Record individual decisions

dec_a = graph.record_decision(
    category="vendor_selection",
    scenario="Choose cloud provider for HIPAA workload",
    reasoning="AWS offers BAA, mature HIPAA tooling, and existing team expertise",
    outcome="selected_aws",
    confidence=0.93,
)

dec_b = graph.record_decision(
    category="compliance_check",
    scenario="Verify AWS HIPAA compliance for workload X",
    reasoning="AWS certifications align with internal policy",
    outcome="compliant",
    confidence=0.98,
)

dec_c = graph.record_decision(
    category="implementation_plan",
    scenario="Deploy workload X on AWS",
    reasoning="Compliant + cost-effective",
    outcome="plan_approved",
    confidence=0.95,
)

# Step 2: Create causal relationships

graph.add_causal_relationship(dec_a, dec_b, relationship_type="CAUSED")
graph.add_causal_relationship(dec_b, dec_c, relationship_type="CAUSED")

# Step 3: Trace the decision chain from the final decision

chain = graph.trace_decision_chain(dec_c, max_steps=5)

print("Causal chain for decision:", dec_c)
for step in chain:
    print(f"- {step['decision_id']} ({step['relationship_type']})")

```

### Retrieving Detailed Hop Information

For audit and compliance scenarios requiring full provenance details, retrieve comprehensive chain metadata:

```python

# Retrieve full chain with hop details

full_chain = graph.trace_decision_chain(dec_c, max_steps=10, max_chains=100)

# Each entry contains decision_id, relationship_type, and hops list

for chain_obj in full_chain:
    print("Chain length:", len(chain_obj["hops"]))
    for hop in chain_obj["hops"]:
        print("  →", hop["from"], "─", hop["relationship_type"], "─>", hop["to"])

```

## Key Architectural Components

Understanding the module structure helps when extending or debugging tracing functionality:

- **[`semantica/context/context_graph.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/context_graph.py)**: Central class exposing `record_decision`, `add_causal_relationship`, and `trace_decision_chain` (lines 5589–5608)
- **[`semantica/context/causal_analyzer.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/causal_analyzer.py)**: Implements the DFS traversal logic and cycle detection for building causal chains
- **[`semantica/context/decision_recorder.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/decision_recorder.py)**: Creates decision nodes with proper schema and metadata storage
- **[`semantica/context/decision_methods.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/decision_methods.py)**: Provides the API for linking decisions via `add_causal_relationship`
- **[`semantica/context/decision_query.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/decision_query.py)**: Offers query helpers used internally by the CausalAnalyzer to fetch decision provenance

## Summary

- **Decision Storage**: Semantica persists every decision as a typed node with unique identifiers via `record_decision` in the ContextGraph.
- **Causal Linking**: Use `add_causal_relationship` with types like **CAUSED**, **INFLUENCED**, or **PRECEDENT_FOR** to build traversable graph edges.
- **Tracing Entry Point**: The `trace_decision_chain` method in [`semantica/context/context_graph.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/context_graph.py) initiates chain reconstruction.
- **Core Algorithm**: The **CausalAnalyzer** component executes a depth-first search with cycle detection, respecting `max_steps` and `max_chains` constraints.
- **Audit Compliance**: The system supports exporting chains as W3C PROV-O provenance for regulatory purposes.

## Frequently Asked Questions

### How does Semantica handle cycles when tracing decision chains?

The **CausalAnalyzer** component implements cycle detection during its depth-first traversal to prevent infinite recursion. When the algorithm encounters a node already present in the current path, it prunes that branch and continues exploration along alternative routes, ensuring `trace_decision_chain` terminates predictably even in graphs with circular causal references.

### What relationship types are available when linking decisions?

According to the source code in [`semantica/context/decision_methods.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/decision_methods.py), you can specify relationship types including **CAUSED**, **INFLUENCED**, and **PRECEDENT_FOR**. These semantic types allow you to distinguish between direct causation, advisory influence, and legal or procedural precedence when reconstructing decision rationale.

### Can I trace chains backward from an outcome to find root causes?

Yes. The `trace_decision_causality` routine in [`semantica/context/causal_analyzer.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/causal_analyzer.py) follows both outgoing and incoming causal edges. When you invoke `trace_decision_chain` with a target decision, the analyzer traverses backward through **CAUSED** and related edge types to identify predecessor decisions, enabling root-cause analysis from any outcome node.

### What performance considerations apply to large decision graphs?

The tracing algorithm respects the `max_steps` and `max_chains` parameters to maintain performance on large graphs. By limiting traversal depth and result set size, the **CausalAnalyzer** prevents exponential explosion during DFS traversal. For production deployments with millions of nodes, the library supports advanced analytics indexing when initializing `ContextGraph(advanced_analytics=True)`.