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

/** The outcome of one operator-configured static-analysis command run against a stage's output. */
@Serializable
data class StaticAnalysisFinding(
    val command: String,
    val exitCode: Int,
    /**
     * Truncated tail of the command's combined stdout+stderr. The full output is fed back to the
     * model verbatim at runtime but is not retained in the log — the tail carries the error summary
     * and keeps the event bounded.
     */
    val summary: String,
) {
    val clean: Boolean get() = exitCode == 0
}

/**
 * Environment observation (invariant #9): the static-analysis commands (compiler / detekt /
 * formatters) a stage ran against its just-produced output, each with its exit code and a truncated
 * output tail, captured at the moment the stage completed. Replay reads these recorded facts and
 * never re-runs the commands.
 *
 * Realizes role-reliability §5 "static-first ordering": deterministic tools run before the LLM
 * reviewer. A non-clean finding fails the producing stage retryably (the output is fed back so the
 * implementer fixes it), so only static-clean output ever reaches the reviewer — its context thereby
 * excludes anything static tools already catch, with no parsing or context plumbing.
 */
@Serializable
@SerialName("StaticAnalysisCompleted")
data class StaticAnalysisCompletedEvent(
    val sessionId: SessionId,
    val stageId: StageId,
    val findings: List<StaticAnalysisFinding>,
) : EventPayload
