179 lines
4.1 KiB
Markdown
179 lines
4.1 KiB
Markdown
# Epic 1.5: Event Store Hardening (Concurrency, Integrity, and Replay Safety)
|
|
|
|
**status:** proposed
|
|
**date:** 08.05.2026 (May)
|
|
**scope:** `:core:events`, `:infrastructure:persistence`
|
|
|
|
---
|
|
|
|
## context
|
|
|
|
Epic 1 establishes a functional event-sourced storage system (in-memory + SQLite) with correct basic semantics: append, read, ordering, and idempotency.
|
|
|
|
However, current implementation assumes ideal conditions:
|
|
|
|
* single-threaded or externally synchronized writes
|
|
* stable event schema
|
|
* no replay pressure under large histories
|
|
* no concurrent access patterns
|
|
|
|
These assumptions do not hold once the system is integrated into orchestration (`:core:kernel`) and async execution (`coroutines`, CLI + server).
|
|
|
|
Epic 1.5 introduces **hard guarantees required for real execution environments**, without changing the external EventStore contract.
|
|
|
|
---
|
|
|
|
## goal
|
|
|
|
Make the event store:
|
|
|
|
> deterministic, concurrency-safe, replay-stable, and schema-resilient under real execution conditions
|
|
|
|
---
|
|
|
|
## scope (what IS included)
|
|
|
|
### 1. concurrency model definition
|
|
|
|
Define and enforce:
|
|
|
|
* single-writer guarantee per EventStore instance
|
|
* behavior under concurrent `append` / `appendAll`
|
|
* read consistency rules during writes
|
|
|
|
**deliverable:**
|
|
|
|
* documented concurrency contract in `EventStore`
|
|
|
|
---
|
|
|
|
### 2. SQLite transactional correctness
|
|
|
|
Ensure SQLite implementation guarantees:
|
|
|
|
* atomic `appendAll` (single transaction boundary)
|
|
* no partial writes on failure
|
|
* deterministic ordering under concurrent calls (within single instance constraints)
|
|
|
|
**work:**
|
|
|
|
* explicit transaction wrapping
|
|
* `BEGIN/COMMIT/ROLLBACK` safety handling
|
|
* removal of implicit autocommit ambiguity
|
|
|
|
---
|
|
|
|
### 3. sequence integrity under concurrency
|
|
|
|
Guarantee:
|
|
|
|
* per-session sequence monotonicity
|
|
* no race-condition-based sequence duplication
|
|
* consistent `lastSequence()` computation under concurrent writes
|
|
|
|
**possible approaches:**
|
|
|
|
* synchronized write lock per session
|
|
* or single global write lock (simpler, acceptable for v1)
|
|
|
|
---
|
|
|
|
### 4. contract test hardening (EventStoreContractTest upgrade)
|
|
|
|
Expand contract tests to include:
|
|
|
|
* concurrent append simulation
|
|
* appendAll atomicity verification
|
|
* read consistency during write bursts
|
|
* deterministic replay under repeated execution
|
|
|
|
---
|
|
|
|
### 5. snapshot preparation layer (interface only)
|
|
|
|
Introduce:
|
|
|
|
* `SnapshotStore` interface (no full implementation required yet)
|
|
* hook points in EventStore for snapshot triggers
|
|
|
|
This is structural preparation only.
|
|
|
|
---
|
|
|
|
### 6. event schema version discipline
|
|
|
|
Enforce:
|
|
|
|
* `version` field is mandatory and meaningful
|
|
* serialization must be version-aware
|
|
* unknown version behavior defined (fail fast initially)
|
|
|
|
No migration logic yet, only rules.
|
|
|
|
---
|
|
|
|
### 7. replay determinism guarantee
|
|
|
|
Formalize:
|
|
|
|
> replay of the same event stream must produce identical projections regardless of store implementation
|
|
|
|
This becomes a top-level invariant.
|
|
|
|
---
|
|
|
|
## explicit exclusions (important)
|
|
|
|
Epic 1.5 does NOT include:
|
|
|
|
* sessions / FSM logic
|
|
* transitions / graph engine
|
|
* approval system evolution
|
|
* context processing
|
|
* inference orchestration
|
|
* distributed storage (Kafka, Redis, etc.)
|
|
|
|
---
|
|
|
|
## consequences
|
|
|
|
### positive
|
|
|
|
* removes race-condition ambiguity in kernel integration
|
|
* guarantees EventStore correctness under async execution
|
|
* makes replay safe for debugging and dataset generation
|
|
* stabilizes foundation for all higher-level epics
|
|
|
|
### negative
|
|
|
|
* introduces stricter constraints on store implementations
|
|
* adds concurrency complexity to SQLite layer
|
|
* increases test surface area significantly
|
|
* forces early clarity on threading model (good, but non-trivial)
|
|
|
|
---
|
|
|
|
## rationale
|
|
|
|
Without this layer, higher-level systems will assume inconsistent event semantics depending on:
|
|
|
|
* execution timing
|
|
* store implementation
|
|
* concurrency patterns in kernel
|
|
|
|
This breaks the core promise of Correx:
|
|
|
|
> deterministic replayable execution over nondeterministic inference systems
|
|
|
|
Epic 1.5 ensures the event layer is not just correct, but **operationally invariant**.
|
|
|
|
---
|
|
|
|
## status
|
|
|
|
Recommended immediately after Epic 1 completion and before introduction of:
|
|
|
|
* `:core:sessions`
|
|
* `:core:kernel`
|
|
* `:core:transitions`
|