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

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 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 file in 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 and 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 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 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:

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:

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:

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:

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 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 or 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 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 and update the serialization helpers. Because the store mixins in vector_store_provenance.py and triplet_store_provenance.py depend on the generic ProvenanceInfo dataclass, they automatically inherit the new fields without additional modifications.

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 →