# How to Implement Decision Tracking in Semantica Using ContextGraph: A Complete Developer Guide

> Implement decision tracking in Semantica using ContextGraph. Record decisions as graph nodes with full provenance and precedent search. A complete developer guide.

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

---

**Record decisions as first-class graph nodes with full provenance, entity linking, and precedent search using Semantica's ContextGraph API.**

Semantica treats decisions as native citizens of its knowledge graph. The `ContextGraph` implementation in [`semantica/context/context_graph.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/context_graph.py) provides built-in methods to persist decisions, link them to relevant entities, and execute powerful analytics like causal chain tracing and semantic precedent search. This guide walks through the complete decision-tracking pipeline using actual source code from the semantica-agi/semantica repository.

## Core Architecture: Three Layers of Decision Intelligence

Semantica's decision tracking operates through three cooperating layers, each exposed for different use cases.

### DecisionRecorder: The Persistence Engine

The `DecisionRecorder` class in [`semantica/context/decision_recorder.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/decision_recorder.py) handles low-level decision persistence. It creates **Decision nodes**, generates embeddings, links entities via `ABOUT` edges, and optionally records W3C PROV-O provenance.

Key responsibilities include:

- `record_decision()` — persists the decision node with metadata
- `link_entities()` — creates graph relationships to involved entities
- `_track_decision_provenance()` — captures creation activity and source documents
- `capture_cross_system_context()` — adds external system state as linked nodes
- `apply_policies()` — creates `APPLIED_POLICY` relationships for compliance

### Convenience API: Lightweight Function Wrappers

For common workflows, [`semantica/context/decision_methods.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/decision_methods.py) exposes standalone functions that compose `DecisionRecorder` operations:

- `record_decision()` — builds a `Decision` model and invokes the recorder
- `find_precedents()` — hybrid vector + graph semantic search
- `get_causal_chain()` — traverses `PRECEDENT_FOR` edges up or downstream

### ContextGraph: High-Level Analytics Interface

The `ContextGraph` class adds graph-wide decision analytics on top of the recorder:

```python

# Core decision methods in ContextGraph (context_graph.py)

graph.record_decision(...)           # Delegate to DecisionRecorder

graph.find_precedents(...)           # Hybrid search for similar decisions

graph.trace_decision_causality(...)  # Causal chain analysis

graph.analyze_decision_influence(...) # Impact assessment

graph.enforce_decision_policy(...)   # Policy compliance check

```

## Recording a Decision: High-Level ContextGraph API

The simplest entry point uses `ContextGraph.record_decision()` directly.

```python
from semantica.context import ContextGraph

# Initialize in-memory graph (use persistent backend in production)

graph = ContextGraph(advanced_analytics=False)

# Record a decision with full metadata

decision_id = graph.record_decision(
    category="loan_approval",
    scenario="First-time homebuyer",
    reasoning="Credit score > 720, debt-to-income < 30%",
    outcome="approved",
    confidence=0.96,
    entities=["customer_123", "property_456"]
)

print(f"Decision recorded with ID: {decision_id}")

```

This method delegates to `DecisionRecorder.record_decision()`, which:

1. Instantiates a `Decision` dataclass from [`decision_models.py`](https://github.com/semantica-agi/semantica/blob/main/decision_models.py) with auto-generated UUID
2. Stores the node in the graph with timestamp and optional decision maker
3. Generates embeddings via `EmbeddingGenerator` if configured
4. Creates `ABOUT` edges to each entity ID via `link_entities()`

## Recording with Cross-System Context

For decisions requiring external system state, use the convenience API in [`decision_methods.py`](https://github.com/semantica-agi/semantica/blob/main/decision_methods.py).

```python
from semantica.context.decision_methods import record_decision
from semantica.context import ContextGraph

graph_store = ContextGraph()

decision_id = record_decision(
    graph_store=graph_store,
    category="fraud_detection",
    scenario="Unusual login location",
    reasoning="IP address from high-risk country, multiple failed attempts",
    outcome="flagged",
    confidence=0.88,
    entities=["user_42"],
    cross_system_context={
        "auth_service": {"login_attempts": 5},
        "geo_service": {"ip_country": "XX", "risk_score": 0.94}
    }
)

print(f"Recorded decision ID: {decision_id}")

```

The `cross_system_context` parameter triggers `DecisionRecorder.capture_cross_system_context()`, which creates a `CrossSystemContext` node and links it to the decision. This enables full audit reconstruction of external state at decision time.

## Finding Semantic Precedents

Leverage hybrid vector + graph search to discover historically similar decisions.

```python
from semantica.context.decision_methods import find_precedents

precedents = find_precedents(
    graph_store=graph,
    scenario="First-time homebuyer",
    category="loan_approval",
    limit=5,
    use_hybrid_search=True  # Combines vector similarity with graph traversal

)

for d in precedents:
    print(f"Precedent {d.decision_id}: outcome={d.outcome}, confidence={d.confidence}")

```

Under the hood, `ContextGraph.find_precedents()` delegates to `DecisionQuery` implementations in [`semantica/context/decision_query.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/decision_query.py). The hybrid search path performs:

