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:
- Document ingestion. When a document is split, each chunk receives a unique
chunk_id. The split pipeline callsProvenanceTracker.track_chunk(chunk_id, source=document_path), which creates aProvenanceInfoinstance and registers it with the unifiedProvenanceManager. - Fact creation. Stores that have
provenance=TrueinvokeProvenanceManager.track_fact(fact_id, activity=ingest_activity, agents=[user_agent])on every write operation. The activity is recorded as aprov:Activityand linked to the originating chunk viaprov:wasDerivedFrom. - Lineage retrieval. Consumers call
ProvenanceManager.get_provenance(fact_id). The manager walks theparent_chunk_idchain and assemblesProvenanceInfoobjects that describe the full derivation path. - 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.provenancepackage, withProvenanceManagerat its core. - Enabling
provenance=TrueonVectorStoreWithProvenanceorTripletStoreWithProvenanceautomatically records lineage for every write operation. - You can query fact-level derivation paths at runtime via
get_provenance, traverse chunk ancestry withget_chunk_lineage, and export standard RDF serializations. - The modular schema design in
schemas.pylets 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →