Skip to main content
Contracts accept only the sentences on this page. Unknown sentences, Cucumber scenarios, tags, tables and trailing text are errors.

Structure

  • Feature is required: letters, digits and underscores.
  • Version defaults to 1. Raise it every time you publish an update.
  • Include, Background, Step blocks and Group blocks are optional.
  • Every step needs exactly one Rule. Groups come after the rules.
Metadata (Feature, Version, Description, Include) comes first. A rule starts with When, then one Then clause, then any number of And clauses. Blank lines and whole-line # comments are allowed; comments after a clause are not. Quoted values use double quotes, with \" and \\ as escapes.

Step blocks

  • Description is required in a Step block. Without a Step block, the rule’s title is used as the description.
  • Add one context line per field. means "..." is optional.
  • A step with no declared context has no fields available to its rules. Extra fields you send are stored with the step but aren’t used in checks.
  • Declaring a field twice, or as both required and optional, is an error.

Step clauses

Once any rule uses next step must be one of, the whole contract uses strict transitions: list every allowed immediate move. Durations use ms, s, m, h or d.

Content clauses

Content clauses check the context sent with the step. Values are compared as strings, and dotted names such as "order.id" are literal field names, not nested paths. A content clause makes its field required. You can’t put one on a field declared as optional.

Regular expressions

Patterns use RE2 syntax (as in Go). A pattern matches anywhere in the value unless you anchor it with ^ and $. Flags such as (?i) work; lookarounds and backreferences don’t. Inside quotes, double your backslashes ("^\\d+$"), or use character classes like [0-9] instead. Invalid patterns are rejected when you preview or publish.

Values from earlier steps

An unquoted step.field on the right of must equal reads a field from an earlier step in the same thread:
  • It reads the most recent successful, validated order_shipped. Failed or violated attempts are ignored.
  • It also makes order_shipped a prerequisite.
  • If that step hasn’t succeeded yet, or the field is missing, the submission is rejected. Threadify doesn’t fall back to an older value.
  • Values must match exactly: "1.00" and "1" are different.
  • A quoted "order_shipped.tracking_number" is plain text, not a reference.

Thread-wide rules

Put these in a Background block before the rules. All are optional.
multiple terminal severity accepts minor, warning, major or error.

Parallel groups

A group needs at least two different steps, each with its own rule. Its name can’t match a step or another group. Only the first line is required. A group doesn’t make later steps wait for its members; add must have succeeded clauses for that.

Reuse a contract

Include pulls in the steps and rules of a contract you’ve already published:
  • Name a specific version. Later changes to the included contract don’t affect versions that already include it.
  • Step and group names must be unique across the combined contract.
  • Your own entry and terminal steps take priority over the included ones.
  • Preview rejects combinations that can’t work, such as two content rules no value can satisfy, or a step that can never be reached.
  • A contract can include up to 16 contracts and 512 steps in total.