1. Vector embedding similarity on decision scenario and reasoning
2. Graph traversal to boost results with shared entities or policy applications

## Tracing Causal Chains

Understand decision dependencies via `PRECEDENT_FOR` edge traversal using `CausalChainAnalyzer` in [`semantica/context/causal_analyzer.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/causal_analyzer.py).

```python
from semantica.context.decision_methods import get_causal_chain

# Trace what led to this decision (upstream)

upstream_chain = get_causal_chain(
    graph_store=graph,
    decision_id=decision_id,
    direction="upstream",
    max_depth=3
)

print("Upstream causal chain:")
for step in upstream_chain:
    print(f"- {step.decision_id}: {step.scenario}")

# Trace consequences (downstream)

downstream_chain = get_causal_chain(
    graph_store=graph,
    decision_id=decision_id,
    direction="downstream",
    max_depth=3
)

```

The `direction` parameter accepts `"upstream"` (prerequisites), `"downstream"` (consequences), or `"both"`. The `CausalChainAnalyzer` performs breadth-first traversal of `PRECEDENT_FOR` relationships with cycle detection.

## Policy Enforcement and Compliance

`DecisionRecorder.apply_policies()` creates `APPLIED_POLICY` edges linking decisions to versioned policy nodes. This supports:

- **Regulatory audit** — query all decisions applied under a specific policy version
- **Exception tracking** — `PolicyException` nodes linked to overriding decisions
- **Approval chains** — `ApprovalChain` verification for high-stakes categories

Policies are defined in [`decision_models.py`](https://github.com/semantica-agi/semantica/blob/main/decision_models.py) and enforced through `ContextGraph.enforce_decision_policy()`.

## Complete Decision Model Structure

The `Decision` dataclass in [`semantica/context/decision_models.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/decision_models.py) defines the following schema:

| Field | Type | Description |
|-------|------|-------------|
| `decision_id` | UUID | Unique identifier (auto-generated) |
| `category` | str | Taxonomic classification (e.g., "loan_approval") |
| `scenario` | str | Human-readable situation description |
| `reasoning` | str | Justification or model explanation |
| `outcome` | str | Result classification |
| `confidence` | float | Certainty score (0.0–1.0) |
| `timestamp` | datetime | UTC record time |
| `decision_maker` | Optional[str] | Human or system identifier |
| `metadata` | Optional[dict] | Arbitrary additional fields |

Related models include `Policy`, `PolicyException`, `ApprovalChain`, and `CrossSystemContext` for comprehensive decision governance.

## Key Source Files Reference

