feat(events): RepoMapComputedEvent as recorded environment observation
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
package com.correx.core.events.events
|
||||
|
||||
import com.correx.core.events.types.SessionId
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/** A single ranked entry in a repo map: a path, its relevance [score], and symbol names. */
|
||||
@Serializable
|
||||
data class RepoMapEntry(
|
||||
val path: String,
|
||||
val score: Double,
|
||||
val symbols: List<String> = emptyList(),
|
||||
)
|
||||
|
||||
/**
|
||||
* Environment observation (invariant #9): the repo map computed once at the moment it ran.
|
||||
* Replay reads these recorded facts and never re-scans the filesystem. Paths + symbol names
|
||||
* only — never file bodies — so it is referenced, not inlined.
|
||||
*/
|
||||
@Serializable
|
||||
@SerialName("RepoMapComputed")
|
||||
data class RepoMapComputedEvent(
|
||||
val sessionId: SessionId,
|
||||
val repoRoot: String,
|
||||
val entries: List<RepoMapEntry>,
|
||||
val computedAt: Instant,
|
||||
) : EventPayload
|
||||
@@ -24,6 +24,7 @@ import com.correx.core.events.events.ModelUnloadedEvent
|
||||
import com.correx.core.events.events.OrchestrationPausedEvent
|
||||
import com.correx.core.events.events.OrchestrationResumedEvent
|
||||
import com.correx.core.events.events.RefinementIterationEvent
|
||||
import com.correx.core.events.events.RepoMapComputedEvent
|
||||
import com.correx.core.events.events.RetryAttemptedEvent
|
||||
import com.correx.core.events.events.RiskAssessedEvent
|
||||
import com.correx.core.events.events.StageCompletedEvent
|
||||
@@ -80,6 +81,7 @@ val eventModule = SerializersModule {
|
||||
subclass(WorkflowCompletedEvent::class)
|
||||
subclass(RetryAttemptedEvent::class)
|
||||
subclass(RefinementIterationEvent::class)
|
||||
subclass(RepoMapComputedEvent::class)
|
||||
subclass(RiskAssessedEvent::class)
|
||||
subclass(ChatSessionStartedEvent::class)
|
||||
subclass(ChatTurnEvent::class)
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import com.correx.core.events.events.EventMetadata
|
||||
import com.correx.core.events.events.NewEvent
|
||||
import com.correx.core.events.events.RepoMapComputedEvent
|
||||
import com.correx.core.events.events.RepoMapEntry
|
||||
import com.correx.core.events.events.StoredEvent
|
||||
import com.correx.core.events.types.EventId
|
||||
import com.correx.core.events.types.SessionId
|
||||
import com.correx.core.sessions.projections.Projection
|
||||
import com.correx.core.sessions.projections.replay.DefaultEventReplayer
|
||||
import com.correx.infrastructure.persistence.InMemoryEventStore
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.datetime.Instant
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
/** Collects the latest recorded repo map purely from events — never touches the filesystem. */
|
||||
private class RepoMapProjection : Projection<List<RepoMapEntry>> {
|
||||
override fun initial(): List<RepoMapEntry> = emptyList()
|
||||
override fun apply(state: List<RepoMapEntry>, event: StoredEvent): List<RepoMapEntry> =
|
||||
when (val p = event.payload) {
|
||||
is RepoMapComputedEvent -> p.entries
|
||||
else -> state
|
||||
}
|
||||
}
|
||||
|
||||
class RepoMapReplayTest {
|
||||
|
||||
@Test
|
||||
fun `repo map is reconstructed from the recorded event without re-scanning`(): Unit = runBlocking {
|
||||
val sessionId = SessionId("s")
|
||||
val store = InMemoryEventStore()
|
||||
val entries = listOf(
|
||||
RepoMapEntry("src/Main.kt", 0.9, listOf("main", "boot")),
|
||||
RepoMapEntry("src/Util.kt", 0.4, listOf("clamp")),
|
||||
)
|
||||
store.append(
|
||||
NewEvent(
|
||||
EventMetadata(EventId("rm"), sessionId, Instant.parse("2026-06-04T00:00:00Z"), 1, null, null),
|
||||
RepoMapComputedEvent(sessionId, "/repo", entries, Instant.parse("2026-06-04T00:00:00Z")),
|
||||
),
|
||||
)
|
||||
|
||||
val rebuilt = DefaultEventReplayer(store, RepoMapProjection()).rebuild(sessionId)
|
||||
|
||||
assertEquals(entries, rebuilt)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user