epic-12: after epic audit and init commit

This commit is contained in:
2026-05-16 11:42:00 +04:00
commit c77277af0b
461 changed files with 28958 additions and 0 deletions
+413
View File
@@ -0,0 +1,413 @@
# 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<StageId>,
val transitions: Set<TransitionEdge>,
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<SessionState> {
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<S>(
private val store: EventStore,
private val projection: Projection<S>
) : EventReplayer<S> {
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<DetectedCycle> {
val adjacency = adjacencyBuilder.build(graph)
val state = mutableMapOf<StageId, VisitState>()
val path = mutableListOf<StageId>()
val cycles = mutableListOf<DetectedCycle>()
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)
}
}
```
---