What Is Temporal Validity in Semantica Context Graphs? A Complete Guide to Bi-Temporal Knowledge Modeling
Temporal validity in Semantica Context Graphs is a bi-temporal modeling system where every node and edge carries validity windows that track both when a fact was true in the real world (valid_from/valid_until) and when it was recorded in the system (recorded_at/superseded_at).
Semantica's Context Graph is a thread-safe, in-memory property graph that treats time as a first-class dimension. This article explains how temporal validity works, why it matters for AI applications, and how to use the full temporal stack (v0.4.0) to build time-aware knowledge systems according to the semantica-agi/semantica source code.
The Bi-Temporal Model: Two Independent Timelines
Semantica implements a bi-temporal data model where each fact stores two distinct time dimensions that operate independently:
- Valid time — the real-world interval when a fact was actually true
- Transaction time — the system interval when the fact was known and recorded
The default "open-ended" sentinel TemporalBound.OPEN represents an indefinite end date, allowing facts to remain valid until explicitly superseded. This design separates what happened from when we knew about it, enabling retroactive corrections without destroying audit history.
In docs/reference/temporal.md (lines 7-15), the bi-temporal model is specified as the foundation for all temporal operations in the graph.
Temporal Layers and the Full Stack
Semantica ships with a comprehensive temporal stack (v0.4.0) that extends basic validity windows into a complete time-aware query system:
- Point-in-time snapshots — freeze the graph state at any moment
- Allen-interval algebra — formal temporal logic for comparing intervals
- Natural-language temporal parsing — convert phrases like "last quarter" into valid bounds
- Three-axis query filtering — filter by
"valid","transaction", or"both"timelines
As documented in docs/reference/temporal.md (lines 9-33), these layers transform the Context Graph from a static structure into a temporal database capable of answering "what-was-true-when" questions deterministically.
Core API: TemporalGraphQuery
The TemporalGraphQuery class in semantica/kg/temporal_query.py provides the primary interface for temporal operations. Key methods include:
| Method | Purpose |
|---|---|
query_at_time(kg, query, at_time) |
Execute a query against the graph as it existed at a specific timestamp |
reconstruct_at_time(kg, timestamp) |
Build a complete subgraph containing only valid nodes/edges |
find_temporal_paths(..., enforce_causal_ordering) |
Discover paths where temporal ordering respects causality |
validate_temporal_consistency(kg) |
Detect inverted intervals, overlaps, and other temporal anomalies |
These methods respect the validity windows of every node and edge, ensuring that query results reflect the exact slice of reality that mattered at any given moment (docs/reference/temporal.md, lines 18-26).
Building Time-Aware Graphs
Validity windows are attached at construction time through the GraphBuilder class in semantica/kg/graph_builder.py.
from semantica.kg import GraphBuilder
builder = GraphBuilder()
kg = builder.build(sources=[{
"entities": [
{"id": "alice", "type": "Person"},
{"id": "acme_corp", "type": "Organization"},
],
"relationships": [
{
"source": "alice",
"target": "acme_corp",
"type": "ceo_of",
"valid_from": "2018-01-01",
"valid_until": "2022-06-01",
},
{
"source": "alice",
"target": "beta_ltd",
"type": "ceo_of",
"valid_from": "2022-06-01",
# valid_until omitted → defaults to TemporalBound.OPEN
},
],
}])
The builder automatically attaches both valid-time and transaction-time bounds to entities and relationships.
Querying at Specific Points in Time
The TemporalGraphQuery class enables precise temporal filtering:
from semantica.kg import TemporalGraphQuery
query = TemporalGraphQuery(temporal_granularity="day")
result_2020 = query.query_at_time(kg, query="", at_time="2020-06-15")
print(result_2020["relationships"])
# → shows only relationships valid during 2020
For low-level subgraph reconstruction:
snapshot = query.reconstruct_at_time(kg, "2021-06-15")
# snapshot contains only nodes/edges whose validity windows include 2021-06-15
Temporal Path Finding with Causal Ordering
The find_temporal_paths method enforces that path traversal respects the arrow of time:
paths = query.find_temporal_paths(
kg,
source="alice",
target="beta_ltd",
start_time="2022-01-01",
end_time="2024-12-31",
enforce_causal_ordering=True,
ordering_strategy="strict",
)
for p in paths["paths"]:
print(" → ".join(p["path"]))
Setting enforce_causal_ordering=True with ordering_strategy="strict" ensures that each step in a path temporally precedes the next, eliminating logically impossible causal chains.
Validating Temporal Consistency
Temporal validity windows can contain inconsistencies—inverted intervals, overlapping contradictory facts, or gaps in required coverage. The validation API detects these automatically:
from semantica.kg import TemporalGraphQuery
report = TemporalGraphQuery().validate_temporal_consistency(kg)
print(f"errors: {len(report.errors)}, warnings: {len(report.warnings)}")
This validation is critical for maintaining data quality in long-running knowledge systems.
ContextGraph: Public Temporal API
The ContextGraph class in semantica/context/context_graph.py exposes simplified temporal methods for common operations:
add_node(..., valid_from, valid_until)— create nodes with explicit validityfind_active_nodes(at_time=...)— retrieve nodes valid at a specific timestamp
These methods wrap the lower-level TemporalGraphQuery functionality for convenience.
Temporal Reasoning Engine
The TemporalReasoningEngine in semantica/kg/temporal_reasoning.py implements Allen-interval algebra, providing formal operations for comparing temporal intervals:
IntervalRelation— enumeration of 13 possible interval relationships (before, meets, overlaps, during, etc.)TemporalBound— bounds handling including theOPENsentinel
This engine powers all temporal comparison operations in the query system.
Real-World Use Cases
Temporal validity windows enable several critical applications according to the Semantica documentation:
- Policy versioning — track how regulations evolved and which version applied when
- Historic responsibility tracing — determine who had what role at a specific time
- Versioned snapshots — reconstruct system state for debugging or audit
- Consistency validation — guarantee that graph state reflects intended time spans
These use cases all rely on the bi-temporal foundation to ensure that the knowledge graph remains a faithful record of changing reality (docs/reference/temporal.md, lines 46-53).
Summary
- Temporal validity in Semantica Context Graphs is implemented as a bi-temporal model with independent valid-time and transaction-time axes.
- Every node and edge carries
valid_from/valid_untilandrecorded_at/superseded_atwindows, withTemporalBound.OPENfor indefinite periods. - The temporal stack (v0.4.0) adds snapshots, Allen-interval algebra, natural-language parsing, and three-axis filtering (
valid,transaction,both). TemporalGraphQueryinsemantica/kg/temporal_query.pyprovides the core API for time-aware queries, path finding, and consistency validation.GraphBuilderattaches validity windows at construction;ContextGraphexposes simplified temporal methods;TemporalReasoningEngineimplements formal interval algebra.
Frequently Asked Questions
What is the difference between valid time and transaction time in Semantica?
Valid time represents when a fact was actually true in the real world, while transaction time records when the system became aware of that fact. These timelines are independent—valid time allows retroactive corrections (stating that something was true earlier than we knew it), and transaction time maintains an immutable audit trail of when information entered the system.
How does TemporalBound.OPEN work for open-ended validity?
TemporalBound.OPEN is a sentinel value representing an indefinite end date. When valid_until or superseded_at is set to OPEN, the fact remains valid until explicitly changed. This is implemented in semantica/kg/temporal_reasoning.py and is the default behavior when no end bound is specified during graph construction.
Can I query Semantica graphs using natural language time expressions?
Yes. The temporal stack (v0.4.0) includes natural-language temporal parsing that converts expressions like "last quarter," "FY2023," or "three months ago" into concrete validity bounds. This integrates with TemporalGraphQuery methods that accept datetime strings or relative time phrases.
What happens if two contradictory facts have overlapping validity windows?
The validate_temporal_consistency method detects overlapping contradictory edges as warnings or errors depending on severity. For explicit conflict resolution, applications must implement domain-specific logic—the bi-temporal model preserves all facts for audit purposes rather than automatically merging or discarding them.
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 →