Declarative data model

The Rules vocabulary is sugar over these types. You rarely construct them by hand, but they are what a declarative machine records and what the IR carries, so this is the reference for reading an export or writing a generator.

Rule

A guard or a field constraint, as data. abstract record Rule with these cases:

CaseFieldsHolds when
PresentSource, Fieldthe field exists and is not null
AbsentSource, Fieldthe field is missing or null
OfTypeSource, Field, Typethe field is present and of Type
NonEmptySource, Fielda non-empty string or array
OneOfSource, Field, Valuesa string equal to one of Values
CompareSource, Field, Op, Value (double)a number in the Op relation to Value
CountSource, Field, Op, Value (int)an array whose length is in the Op relation to Value
LengthSource, Field, Op, Value (int)a string whose length is in the Op relation to Value
BoolEqualsSource, Field, Value (bool)a boolean field equals Value
ArrayOfSource, Field, ElementTypean array whose every element is of ElementType
AllRulesevery sub-rule holds (empty is true)
AnyRulesat least one sub-rule holds (empty is false)
CustomNamethe handler bound with CustomGuard(name, fn) resolves it (the escape hatch)

Evaluation is total: RuleEvaluator returns false for a missing or wrong-typed field, never an exception. A Custom name with no handler in the map is also false, but a machine built with MachineBuilder cannot reach that case: Build() refuses a custom name that has no handler bound.

Reduction

How a transition computes the destination context, as data. abstract record Reduction:

CaseFieldsProduces
Keepthe current context, unchanged
Clearan empty context
Resetthe machine's initial context
SetStepsa clone of the context with each SetStep applied
CustomNamethe result of the handler bound with CustomReducer(name, fn)

ReductionEvaluator always returns a fresh JsonObject; it never mutates the inputs.

SetStep and ValueSource

A Set carries one or more SetStep(string Field, ValueSource Source). ValueSource is where the value comes from:

CaseFieldsValue
FromInputFieldthe named field copied from the trigger input
ConstantValue (JsonNode?)a literal

Context schema

Reflected from a context record and carried in the IR.

TypeFieldsMeaning
ContextSchemaFieldsthe state's fields, sorted by key (ordinal) to match the canonical wire; ContextSchema.Empty is a state with no context
FieldSchemaName, Type, Nullable, Constraintsone field: its JSON key, JSON type, whether it may be null, and any Rule constraints (e.g. non-empty from [MinLength(1)])

Enums

EnumValues
RuleSourceContext, Input
JsonFieldTypeString, Number, Boolean, Array, Object
CompareOpGreaterThan, GreaterOrEqual, LessThan, LessOrEqual, EqualTo