# How to Implement W3C PROV-O Provenance Tracking on Knowledge Graph Facts in Semantica

> Implement W3C PROV-O provenance tracking on knowledge graph facts with Semantica. Automatically map facts to PROV-O ontology for runtime lineage queries and RDF exports.

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

---

**Semantica's unified provenance subsystem automatically maps every knowledge graph fact to the W3C PROV-O ontology through store-level mixins, enabling runtime lineage queries and standard RDF exports.**

Semantica is an open-source framework that ships with built-in W3C PROV-O provenance tracking for knowledge graph facts. The implementation lives in the `semantica.provenance` package and weaves provenance capture into vector stores, triplet stores, document splitters, and the visualization layer. By enabling the `provenance=True` flag, every fact inserted into the graph carries a traceable record of its origin, derivation, and generating activity.

## Core Components of the PROV-O Subsystem

The provenance architecture centers on a coordinator-driven design that delegates capture to store-level mixins while standardizing output through PROV-O schemas.

### ProvenanceManager

The `ProvenanceManager` class in [`semantica/provenance/manager.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/provenance/manager.py) serves as the central coordinator for creating, storing, and retrieving provenance records. It exposes methods such as `track_fact`, `get_provenance`, `get_chunk_lineage`, and `export_provenance` that emit PROV-O compliant RDF and JSON-LD. Because the manager can persist its internal store to a backing database, provenance data remains reproducible across runs when a persistent backend is configured.

### PROV-O Schema Definitions

The [`schemas.py`](https://github.com/semantica-agi/semantica/blob/main/schemas.py) file in [`semantica/provenance/schemas.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/provenance/schemas.py) defines the PROV-O data model used throughout Semantica, including classes such as `Entity`, `Activity`, and `Agent`, and predicates such as `wasGeneratedBy` and `wasDerivedFrom`. It also provides serialization helpers that convert internal `ProvenanceInfo` dataclass instances into standard PROV-O representations. All higher-level components rely on this generic dataclass, so extending the schema propagates automatically.

### Store-Level Mixins

`VectorStoreWithProvenance` and `TripletStoreWithProvenance` extend the regular stores with a `provenance=True` initialization flag. These mixins live in [`semantica/vector_store/vector_store_provenance.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/vector_store/vector_store_provenance.py) and [`semantica/triplet_store/triplet_store_provenance.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/triplet_store/triplet_store_provenance.py). When provenance is enabled, every `add_vector` or `add_triplet` call automatically invokes `ProvenanceManager.track_fact` with the current activity and agent context.

### Chunk-Level and Visualization Wrappers

The `ProvenanceTracker` wrapper in [`semantica/split/provenance_tracker.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/split/provenance_tracker.py) forwards chunk-level provenance to the unified manager while maintaining backward compatibility with legacy APIs. On the visualization side, `VisualizerWithProvenance` in [`semantica/visualization/visualization_provenance.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/visualization/visualization_provenance.py) adds a provenance toggle that queries the manager for lineage data and decorates rendered graphs with PROV-O annotations.

## How Provenance Tracking Works on Knowledge Graph Facts

The system captures lineage across four distinct stages:

1. **Document ingestion.** When a document is split, each chunk receives a unique `chunk_id`. The split pipeline calls `ProvenanceTracker.track_chunk(chunk_id, source=document_path)`, which creates a `ProvenanceInfo` instance and registers it with the unified `ProvenanceManager`.
2. **Fact creation.** Stores that have `provenance=True` invoke `ProvenanceManager.track_fact(fact_id, activity=ingest_activity, agents=[user_agent])` on every write operation. The activity is recorded as a `prov:Activity` and linked to the originating chunk via `prov:wasDerivedFrom`.
3. **Lineage retrieval.** Consumers call `ProvenanceManager.get_provenance(fact_id)`. The manager walks the `parent_chunk_id` chain and assembles `ProvenanceInfo` objects that describe the full derivation path.
4. **Export and serialization.** `ProvenanceManager.export_provenance()` serializes the internal store into PROV-O RDF. The output can be written to a file, streamed to an external triple store, or embedded in a visualization pipeline.

## Enabling PROV-O Tracking in Python

You can activate and consume provenance tracking with a few lines of Python.

### Initialize Stores with Provenance

Create store instances with the `provenance=True` flag and ingest documents as usual:

