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:
2026-06-29 00:45:33 +04:00
parent d26f20c316
commit c1e4c7b25e
14 changed files with 164 additions and 1 deletions
@@ -10,6 +10,7 @@ import com.correx.core.transitions.conditions.ArtifactPresent
import com.correx.core.transitions.conditions.ArtifactValidated
import com.correx.core.transitions.conditions.FieldOperator
import com.correx.core.transitions.conditions.Not
import com.correx.core.transitions.conditions.TasksReady
import com.correx.core.transitions.conditions.VariableEquals
import com.correx.core.transitions.graph.TransitionCondition
@@ -20,6 +21,7 @@ fun ConditionSpec.toCondition(): TransitionCondition = when (type) {
"artifact_validated" -> buildArtifactValidated()
"variable_equals" -> buildVariableEquals()
"artifact_field_equals" -> buildArtifactFieldEquals()
"tasks_ready" -> TasksReady
"all_of" -> AllOf(conditions.map { it.toCondition() })
"any_of" -> AnyOf(conditions.map { it.toCondition() })
"not" -> Not((condition ?: error("condition required for not")).toCondition())
@@ -0,0 +1,19 @@
package com.correx.infrastructure.workflow
import com.correx.core.transitions.conditions.TasksReady
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import kotlin.test.assertSame
class ConditionFactoryTest {
@Test
fun `tasks_ready maps to TasksReady`() {
assertSame(TasksReady, ConditionSpec(type = "tasks_ready").toCondition())
}
@Test
fun `unknown type rejected`() {
assertThrows<WorkflowValidationException> { ConditionSpec(type = "nope").toCondition() }
}
}