# How to Record and Audit AI Decisions Using Semantica's ContextGraph

> Record and audit AI decisions effectively using Semantica's ContextGraph. Learn how to create tamper-evident audit trails with the record_decision API and provenance audit CLI.

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

---

**Semantica stores every AI decision as a first-class node in its ContextGraph, enabling tamper-evident audit trails through the `record_decision` API and the `provenance audit` CLI command.**

The `semantica-agi/semantica` repository provides a governance-first framework for AI systems that treats decisions as graph-native entities. By implementing a dual-layer recording and provenance system, Semantica ensures that every automated choice—from loan approvals to content moderation—can be reconstructed, validated, and audited for regulatory compliance.

## Understanding the Decision Recording Architecture

At the core of Semantica's audit capability is the **ContextGraph**, a persistent graph structure that treats decisions as nodes with full lineage tracking. When you invoke `record_decision` on a `ContextGraph` instance (or its specialized subclass `AgentContext`), the system performs a multi-stage validation and indexing process defined in [`semantica/context/context_graph.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/context_graph.py).

The method transforms high-level decision metadata into immutable provenance records, storing them in both the graph structure and an optimized internal index. This dual-storage approach—graph nodes for relationship traversal and dictionary indexing for fast category-based lookup—enables sub-second retrieval even with millions of historical decisions.

## Recording Decisions with `record_decision`

The primary interface for capturing AI decisions is the `ContextGraph.record_decision` method. According to the source code in [`semantica/context/context_graph.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/context_graph.py) (lines 4330–4446), this method orchestrates validation, normalization, and persistence.

### Method Signature and Validation

The `record_decision` method accepts rich metadata that captures the full context of automated decision-making:

- **Categorical data**: `category` (e.g., "loan_approval"), `scenario` (human-readable description), `outcome` (the decision result), and `reasoning` (chain-of-thought or logic)
- **Quantitative metrics**: `confidence` (float between 0 and 1), temporal bounds (`valid_from` and `valid_until`)
- **Entity linking**: `entities` (list of affected entity IDs), `decision_maker` (model or system identifier)
- **Extensible metadata**: `metadata` dictionary for domain-specific key-value pairs

The validation block (lines 4356–4444) enforces strict type checking and length limits before any persistence occurs. Invalid inputs raise immediate exceptions, preventing corrupted audit trails from entering the system.

### The Recording Pipeline

Once validation passes, the method executes a four-stage pipeline:

1. **UUID Generation**: Creates a deterministic unique identifier for the decision
2. **Timestamp Normalization**: Converts temporal inputs to ISO-8601 UTC strings
3. **Graph Insertion**: Calls `_add_decision_to_graph` to create the provenance-tracked node
4. **Index Updates**: Stores the decision in `self._decisions` and builds reverse indices by category, entity, and time range

The method returns the generated decision ID, which serves as the anchor for future audits or decision chaining.

```python
from semantica.context import ContextGraph

# Initialize context (can be persistent or in-memory)

ctx = ContextGraph()

# Record a complex business decision

decision_id = ctx.record_decision(
    category="loan_approval",
    scenario="Applicant requests $10k small business loan",
    reasoning="Credit score 720, debt-to-income ratio 30%, 5-year payment history clean",
    outcome="approved",
    confidence=0.93,
    entities=["applicant_123", "loan_product_A", "underwriting_bot_v2"],
    decision_maker="risk_engine_v2",
    metadata={"loan_amount": 10_000, "currency": "USD", "risk_tier": "low"},
    valid_from="2026-01-01T00:00:00Z",
    valid_until="2026-12-31T23:59:59Z"
)

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

```

## Building the Audit Trail Through Provenance

While recording captures decisions, the **Provenance** subsystem enables retrospective analysis. Implemented across [`semantica/cli.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/cli.py) and [`semantica/provenance/manager.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/provenance/manager.py), this system aggregates decision nodes into human-readable audit logs.

### CLI Auditing with `semantica provenance audit`

The command-line interface in [`semantica/cli.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/cli.py) (lines 2825–2892) exposes the `provenance audit` command, which instantiates a `ProvenanceManager` and invokes `audit_log`. This command supports three critical filtering and export options:

