Files
cleveragents-core/docs/reference/temporal_data_model.md
T
hamza.khyari d5f7f15215
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 14s
CI / build (pull_request) Successful in 14s
CI / quality (pull_request) Successful in 20s
CI / security (pull_request) Successful in 34s
CI / typecheck (pull_request) Successful in 39s
CI / unit_tests (pull_request) Successful in 2m50s
CI / integration_tests (pull_request) Successful in 3m22s
CI / docker (pull_request) Successful in 40s
CI / coverage (pull_request) Successful in 5m49s
CI / benchmark-regression (pull_request) Successful in 35m15s
feat(acms): implement Temporal Data Model (Revision-Aware RDF) with 3 storage tiers
Temporal metadata fields (validFrom, validUntil, isCurrent, isRevisionOf)
on UKO InformationUnit nodes enable revision chain tracking: when code
changes, old nodes are marked historical and new revision nodes are
created with back-links. Three storage tiers (hot/warm/cold) filter
nodes by temporal scope (current/recent/all) with configurable retention
(warm_retention_hours default 24h, cold_retention_days default 90d).

Includes TemporalMetadata, TemporalNode, RevisionChain, TierQueryResult,
TierRetentionConfig frozen domain models, TemporalBackend protocol,
InMemoryTemporalBackend stub, TemporalService with structlog and DI,
BackendSet.temporal typing upgrade from object|None to TemporalBackend|None.
67 Behave scenarios, 8 Robot Framework tests, ASV benchmarks, and
reference documentation.

ISSUES CLOSED: #577
2026-03-11 01:36:06 +00:00

5.1 KiB

Temporal Data Model (Revision-Aware RDF)

The Temporal Data Model enables revision tracking of UKO knowledge graph nodes across three storage tiers (hot/warm/cold). When code changes, existing nodes are not deleted -- they are marked historical and a new revision node is created with a back-link to the predecessor.

Based on docs/specification.md lines 41940--42499.

Architecture

Code Change ──► Analyzer ──► TemporalService.create_revision()
                                    │
                         ┌──────────┴──────────┐
                         │  TemporalBackend     │
                         │  ┌─────────────────┐ │
                         │  │ Old node:       │ │
                         │  │  isCurrent=false│ │
                         │  │  validUntil=now │ │
                         │  ├─────────────────┤ │
                         │  │ New node:       │ │
                         │  │  isCurrent=true │ │
                         │  │  isRevisionOf=  │ │
                         │  │    old_uri      │ │
                         │  └─────────────────┘ │
                         └──────────────────────┘

Domain Models

All models are frozen Pydantic BaseModel instances (immutable value objects).

TemporalMetadata

Temporal fields carried by every UKO InformationUnit. Maps to the OWL temporal properties defined in UKO Layer 0.

Field Type Default Spec Property
valid_from datetime (UTC) required uko:validFrom
valid_until datetime | None None uko:validUntil
is_current bool True uko:isCurrent
is_revision_of str | None None uko:isRevisionOf

TemporalNode

A UKO InformationUnit with full temporal metadata and provenance.

Field Type Default Description
node_uri str required Unique UKO URI (e.g., uko-py:class/Auth_v2)
source_resource str required ULID of originating resource
source_path str required File path within the resource
source_range str | None None Source range (e.g., "15:1-87:0")
temporal TemporalMetadata required Embedded temporal metadata

RevisionChain

Ordered chain of node versions for a single UKO concept.

Field Type Default Description
current_uri str required URI of the current head node
predecessors tuple[str, ...] () Predecessor URIs (oldest-first)

Properties: depth (total versions), all_uris (predecessors + current).

TierRetentionConfig

Retention policy for warm and cold tiers.

Field Type Default Config Key
warm_retention_hours int (≥1) 24 context.tiers.warm.retention-hours
cold_retention_days int (≥1) 90 context.tiers.cold.retention-days

TierQueryResult

Result from a tier-aware temporal query.

Field Type Default Description
nodes tuple[TemporalNode, ...] () Matching nodes
tier ContextTier required HOT / WARM / COLD
temporal_scope TemporalScope required CURRENT / RECENT / ALL

TemporalBackend Protocol

class TemporalBackend(Protocol):
    def store_node(self, node) -> None: ...
    def create_revision(self, current_uri, new_node, timestamp) -> TemporalNode: ...
    def get_current(self, node_uri_base) -> TemporalNode | None: ...
    def get_history(self, node_uri_base, temporal_scope) -> tuple[TemporalNode, ...]: ...
    def get_revision_chain(self, node_uri) -> RevisionChain: ...
    def query_by_tier(self, tier, temporal_scope, retention) -> TierQueryResult: ...
    def mark_historical(self, node_uri, timestamp) -> TemporalNode: ...

Three Storage Tiers

Tier Content Temporal Filter Retention
Hot Current UKO graph isCurrent = true only Until removed
Warm Recent context Current + recently-expired warm_retention_hours (24h)
Cold All historical All temporal versions cold_retention_days (90d)

Revision Chain Mechanics

  1. Old node: is_currentFalse, valid_until → timestamp
  2. New node: is_currentTrue, valid_from → timestamp
  3. New node: is_revision_of → old node URI
  4. Old node's valid_from is preserved unchanged

v1 Limitations

  • InMemoryTemporalBackend stores all nodes in a dict; no persistence.
  • No SPARQL query helpers yet (deferred to graph backend integration).
  • temporal-archaeology strategy stub exists but does not yet use the temporal backend (wiring deferred to strategy integration milestone).