Reference

Context and input schemas

Source SchemaReflection.cs, ContextSchema.cs

Context<T>() declares a state's context schema from a record, and WithInput<T>() a trigger's input schema. Both reflect the record when the machine is configured. The schema is the state's validator on the server and is exported in the IR; its data model is under Context schema.

JSON types

Each field's JSON type is the one System.Text.Json writes for its CLR type, so a record validates against its own camelCase JSON.

CLR typeJSON type
string, char, Guid, DateTime, DateTimeOffset, DateOnly, TimeOnly, TimeSpan, Uri, an enum without [Flags]string (an enum under JsonStringEnumConverter)
every integral type, signed or unsigned, including Int128 and UInt128integer (a number with no fractional part)
float, double, decimal, Halfnumber
boolboolean
IDictionary<K, V>, IReadOnlyDictionary<K, V>, JsonObject, a record or classobject
any other IEnumerable, JsonArrayarray, with an element-type constraint when the element is one of the scalars above

Field names

PropertyField
with [JsonPropertyName]that name
withoutits name under JsonNamingPolicy.CamelCase (PaidWith is paidWith, ID is id, URLValue is urlValue)
with [JsonIgnore]not a field
computed (get-only, never set on read)not an input field; a client sending one is refused as an unknown field

Constraints

SourceConstraint
[MinLength(1)] (or more) on a string or a collectionnon-empty
[MaxLength(n)] on a string or a collectionlength or count at most n, checked when the value is present (a Length or Count rule with LessOrEqual)
an integral typeits CLR range: an int field refuses 1e10. An integer within one double step of a 64-bit (or wider) type's end is refused too, since an engine reading numbers as doubles cannot tell it from one past the end.
a dictionary's values, a list's elementschecked against their own type: a Dictionary<string, int> refuses {"a": "one"}
a nullable annotation (string?) or nullable value type (int?)the field may be null

The full constraint set (formats, enum names, dictionary keys) is listed under the IR format.

Depth

SchemaDescribed
A context (Context<T>())one level deep
A trigger input (WithInput<T>()) and an invoked train's outputas strictly as the CLR type: a nested record and the elements of a list of records carry their own field shapes

Both engines refuse a trigger input that does not match its schema as INVALID_INPUT, before any guard reads it. A trigger declared without WithInput takes no input. See Trigger input.

Refusals

Context<T>() and WithInput<T>() throw InvalidOperationException, naming the property, when the machine is configured, for:

Property or typeReason
a property with no fixed JSON type: object, JsonNode, JsonElement, BigInteger, a delegateits values would not match any one JSON type
a [Flags] enumuse a list of an enum without [Flags]
a record that contains itselfit has no finite shape

A state whose context cannot be described this way is validated with Holds(...), which makes the machine non-exportable, or with a custom rule (Rule.Custom), which keeps it exportable.

See also