feat(cas): content-addressed artifact store (steps 1–8)
New core:artifacts-store interface + infrastructure/artifacts-cas implementation: segment files + SQLite index, Blake3 hashing, group-commit fsync via flushBefore, recovery tail-scan, manual compactor, and oldest-first disk-cap evictor. Inference events now carry promptArtifactId / responseArtifactId; orchestrators put bytes before emitting. SqliteEventStore wraps its txn in artifactStore.flushBefore so segment data is fsynced before the event commit, making the crash window non-corrupting (TailScanner re-indexes orphan tail records on reopen). Compactor and evictor are mutually exclusive via maintenanceMutex. Step 9 (cloud sync) deferred to a later epic. See docs/reviews/2026-05-18-cas-steps-1-8-review.md for the final review.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package com.correx.infrastructure
|
||||
|
||||
import com.correx.core.approvals.domain.ApprovalEngine
|
||||
import com.correx.core.artifactstore.ArtifactStore
|
||||
import com.correx.core.events.EventDispatcher
|
||||
import com.correx.core.events.stores.EventStore
|
||||
import com.correx.core.inference.DefaultInferenceRouter
|
||||
@@ -17,6 +18,10 @@ import com.correx.infrastructure.inference.commons.ModelManager
|
||||
import com.correx.infrastructure.inference.commons.ResidencyMode
|
||||
import com.correx.infrastructure.inference.llama.cpp.DefaultModelManager
|
||||
import com.correx.infrastructure.inference.llama.cpp.LlamaCppInferenceProvider
|
||||
import com.correx.infrastructure.artifactscas.CasArtifactStore
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import com.correx.infrastructure.artifactscas.config.CasConfig
|
||||
import com.correx.infrastructure.artifactscas.index.SqliteArtifactIndex
|
||||
import com.correx.infrastructure.persistence.SqliteEventStore
|
||||
import com.correx.infrastructure.tools.DefaultToolRegistry
|
||||
import com.correx.infrastructure.tools.DispatchingToolExecutor
|
||||
@@ -31,17 +36,32 @@ import com.correx.infrastructure.persistence.artifact.LiveArtifactRepository
|
||||
import com.correx.core.artifacts.repository.ArtifactRepository
|
||||
import com.correx.core.artifacts.DefaultArtifactReducer
|
||||
import io.ktor.client.HttpClient
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
import java.sql.DriverManager
|
||||
|
||||
@Suppress("TooManyFunctions")
|
||||
object InfrastructureModule {
|
||||
private val defaultDbPath: String =
|
||||
"${System.getProperty("user.home")}/.config/correx/correx.db"
|
||||
|
||||
fun createEventStore(dbPath: String = defaultDbPath): EventStore {
|
||||
private val defaultArtifactsRoot: String =
|
||||
"${System.getProperty("user.home")}/.config/correx/artifacts"
|
||||
|
||||
fun createEventStore(artifactStore: ArtifactStore, dbPath: String = defaultDbPath): EventStore {
|
||||
val dir = java.io.File(dbPath).parentFile
|
||||
if (!dir.exists()) dir.mkdirs()
|
||||
return SqliteEventStore(DriverManager.getConnection("jdbc:sqlite:$dbPath"))
|
||||
return SqliteEventStore(
|
||||
connection = DriverManager.getConnection("jdbc:sqlite:$dbPath"),
|
||||
artifactStore = artifactStore,
|
||||
)
|
||||
}
|
||||
|
||||
fun createArtifactStore(rootDir: Path = Paths.get(defaultArtifactsRoot)): ArtifactStore {
|
||||
Files.createDirectories(rootDir)
|
||||
val index = SqliteArtifactIndex(rootDir.resolve("index.sqlite"))
|
||||
return runBlocking { CasArtifactStore.open(CasConfig(rootDir), index) }
|
||||
}
|
||||
|
||||
fun createModelManager(
|
||||
|
||||
Reference in New Issue
Block a user