Files
correx/docs/decisions/adr-0006-event-store-append-only.md

76 lines
2.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: "Adr 0006 Event Store Append Only"
description: "Appendonly, ordered, idempotent event store invariants"
depth: 2
links: ["../index.md", "../modules/core-events-submodule-spec.md", "./adr-0005-persistence-choice.md"]
---
# ADR-0006: Event Store Append-Only & Ordering Invariant
**status:** accepted
**date:** 08.05.2026
**deciders:** Kami
---
## context
The system relies on an append-only event log as the single source of truth. Replay correctness, session reconstruction, and deterministic projections all depend on strict ordering and immutability of persisted events.
Without enforced guarantees at the storage layer, higher-level invariants (projection determinism, replay correctness) cannot be trusted.
This ADR formalizes storage-level constraints for all EventStore implementations.
---
## content
The EventStore MUST enforce:
### 1. append-only semantics
* events cannot be updated or deleted
* event_id is immutable and unique per event
### 2. idempotency
* repeated append attempts with same event_id MUST be ignored or rejected safely
* duplicate events MUST NOT be stored
### 3. per-session ordering
* sequence MUST be strictly monotonically increasing per session_id
* ordering MUST be total within a session stream
### 4. causality preservation
* causation_id and correlation_id MUST be preserved as metadata only
* they MUST NOT affect ordering
### 5. deterministic read model
* read(session_id) MUST always return events in sequence order
* read consistency MUST not depend on implementation timing
---
## consequences
**positive:**
* guarantees replay correctness foundation
* enables deterministic projection logic
* simplifies concurrency model (append-only reduces state conflicts)
* allows multiple backend implementations (sqlite, in-memory)
**negative:**
* no event mutation allowed (requires compensating events instead)
* stricter implementation requirements for persistence engines
* potential write amplification in correction scenarios
---
## status
accepted