# UKO Runtime Services This document covers the three runtime services that operationalize the Universal Knowledge Ontology (UKO) within the ACMS context pipeline. These services were introduced in v3.7.0 (issue #891) and extended in v3.8.0 (issue #891) with provenance tracking and temporal versioning. They implement the runtime requirements from `docs/specification.md` §185, §20568, §43924. For the ontology structure itself, see [`uko.md`](uko.md). For the indexer that populates the graph, see [`uko_indexer.md`](uko_indexer.md). For the temporal data model, see [`temporal_data_model.md`](temporal_data_model.md). For the dedicated provenance module guide, see [`../modules/uko-provenance.md`](../modules/uko-provenance.md). ## Overview The three runtime services work together as follows: ``` UKOIndexer.index_graph() │ ├── UKOInferenceEngine.infer() ← adds implicit triples (confidence 0.7) │ ├── ProvenanceMetadata attached ← sourceResource, validFrom, isCurrent (v3.8.0+) │ └── GraphIndexBackend ← stores all triples (explicit + implicit) │ ├── UKOQueryInterface ← ACMS context strategies query here │ ├── UKOGraphPersistence ← serialise/restore across restarts │ └── RevisionChain ← tracks ontology state across indexing runs (v3.8.0+) ``` ## Provenance Tracking (v3.8.0+) Every typed triple produced by `UKOIndexer.index_graph()` now carries provenance metadata. This enables temporal queries over historical UKO snapshots and supports audit trails for context decisions. ### Provenance Fields on Typed Triples | Field | OWL Property | Description | |-------|-------------|-------------| | `sourceResource` | `uko:sourceResource` | ULID of the CleverAgents resource that produced this triple | | `validFrom` | `uko:validFrom` | UTC timestamp when this triple version became valid | | `isCurrent` | `uko:isCurrent` | Whether this is the current (non-superseded) version of the triple | When a resource is re-indexed, the previous triples for that resource are marked `isCurrent=False` and `validUntil` is set to the re-indexing timestamp. New triples are created with `isCurrent=True` and a fresh `validFrom`. ### Revision Chain A revision chain tracks the full history of ontology state across indexing runs. Each indexing run creates a new revision entry linked to the previous one, enabling point-in-time queries: ```python 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_triples = persistence.query_at_time( timestamp=datetime(2026, 3, 15, tzinfo=timezone.utc) ) ``` ### Temporal Query Patterns | Query | Description | |-------|-------------| | `isCurrent=True` | Current (hot-tier) triples only | | `validFrom <= T < validUntil` | Triples valid at timestamp T | | `sourceResource = ULID` | All triples from a specific resource | | All triples | Full historical graph (cold-tier) | --- ## UKOQueryInterface **Module**: `cleveragents.application.services.uko_query_interface` Provides ACMS context strategies with a typed interface to the UKO knowledge graph. Strategies use this to discover resource types, ontology layers, and implicit relationships without constructing raw SPARQL queries. ### Constructor | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `graph_backend` | `GraphIndexBackend` | Yes | Graph index backend to query | | `project` | `str` | Yes | Namespaced project name (e.g. `"local/my-app"`) | Raises `TypeError` if `graph_backend` does not satisfy `GraphIndexBackend`. Raises `ValueError` if `project` is empty or whitespace-only. ### ClassificationResult Frozen dataclass returned by `classify_resource()`. | Field | Type | Description | |-------|------|-------------| | `resource_id` | `str` | ULID of the classified resource | | `layer` | `int` | Highest UKO layer populated for this resource (0–3) | | `primary_type` | `str` | Primary UKO type URI (e.g. `uko-py:Module`) | | `all_types` | `tuple[str, ...]` | All UKO type URIs found for this resource | | `implicit_relations` | `tuple[tuple[str, str, str], ...]` | Inferred (subject, predicate, object) triples | Layer constants: | Constant | Value | Description | |----------|-------|-------------| | `LAYER_UNIVERSAL` | `0` | Foundation concepts | | `LAYER_DOMAIN` | `1` | Software, documents, data schemas, infrastructure | | `LAYER_PARADIGM` | `2` | OO, functional, procedural, markdown | | `LAYER_TECHNOLOGY` | `3` | Python, TypeScript, Rust, Java, PostgreSQL | ### Methods #### `classify_resource(resource_id: str) → ClassificationResult` Queries the graph backend for all triples associated with the given resource and extracts type, layer, and relationship data. Returns a default `ClassificationResult` (layer 0, no types) if the resource has not been indexed. Raises `ValueError` if `resource_id` is empty. #### `get_resources_by_layer(layer: int) → list[str]` Returns resource ULIDs classified at the given ontology layer (0–3). Raises `ValueError` if `layer` is outside 0–3. #### `get_implicit_relations(resource_id: str) → list[tuple[str, str, str]]` Returns implicit relationships inferred for a resource as a list of `(subject, predicate, object)` tuples. Raises `ValueError` if `resource_id` is empty. ### Usage Example ```python from cleveragents.application.services.uko_query_interface import ( UKOQueryInterface, LAYER_TECHNOLOGY, ) query = UKOQueryInterface(graph_backend=backend, project="local/my-app") # Classify a resource result = query.classify_resource("01HXYZ...") print(result.layer) # e.g. 3 (Technology) print(result.primary_type) # e.g. "uko-py:Module" print(result.all_types) # all UKO type URIs # Find all Python-layer resources python_resources = query.get_resources_by_layer(LAYER_TECHNOLOGY) # Get inferred relationships relations = query.get_implicit_relations("01HXYZ...") for subject, predicate, obj in relations: print(f"{subject} --[{predicate}]--> {obj}") ``` --- ## UKOInferenceEngine **Module**: `cleveragents.application.services.uko_inference` Analyses UKO triples produced by domain analyzers and generates additional triples representing inferred semantic relationships. Inferred triples are stored with a confidence score of **0.7** to distinguish them from deterministic extractions. Three inference patterns are applied: | Pattern | Predicate | Condition | |---------|-----------|-----------| | Co-occurrence | `uko:implicitSiblingOf` | Two subjects share the same `rdf:type` | | Containment | `uko:implicitContains` | Subject URI is a prefix of another subject's URI | | Dependency | `uko:implicitDependsOn` | Subject references another subject's URI in its object values | ### Methods #### `infer(triples: Sequence[UKOTriple]) → list[UKOTriple]` Analyses the provided triples and returns a list of inferred implicit triples. The returned triples have `confidence=0.7`. ### Integration with UKOIndexer `UKOIndexer.index_graph()` automatically calls `UKOInferenceEngine.infer()` after the domain analyzer produces triples, then stores both the original and inferred triples in the graph backend. ```python from cleveragents.application.services.uko_inference import UKOInferenceEngine engine = UKOInferenceEngine() implicit_triples = engine.infer(original_triples) # implicit_triples[0].confidence == 0.7 ``` --- ## UKOGraphPersistence **Module**: `cleveragents.application.services.uko_persistence` Serialises the in-memory UKO graph (triples stored in a `GraphIndexBackend`) to a JSON file and restores it on application restart. This satisfies the acceptance criterion: *"UKO data persists across application restarts."* ### Persistence Format ```json { "version": "1", "project": "local/my-app", "triples": [ {"subject": "...", "predicate": "...", "object": "..."} ] } ``` ### UKOPersistenceBackend Protocol Custom persistence backends must implement: ```python class UKOPersistenceBackend(Protocol): def save(self, data: dict[str, object]) -> None: ... def load(self) -> dict[str, object] | None: ... ``` The default implementation writes to a JSON file. An in-memory backend is provided for testing. ### UKOGraphPersistence | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `graph_backend` | `GraphIndexBackend` | Yes | Backend holding the live graph | | `project` | `str` | Yes | Namespaced project name | | `backend` | `UKOPersistenceBackend \| None` | No | Persistence backend (default: JSON file) | | `persist_path` | `Path \| None` | No | Path for the JSON file backend | #### `save() → None` Serialises all triples from the graph backend to the persistence store. #### `load() → bool` Restores triples from the persistence store into the graph backend. Returns `True` if data was loaded, `False` if no persisted data exists. ### Usage Example ```python from pathlib import Path 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(), ) # On shutdown — save the graph persistence.save() # On startup — restore the graph loaded = persistence.load() if loaded: print("UKO graph restored from disk") ``` --- ## Layer URI Prefix Mapping The `_infer_layer_from_uri()` helper (used internally by `UKOQueryInterface`) maps type URIs to layer numbers: | Prefix | Layer | |--------|-------| | `uko:` / `https://cleveragents.ai/ontology/uko#` | 0 (Universal) | | `uko-code:`, `uko-doc:`, `uko-data:`, `uko-infra:` | 1 (Domain) | | `uko-oo:`, `uko-func:`, `uko-proc:` | 2 (Paradigm) | | `uko-py:`, `uko-ts:`, `uko-rs:`, `uko-java:` | 3 (Technology) | ## Related Documentation - [UKO Ontology](uko.md) — four-layer ontology structure and URI conventions - [UKO Indexer](uko_indexer.md) — real-time index synchronization - [Temporal Data Model](temporal_data_model.md) — revision-aware RDF and three-tier storage - [UKO Provenance Module](../modules/uko-provenance.md) — provenance tracking and temporal versioning guide - [ACMS](acms.md) — Advanced Context Management System overview - [ACMS Fusion](acms_fusion.md) — Fragment Fusion pipeline (Phase 2 protocols)