# How the Semantica Decision Tracking API Records, Traces, and Audits Agent Decisions

> Discover how the Semantica decision tracking API records, traces, and audits agent decisions. Leverage embedded vectors, provenance metadata, and powerful audit primitives for deep insights.

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

---

**The Semantica decision tracking API captures agent decisions via an MCP tool endpoint, persists them as embedded vectors with full provenance metadata, and provides audit primitives including precedent search, causal chain analysis, and impact assessment.**

The decision tracking subsystem in the open-source [semantica-agi/semantica](https://github.com/semantica-agi/semantica) repository implements a two-layer architecture that bridges command-line interfaces with persistent vector storage. This system ensures every agent decision is recorded with complete contextual metadata, enabling full traceability and deterministic audit trails across the knowledge graph.

## Recording Decisions via the MCP Tool Layer

When an agent or user initiates a decision recording, the MCP dispatcher routes the request to `handle_record_decision` in [`mcp/tools/decisions.py`](https://github.com/semantica-agi/semantica/blob/main/mcp/tools/decisions.py). This handler serves as the primary entry point for the decision tracking API, validating required fields before persisting data.

The function enforces a strict schema requiring five mandatory fields:

- `category` – the decision classification
- `scenario` – the situational context
- `reasoning` – the logical justification
- `outcome` – the resulting action or state
- `confidence` – a numerical certainty score

After validation, the handler retrieves the active knowledge-graph instance via `get_graph()` and delegates to `graph.record_decision`.

```python

# mcp/tools/decisions.py – recording entry point

# Lines 21-40

def handle_record_decision(args: dict) -> dict:
    """Record a decision with full context into the knowledge graph."""
    required = ["category", "scenario", "reasoning", "outcome", "confidence"]
    ...
    graph = get_graph()
    decision_id = graph.record_decision(
        category=str(args["category"]),
        scenario=str(args["scenario"]),
        reasoning=str(args["reasoning"]),
        outcome=str(args["outcome"]),
        confidence=float(args["confidence"]),
        entities=args.get("entities", []),
        decision_maker=args.get("decision_maker", "mcp_client"),
        ...
    )
    ...

```

[Source ↗](https://github.com/semantica-agi/semantica/blob/main/mcp/tools/decisions.py#L21-L40)

## Persisting Decisions in the Vector Store

The `graph.record_decision` method forwards the payload to the vector-store implementation in [`semantica/vector_store/vector_store.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/vector_store/vector_store.py). Here, the `store_decision` method manages the actual persistence logic, generating embeddings and assigning immutable identifiers.

If a **DecisionEmbeddingPipeline** is configured, the pipeline generates dual embeddings: a semantic embedding derived from textual fields (scenario, reasoning, outcome) and a structural embedding representing the graph context. The method stores the complete metadata payload alongside these vectors and returns a unique vector ID that serves as the canonical decision identifier for all subsequent audit operations.

```python

# semantica/vector_store/vector_store.py – core storage routine

# Lines 75-99

def store_decision(
    self,
    scenario: str,
    reasoning: Optional[str] = None,
    outcome: Optional[str] = None,
    confidence: Optional[float] = None,
    entities: Optional[List[str]] = None,
    category: Optional[str] = None,
    **additional_metadata
) -> str:
    ...
    decision_data = {
        "scenario": scenario,
        "reasoning": reasoning or "",
        "outcome": outcome or "unknown",
        "confidence": confidence or 0.5,
        "entities": entities or [],
        "category": category or "general",
        **additional_metadata
    }
    if self.decision_pipeline:
        result = self.decision_pipeline.process_decision(decision_data)
        return result["vector_id"]
    ...

```

[Source ↗](https://github.com/semantica-agi/semantica/blob/main/semantica/vector_store/vector_store.py#L75-L99)

## Auditing and Tracing Decision Lineage

The decision tracking API provides several query primitives that enable agents to explore decision provenance and causal relationships. All audit operations reference the single source of truth stored in the vector store, ensuring deterministic reproducibility.

### Finding Precedents and Similar Decisions

The `find_precedents` and `query_decisions` methods retrieve historically similar decisions by computing hybrid similarity scores. These functions feed the query through the same **DecisionEmbeddingPipeline** used during storage, comparing semantic and structural embeddings against the archived decision vectors.

### Explaining Decision Rationale

The `explain_decision` primitive assembles human-readable explanations by retrieving the stored reasoning paths and confidence scores. Implemented in the vector store layer, this method walks the embedding graph to reconstruct the contextual basis for any recorded choice.

### Causal Chain Analysis

For tracking upstream dependencies or downstream effects, the `get_causal_chain` method utilizes the `CausalChainAnalyzer` (located in [`semantica/context/causal_analyzer.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/causal_analyzer.py)) to traverse decision relationships. If the analyzer is unavailable, the system falls back to `graph.get_causal_chain`.

### Impact Analysis

The `analyze_decision_impact` method (also aliased as `analyze_decision_influence`) quantifies how a specific decision affected the knowledge graph, reporting metrics such as affected entities and policy modifications triggered by the outcome.

## End-to-End Decision Flow

The complete lifecycle of a tracked decision follows this deterministic path:

1. **CLI or API invocation** – The `handle_record_decision` function validates input parameters
2. **Graph layer processing** – `graph.record_decision` prepares the payload and selects the storage backend
3. **Vector embedding** – `store_decision` generates embeddings, persists metadata, and returns the vector ID
4. **Audit retrieval** – Subsequent calls to `find_precedents`, `explain_decision`, or `get_causal_chain` retrieve vectors by ID and execute hybrid similarity or causal analysis

Because the vector ID is immutable and indexed, every audit operation can reproduce the exact state of the knowledge graph at the moment of the original decision, providing complete traceability of who, what, why, and when.

## Code Examples

Record a decision via the command-line interface:

```bash

# Record a decision via the CLI

$ semantica decision record \
    --title "Approve loan extension" \
    --category finance \
    --scenario "Customer requests 6-month extension" \
    --reasoning "Credit score > 750, low utilization" \
    --outcome approved \
    --confidence 0.93

```

Record a decision programmatically using the convenience wrapper:

```python

# Record a decision programmatically (quick helper)

from semantica.vector_store.decision_vector_methods import quick_decision

decision_id = quick_decision(
    scenario="Approve loan extension",
    outcome="approved",
    reasoning="Credit score > 750, low utilization",
    confidence=0.93,
    category="finance"
)
print(decision_id)   # → "vec_7f3c2a..."

```

Retrieve semantically similar past decisions:

```python

# Find precedents (similar past decisions)

from semantica.vector_store.decision_vector_methods import find_precedents

precedents = find_precedents(
    query="Approve loan extension",
    limit=5,
    category="finance"
)
print(precedents)    # List of decision dicts with similarity scores

```

Generate a human-readable explanation:

```python

# Explain a recorded decision

from semantica.vector_store.decision_vector_methods import explain

explanation = explain(decision_id)
print(explanation["reasoning"])
print(explanation["confidence"])

```

Trace causal dependencies:

```python

# Retrieve the causal chain of a decision

from semantica.mcp.tools.decisions import handle_get_causal_chain

chain = handle_get_causal_chain({"decision_id": decision_id, "direction": "downstream"})
print(chain["chain"])

```

## Summary

- The **decision tracking API** in Semantica uses a two-layer architecture combining MCP tools with vector storage
- **Recording** occurs through `handle_record_decision` in [`mcp/tools/decisions.py`](https://github.com/semantica-agi/semantica/blob/main/mcp/tools/decisions.py), which validates required fields (`category`, `scenario`, `reasoning`, `outcome`, `confidence`) before delegating to the graph layer
- **Persistence** happens in [`semantica/vector_store/vector_store.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/vector_store/vector_store.py) via `store_decision`, which generates dual semantic and structural embeddings and returns an immutable vector ID
- **Auditing** capabilities include precedent search (`find_precedents`), explanation generation (`explain_decision`), causal chain traversal (`get_causal_chain` via `CausalChainAnalyzer`), and impact analysis (`analyze_decision_impact`)
- All audit operations reference the same vector-store instance, ensuring deterministic traceability from a single source of truth

## Frequently Asked Questions

### What fields are required when recording a decision?

The decision tracking API requires five mandatory fields: `category` (classification), `scenario` (context), `reasoning` (justification), `outcome` (result), and `confidence` (numerical score). The `handle_record_decision` function in [`mcp/tools/decisions.py`](https://github.com/semantica-agi/semantica/blob/main/mcp/tools/decisions.py) validates these fields before processing, rejecting any request missing required parameters.

### How does the API ensure decision traceability?

Every decision receives an immutable vector ID upon storage in [`semantica/vector_store/vector_store.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/vector_store/vector_store.py). This ID serves as the canonical reference for all subsequent audit operations, including causal chain analysis and impact assessment. Because the vector store maintains both embeddings and complete metadata, the system can deterministically reproduce the knowledge graph state at the moment of decision recording.

### Can decisions be queried by semantic similarity?

Yes. The `find_precedents` and `query_decisions` methods compute hybrid similarity scores by feeding queries through the **DecisionEmbeddingPipeline**. This pipeline generates embeddings using the same algorithm applied during initial storage, enabling retrieval of historically similar decisions based on semantic content and structural graph context rather than exact keyword matching.

### What is the role of the DecisionEmbeddingPipeline?

The **DecisionEmbeddingPipeline** generates dual embeddings for each decision: a semantic embedding derived from textual fields (scenario, reasoning, outcome) and a structural embedding representing the decision's position within the knowledge graph. Configured in the vector store layer, this pipeline ensures that both meaning and context are preserved for similarity search and causal analysis operations.