eventcore-fs: ADR-0043: projection local-ingestion cursor after merge #391

Closed
opened 2026-06-12 21:34:02 -07:00 by jwilger · 0 comments
Owner

Follow-up to PR #390 (eventcore-fs file backend). The merge-mode core is
implemented; this covers the remaining projection-after-merge work from
ADR-0043.

Context

EventReader returns events ordered by StreamPosition (UUID7) and paginates
with after_position. A structural git merge can introduce events whose
canonical linearized position is earlier than a cursor a projection already
passed, so a naive cursor-based projection could silently miss them.

PR #390 shipped the safety-net signal — FileEventStore::topology_generation()
— so a projection can detect a structural merge and rebuild. This issue covers
the larger remaining piece.

Scope

  • Add a per-replica local-ingestion-order cursor so a live cursor-based
    projection never rewinds: canonical linearized order governs state-folding and
    StreamVersion, while local-ingestion order governs cursor progress (merge
    events get a fresh, larger local position even though their linearized
    position is earlier).
  • Document the app-author constraint: a reconciliation command's events must
    compensate to a correct read-model state whether or not the diverged events
    were already projected.

Acceptance

  • A live projection that has already advanced past a position still observes a
    later-arriving merge's compensation events (does not rewind, does not miss).
  • A projection that opts into rebuild-on-topology-change reaches the same state.
  • Behaviour documented in blueprints/fs-merge-mode.md.

References: ADR-0043, PR #390.

Follow-up to PR #390 (eventcore-fs file backend). The merge-mode core is implemented; this covers the remaining projection-after-merge work from **ADR-0043**. ## Context `EventReader` returns events ordered by `StreamPosition` (UUID7) and paginates with `after_position`. A structural `git merge` can introduce events whose canonical linearized position is *earlier* than a cursor a projection already passed, so a naive cursor-based projection could silently miss them. PR #390 shipped the safety-net signal — `FileEventStore::topology_generation()` — so a projection can detect a structural merge and rebuild. This issue covers the larger remaining piece. ## Scope - Add a per-replica **local-ingestion-order cursor** so a live cursor-based projection never rewinds: canonical linearized order governs state-folding and `StreamVersion`, while local-ingestion order governs cursor progress (merge events get a fresh, larger local position even though their linearized position is earlier). - Document the app-author constraint: a reconciliation command's events must compensate to a correct read-model state whether or not the diverged events were already projected. ## Acceptance - A live projection that has already advanced past a position still observes a later-arriving merge's compensation events (does not rewind, does not miss). - A projection that opts into rebuild-on-topology-change reaches the same state. - Behaviour documented in `blueprints/fs-merge-mode.md`. References: ADR-0043, PR #390.
jwilger added this to the 1.0.0 milestone 2026-06-13 05:44:58 -07:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Slipstream/eventcore#391
No description provided.