Skip to content
Documentation GitHub
Platform

Event Log System

Status: Implemented (event log + bookmarks live; history collapse scheduled via background task) Crate: crates/infrastructure/sqlite/src/workspace/event_log_repository.rs Migration: V001 baseline (includes event_log, bookmarks, and event_log_summaries tables)


The history system evolved from periodic full-database snapshots (git-backed checkpoints) to a continuous event log that captures every structural mutation. Combined with Loro CRDT operation history for content, this provides fine-grained point-in-time reconstruction without the storage cost of full database copies.

This evolution is motivated by three forces:

  1. Cloud sync makes local snapshots redundant — Supabase sync already replicates workspace state. Full SQLite snapshots duplicate what the cloud (and CRDTs) already preserve.

  2. Event logs are more valuable to agents — A rich temporal dataset of structural changes enables agents to discover patterns (editing rhythms, concept evolution, relationship formation) that periodic snapshots cannot capture.

  3. Named bookmarks are more intuitive than checkpoints — Users think in terms of meaningful milestones (“Chapter 3 Draft”), not database snapshots. Bookmarks are lightweight markers in the event timeline, not full copies.

Loro CRDT operation logs capture every text edit at the operation level. Any point-in-time content state is reconstructable from CRDT replay. This requires no changes.

Capabilities:

  • Reconstruct any block’s content at any historical timestamp
  • View the full edit timeline for any block
  • Cross-session undo/redo (via Loro undo manager)
  • Diff any two points in time for content comparison

A continuous, immutable log of all non-content mutations. Each event records:

  • What changed: Entity type + entity ID + change type
  • When: Timestamp (ISO 8601 with sub-second precision)
  • What the change was: Before/after values for the mutated fields
  • Who/what: Device ID or agent ID (for attribution)
EntityEvent Types
Pagecreated, moved, renamed, deleted, restored, type_changed
Blockcreated, deleted, reordered, type_changed, area_assigned
Tagcreated, renamed, merged, deleted
Page-Tagassigned, removed
Attachmentadded, removed, replaced
Propertyset, changed, removed
Layoutapplied, removed, changed
Referencecreated, removed (backlink tracking)
Metadatafield_changed (catch-all for any entity field mutation)
CREATE TABLE event_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
entity_type TEXT NOT NULL, -- 'page', 'block', 'tag', 'attachment', etc.
entity_id TEXT NOT NULL, -- UUID of the affected entity
event_type TEXT NOT NULL, -- 'created', 'moved', 'renamed', etc.
before_value TEXT, -- JSON: previous state of changed fields (NULL for 'created')
after_value TEXT, -- JSON: new state of changed fields (NULL for 'deleted')
device_id TEXT, -- Attribution: which device or agent
timestamp TEXT NOT NULL -- ISO 8601 with sub-second precision
DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now'))
);
CREATE INDEX idx_event_log_entity ON event_log(entity_type, entity_id, timestamp);
CREATE INDEX idx_event_log_timestamp ON event_log(timestamp);
CREATE INDEX idx_event_log_type ON event_log(event_type, timestamp);

Events are recorded at the application layer during use case execution. The event log is an additional side-effect of every mutation use case, coordinated through WriteEffectCoordinator.

3. Named Bookmarks (Replaces Git Checkpoints)

Section titled “3. Named Bookmarks (Replaces Git Checkpoints)”

User-created (or agent-created) markers in the event timeline. A bookmark is not a database copy — it is a lightweight marker that anchors a point in time.

CREATE TABLE bookmarks (
id TEXT PRIMARY KEY, -- UUID
name TEXT NOT NULL, -- User-visible name ("Chapter 3 Draft")
description TEXT, -- Optional context
timestamp TEXT NOT NULL, -- The point in the event log this bookmark marks
created_by TEXT, -- User ID or agent ID
created_at TEXT NOT NULL
);

“Restore to bookmark X” means:

  1. Identify the bookmark’s timestamp
  2. Replay the structural event log up to that timestamp
  3. Load CRDT snapshots at that timestamp for content

Full event log granularity is preserved. Every individual mutation is available for agent pattern discovery, user inspection, and fine-grained point-in-time reconstruction. Default: 90 days (configurable via event_log_retention_days setting).

History between named bookmarks collapses into a single summary entry per entity per bookmark interval. Collapse is performed by the Background Task Runner on a scheduled cadence. Summaries are stored in the event_log_summaries table (V001 baseline).

Named bookmarks are never pruned — they are the user’s explicit markers.

  • query_page_events — Events for a specific page
  • query_page_timeline — Timeline view for a page
  • query_timeline — Workspace-wide timeline
  • create_bookmark — Create a named bookmark
  • get_bookmark / list_bookmarks / delete_bookmark — Bookmark management

Located in crates/application/src/event_log/ and crates/application/src/bookmark/:

  • RecordEventUseCase — Records mutations as they occur
  • QueryPageEventsUseCase — Page-scoped event history
  • QueryTimelineUseCase — Workspace-wide timeline
  • QueryPageTimelineUseCase — Page timeline with CRDT content events merged
  • CreateBookmarkUseCase / GetBookmarkUseCase / ListBookmarksUseCase / DeleteBookmarkUseCase

The event log is a primary data source for agent temporal navigation:

  • Researchers can query “what changed in the last week” via event log
  • The RLM executor can write Python code to filter and aggregate events
  • Pattern discovery (“user edits worldbuilding pages on weekends”) uses event timestamps
  • Bookmarks provide natural session boundaries for agent context
  • Agent Core System
  • CRDT BLOB Passthrough Pipeline: docs/solutions/architecture/crdt-blob-passthrough-pipeline.md (developer docs)
  • Sync Engine Cursor Safety: docs/solutions/architecture/sync-engine-cursor-safety.md (developer docs)

Was this page helpful?