feat(transitions): tasks_ready predicate for execution loop
New TasksReady condition driven by EvaluationContext.readyTaskCount, fed at resolve time via a kernel-declared ReadyTaskCounter interface implemented in apps/server over TaskService (keeps core:kernel decoupled from core:tasks). Loops a graph while ready>0, exits at 0.
This commit is contained in:
@@ -368,6 +368,7 @@ fun main() {
|
||||
compactionService = journalCompactionService,
|
||||
artifactKindRegistry = artifactKindRegistry,
|
||||
repoKnowledgeRetriever = repoKnowledgeRetriever,
|
||||
readyTaskCounter = com.correx.apps.server.tasks.ProjectReadyTaskCounter(eventStore, taskService),
|
||||
)
|
||||
val workflowRegistry = FileSystemWorkflowRegistry(
|
||||
InfrastructureModule.createWorkflowLoader(configArtifactKindsEarly),
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.correx.apps.server.tasks
|
||||
|
||||
import com.correx.core.approvals.ProjectIdentity
|
||||
import com.correx.core.events.events.SessionWorkspaceBoundEvent
|
||||
import com.correx.core.events.stores.EventStore
|
||||
import com.correx.core.events.types.SessionId
|
||||
import com.correx.core.kernel.orchestration.ReadyTaskCounter
|
||||
import com.correx.core.tasks.TaskService
|
||||
|
||||
/**
|
||||
* [ReadyTaskCounter] over the task projection. Resolves the session to its project the same way the
|
||||
* approval gate does (bound workspace root → [ProjectIdentity.of]) and counts the ready tasks there.
|
||||
* Pure read over event-derived state, so it stays replay-safe.
|
||||
*
|
||||
* Caveat for the execution loop: tasks are keyed by whatever `project` string the decomposer passes
|
||||
* to task tools; this counts the project derived from the workspace root. Those must agree for the
|
||||
* loop predicate to fire — Slice 2/4 pins that down.
|
||||
*/
|
||||
class ProjectReadyTaskCounter(
|
||||
private val eventStore: EventStore,
|
||||
private val taskService: TaskService,
|
||||
) : ReadyTaskCounter {
|
||||
override fun count(sessionId: SessionId): Int {
|
||||
val workspaceRoot = eventStore.read(sessionId)
|
||||
.mapNotNull { it.payload as? SessionWorkspaceBoundEvent }
|
||||
.lastOrNull()
|
||||
?.workspaceRoot
|
||||
?: return 0
|
||||
return taskService.ready(ProjectIdentity.of(workspaceRoot)).size
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user