# What Are the Available Relationship Types for Linking Decisions in Semantica?

> Discover Semantica's flexible relationship types for linking decisions. Define custom semantic edges like precedes or causes. Explore the possibilities today.

- Repository: [Semantica /semantica](https://github.com/semantica-agi/semantica)
- Tags: api-reference
- Published: 2026-09-13

---

**Semantica does not enforce a closed enumeration of relationship types; instead, the `type` field is a free-form string that allows you to define any semantic edge such as "precedes," "causes," or "conforms_to" when linking decisions.**

In the `semantica-agi/semantica` repository, decisions are connected within a knowledge graph using flexible relationship objects. Unlike rigid database schemas that restrict you to predefined categories, Semantica uses a dictionary-based structure where the **relationship type** is entirely user-defined, enabling domain-specific ontologies for decision traceability.

## Understanding the Relationship Schema Structure

Each relationship in Semantica is a simple dictionary containing three required keys: `source`, `target`, and `type`. The `type` value is a plain string with no validation against a closed set, meaning you can inject domain-specific labels that describe the nature of the connection between decisions, entities, or other graph nodes. This design is intentional to support open-ended knowledge graphs where decision provenance might require labels like "R1", "knows", "involves", or custom business logic such as "approved_by" or "derived_from".

## Core Implementation in Decisions Module

The code that creates and consumes these relationship objects lives in [`semantica_mcp/mcp/tools/decisions.py`](https://github.com/semantica-agi/semantica/blob/main/semantica_mcp/mcp/tools/decisions.py). When you record a decision via the API, you may include an optional `relationships` list where each entry follows the `{"source": "id", "target": "id", "type": "string"}` format. The same dictionary shape is reused throughout the visualization utilities in `tests/visualization/` and the seed-manager test suite in [`tests/test_seed_manager.py`](https://github.com/semantica-agi/semantica/blob/main/tests/test_seed_manager.py), confirming that the schema is consistent across persistence, querying, and rendering layers.

## Documented Examples from the Test Suite

The repository’s test fixtures illustrate the flexibility of the schema through several concrete examples:

- **`"R1"`**: Used in [`tests/visualization/test_visualization_comprehensive.py`](https://github.com/semantica-agi/semantica/blob/main/tests/visualization/test_visualization_comprehensive.py) at line 65 to demonstrate visualization logic for generic edges.
- **`"knows"`**: Appears in [`tests/triplet_store/test_triplet_store.py`](https://github.com/semantica-agi/semantica/blob/main/tests/triplet_store/test_triplet_store.py) at line 526, modeling a social or acquaintance relationship between entities.
- **`"involves"`**: Found in [`tests/test_unreleased_changelog_comprehensive.py`](https://github.com/semantica-agi/semantica/blob/main/tests/test_unreleased_changelog_comprehensive.py) at line 143, showing how decisions can involve external components.

These examples confirm that **any string value** is valid for the `type` field, provided it matches the semantic intent of your application.

## Working with Custom Relationship Types

Because the `type` field accepts arbitrary strings, you can model sophisticated decision networks. Below are practical patterns for creating, extending, and querying relationships.

### Recording Decisions with Relationships

When creating a decision, pass a list of relationship dictionaries to the `relationships` parameter of `record_decision()`:

```python
from semantica_mcp.mcp.session import get_graph

graph = get_graph()
decision_id = graph.record_decision(
    category="financial",
    scenario="loan_approval",
    reasoning="credit_score > 700",
    outcome="approved",
    confidence=0.95,
    entities=[{"id": "applicant", "type": "Person"}],
    relationships=[
        {"source": "decision_123", "target": "decision_456", "type": "precedes"}
    ],
)

```

### Adding Relationships Post-Creation

You can append new links to existing decisions using the `add_relationship()` method, specifying the `rel_type` as a free-form string:

```python
graph.add_relationship(
    source_id=decision_id,
    target_id="external_policy_001",
    rel_type="conforms_to",
    properties={"since": 2024}
)

```

### Querying by Relationship Type

To filter decisions based on their connections, retrieve nodes with `find_nodes()` and inspect the `relationships` list:

```python
decisions = graph.find_nodes(node_type="decision")
filtered = [
    d for d in decisions
    if any(rel["type"] == "precedes" for rel in d.get("relationships", []))
]
print(f"Decisions that *precede* another: {len(filtered)}")

```

## Summary

- **Relationship types in Semantica are open-ended**: The `type` field in relationship dictionaries accepts any string value; there is no enforced enumeration.
- **Core logic resides in [`decisions.py`](https://github.com/semantica-agi/semantica/blob/main/decisions.py)**: The [`semantica_mcp/mcp/tools/decisions.py`](https://github.com/semantica-agi/semantica/blob/main/semantica_mcp/mcp/tools/decisions.py) file handles the creation and parsing of relationship payloads.
- **Schema is consistent across the codebase**: The same `{"source", "target", "type"}` structure appears in visualization tests, triplet store tests, and seed manager fixtures.
- **Domain flexibility**: You can define custom semantics such as "precedes", "conforms_to", "causes", or "R1" to match your specific decision-tracking requirements.

## Frequently Asked Questions

### Is there a predefined list of relationship types in Semantica?

No. According to the source code in [`semantica_mcp/mcp/tools/decisions.py`](https://github.com/semantica-agi/semantica/blob/main/semantica_mcp/mcp/tools/decisions.py), the `type` field is a free-form string. The system does not validate against a closed vocabulary, allowing you to define types like "knows", "involves", or entirely custom labels.

### How does the relationship type affect graph visualization?

The visualization utilities in [`tests/visualization/test_visualization_comprehensive.py`](https://github.com/semantica-agi/semantica/blob/main/tests/visualization/test_visualization_comprehensive.py) treat the `type` string as a label for edges. Because the value is arbitrary, you can render domain-specific legends without modifying the core engine, as long as the string is provided in the relationship dictionary.

### Can I enforce validation on relationship types in my application?

Yes. While Semantica stores any string you provide, you can implement application-level validation before calling `record_decision()` or `add_relationship()`. Inspect the `type` field in your client code to ensure it matches your internal ontology before persisting to the graph.

### Where are relationship definitions stored if they are not in an enum?

Relationship instances are stored as dictionaries within decision objects or triplet stores. The schema definition is implicit in the code and test fixtures (such as [`tests/test_seed_manager.py`](https://github.com/semantica-agi/semantica/blob/main/tests/test_seed_manager.py) and [`tests/triplet_store/test_triplet_store.py`](https://github.com/semantica-agi/semantica/blob/main/tests/triplet_store/test_triplet_store.py)), which demonstrate that the `type` key always maps to a string value.