4.1 KiB
Epic 2: Session Lifecycle (Finite State Machine + Projection Layer)
status: proposed
date: 08.05.2026 (May)
scope: :core:sessions (depends on :core:events)
context
With a stable event log (Epic 1 complete), Correx now needs a structured runtime abstraction that turns raw events into meaningful execution units.
A session is the primary unit of work in the system:
- it represents a single interactive or automated workflow
- it evolves over time through events
- it must be reconstructible from the event log (replayable state)
Without a session layer, events remain unstructured history with no execution semantics.
goal
Introduce a deterministic session lifecycle system built on top of events:
a finite state machine + projection model that reconstructs session state from the event stream
scope (what IS included)
1. session model
Define Session as a projection, not stored state:
sessionIdstatuscreatedAtupdatedAt- derived metadata (optional: stage, counters, flags)
Session state is derived from events only, never mutated directly.
2. session states (FSM)
Define explicit lifecycle states:
CREATEDACTIVEPAUSEDCOMPLETEDFAILEDREPLAYED(optional diagnostic state)
Transitions are strictly event-driven.
3. session events (from Epic 1)
Introduce interpretation layer over existing events:
SessionStartedSessionPausedSessionResumedSessionCompletedSessionFailed
These are stored in :core:events, not duplicated.
4. session projection builder
Implement:
SessionProjector
Responsibilities:
- consumes ordered
EventEnvelopestream - rebuilds current session state
- applies deterministic reduction logic
Rules:
- pure function behavior (events → state)
- no side effects
- replay-safe
5. transition rules (FSM logic)
Define strict rules:
- invalid transitions must be rejected during projection validation
- transitions are derived from event sequences, not external mutation
- last valid state wins (replay consistency rule)
Example:
CREATED → ACTIVEallowedACTIVE → COMPLETEDallowedCOMPLETED → ACTIVEinvalid (ignored or flagged)
6. session repository
Provide abstraction:
getSession(sessionId): SessiongetAllSessions()rebuild(sessionId)(replay from events)
Backed entirely by EventStore.
7. minimal runtime behavior (no orchestration yet)
Session layer only:
- no kernel execution
- no tool execution
- no transitions engine
- no approvals
It is purely state interpretation over events
8. test coverage
- session reconstruction from event stream
- invalid transition detection
- replay determinism (same events → same session state)
- multi-event lifecycle correctness
- empty session handling
explicit exclusions
Epic 2 does NOT include:
- workflow graph / transitions engine (
:core:transitions) - approval system (
:core:approvals) - tool execution (
:core:tools) - inference or routing
- context compression
- orchestration kernel
consequences
positive
- introduces first meaningful domain abstraction over events
- enables reasoning about execution lifecycle
- provides foundation for orchestration layer
- makes replay human-interpretable (not just raw logs)
- isolates state interpretation logic from persistence
negative
- introduces FSM complexity early in system lifecycle
- requires strict discipline to avoid state mutation leaks
- projection correctness becomes critical dependency for all higher layers
- may require refactoring if event types evolve significantly
rationale
Events alone are insufficient for system reasoning.
A session layer is required to:
translate raw event history into structured execution semantics
This is the first step from:
- “log of facts” to
- “interpretable system state”
status
Epic 2 becomes valid only after:
- Epic 1 is complete ✔
- EventStore contract is stable ✔
- replay guarantees are verified ✔
It is the first domain layer built on top of the event system, and the first step toward orchestration.