```python
from semantica.provenance import ProvenanceManager
from semantica.vector_store import VectorStoreWithProvenance
from semantica.triplet_store import TripletStoreWithProvenance

# Initialise the global manager (singleton pattern is used internally)

prov_manager = ProvenanceManager()

# Create stores with provenance tracking enabled

vector_store = VectorStoreWithProvenance(provenance=True)
triplet_store = TripletStoreWithProvenance(provenance=True)

# Ingest a document

doc_path = "data/articles/article1.pdf"
chunks = splitter.split_file(doc_path)

for chunk_id, embedding in zip(chunks.ids, chunks.embeddings):
    vector_store.add_vector(chunk_id, embedding)
    triplet_store.add_triplet(chunk_id, "rdf:type", "ex:Article")

```

Because `provenance=True` is set, both stores automatically record a `ProvenanceInfo` entry for every insertion.

### Query Lineage for a Specific Fact

Retrieve the full derivation history for any stored identifier:

```python
fact_id = "vector:12345"
prov_info = prov_manager.get_provenance(fact_id)

print("Fact was generated by activity:", prov_info.activity)
print("Source chunk:", prov_info.source_chunk_id)
print("Original document:", prov_info.source_document)

```

The returned object exposes the `activity`, `source_chunk_id`, and `source_document` fields that describe how the fact was derived.

### Export PROV-O RDF Serializations

Export the entire provenance graph to standard W3C formats for downstream auditing:

```python
turtle_str = prov_manager.export_provenance(format="turtle")

with open("knowledge_graph_provenance.ttl", "w") as f:
    f.write(turtle_str)

```

Supported formats include RDF/XML, Turtle, and JSON-LD.

### Visualize Annotated Subgraphs

Enrich visualizations with PROV-O metadata using the provenance-aware visualizer:

```python
from semantica.visualization import VisualizerWithProvenance

viz = VisualizerWithProvenance(provenance=True)
subgraph = triplet_store.query("SELECT ?s ?p ?o WHERE { ?s ?p ?o } LIMIT 100")
viz.visualize(subgraph, title="Sample KG with Provenance")

```

The visualizer queries `ProvenanceManager` for lineage data and augments each node with its derivation history.

## Extending the PROV-O Model

If you need to record additional PROV-O properties such as `prov:hadMember` for collections, extend [`semantica/provenance/schemas.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/provenance/schemas.py) with the new predicate and update the serialization helpers. Because `ProvenanceManager` and all store mixins rely on the generic `ProvenanceInfo` dataclass, the higher-level components automatically pick up the new fields without further changes to [`vector_store_provenance.py`](https://github.com/semantica-agi/semantica/blob/main/vector_store_provenance.py) or [`triplet_store_provenance.py`](https://github.com/semantica-agi/semantica/blob/main/triplet_store_provenance.py).

## Summary

- Semantica implements W3C PROV-O provenance tracking through the `semantica.provenance` package, with `ProvenanceManager` at its core.
- Enabling `provenance=True` on `VectorStoreWithProvenance` or `TripletStoreWithProvenance` automatically records lineage for every write operation.
- You can query fact-level derivation paths at runtime via `get_provenance`, traverse chunk ancestry with `get_chunk_lineage`, and export standard RDF serializations.
- The modular schema design in [`schemas.py`](https://github.com/semantica-agi/semantica/blob/main/schemas.py) lets you extend the PROV-O model without rewriting store-level logic.

## Frequently Asked Questions

### How do I enable W3C PROV-O provenance tracking on knowledge graph facts in Semantica?

Instantiate your stores with the `provenance=True` flag and initialize a `ProvenanceManager`. For example, create `VectorStoreWithProvenance(provenance=True)` and `TripletStoreWithProvenance(provenance=True)`. Every subsequent `add_vector` or `add_triplet` call automatically records PROV-O compliant lineage through the manager.

### What file formats does Semantica support for PROV-O export?

`ProvenanceManager.export_provenance()` supports standard W3C serializations including Turtle, RDF/XML, and JSON-LD. You can stream the output to a file, an external triple store, or a visualization pipeline.

### Can I query the lineage of an individual fact at runtime?

Yes. Call `ProvenanceManager.get_provenance(fact_id)` with any internal store identifier. The manager walks the `parent_chunk_id` chain and returns a `ProvenanceInfo` object that exposes the generating activity, source chunk, and original document path.

### How do I extend the default PROV-O schema with custom properties?

Add new predicates to [`semantica/provenance/schemas.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/provenance/schemas.py) and update the serialization helpers. Because the store mixins in [`vector_store_provenance.py`](https://github.com/semantica-agi/semantica/blob/main/vector_store_provenance.py) and [`triplet_store_provenance.py`](https://github.com/semantica-agi/semantica/blob/main/triplet_store_provenance.py) depend on the generic `ProvenanceInfo` dataclass, they automatically inherit the new fields without additional modifications.