- **Temporal filtering**: `--since` parameter accepts ISO dates to limit scope (e.g., `--since 2026-08-01`)
- **Format flexibility**: `--format` accepts `json` (machine-parseable), `csv` (spreadsheet analysis), or `table` (human-readable terminal output)
- **Export persistence**: `--output` writes results to disk for regulatory submission

```bash

# Display recent decisions in terminal-friendly table format

semantica provenance audit --since 2026-08-01 --format table

# Export CSV for compliance reporting

semantica provenance audit --since 2026-08-01 --format csv --output q3_audit_trail.csv

# Generate JSON for downstream SIEM integration

semantica provenance audit --since 2026-01-01 --format json --output annual_audit.json

```

### Programmatic Access via ProvenanceManager

For application-embedded auditing, import the `ProvenanceManager` directly from `semantica/provenance`. The `audit_log` method returns a serializable list of decision records containing timestamps, entity IDs, operation types, and stored metadata.

```python
from semantica.provenance import ProvenanceManager

# Initialize manager (inherits configuration from CLIContext when available)

pm = ProvenanceManager()

# Retrieve audit trail programmatically

log = pm.audit_log(since="2026-08-01", format="json")

# Process individual decision records

for entry in log:
    print(f"{entry['timestamp']} | {entry['category']} | "
          f"Confidence: {entry.get('confidence', 'N/A')} | "
          f"Outcome: {entry['outcome']}")

```

## Implementation Best Practices

When deploying Semantica for governance-critical systems, structure your decision categories hierarchically using dot-notation (e.g., `finance.loan.retail`) to leverage the built-in category indexing. Always provide explicit `valid_until` timestamps for time-bounded decisions, allowing the system to automatically archive obsolete records.

For high-throughput applications, batch multiple decisions into a single context instance rather than instantiating `ContextGraph` per decision, as the internal `_decisions` dictionary maintains memory-resident indices that optimize category-based lookups.

## Summary

- **Semantica's ContextGraph stores AI decisions as first-class nodes** with full provenance tracking in [`semantica/context/context_graph.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/context_graph.py)
- **The `record_decision` method** validates rich metadata (confidence, entities, temporal bounds) and returns a UUID for future reference
- **The `_add_decision_to_graph` internal method** creates tamper-evident links while `self._decisions` enables fast indexed retrieval
- **The `semantica provenance audit` CLI** (defined in [`semantica/cli.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/cli.py)) exports audit trails in JSON, CSV, or table formats with temporal filtering
- **ProvenanceManager** provides programmatic access to audit logs for integration with external compliance systems

## Frequently Asked Questions

### How does Semantica ensure decision records cannot be altered after creation?

Once `record_decision` completes the pipeline in [`semantica/context/context_graph.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/context_graph.py), the decision node is integrated into the graph via `_add_decision_to_graph`, which establishes cryptographic provenance links to previous state. The internal `self._decisions` dictionary stores references to these immutable nodes, and the validation layer (lines 4356–4444) rejects any attempts to overwrite existing decision IDs, creating an append-only audit trail.

### What is the maximum size for metadata when recording a decision?

The validation block in [`semantica/context/context_graph.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/context_graph.py) enforces length limits on string fields and recursion depth on dictionary metadata, though exact byte limits depend on the underlying graph storage backend. For production deployments, keep individual metadata values under 1MB to ensure the `_add_decision_to_graph` serialization remains performant during high-volume ingestion.

### Can I record decisions for a specific time range in the past or future?

Yes. The `record_decision` method accepts `valid_from` and `valid_until` parameters that accept ISO-8601 formatted strings. These temporal bounds are normalized to UTC during the recording pipeline (lines 4330–4446) and indexed separately from the physical recording timestamp, allowing you to query decisions by their logical validity period using the `ProvenanceManager` temporal filters.

### How do I export audit logs for regulatory compliance requirements?

Use the `semantica provenance audit` command with `--format csv` and `--output` flags as implemented in [`semantica/cli.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/cli.py) (lines 2825–2892). The CSV export includes all mandatory fields (decision ID, timestamp, category, outcome, confidence) plus serialized metadata columns. For GDPR or CCPA compliance, filter exports using `--since` to limit data to specific reporting periods, reducing exposure of historical personal data.