Files
cleveragents-core/docs/modules/uko-provenance.md
freemo a0ac30d5de
CI / lint (pull_request) Successful in 21s
CI / typecheck (pull_request) Successful in 52s
CI / security (pull_request) Successful in 55s
CI / quality (pull_request) Successful in 39s
CI / build (pull_request) Successful in 29s
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Failing after 6m49s
CI / docker (pull_request) Has been skipped
CI / e2e_tests (pull_request) Successful in 17m22s
CI / integration_tests (pull_request) Failing after 23m1s
CI / coverage (pull_request) Successful in 11m3s
CI / status-check (pull_request) Failing after 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 56m57s
docs: update and extend documentation for v3.8.0 changes
- docs/reference/plan_cli.md: add note about legacy/v3 plan workflow
  mixing being disallowed (introduced in v3.8.0, issue #1577)
- docs/reference/uko_runtime.md: document v3.8.0 provenance tracking
  (sourceResource, validFrom, isCurrent on typed triples) and revision
  chain for temporal queries across indexing runs (issue #891)
- docs/reference/decision_correction.md: add CorrectionAttemptRecord
  section documenting the correction_attempts table, state lifecycle,
  repository API, and usage examples (issue #920)
- docs/modules/uko-provenance.md: new module guide for UKO provenance
  tracking covering purpose, how provenance is attached, revision chain
  mechanics, query patterns, persistence format, BDD coverage, and gotchas
2026-04-05 20:05:48 +00:00

196 lines
6.0 KiB
Markdown

# UKO Provenance Tracking
**Package:** `cleveragents.application.services` (UKOIndexer, UKOGraphPersistence)
**Introduced:** v3.8.0 (issue #891)
This module guide covers the provenance tracking and temporal versioning
capabilities added to the UKO runtime in v3.8.0. Provenance metadata
enables audit trails, point-in-time queries, and historical analysis of
the knowledge graph.
For the full UKO runtime API reference, see
[`docs/reference/uko_runtime.md`](../reference/uko_runtime.md).
For the temporal data model, see
[`docs/reference/temporal_data_model.md`](../reference/temporal_data_model.md).
---
## Purpose
Every typed triple produced by `UKOIndexer.index_graph()` now carries three
provenance fields:
| Field | OWL Property | Type | Description |
|-------|-------------|------|-------------|
| `sourceResource` | `uko:sourceResource` | `str` (ULID) | The CleverAgents resource that produced this triple |
| `validFrom` | `uko:validFrom` | `datetime` (UTC) | When this triple version became valid |
| `isCurrent` | `uko:isCurrent` | `bool` | Whether this is the current (non-superseded) version |
These fields are defined in UKO Layer 0 (see
[`docs/reference/uko.md`](../reference/uko.md#layer-0--universal-foundation-uko)).
---
## How Provenance Is Attached
When `UKOIndexer.index_graph()` runs, it calls `attach_provenance()` on
every triple before storing it in the graph backend:
```python
# Conceptual flow (simplified)
triples = analyzer.analyze(content, resource_uri)
implicit = inference_engine.infer(triples)
all_triples = triples + implicit
for triple in all_triples:
provenanced = ProvenancedTriple(
triple=triple,
provenance=ProvenanceMetadata(
source_resource=resource.id,
source_path=resource.location,
valid_from=datetime.now(UTC),
is_current=True,
),
)
graph_backend.add_triple(project, provenanced)
```
---
## Revision Chain
A revision chain tracks the full history of ontology state across indexing
runs. When a resource is re-indexed:
1. All existing triples for that resource are marked `isCurrent=False` and
`validUntil` is set to the re-indexing timestamp.
2. New triples are created with `isCurrent=True` and a fresh `validFrom`.
3. A new revision entry is appended to the chain, linked to the previous
revision.
This enables point-in-time queries: "what did the knowledge graph look like
at timestamp T?"
```
Revision 1 (2026-03-01) → Revision 2 (2026-03-15) → Revision 3 (2026-04-01)
isCurrent=False isCurrent=False isCurrent=True
validUntil=2026-03-15 validUntil=2026-04-01 validUntil=None
```
---
## Querying Provenance
### Current Triples Only
```python
from cleveragents.application.services.uko_query_interface import UKOQueryInterface
query = UKOQueryInterface(graph_backend=backend, project="local/my-app")
# Classify a resource using only current triples
result = query.classify_resource("01HXYZ...")
# result.layer, result.primary_type, result.all_types, result.implicit_relations
```
### Historical Triples (Point-in-Time)
```python
from datetime import datetime, timezone
from cleveragents.application.services.uko_persistence import UKOGraphPersistence
persistence = UKOGraphPersistence(
graph_backend=backend,
project="local/my-app",
persist_path=Path("~/.config/cleveragents/uko-graph.json").expanduser(),
)
# Query triples valid at a specific point in time
historical = persistence.query_at_time(
timestamp=datetime(2026, 3, 15, tzinfo=timezone.utc)
)
```
### Triples by Source Resource
```python
# Get all triples (current and historical) from a specific resource
triples = graph_backend.query(
project="local/my-app",
sparql="""
SELECT ?s ?p ?o WHERE {
?s ?p ?o .
?s uko:sourceResource "01HXYZ..." .
}
"""
)
```
---
## Persistence Format
`UKOGraphPersistence` serialises the full graph (including provenance) to
JSON. The format includes all triples with their provenance metadata:
```json
{
"version": "1",
"project": "local/my-app",
"revision": 3,
"triples": [
{
"subject": "uko-py:class/AuthService",
"predicate": "rdf:type",
"object": "uko-oo:Class",
"provenance": {
"source_resource": "01HXYZ...",
"source_path": "src/auth/service.py",
"source_range": "15:1-87:0",
"valid_from": "2026-04-01T10:00:00Z",
"valid_until": null,
"is_current": true
}
}
]
}
```
---
## BDD Coverage
The provenance tracking feature is covered by 47 BDD scenarios in
`features/uko_provenance.feature`:
- Typed triple provenance fields (`sourceResource`, `validFrom`, `isCurrent`)
- Temporal queries (point-in-time, current-only, historical)
- Revision chain creation and traversal
- Graph persistence with provenance (save/restore round-trip)
- Re-indexing marks previous triples as historical
---
## Gotchas
- **Naive datetimes are rejected.** All `validFrom` and `validUntil` values
must be timezone-aware UTC datetimes. Passing a naive `datetime` raises
`ValueError`.
- **Re-indexing is not atomic.** If `index_graph()` fails partway through,
some triples may be marked historical while their replacements were not
yet written. The indexer logs a warning in this case; re-running
`reindex_resource()` will repair the state.
- **In-memory backend has no persistence.** The `InMemoryGraphIndexBackend`
used in tests does not persist across process restarts. Use
`UKOGraphPersistence` with a file backend in production.
---
## Related Documentation
- [UKO Runtime Services](../reference/uko_runtime.md) — full API reference
- [UKO Ontology](../reference/uko.md) — four-layer ontology and provenance property definitions
- [UKO Indexer](../reference/uko_indexer.md) — `ProvenanceMetadata` and `ProvenancedTriple` types
- [Temporal Data Model](../reference/temporal_data_model.md) — `TemporalNode`, `RevisionChain`, tier storage
- [ACMS](../reference/acms.md) — how provenance feeds into context assembly