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