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

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 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 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 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:


# 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.

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 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.

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.

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. 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.

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 and enforced through ContextGraph.enforce_decision_policy().

Complete Decision Model Structure

The Decision dataclass in 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 semantica/context/decision_recorder.py Core persistence, entity linking, provenance
decision_methods.py semantica/context/decision_methods.py Convenience API wrappers
context_graph.py semantica/context/context_graph.py High-level decision analytics
decision_models.py semantica/context/decision_models.py Data classes and schemas
decision_query.py semantica/context/decision_query.py Hybrid precedent search implementation
causal_analyzer.py 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 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. 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 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.

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 →