| File | Path | Responsibility |
|------|------|--------------|
| [`decision_recorder.py`](https://github.com/semantica-agi/semantica/blob/main/decision_recorder.py) | [`semantica/context/decision_recorder.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/decision_recorder.py) | Core persistence, entity linking, provenance |
| [`decision_methods.py`](https://github.com/semantica-agi/semantica/blob/main/decision_methods.py) | [`semantica/context/decision_methods.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/decision_methods.py) | Convenience API wrappers |
| [`context_graph.py`](https://github.com/semantica-agi/semantica/blob/main/context_graph.py) | [`semantica/context/context_graph.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/context_graph.py) | High-level decision analytics |
| [`decision_models.py`](https://github.com/semantica-agi/semantica/blob/main/decision_models.py) | [`semantica/context/decision_models.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/decision_models.py) | Data classes and schemas |
| [`decision_query.py`](https://github.com/semantica-agi/semantica/blob/main/decision_query.py) | [`semantica/context/decision_query.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/decision_query.py) | Hybrid precedent search implementation |
| [`causal_analyzer.py`](https://github.com/semantica-agi/semantica/blob/main/causal_analyzer.py) | [`semantica/context/causal_analyzer.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/causal_analyzer.py) | `CausalChainAnalyzer` for dependency traversal |

## Summary

- **Decisions are first-class graph nodes** — stored with full metadata, embeddings, and provenance via `DecisionRecorder`
- **Three API layers** — use `ContextGraph` methods for analytics, `decision_methods` functions for convenience, or `DecisionRecorder` directly for control
- **Entity linking** — automatic `ABOUT` edges connect decisions to involved entities for graph traversal
- **Hybrid search** — `find_precedents()` combines vector similarity with graph structure for semantic case retrieval
- **Causal analysis** — `get_causal_chain()` traverses `PRECEDENT_FOR` edges to audit decision dependencies
- **Cross-system context** — capture external state at decision time for complete audit reconstruction
- **Policy integration** — versioned policies and exceptions tracked via dedicated relationship types

## Frequently Asked Questions

### What is the difference between `ContextGraph.record_decision()` and `record_decision()` from decision_methods?

Both persist decisions, but `ContextGraph.record_decision()` requires an initialized `ContextGraph` instance and provides direct access to graph analytics. The standalone `record_decision()` function in [`decision_methods.py`](https://github.com/semantica-agi/semantica/blob/main/decision_methods.py) accepts any `GraphStore` implementation and optionally captures `cross_system_context` with less boilerplate. Use `ContextGraph` for integrated analytics, `decision_methods` for quick integration with external stores.

### How does Semantica's precedent search combine vector and graph techniques?

The `find_precedents()` function with `use_hybrid_search=True` executes a two-stage query implemented in [`decision_query.py`](https://github.com/semantica-agi/semantica/blob/main/decision_query.py). First, it retrieves candidate decisions via embedding similarity on scenario and reasoning text. Then it reranks results using graph features: shared `ABOUT` entities, common `APPLIED_POLICY` relationships, and `PRECEDENT_FOR` path proximity. This balances semantic relevance with structural relevance.

### Can I trace why a specific decision was made months later?

Yes. Call `get_causal_chain()` with `direction="upstream"` to traverse all `PRECEDENT_FOR` edges leading to the target decision. The `CausalChainAnalyzer` in [`causal_analyzer.py`](https://github.com/semantica-agi/semantica/blob/main/causal_analyzer.py) reconstructs the dependency graph up to `max_depth` levels. For complete auditability, ensure `cross_system_context` was captured at record time—this external state is preserved as linked nodes and can be queried alongside the causal chain.

### What provenance standards does Semantica use for decision tracking?

When a `ProvenanceManager` is supplied to `DecisionRecorder`, the `_track_decision_provenance()` method records decision creation using W3C PROV-O ontology. This captures the decision activity, associated agent (decision maker), and source documents as provenance entities. The provenance graph is queryable separately or alongside the primary decision graph for compliance reporting.