Skip to content

Temporal Intelligence

Varun Pratap Bhardwaj edited this page Mar 30, 2026 · 1 revision

Temporal Intelligence: Bi-Temporal Validity and Contradiction Detection

Temporal Intelligence gives facts expiration dates. When new information contradicts old information, the old fact is invalidated --- not deleted. SLM never destroys data. Instead, it tracks when something was true and when the system learned it was no longer true, using a 4-timestamp bi-temporal model inspired by Zep/Graphiti.

What It Does

  1. Temporal invalidation without deletion. Old facts get valid_until set rather than being removed. Every fact that ever existed remains in the database.
  2. Contradiction detection. When a new fact is stored, SLM checks it against existing facts for conflicts. Mode A uses sheaf cohomology (pure linear algebra). Mode B/C uses LLM verification with a sheaf pre-filter.
  3. Trust penalty on expired facts. Invalidated facts receive a Bayesian trust downgrade via the existing TrustScorer.
  4. Historical queries. You can ask "What did we know about X at time T?" and get the facts that were considered valid at that point.
  5. Retrieval filtering. Expired facts are excluded from default retrieval results. Include them explicitly for historical analysis.

The 4-Timestamp Model

Every fact tracked by the temporal system has four timestamps that separate two independent time dimensions:

Event Time (When was this true in the real world?)

Timestamp Meaning NULL Means
valid_from When this fact became true Always been true
valid_until When this fact stopped being true Still true now

Transaction Time (When did the system learn about it?)

Timestamp Meaning NULL Means
system_created_at When the system first recorded this fact Never (always populated)
system_expired_at When the system marked this fact as invalid System still considers it current

This bi-temporal model distinguishes between "the meeting was actually on Tuesday" (event time) and "we learned on Wednesday that the meeting was on Tuesday" (transaction time). Both dimensions are tracked independently.

Invalidation Integrity

When a fact is invalidated, both valid_until and system_expired_at are set in the same operation. This is an invariant --- you will never find a fact where one is set but the other is not.

Contradiction Detection

Mode A: Sheaf Cohomology (Pure Math)

Mode A detects contradictions using the existing SheafConsistencyChecker from SLM's mathematical layer (see Mathematical Foundations). No LLM is needed.

The sheaf coboundary operator measures disagreement between two connected facts:

residual = R_b @ embedding_b - R_a @ embedding_a
severity = ||residual|| / (||R_a @ embedding_a|| + ||R_b @ embedding_b||)

Where R_a and R_b are restriction maps along the connecting edge. A severity above the threshold (0.45 for 768d embeddings) indicates a contradiction.

This is pure linear algebra --- it runs without network calls, LLM tokens, or cloud dependencies. The sheaf consistency checker was introduced in v3.0 and is described in the V3 paper.

Mode B/C: LLM Verification with Sheaf Pre-Filter

Mode B and C use a two-stage pipeline:

  1. Sheaf pre-filter: Run the sheaf consistency check with a lower threshold (0.30) to find candidates. This avoids sending every fact pair to the LLM.
  2. LLM verification: For each candidate (up to 5 per new fact), ask the LLM: "Do these two statements contradict each other?" The LLM responds yes or no.

This approach balances accuracy (LLM verification) with cost (at most 5 LLM calls per stored fact, only for likely contradictions).

If no sheaf candidates are found, the system falls back to entity-based candidate search, looking for facts that share entities with the new fact.

Trust Penalty

When a fact is invalidated, the TrustScorer applies a Bayesian penalty. Specifically, update_on_contradiction() adds +3.0 to the Beta distribution's beta parameter:

  • Starting trust 0.5 (uniform prior Beta(1,1)): After contradiction -> Beta(1,4) -> trust = 0.20
  • Starting trust 0.8 (Beta(4,1)): After contradiction -> Beta(4,4) -> trust = 0.50

The effective penalty is approximately -0.20 to -0.30 depending on the prior. This combines with the retrieval filter (which excludes expired facts entirely) to make invalidated facts effectively invisible in default retrieval.

Trust recovery is possible. If future evidence confirms an invalidated fact, update_on_confirmation() can restore trust.

Historical Queries

The 4-timestamp model enables two types of historical queries:

"What was true at event time T?" --- Returns facts whose real-world validity window includes time T:

WHERE valid_from <= T AND (valid_until IS NULL OR valid_until > T)

"What did the system know at transaction time T?" --- Returns facts the system considered current at time T:

WHERE system_created_at <= T AND (system_expired_at IS NULL OR system_expired_at > T)

These queries are useful for debugging ("when did we start believing X?"), auditing ("what was the system state at the time of the incident?"), and understanding how knowledge evolved over time.

Retrieval Filtering

A temporal filter is registered with the ChannelRegistry and runs after all retrieval channels return results but before RRF fusion. By default, it excludes facts where valid_until IS NOT NULL or system_expired_at IS NOT NULL.

When the filter finds no expired facts for a profile, it is a no-op with no performance overhead.

To include expired facts (for historical analysis), set:

slm config set temporal_validator.include_expired_in_history true

Never Deletes Facts

This is the central design principle of temporal intelligence. SLM never removes rows from the atomic_facts table. Invalidation works by setting timestamps in the fact_temporal_validity table:

  • The original fact content remains intact
  • The embedding remains in the vector store
  • The graph edges remain in place
  • Only the temporal validity record marks the fact as expired

This preserves full auditability and enables historical queries.

Configuration

Enable temporal intelligence:

slm config set temporal_validator.enabled true

Adjust contradiction detection sensitivity:

# Mode A: sheaf threshold (lower = more sensitive)
slm config set temporal_validator.contradiction_threshold 0.45

# Mode B/C: pre-filter threshold for LLM candidates
slm config set temporal_validator.llm_prefilter_threshold 0.30

# Max LLM checks per new fact (cost control)
slm config set temporal_validator.max_llm_checks 5

Full Configuration Reference

Parameter Default Description
enabled false Feature flag. Must be true to activate.
mode "a" "a" for sheaf, "b"/"c" for LLM verification
contradiction_threshold 0.45 Sheaf severity threshold for Mode A (768d embeddings)
llm_prefilter_threshold 0.30 Sheaf pre-filter threshold for Mode B/C candidates
max_llm_checks 5 Maximum LLM verification calls per new fact
expiration_trust_penalty -0.2 Approximate trust reduction for invalidated facts
include_expired_in_history true Include expired facts in historical query results

Example: Contradiction Resolution

Consider this sequence of events:

  1. You store: "The API rate limit is 100 requests per minute."
  2. Later, you store: "The API rate limit was increased to 500 requests per minute."

When fact #2 is stored:

  • Sheaf check: The embeddings of both facts are semantically related (shared entities: "API", "rate limit") but directionally opposed (100 vs 500). Coboundary severity exceeds 0.45.
  • Invalidation: Fact #1 gets valid_until = now and system_expired_at = now. The field invalidated_by points to fact #2.
  • Trust penalty: Fact #1's trust drops from 0.50 to approximately 0.20.
  • Retrieval: Future queries about "API rate limit" return only fact #2. Fact #1 still exists in the database for historical queries.

Neither fact is deleted. The system maintains a complete audit trail of how knowledge evolved.


Part of Qualixar | Created by Varun Pratap Bhardwaj

Clone this wiki locally