CHR0018: Constraint Define() must not contain imperative code
Rule Description
Section titled “Rule Description”The Define() method of a class implementing IConstraint must not contain imperative statements such as if/else, loops, variable declarations, or assignments. Constraint definitions only declare rules; they do not execute.
Severity
Section titled “Severity”Error
Example
Section titled “Example”Violation
Section titled “Violation”using Cratis.Chronicle.Events;using Cratis.Chronicle.Events.Constraints;
[EventType]public record Chr0018UserRegistered;
public class Chr0018UniqueEmailConstraint : IConstraint{ public bool SomeCondition { get; init; }
// CHR0018: Define must not contain conditional logic public void Define(IConstraintBuilder builder) { if (SomeCondition) { builder.Unique<Chr0018UserRegistered>(); } }}using Cratis.Chronicle.Events;using Cratis.Chronicle.Events.Constraints;
[EventType]public record Chr0018UserRegisteredFixed;
public class Chr0018UniqueEmailConstraintFixed : IConstraint{ // Now valid - unconditional public void Define(IConstraintBuilder builder) => builder.Unique<Chr0018UserRegisteredFixed>();}Why This Rule Exists
Section titled “Why This Rule Exists”The Define() method is called once at registration time to declare constraint rules. The resulting definition is serialized and sent to the server. Imperative code such as conditionals or loops creates non-determinism: different runs could produce different constraint definitions, breaking consistency.