package com.correx.core.events.events

import com.correx.core.events.types.SessionId
import com.correx.core.events.types.StageId
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
@SerialName("SteeringNoteAdded")
data class SteeringNoteAddedEvent(
    val sessionId: SessionId,
    val content: String,
    val stageId: StageId? = null,
) : EventPayload

/**
 * One entry in a [ContextAssembledEvent] manifest. Mirrors the identifying fields of
 * core:context's ContextEntry (sourceType, sourceId, tokenEstimate, layer, role) but NEVER the
 * content — content is a derived projection of the event log (reproducible on replay, see
 * invariant #9 / #6) and already lives in CAS via the prompt artifact. This is manifest-only,
 * for auditing what got injected without decoding CAS.
 */
@Serializable
data class ContextManifestEntry(
    val sourceType: String,
    val sourceId: String,
    val tokenEstimate: Int,
    val layer: String,
    val role: String,
)

/**
 * Records the manifest of entries injected into a stage's initial context build (#307). Emitted
 * once per [core.context.builder.ContextPackBuilder]-produced ContextPack, from the entries that
 * actually made it into the pack (post budget/truncation) — the same set that
 * [ContextTruncatedEvent] reports drops against. Purely observational: the hints themselves stay
 * unevented derived projections; this only names what was fed to the model, so an operator can
 * answer "did entry X fire in session Y" from the event log instead of CAS-spelunking.
 */
@Serializable
@SerialName("ContextAssembled")
data class ContextAssembledEvent(
    val sessionId: SessionId,
    val stageId: StageId,
    val contextPackId: String,
    val entries: List<ContextManifestEntry>,
    val timestampMs: Long,
) : EventPayload
