refactor: merge cycle policy into semantic validation layer
Wire SemanticValidator into the production validator pipeline and consolidate cycle-policy types under core:validation. - Add SemanticValidator(CycleExitRule(requirePolicyForCycles=false)) to the prod ValidationPipeline (no-op default, preserves behavior) - Move CyclePolicy/Binding/Signature/Factory from core:transitions.policy to core:validation.policy (validation already owns ValidationContext) - Rename CyclePolicyBindingRule -> CycleExitRule (issue code unchanged) - Delete dead CyclePolicyResolver + PolicyValidation
This commit is contained in:
@@ -10,7 +10,7 @@ import com.correx.core.validation.model.ValidationContext
|
||||
import com.correx.core.validation.pipeline.ValidationOutcome
|
||||
import com.correx.core.validation.pipeline.ValidationPipeline
|
||||
import com.correx.core.validation.semantic.SemanticValidator
|
||||
import com.correx.core.validation.semantic.rules.CyclePolicyBindingRule
|
||||
import com.correx.core.validation.semantic.rules.CycleExitRule
|
||||
import com.correx.core.validation.transition.TransitionValidator
|
||||
import com.correx.testing.fixtures.CycleFixtures
|
||||
import com.correx.testing.fixtures.WorkflowFixtures
|
||||
@@ -27,7 +27,7 @@ class ValidationPipelineIntegrationTest {
|
||||
TransitionValidator(TransitionOrdering.comparator),
|
||||
SemanticValidator(
|
||||
rules = listOf(
|
||||
CyclePolicyBindingRule(requirePolicyForCycles = true),
|
||||
CycleExitRule(requirePolicyForCycles = true),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -70,4 +70,35 @@ class ValidationPipelineIntegrationTest {
|
||||
assertInstanceOf(ValidationOutcome.Rejected::class.java, outcome)
|
||||
assertFalse((outcome as ValidationOutcome.Rejected).retryable)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `SemanticValidator with requirePolicyForCycles = false ignores unbound cycles`(): Unit = runBlocking {
|
||||
// Verify that when requirePolicyForCycles is false, SemanticValidator returns no issues
|
||||
// even if there are unbound cycles. This is the production default behavior.
|
||||
val graph = WorkflowFixtures.simpleGraph()
|
||||
val cycles = listOf(CycleFixtures.simpleCycle())
|
||||
|
||||
val pipelineWithFalseFlagValidator = ValidationPipeline(
|
||||
validators = listOf(
|
||||
SemanticValidator(
|
||||
rules = listOf(
|
||||
CycleExitRule(requirePolicyForCycles = false),
|
||||
),
|
||||
),
|
||||
),
|
||||
approvalTrigger = null
|
||||
)
|
||||
|
||||
val context = ValidationContext(
|
||||
graph = graph,
|
||||
detectedCycles = cycles,
|
||||
cyclePolicies = emptySet(),
|
||||
)
|
||||
|
||||
val outcome = pipelineWithFalseFlagValidator.validate(context)
|
||||
|
||||
// With requirePolicyForCycles = false, the rule returns no issues,
|
||||
// so the outcome should be Passed (not NeedsApproval).
|
||||
assertInstanceOf(ValidationOutcome.Passed::class.java, outcome)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user