package com.correx.core.events.events

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

/**
 * A validated failure→fix pattern the heuristic concept compiler has seen resolved reliably enough to
 * promote (design 2026-07-12-acr-concept-compiler.md). The only "write" the compiler makes: a
 * deterministic rule firing — a [fingerprint] whose validated-fix count crossed the promotion
 * threshold, never contradicted — so it needs no assessor gate (invariant #3/#7 hold trivially:
 * nothing model-proposed reaches state here).
 *
 * Read-only over the log otherwise: the promotion is derivable from the RetryAttempted→StageCompleted
 * stream, and this event makes the promotion idempotent under replay (the compiler folds already-emitted
 * fingerprints into its promoted set and never re-promotes). Best-effort injected into L3 as a
 * retrieval-on-demand concept; the L3 write is non-authoritative (invariant #6) — this event is truth.
 */
@Serializable
@SerialName("ConceptPromoted")
data class ConceptPromotedEvent(
    // A dedicated system session (ConceptCompilerService.SYSTEM_SESSION) — concepts are cross-session,
    // so they live on their own stream rather than polluting any user session's replay.
    val sessionId: SessionId,
    // Gate-agnostic fingerprint of the recurring failure (see FailureFingerprint) — the last-seen
    // instance, used as the L3 instance-recall id.
    val fingerprint: String,
    // Reusable class key `gate + normalized(signature)` the concept is promoted on (design §"class key").
    // Defaulted for back-compat with v1 events that predate class-key promotion.
    val classKey: String = "",
    // The gate the failure recurred on ("contract" | "review" | "plan-compile" | "lint" | "static" | …).
    val gate: String,
    // Templated, retrieval-friendly concept text injected into L3.
    val conceptText: String,
    // Count of validated fixes observed at promotion time (≥ threshold).
    val occurrences: Int,
    // Reference to the validated fix: the CAS path + post-image hash of the file the resolving stage
    // wrote to clear this failure (design 2026-07-12-acr-concept-compiler.md §"carry the fix").
    // Null when no file write was observed between the retry and the completion. Additive/back-compat.
    val fixPath: String? = null,
    val fixHash: String? = null,
) : EventPayload
