How ai-memory Handles Time-Travel and Revision History: A Deep Dive into Supersession Chains

ai-memory implements time-travel and revision history through an immutable supersession chain where every wiki page write creates a new versioned row, with superseded_at linking older revisions and NULL marking the current version.

The ai-memory crate achieves built-in versioning without external tools by treating the pages table as an append-only log. Each edit spawns a fresh row while preserving the full ancestry—enabling queries to retrieve any historical state of a wiki page.

Core Design: The Supersession Chain

The foundation of ai-memory's time-travel capability rests on a supersession chain architecture in the pages table.

How Supersession Works

When Wiki::write_page is invoked in crates/ai-memory-wiki/src/wiki.rs at line 1269, the system performs these steps:

  1. SHA-256 short-circuit check – Compare the new body against the current version. Identical content aborts the write.
  2. New row insertion – Create a fresh pages row with the updated content, timestamp, and author.
  3. Chain linkage – Set superseded_at on the previous row to the new row's creation time.
  4. Current version marker – Leave superseded_at = NULL on the newest row.

This design yields an immutable linked list of revisions. Even no-op writes produce supersession entries at line 1652, preserving complete auditability. Author attribution travels with each version via pages.author_id at line 2206.

Write Path: Atomic Chain Updates

The writer actor in crates/ai-memory-store/src/writer.rs at line 1512 guarantees transactional consistency across the entire supersession chain. All link updates occur in a single database transaction—partial writes cannot corrupt the revision history.

Key properties of the write implementation:

  • Graceful deduplication – SHA-256 comparison prevents redundant versions for unchanged content.
  • Forced versioning – Explicit no-op writes still create chain entries when audit trails matter.
  • Author tracking – Every revision captures author_id for blame and attribution queries.

Read Path: Time-Travel Queries

The reader implementation in crates/ai-memory-store/src/reader.rs at line 7894 supports three access patterns:

Access Mode Method How It Works
Latest read_page(path) Select where superseded_at IS NULL
By ID read_page_by_id(path, id) Direct primary key lookup
By timestamp Follow supersession links Traverse chain to find version active at given time

The reader follows supersession pointers backward through the chain when historical resolution is required. This enables point-in-time reconstruction of any wiki page state.

Operations Layer: CRUD Semantics and Statistics

The store surface in crates/ai-memory-store/src/ops.rs documents supersession behavior explicitly:

  • Line 1803: A later version starts a new supersession—no in-place updates exist.
  • Line 1979: Every supersession row counts in page-level statistics; revision count equals chain length.
  • Line 3094: Page deletion cascades through the entire supersession ancestry after a configurable grace period, enabling soft-delete with eventual hard removal.

Core Abstraction: The Versioned Page Type

The Page struct in crates/ai-memory-core/src/page.rs at line 5 encapsulates the versioning model. Its documentation established ai-memory's core invariant: pages are versioned entities, not mutable records.

Practical Examples: Time-Travel in Action

use ai_memory_wiki::Wiki;

// Write creates a new supersession entry automatically
let page_path = "projects/example.md";
let new_body = format!("Updated content at {}", chrono::Utc::now());
wiki.write_page(page_path, &new_body).await?;

// Retrieve current version (superseded_at = NULL)
let latest = wiki.read_page(page_path).await?;
println!("Current: {}", latest.body);

// Time-travel: fetch specific revision by ID
let revision_id = 42u64;
let historic = wiki.read_page_by_id(page_path, revision_id).await?;
println!("Revision {}: {}", historic.id, historic.body);

// Reconstruct full timeline
let chain = wiki.page_history(page_path).await?;
for rev in chain {
    let status = if rev.superseded_at.is_none() { "CURRENT" } else { "archived" };
    println!("[{}] rev {} @ {} — {}", status, rev.id, rev.created_at, rev.body);
}

The API surface hides chain complexity—callers simply write and read, with time-travel available through optional parameters.

Performance and Storage Considerations

The supersession chain design trades storage for simplicity and correctness:

  • O(1) latest version lookup via superseded_at IS NULL index.
  • O(n) history traversal where n = revision depth (typically small for wiki pages).
  • Storage growth is linear with edits; no compression or delta encoding is currently implemented.

Summary

Frequently Asked Questions

How does ai-memory prevent revision history corruption?

The writer actor performs all supersession updates inside a single database transaction at line 1512 of crates/ai-memory-store/src/writer.rs. Either the entire chain update succeeds, or the transaction rolls back—no partial states are possible.

Can ai-memory retrieve a page as it appeared on a specific date?

Yes, though the API emphasizes ID-based and latest-version access. The reader follows supersession links at line 7894 of crates/ai-memory-store/src/reader.rs, which enables timestamp-based resolution by walking the chain to find the version active at a given point.

What happens when a page is deleted in ai-memory?

Deletion marks the page for removal but preserves the supersession chain until a configurable grace period expires. Afterward, line 3094 of crates/ai-memory-store/src/ops.rs hard-deletes the entire ancestry—enabling recovery windows before permanent erasure.

Does ai-memory support branching or merging of page versions?

No. The supersession chain is strictly linear as implemented in crates/ai-memory-core/src/page.rs. Each version has exactly one predecessor and (at most) one successor—there is no support for divergent branches or three-way merge operations.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →