Files

414 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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)
}
}
```
---