# 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:

* `sessionId`
* `status`
* `createdAt`
* `updatedAt`
* derived metadata (optional: stage, counters, flags)

Session state is **derived from events only**, never mutated directly.

---

### 2. session states (FSM)

Define explicit lifecycle states:

* `CREATED`
* `ACTIVE`
* `PAUSED`
* `COMPLETED`
* `FAILED`
* `REPLAYED` (optional diagnostic state)

Transitions are strictly event-driven.

---

### 3. session events (from Epic 1)

Introduce interpretation layer over existing events:

* `SessionStarted`
* `SessionPaused`
* `SessionResumed`
* `SessionCompleted`
* `SessionFailed`

These are stored in `:core:events`, not duplicated.

---

### 4. session projection builder

Implement:

> `SessionProjector`

Responsibilities:

* consumes ordered `EventEnvelope` stream
* 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 → ACTIVE` allowed
* `ACTIVE → COMPLETED` allowed
* `COMPLETED → ACTIVE` invalid (ignored or flagged)

---

### 6. session repository

Provide abstraction:

* `getSession(sessionId): Session`
* `getAllSessions()`
* `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.
