@startuml
package "core:events" {
  interface EventPayload

  abstract class NewEvent {
    + metadata: EventMetadata
    + payload: EventPayload
  }

  abstract class StoredEvent {
    + metadata: EventMetadata
    + sequence: Long
    + sessionSequence: Long
    + payload: EventPayload
  }

  class EventMetadata {
    + eventId: EventId
    + sessionId: SessionId
    + timestamp: Instant
    + schemaVersion: Int
    + causationId: CausationId?
    + correlationId: CorrelationId?
  }

  interface EventStore {
    + append(NewEvent): StoredEvent
    + read(SessionId): List<StoredEvent>
    + subscribe(SessionId): Flow<StoredEvent>
  }

  class EventDispatcher {
    + emit(EventPayload, SessionId, ...)
  }

  interface EventSerializer {
    + serialize(EventPayload): String
    + deserialize(String): EventPayload
  }

  class JsonEventSerializer

  interface Projection<S> {
    + initial(): S
    + apply(S, StoredEvent): S
  }

  interface StateBuilder<S> {
    + build(List<StoredEvent>): S
  }

  class DefaultStateBuilder<S>

  interface EventReplayer<S> {
    + rebuild(SessionId): S
  }

  class DefaultEventReplayer<S>

  EventPayload <|.. SessionStartedEvent
  EventPayload <|.. SessionPausedEvent
  EventPayload <|.. WorkflowStartedEvent
  EventPayload <|.. WorkflowCompletedEvent
  EventPayload <|.. StageStartedEvent
  EventPayload <|.. StageCompletedEvent
  EventPayload <|.. TransitionExecutedEvent
  EventPayload <|.. InferenceStartedEvent
  EventPayload <|.. InferenceCompletedEvent
  EventPayload <|.. ToolInvocationRequestedEvent
  EventPayload <|.. ApprovalRequestedEvent
  EventPayload <|.. ApprovalDecisionResolvedEvent
  EventPayload <|.. ArtifactCreatedEvent
  EventPayload <|.. ArtifactValidatedEvent
  EventPayload <|.. RiskAssessedEvent
  EventPayload <|.. ContextPackBuiltEvent
  EventPayload <|.. OrchestrationPausedEvent
  EventPayload <|.. OrchestrationResumedEvent
  EventPayload <|.. RetryAttemptedEvent

  NewEvent *-- EventMetadata
  NewEvent *-- EventPayload
  StoredEvent *-- EventMetadata
  StoredEvent *-- EventPayload
  EventDispatcher --> EventStore
  EventDispatcher ..> NewEvent : creates

  DefaultStateBuilder --> Projection
  DefaultEventReplayer --> EventStore
  DefaultEventReplayer --> DefaultStateBuilder

  JsonEventSerializer ..|> EventSerializer
  JsonEventSerializer --> eventJson

  note right of EventPayload : 35+ concrete subtypes\nregistered in polymorphic block
}

package "shared types" {
  value class TypeId
  enum Tier
  enum RiskLevel
  enum RiskAction
  sealed interface ApprovalStatus
  enum ApprovalOutcome
  sealed interface GrantScope
  data class RetryPolicy
  data class TokenUsage
}

TypeId <|.. SessionId
TypeId <|.. StageId
TypeId <|.. EventId
TypeId <|.. ArtifactId

@enduml
