feat(journal): ProjectMemoryDistiller — pure repo-scoped decision distillation
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
package com.correx.core.journal
|
||||
|
||||
import com.correx.core.journal.model.DecisionJournalState
|
||||
|
||||
/**
|
||||
* Distils a decision journal into durable, repo-scoped memory lines for persistence to the
|
||||
* cross-session L3 store. Pure transform (no I/O) so `core:journal` stays dependent only on
|
||||
* `core:events`; the actual L3 upsert/retrieve lives in the wiring layer that owns the store.
|
||||
*
|
||||
* Each line is namespaced by [repoRoot] so retrieval can attribute a decision to its project.
|
||||
*/
|
||||
class ProjectMemoryDistiller(private val keepLast: Int = 40) {
|
||||
fun distill(state: DecisionJournalState, repoRoot: String): List<String> =
|
||||
state.records.takeLast(keepLast).map { "[$repoRoot] [${it.kind}] ${it.summary}" }
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import com.correx.core.journal.ProjectMemoryDistiller
|
||||
import com.correx.core.journal.model.DecisionJournalState
|
||||
import com.correx.core.journal.model.DecisionKind
|
||||
import com.correx.core.journal.model.DecisionRecord
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class ProjectMemoryDistillerTest {
|
||||
|
||||
@Test
|
||||
fun `distils records into repo-namespaced lines`() {
|
||||
val state = DecisionJournalState(
|
||||
records = listOf(
|
||||
DecisionRecord(1, DecisionKind.STEERING, "User steering: use jwt"),
|
||||
DecisionRecord(2, DecisionKind.TRANSITION, "Advanced plan → impl (t1)"),
|
||||
),
|
||||
)
|
||||
val lines = ProjectMemoryDistiller().distill(state, "/home/me/repo")
|
||||
|
||||
assertEquals(2, lines.size)
|
||||
assertEquals("[/home/me/repo] [STEERING] User steering: use jwt", lines[0])
|
||||
assertTrue(lines[1].startsWith("[/home/me/repo] [TRANSITION]"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `keepLast bounds the distilled output`() {
|
||||
val records = (1..50).map { DecisionRecord(it.toLong(), DecisionKind.ARTIFACT, "v$it") }
|
||||
val lines = ProjectMemoryDistiller(keepLast = 10).distill(DecisionJournalState(records), "/r")
|
||||
|
||||
assertEquals(10, lines.size)
|
||||
assertTrue(lines.last().contains("v50"))
|
||||
assertTrue(lines.first().contains("v41"))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user