feat(server,kernel): bind ProjectProfile per session and inject as L0 context

This commit is contained in:
2026-06-10 21:49:31 +04:00
parent 4389163c5c
commit 91cca9aee3
4 changed files with 111 additions and 2 deletions
@@ -11,10 +11,12 @@ import com.correx.core.approvals.DefaultApprovalReducer
import com.correx.core.approvals.DefaultApprovalRepository
import com.correx.core.artifactstore.ArtifactStore
import com.correx.core.config.OperatorProfile
import com.correx.core.config.ProjectProfileLoader
import com.correx.core.events.events.ApprovalRequestedEvent
import com.correx.core.events.events.EventMetadata
import com.correx.core.events.events.NewEvent
import com.correx.core.events.events.OperatorProfileBoundEvent
import com.correx.core.events.events.ProjectProfileBoundEvent
import com.correx.core.events.events.OrchestrationResumedEvent
import com.correx.core.events.events.WorkflowFailedEvent
import com.correx.core.events.stores.EventStore
@@ -217,6 +219,35 @@ class ServerModule(
),
)
}
// Bind the per-repo project profile (curated .correx/project.toml) as an event so
// stages and replay read the recorded snapshot, never the live file (invariants #8/#9).
val workspaceRoot = runCatching {
sessionRepository.getSession(sessionId).state.boundWorkspace?.workspaceRoot
}.getOrNull() ?: projectMemory?.repoRoot()
workspaceRoot?.let { root ->
val projectProfile = ProjectProfileLoader.load(root)
if (!projectProfile.isEmpty()) {
eventStore.append(
NewEvent(
metadata = EventMetadata(
eventId = EventId(java.util.UUID.randomUUID().toString()),
sessionId = sessionId,
timestamp = Clock.System.now(),
schemaVersion = 1,
causationId = null,
correlationId = null,
),
payload = ProjectProfileBoundEvent(
sessionId = sessionId,
workspaceRoot = root,
about = projectProfile.about,
conventions = projectProfile.conventions,
commands = projectProfile.commands,
),
),
)
}
}
runCatching {
orchestrator.run(sessionId, graph, sessionConfig)
// After a successful freestyle planning run, lock the plan and execute phase 2.