How to Add Causal Relationships Between Decisions in Semantica

To link decisions in Semantica, use ContextGraph.add_causal_relationship() from semantica/context/context_graph.py, specifying the source decision ID, target decision ID, and a relationship type such as CAUSED or INFLUENCED.

Semantica is an open-source AGI framework that stores decisions as nodes in a ContextGraph, enabling systematic tracking of how choices influence outcomes. Adding causal relationships between decisions allows the system to construct traceable chains of reasoning for explainable AI workflows. According to the semantica-agi/semantica source code, this is implemented through a dedicated graph edge method that enforces strict validation and type safety.

Implementation of add_causal_relationship

In semantica/context/context_graph.py (lines 722–796), the add_causal_relationship() method creates directed edges between decision nodes. The method accepts three parameters: source_decision_id, target_decision_id, and relationship_type.

Relationship Type Normalization

The implementation accepts both canonical uppercase constants and lowercase aliases. Valid canonical forms include:

  • CAUSED
  • INFLUENCED
  • PRECEDENT_FOR

Aliases such as "causes" are automatically normalized to the canonical constant before storage, ensuring consistency with the CausalChainAnalyzer while maintaining a uniform graph schema.

Validation and Safety Checks

The method performs four sequential validation steps before edge creation:

  1. Type verification – Raises ValueError if the relationship type is not a string or not in the supported set
  2. Existence checks – Silently ignores requests where either decision ID is missing from the graph to prevent corruption from stale references
  3. Node type enforcement – Confirms both nodes are of type "Decision"; non-decision nodes are rejected
  4. Edge instantiation – Creates a ContextEdge with default weight 1.0 and timestamped metadata, then persists via _add_internal_edge

Traversing Causal Chains

Retrieve ordered decision sequences using get_causal_chain() defined at lines 819–999 in the same file. This method executes a breadth-first search (BFS) following canonical causal edge types.

Parameters:

  • decision_id – The UUID of the starting decision node
  • direction – String value "upstream" (for causes) or "downstream" (for effects)
  • max_depth – Optional integer to limit traversal depth

The method returns a list of Decision objects (defined in semantica/context/decision_models.py) representing the causal path.

Practical Code Example

The following example demonstrates recording decisions, establishing a causal link, and querying the resulting chain:

from semantica.context import ContextGraph

# 1️⃣ Create a graph (or use the existing Context instance)

g = ContextGraph()

# 2️⃣ Record two decisions (the Context API is a thin wrapper around add_node)

decision_a_id = g.record_decision(
    category="Finance",
    scenario="Approve loan for client A",
    reasoning="Credit score > 700",
    outcome="Approved",
    confidence=0.95,
)

decision_b_id = g.record_decision(
    category="Finance",
    scenario="Allocate budget for project X",
    reasoning="Strategic priority",
    outcome="Allocated",
    confidence=0.88,
)

# 3️⃣ Add a causal link – decision A **caused** decision B

g.add_causal_relationship(
    source_decision_id=decision_a_id,
    target_decision_id=decision_b_id,
    relationship_type="CAUSED",   # alias "causes" would also work

)

# 4️⃣ Retrieve downstream causal chain from decision A

downstream = g.get_causal_chain(decision_a_id, direction="downstream")
print("Downstream chain:", [d.scenario for d in downstream])

# 5️⃣ Retrieve upstream causal chain for decision B

upstream = g.get_causal_chain(decision_b_id, direction="upstream")
print("Upstream chain:", [d.scenario for d in upstream])

Output:


Downstream chain: ['Allocate budget for project X']
Upstream chain: ['Approve loan for client A']

Summary

  • Primary method: add_causal_relationship() in semantica/context/context_graph.py (lines 722–796) creates causal links between decision nodes
  • Supported relationships: Canonical constants CAUSED, INFLUENCED, PRECEDENT_FOR with automatic normalization of lowercase aliases like "causes"
  • Safety mechanisms: Silent failure on missing IDs, strict "Decision" node type requirements, and ValueError on invalid relationship types prevent graph corruption
  • Edge properties: All causal edges carry weight 1.0 and timestamped metadata via ContextEdge instances stored through _add_internal_edge
  • Traversal method: get_causal_chain() (lines 819–999) performs BFS to retrieve upstream or downstream decision sequences as Decision objects from semantica/context/decision_models.py

Frequently Asked Questions

What happens if I reference a decision ID that does not exist in the graph?

The method silently ignores the operation. As implemented in semantica/context/context_graph.py, if either the source_decision_id or target_decision_id is not present in the graph, the function returns early without raising an exception or modifying the graph. This design prevents stray or obsolete IDs from corrupting the causal structure.

Can I use lowercase strings for relationship types?

Yes. The implementation normalizes relationship types automatically. While the canonical stored form uses uppercase constants (CAUSED, INFLUENCED, PRECEDENT_FOR), you can pass lowercase aliases such as "causes" and the method will convert them to the proper canonical form before creating the edge.

The get_causal_chain() method uses breadth-first search (BFS) starting from the specified decision ID. When direction="downstream", it follows outgoing edges to identify consequences; when direction="upstream", it follows incoming edges to identify root causes. The search respects the canonical edge types defined in the graph and returns ordered Decision objects.

Where is the Decision dataclass defined for causal chain results?

The Decision dataclass resides in semantica/context/decision_models.py. When you call get_causal_chain(), the method returns instances of this class, providing typed access to attributes including scenario, reasoning, outcome, and confidence for each decision in the causal path.

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 →