# Correx Context Bootstrap --- ## 1. module architecture ```text ❯ tree -L 2 . ├── apps │ ├── cli │ ├── desktop │ ├── server │ └── worker ├── build │ └── reports ├── build.gradle ├── core │ ├── agents │ ├── approvals │ ├── artifacts │ ├── config │ ├── context │ ├── events │ ├── inference │ ├── kernel │ ├── observability │ ├── policies │ ├── router │ ├── sessions │ ├── stages │ ├── tools │ ├── transitions │ └── validation ├── detekt.yml ├── docs │ ├── architecture │ ├── configs │ ├── decisions │ ├── des-doc-v0.1.md │ ├── epics.md │ ├── events │ ├── example.yaml │ ├── lang-framewok-missing-pieces.md │ ├── modules │ ├── plugins │ ├── spec-v0.1.md │ ├── structure.md │ ├── threat_model │ └── transitions ├── epics │ ├── epic-1.5.md │ ├── epic-1.md │ ├── epic-2.md │ └── epic-3.md ├── examples │ ├── configs │ ├── plugins │ ├── stages │ └── workflows ├── frontend │ ├── src │ └── static ├── gradle │ └── wrapper ├── gradle.properties ├── gradlew ├── gradlew.bat ├── infrastructure │ ├── inference │ ├── persistence │ ├── scheduler │ ├── security │ ├── telemetry │ └── tools ├── interfaces │ ├── api │ ├── cli │ └── sdk ├── plugins │ ├── compressors │ ├── policies │ ├── providers │ ├── stages │ ├── tools │ ├── transitions │ └── validators ├── settings.gradle └── testing ├── approvals ├── contracts ├── deterministic ├── fixtures ├── integration ├── projections ├── replay └── transitions ``` --- ## dependency rules (important) * core modules → no infrastructure dependencies * infrastructure → implements core interfaces * testing/contracts → defines reusable invariants * core/events = event system foundation * core/sessions = deterministic event-sourced lifecycle projection layer * core/transitions = deterministic workflow graph evaluation engine * projections are domain-specific folds over event streams * replay engine stays generic and domain-agnostic * transition engine is pure evaluation logic (no orchestration) --- ## 2. current epic ```text Epic 4: Validation pipeline goal: deterministic multi-layer validation system for workflows, sessions, and transitions deliverables: - routing validation layer (graph + transition correctness) - schema validation layer (event + config integrity) - semantic validation hooks (domain rules without execution coupling) - validation pipeline executor (ordered deterministic execution) - approval trigger integration point (event-based, no direct execution coupling) dependencies: - Epic 1 (event system + replay foundation) - Epic 2 (session projection layer) - Epic 3 (workflow transition engine) ``` --- ## 3. implementation state ```text READY TO START Completed before Epic 4: - append-only EventStore with strict ordering guarantees - polymorphic EventPayload serialization (kotlinx.serialization) - deterministic replay infrastructure (EventReplayer + Projection fold model) - session lifecycle projection (SessionProjector + SessionReducer) - FSM abstraction replaced by deterministic reducer semantics - workflow graph model (WorkflowGraph, TransitionEdge, StageId) - deterministic transition evaluation engine (resolver + condition evaluation) - cycle detection + canonicalization (DFS-based graph analysis) - stage execution contract (execution isolated from orchestration) - workflow execution events integrated into event stream - session ↔ transition integration via event-driven projection model - full replay determinism across session + workflow execution ``` --- ## 4. key design decisions (do not violate) ```text - EventPayload uses kotlinx.serialization polymorphic serialization - EventStore is append-only per session stream - sequence is strictly monotonic per session - projections are pure functions: (state, event) -> new state - replay must be deterministic across implementations - core/events contains replay infrastructure only - core/sessions contains event-driven lifecycle projection (no FSM coupling) - SessionProjector is a deterministic reducer over StoredEvent stream - SessionReducer replaces FSM semantics (no imperative state transitions) - core/transitions is a pure workflow graph evaluation engine - transitions do NOT execute runtime logic - transitions do NOT schedule or orchestrate execution - transitions only emit execution-relevant events - workflow graph is immutable and unordered (Set-based topology) - determinism is enforced by resolver, not input structure - cycle detection is analysis-only in Epic 3 (no runtime policy enforcement yet) - Event stream is the single source of truth for all system state - projections MUST NOT perform IO, side effects, or runtime clock access - createdAt/updatedAt derived strictly from EventMetadata timestamps - same event stream MUST always reconstruct identical system state ``` --- ## 5. current invariants ```text - no mutation outside store/projection boundaries - ordering is enforced at EventStore level - idempotency enforced by eventId - replay must be deterministic for identical event streams - projections are stateless deterministic reducers - projections MUST NOT depend on external mutable state - projections MUST NOT perform side effects - event sequence is authoritative ordering source - event stream is the only system truth source - session state is fully derived from replay - session state is never persisted directly - workflow execution is event-driven and replay-safe - transition evaluation must be deterministic and context-bound - workflow topology is independent from execution semantics - graph structure does not define execution order - cycles are structurally allowed but not yet policy-governed ``` --- ## 6. current task ```text Epic 4 implementation: Design and implement deterministic validation pipeline over workflow + session + transition layers. Focus areas: 1. validate workflow graph correctness (structural + cycle awareness hooks) 2. validate transition definitions (conditions + reachability consistency) 3. validate session-event consistency against workflow semantics 4. introduce ordered validation pipeline executor 5. define extension points for semantic validation rules 6. ensure validation is replay-safe and deterministic Important constraint: validation MUST NOT mutate state or trigger execution it only produces deterministic validation results over existing models ``` --- ## 7. relevant code no new core code required at bootstrap level beyond existing: ```kotlin data class WorkflowGraph( val stages: Set, val transitions: Set, val start: StageId ) { init { require(start in stages) { "start stage must exist in stages" } } } ``` ```kotlin class DefaultTransitionResolver( private val evaluator: TransitionConditionEvaluator ) : TransitionResolver { override fun resolve( graph: WorkflowGraph, context: EvaluationContext ): TransitionDecision { val outgoing = graph.transitions .asSequence() .filter { it.from == context.currentStage } .sortedWith(TransitionOrdering.comparator) .toList() for (edge in outgoing) { val result = evaluator.evaluate(edge.condition, context) if (result) { return TransitionDecision.Move( transitionId = edge.id, to = edge.to ) } } return TransitionDecision.Stay } } ``` ```kotlin class SessionProjector( private val reducer: SessionReducer ) : Projection { override fun initial(): SessionState = SessionState( status = SessionStatus.CREATED ) override fun apply( state: SessionState, event: StoredEvent ): SessionState = reducer.reduce(state, event) } ``` ```kotlin class DefaultSessionReducer : SessionReducer { override fun reduce( state: SessionState, event: StoredEvent ): SessionState { val payload = event.payload val newStatus = when (payload) { is SessionStartedEvent -> SessionStatus.ACTIVE is SessionPausedEvent -> SessionStatus.PAUSED is SessionResumedEvent -> SessionStatus.ACTIVE is SessionCompletedEvent -> SessionStatus.COMPLETED is SessionFailedEvent, is StageFailedEvent -> SessionStatus.FAILED is StageStartedEvent, is StageCompletedEvent, is TransitionExecutedEvent -> SessionStatus.ACTIVE else -> state.status } val createdAt = state.createdAt ?: event.metadata.timestamp return state.copy( status = newStatus, createdAt = createdAt, updatedAt = event.metadata.timestamp ) } } ``` ```kotlin class DefaultEventReplayer( private val store: EventStore, private val projection: Projection ) : EventReplayer { override fun rebuild(sessionId: SessionId): S { val events = store.read(sessionId) return DefaultStateBuilder(projection) .build(events) } } ``` ```kotlin internal class CycleExtractor( private val adjacencyBuilder: DeterministicAdjacencyBuilder, private val dfs: CycleDfs, ) { fun extract(graph: WorkflowGraph): List { val adjacency = adjacencyBuilder.build(graph) val state = mutableMapOf() val path = mutableListOf() val cycles = mutableListOf() val sortedNodes = graph.stages .sortedBy { it.value } for (node in sortedNodes) { if (state[node] == null) { dfs.dfs(node, adjacency, state, path, cycles) } } return canonicalize(cycles) } } ``` ---