epic-12: after epic audit and init commit
This commit is contained in:
@@ -0,0 +1,280 @@
|
||||
# Epic 2 — Session Lifecycle (FSM + Projection Layer)
|
||||
|
||||
## completed deliverables
|
||||
|
||||
### 1. session state model (projection output)
|
||||
|
||||
implemented a deterministic session state representation derived entirely from event streams.
|
||||
|
||||
final structure:
|
||||
|
||||
* `SessionState` (pure projection output)
|
||||
* `SessionStatus`
|
||||
* `SessionEvent` (FSM input domain)
|
||||
|
||||
key characteristics:
|
||||
|
||||
* immutable
|
||||
* replay-safe
|
||||
* derived only from events
|
||||
* no identity leakage
|
||||
|
||||
session identity explicitly removed from projection state.
|
||||
|
||||
---
|
||||
|
||||
### 2. session identity boundary separation
|
||||
|
||||
introduced explicit separation between identity and state.
|
||||
|
||||
final model:
|
||||
|
||||
* `Session` → identity wrapper
|
||||
* `SessionState` → projection result
|
||||
|
||||
structure:
|
||||
|
||||
```text id="s1"
|
||||
Session(sessionId)
|
||||
↓
|
||||
SessionState
|
||||
```
|
||||
|
||||
this removed previous anti-pattern:
|
||||
|
||||
* embedding sessionId inside projection state
|
||||
* late-binding identity during replay fold
|
||||
|
||||
---
|
||||
|
||||
### 3. session FSM (deterministic lifecycle rules)
|
||||
|
||||
implemented deterministic finite state machine governing session lifecycle transitions.
|
||||
|
||||
states:
|
||||
|
||||
* `CREATED`
|
||||
* `ACTIVE`
|
||||
* `PAUSED`
|
||||
* `COMPLETED`
|
||||
* `FAILED`
|
||||
* `REPLAYED` (diagnostic)
|
||||
|
||||
properties:
|
||||
|
||||
* deterministic transitions
|
||||
* no side effects
|
||||
* replay-safe behavior
|
||||
* strictly event-driven evaluation
|
||||
|
||||
FSM is pure function:
|
||||
|
||||
```text id="s2"
|
||||
(SessionStatus, SessionEvent) → SessionStatus
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. session event interpretation layer
|
||||
|
||||
introduced mapping layer between persisted events and domain FSM events.
|
||||
|
||||
components:
|
||||
|
||||
* `SessionEventMapper`
|
||||
|
||||
responsibilities:
|
||||
|
||||
* convert `StoredEvent → SessionEvent`
|
||||
* isolate domain semantics from persistence format
|
||||
|
||||
properties:
|
||||
|
||||
* no state mutation
|
||||
* no replay logic
|
||||
* stateless transformation only
|
||||
|
||||
---
|
||||
|
||||
### 5. session projection engine
|
||||
|
||||
implemented `SessionProjector` as domain-specific projection over generic replay infrastructure.
|
||||
|
||||
responsibilities:
|
||||
|
||||
* consumes ordered event stream
|
||||
* applies FSM transitions
|
||||
* produces deterministic session state
|
||||
* tracks lifecycle metadata
|
||||
|
||||
properties:
|
||||
|
||||
* pure fold reducer
|
||||
* stateless across executions
|
||||
* deterministic replay behavior
|
||||
|
||||
state evolution:
|
||||
|
||||
```text id="s3"
|
||||
StoredEvent → SessionEvent → FSM → SessionState
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. projection infrastructure alignment
|
||||
|
||||
aligned session model with generic replay engine (`:core:events`).
|
||||
|
||||
final integration:
|
||||
|
||||
* `Projection<S>` reused as abstraction boundary
|
||||
* `EventReplayer<S>` drives deterministic reconstruction
|
||||
* `SessionProjector` plugs into generic replay system
|
||||
|
||||
no duplication of replay logic inside sessions.
|
||||
|
||||
---
|
||||
|
||||
### 7. session repository (identity boundary)
|
||||
|
||||
introduced repository as thin orchestration facade over replay engine.
|
||||
|
||||
final structure:
|
||||
|
||||
```kotlin id="s4"
|
||||
class DefaultSessionRepository(
|
||||
private val replayer: EventReplayer<SessionState>
|
||||
) {
|
||||
|
||||
fun getSession(sessionId: String): Session =
|
||||
Session(
|
||||
sessionId = sessionId,
|
||||
state = replayer.rebuild(sessionId)
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
responsibilities:
|
||||
|
||||
* binds session identity to replay result
|
||||
* no projection logic
|
||||
* no FSM logic
|
||||
* no event interpretation
|
||||
|
||||
---
|
||||
|
||||
### 8. replay integration
|
||||
|
||||
session lifecycle fully integrated into event-sourced replay pipeline.
|
||||
|
||||
final flow:
|
||||
|
||||
```text id="s5"
|
||||
EventStore
|
||||
↓
|
||||
EventReplayer<SessionState>
|
||||
↓
|
||||
SessionProjector
|
||||
↓
|
||||
SessionState
|
||||
↓
|
||||
Session (identity wrapper)
|
||||
```
|
||||
|
||||
system guarantees:
|
||||
|
||||
* full replay determinism
|
||||
* identical event streams → identical session states
|
||||
* ordering enforced by store layer
|
||||
|
||||
---
|
||||
|
||||
### 9. test coverage completed
|
||||
|
||||
implemented deterministic coverage across session lifecycle:
|
||||
|
||||
* session reconstruction from event stream
|
||||
* FSM transition correctness
|
||||
* invalid transition detection
|
||||
* replay determinism guarantees
|
||||
* empty stream handling
|
||||
* multi-event lifecycle correctness
|
||||
|
||||
introduced fixtures:
|
||||
|
||||
* `stored()` event builder for deterministic event creation
|
||||
|
||||
aligned contract tests:
|
||||
|
||||
* projection contract compliance
|
||||
* replay contract validation
|
||||
* event store contract enforcement
|
||||
|
||||
---
|
||||
|
||||
### 10. architectural cleanup (refactor milestone)
|
||||
|
||||
removed legacy session coupling patterns:
|
||||
|
||||
* sessionId inside `SessionState`
|
||||
* implicit state hydration logic
|
||||
* repository-level replay duplication
|
||||
* ambiguous projection initialization patterns
|
||||
|
||||
removed or deprecated:
|
||||
|
||||
* `SessionCounterProjection` as state-embedded counter logic (moved toward event-derived metrics approach)
|
||||
* FSM leakage into repository layer
|
||||
|
||||
---
|
||||
|
||||
# final architecture after Epic 2
|
||||
|
||||
```text id="s6"
|
||||
EventStore
|
||||
↓
|
||||
EventReplayer<SessionState>
|
||||
↓
|
||||
SessionProjector
|
||||
↓
|
||||
SessionState
|
||||
↓
|
||||
Session (identity wrapper)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# major architectural outcomes
|
||||
|
||||
Epic 2 established:
|
||||
|
||||
* strict separation between identity and state
|
||||
* deterministic FSM-driven session lifecycle
|
||||
* event-sourced state reconstruction model
|
||||
* reusable generic replay engine (`:core:events`)
|
||||
* domain-specific projection layer (`:core:sessions`)
|
||||
* repository as pure boundary adapter
|
||||
* fully replay-safe session lifecycle semantics
|
||||
|
||||
---
|
||||
|
||||
# what Epic 2 intentionally does NOT include
|
||||
|
||||
not implemented:
|
||||
|
||||
* workflow graph execution
|
||||
* transition DSL
|
||||
* orchestration runtime
|
||||
* stage execution engine
|
||||
* scheduling or async coordination
|
||||
* tool execution or kernel integration
|
||||
|
||||
those are explicitly deferred to Epic 3+
|
||||
|
||||
---
|
||||
|
||||
# final state
|
||||
|
||||
Correx now has:
|
||||
|
||||
> a deterministic, event-sourced session lifecycle system built on a generic replay engine, with strict separation between identity, state, and event interpretation, fully replay-safe and FSM-driven.
|
||||
Reference in New Issue
Block a user