atagen

macltok

public
Star0
Watch0
722b4c3d0a09ca2aa7b242170395338933a65d52
3
ssh://brewery@pls.lobotomise.me:33/atagen/macltok.git
docs/segmented-history.mdMarkdown115 lines4.1 KB

segmented history

a room’s history is sections of events with durable gaps between them. the sdk event cache keeps the sections, gap identity, boundaries and each gap’s cursor, encrypted at rest, across room close and restart. macltok shows gaps inline and fills them on request.

opening a room

opening loads retained history and its gaps, then starts a recent load in the background, so opening never waits on the network. the recent load fetches up to four pages of 50 events from a fresh server position. if it reaches the newest retained event the sections join. if it doesn’t, a gap is left between the fresh window and what was retained.

Event::RecentHistoryChanged reports it, one event per edge.

  • Loading as it starts
  • Loaded, Cancelled or Failed(message) as it settles
  • Idle when the room closes, whatever was happening

Failed stays until HistoryRepairCommand::RetryRecent or a reopen. a failed load falls back to paginating EngineConfig::initial_history_limit events, so the room isn’t left empty.

filling a gap

HistoryRepairCommand::FillGap { room_id, gap_id } walks one gap backwards, up to four pages of 50, each page committing its events and the gap’s new cursor together. Event::HistoryRepairChanged carries a HistoryRepairReport, once with phase Bridging as the fill starts and once more as it settles.

  • Ready, continuity Verified. the older section was reached and the gap is gone
  • Paused with a stop. Budget after four pages, CursorStalled when the server repeats a cursor, HistoryUnavailable (continuity AccessibleStart) when accessible history ends first, Cancelled
  • Paused with a failure, and the gap row goes Failed

a gap that is already unavailable answers at once and counts no page. one that has already joined is gone, so filling it answers EventNotFound.

one operation per room

a room runs one history operation at a time. RetryRecent joins a recent load that is already running. everything else that overlaps, a fill during a recent load, a recent load during a fill, a second fill, answers RoomBusy.

HistoryRepairCommand::Cancel stops whatever is running. its own answer is Ok, the cancelled command answers Interrupted, and the published outcome is Cancelled, never a failure. pages already committed stay.

the timeline

gaps appear in TimelineState.items as TimelineItem::HistoryGap, between the sections they separate. a row keeps its id while its lifecycle changes, and is removed once the gap joins. joined gaps never appear.

history lands as incremental TimelineChanged diffs, never a TimelineReset. before answering, the room fences on Timeline::flush_history, which applies what the cache already queued without replacing the timeline, so receipts, the read marker and row ids survive.

a command’s answer comes after its outcome is published, and after the mirror has applied it when one is attached.

known holes

a limited sync for a room with no events in memory records a plain gap instead of a history gap (review 2026-10-25 S1), so an interval can still render as continuous. both prev_batch drops in the sdk’s handle_sync remain.

wire shapes

serde enums are externally tagged.

{ "HistoryRepair": { "FillGap": { "room_id": "!room:example.org", "gap_id": "opaque" } } }
{ "HistoryRepair": { "RetryRecent": { "room_id": "!room:example.org" } } }
{ "HistoryRepair": { "Cancel": { "room_id": "!room:example.org" } } }

a gap row.

{
  "HistoryGap": {
    "id": "opaque",
    "older_boundary": "$older:example.org",
    "newer_boundary": "$newer:example.org",
    "lifecycle": "Idle",
    "failure": null
  }
}

lifecycle is Idle, Paused, Failed or Unavailable. failure is set with Failed.

a settled fill.

{
  "room_id": "!room:example.org",
  "gap_id": "opaque",
  "pages": 2,
  "events": 63,
  "phase": "Ready",
  "continuity": "Verified",
  "stop": null,
  "failure": null
}

the mirror keeps State.recent_history, a room without an entry being idle, and State.repairs, the last fill report per room. closing a room drops both.