Appearance
Rule Catalog
This is the lookup table for canonical rules. Each entry gives the seeded slug, the canonical rule id, the human-readable name, and the exact expression — copy the expression as written.
The shape of a step-pattern rule
Every step-pattern rule in this catalog is built from the same three clauses:
current_value > 0 AND formula = N AND digitBefore IN (d1, d2, …)| Clause | Meaning |
|---|---|
current_value > 0 | The operation is an addition. Subtraction rules use current_value < 0 instead. |
formula = N | The normalized formula digit is N. |
digitBefore IN (…) | The digit of the running total at the affected place must be one of the listed values. |
Because formula normalizes the operand and digitBefore looks at a single digit place, these expressions are place-independent: one expression matches the pattern at the ones place, the tens place, the hundreds place, and beyond. Both +8 and +80 have formula = 8. See decimal places for how formula and digitBefore are derived, and functions for their full definitions.
The four step-pattern families partition every atomic step: a step crosses the 5-boundary (Rule 5), the 10-boundary (Rule 10), both (Combo), or neither (Plain).
Rule 5
The operation crosses or reaches the 5-boundary within a single digit place, with no carry into the next place. Adding pushes the digit from the lower half-decade (0–4) up to or past 5; subtracting brings it back down through 5. Applies to formulas 1–4 only — larger formulas cannot cross 5 without also crossing 10.
Addition
| Slug | Rule ID | Name | Expression |
|---|---|---|---|
RULE-1 | rule-5:1:add | Rule 5 (1) - Addition | current_value > 0 AND formula = 1 AND digitBefore IN (4) |
RULE-2 | rule-5:2:add | Rule 5 (2) - Addition | current_value > 0 AND formula = 2 AND digitBefore IN (3, 4) |
RULE-3 | rule-5:3:add | Rule 5 (3) - Addition | current_value > 0 AND formula = 3 AND digitBefore IN (2, 3, 4) |
RULE-4 | rule-5:4:add | Rule 5 (4) - Addition | current_value > 0 AND formula = 4 AND digitBefore IN (1, 2, 3, 4) |
Subtraction
| Slug | Rule ID | Name | Expression |
|---|---|---|---|
RULE-5 | rule-5:1:subtract | Rule 5 (1) - Subtraction | current_value < 0 AND formula = 1 AND digitBefore IN (5) |
RULE-6 | rule-5:2:subtract | Rule 5 (2) - Subtraction | current_value < 0 AND formula = 2 AND digitBefore IN (5, 6) |
RULE-7 | rule-5:3:subtract | Rule 5 (3) - Subtraction | current_value < 0 AND formula = 3 AND digitBefore IN (5, 6, 7) |
RULE-8 | rule-5:4:subtract | Rule 5 (4) - Subtraction | current_value < 0 AND formula = 4 AND digitBefore IN (5, 6, 7, 8) |
Rule 10
The operation crosses the 10-boundary of the affected place: the digit wraps off the top of the 0–9 range and carries into the next place, or wraps off the bottom and borrows. Applies to formulas 1–9.
For formulas 6–9 the digit sets split in two. Low-side digits carry without ever touching 5 (4 + 6 = 10); high-side digits carry from above 5 (9 + 6 = 15). The digits between those two groups belong to Combo instead, which is why the larger formulas have gapped digit lists such as (4, 9) and (3, 4, 8, 9).
Addition
| Slug | Rule ID | Name | Expression |
|---|---|---|---|
RULE-9 | rule-10:1:add | Rule 10 (1) - Addition | current_value > 0 AND formula = 1 AND digitBefore IN (9) |
RULE-10 | rule-10:2:add | Rule 10 (2) - Addition | current_value > 0 AND formula = 2 AND digitBefore IN (8, 9) |
RULE-11 | rule-10:3:add | Rule 10 (3) - Addition | current_value > 0 AND formula = 3 AND digitBefore IN (7, 8, 9) |
RULE-12 | rule-10:4:add | Rule 10 (4) - Addition | current_value > 0 AND formula = 4 AND digitBefore IN (6, 7, 8, 9) |
RULE-13 | rule-10:5:add | Rule 10 (5) - Addition | current_value > 0 AND formula = 5 AND digitBefore IN (5) |
RULE-14 | rule-10:6:add | Rule 10 (6) - Addition | current_value > 0 AND formula = 6 AND digitBefore IN (4, 9) |
RULE-15 | rule-10:7:add | Rule 10 (7) - Addition | current_value > 0 AND formula = 7 AND digitBefore IN (3, 4, 8, 9) |
RULE-16 | rule-10:8:add | Rule 10 (8) - Addition | current_value > 0 AND formula = 8 AND digitBefore IN (2, 3, 4, 7, 8, 9) |
RULE-17 | rule-10:9:add | Rule 10 (9) - Addition | current_value > 0 AND formula = 9 AND digitBefore IN (1, 2, 3, 4, 6, 7, 8, 9) |
Subtraction
| Slug | Rule ID | Name | Expression |
|---|---|---|---|
RULE-18 | rule-10:1:subtract | Rule 10 (1) - Subtraction | current_value < 0 AND formula = 1 AND digitBefore IN (0) |
RULE-19 | rule-10:2:subtract | Rule 10 (2) - Subtraction | current_value < 0 AND formula = 2 AND digitBefore IN (0, 1) |
RULE-20 | rule-10:3:subtract | Rule 10 (3) - Subtraction | current_value < 0 AND formula = 3 AND digitBefore IN (0, 1, 2) |
RULE-21 | rule-10:4:subtract | Rule 10 (4) - Subtraction | current_value < 0 AND formula = 4 AND digitBefore IN (0, 1, 2, 3) |
RULE-22 | rule-10:5:subtract | Rule 10 (5) - Subtraction | current_value < 0 AND formula = 5 AND digitBefore IN (0) |
RULE-23 | rule-10:6:subtract | Rule 10 (6) - Subtraction | current_value < 0 AND formula = 6 AND digitBefore IN (0, 5, 6, 7, 8, 9) |
RULE-24 | rule-10:7:subtract | Rule 10 (7) - Subtraction | current_value < 0 AND formula = 7 AND digitBefore IN (0, 1, 5, 6, 7, 8, 9) |
RULE-25 | rule-10:8:subtract | Rule 10 (8) - Subtraction | current_value < 0 AND formula = 8 AND digitBefore IN (0, 1, 2, 5, 6, 7, 8, 9) |
RULE-26 | rule-10:9:subtract | Rule 10 (9) - Subtraction | current_value < 0 AND formula = 9 AND digitBefore IN (0, 1, 2, 3, 5, 6, 7, 8, 9) |
Combo
The operation crosses the 5-boundary and the 10-boundary at once — the digit passes through 5 on its way over 10, or back under 5 on its way below 0. Applies to formulas 6–9 only; smaller formulas cannot span both boundaries in one step.
Addition
| Slug | Rule ID | Name | Expression |
|---|---|---|---|
RULE-27 | combo:6:add | Combo (6) - Addition | current_value > 0 AND formula = 6 AND digitBefore IN (5, 6, 7, 8) |
RULE-28 | combo:7:add | Combo (7) - Addition | current_value > 0 AND formula = 7 AND digitBefore IN (5, 6, 7) |
RULE-29 | combo:8:add | Combo (8) - Addition | current_value > 0 AND formula = 8 AND digitBefore IN (5, 6) |
RULE-30 | combo:9:add | Combo (9) - Addition | current_value > 0 AND formula = 9 AND digitBefore IN (5) |
Subtraction
| Slug | Rule ID | Name | Expression |
|---|---|---|---|
RULE-31 | combo:6:subtract | Combo (6) - Subtraction | current_value < 0 AND formula = 6 AND digitBefore IN (1, 2, 3, 4) |
RULE-32 | combo:7:subtract | Combo (7) - Subtraction | current_value < 0 AND formula = 7 AND digitBefore IN (2, 3, 4) |
RULE-33 | combo:8:subtract | Combo (8) - Subtraction | current_value < 0 AND formula = 8 AND digitBefore IN (3, 4) |
RULE-34 | combo:9:subtract | Combo (9) - Subtraction | current_value < 0 AND formula = 9 AND digitBefore IN (4) |
Plain
The complement family: steps that cross no boundary at all. No carry, no borrow, no 5-crossing — the digit simply moves to another value inside the same half-decade (0–4 or 5–9). Applies to all formulas 1–9 in both directions. Each Plain digit set is exactly what is left over once the Rule 5, Rule 10, and Combo digits for that formula are removed.
Addition
| Slug | Rule ID | Name | Expression |
|---|---|---|---|
RULE-35 | plain:1:add | Plain (1) - Addition | current_value > 0 AND formula = 1 AND digitBefore IN (0, 1, 2, 3, 5, 6, 7, 8) |
RULE-36 | plain:2:add | Plain (2) - Addition | current_value > 0 AND formula = 2 AND digitBefore IN (0, 1, 2, 5, 6, 7) |
RULE-37 | plain:3:add | Plain (3) - Addition | current_value > 0 AND formula = 3 AND digitBefore IN (0, 1, 5, 6) |
RULE-38 | plain:4:add | Plain (4) - Addition | current_value > 0 AND formula = 4 AND digitBefore IN (0, 5) |
RULE-39 | plain:5:add | Plain (5) - Addition | current_value > 0 AND formula = 5 AND digitBefore IN (1, 2, 3, 4) |
RULE-40 | plain:6:add | Plain (6) - Addition | current_value > 0 AND formula = 6 AND digitBefore IN (0, 1, 2, 3) |
RULE-41 | plain:7:add | Plain (7) - Addition | current_value > 0 AND formula = 7 AND digitBefore IN (0, 1, 2) |
RULE-42 | plain:8:add | Plain (8) - Addition | current_value > 0 AND formula = 8 AND digitBefore IN (0, 1) |
RULE-43 | plain:9:add | Plain (9) - Addition | current_value > 0 AND formula = 9 AND digitBefore IN (0) |
Subtraction
| Slug | Rule ID | Name | Expression |
|---|---|---|---|
RULE-44 | plain:1:subtract | Plain (1) - Subtraction | current_value < 0 AND formula = 1 AND digitBefore IN (1, 2, 3, 4, 6, 7, 8, 9) |
RULE-45 | plain:2:subtract | Plain (2) - Subtraction | current_value < 0 AND formula = 2 AND digitBefore IN (2, 3, 4, 7, 8, 9) |
RULE-46 | plain:3:subtract | Plain (3) - Subtraction | current_value < 0 AND formula = 3 AND digitBefore IN (3, 4, 8, 9) |
RULE-47 | plain:4:subtract | Plain (4) - Subtraction | current_value < 0 AND formula = 4 AND digitBefore IN (4, 9) |
RULE-48 | plain:5:subtract | Plain (5) - Subtraction | current_value < 0 AND formula = 5 AND digitBefore IN (6, 7, 8, 9) |
RULE-49 | plain:6:subtract | Plain (6) - Subtraction | current_value < 0 AND formula = 6 AND digitBefore IN (6, 7, 8, 9) |
RULE-50 | plain:7:subtract | Plain (7) - Subtraction | current_value < 0 AND formula = 7 AND digitBefore IN (7, 8, 9) |
RULE-51 | plain:8:subtract | Plain (8) - Subtraction | current_value < 0 AND formula = 8 AND digitBefore IN (8, 9) |
RULE-52 | plain:9:subtract | Plain (9) - Subtraction | current_value < 0 AND formula = 9 AND digitBefore IN (9) |
Global constraint rules
These do not use the formula / digitBefore pattern structure. They read the running sum or the step position and act as guards, evaluated independently of the step-pattern families.
| Slug | Rule ID | Name | Expression |
|---|---|---|---|
RULE-53 | no_negative_sum | No negative sum | current_sum > 0 OR current_sum = 0 |
RULE-54 | plain:5:last_step_restriction | Plain (5) - Last step restriction | IF isLastStep THEN current_sum IN (0, 1, 2, 3, 4, 5) AND current_value > -6 AND current_value < 6 |
no_negative_sum requires the running total to stay at or above zero at every step: sum = 5 → 5 + 3 = 8 passes, sum = 2 → 2 - 5 = -3 fails.
plain:5:last_step_restriction only fires on the final step. When it fires it requires the total to land in [0, 5] and the step value to be small in absolute terms. On every other step the IF guard makes it vacuously true — see quantifiers for how conditional rules behave.
Custom rules you can create
The rules below are not seeded — they are not part of the canonical set in seed.ts and will not exist on a fresh install. They are examples of custom constraint rules, created by hand in the admin UI, that some of the worked examples in the cookbook and combo steps reference by slug. Each encodes a specific pedagogical choice (a specific ceiling, a specific place) that your own instance may want differently — create the ones you need, with these exact expressions, before following an example that uses one.
| Slug | Name | Expression |
|---|---|---|
RULE-55 | Up to 4 | current_value < 5 AND current_sum < 5 |
RULE-56 | Current Value Up to 5 | current_value < 6 |
RULE-57 | Current Value up to 9 | current_value < 10 AND current_value > -10 |
RULE-58 | Place 1 | place = 1 |
RULE-63 | Place 2 | place = 10 |
Place-scoped rules
place = 1 and place = 10 restrict a rule to a single decimal-place channel. Use them when building multi-place composite steps — see combo steps and places.
Consolidated "(any)" rules
Each family also exists as a single consolidated rule that ORs together every clause in that family. Attach one of these when a recipe should accept the whole family rather than one specific formula and direction. They are exactly equivalent to attaching every individual rule of the family as alternatives — no new behavior, just fewer attachments.
A recipe may attach at most 31 pattern rules. Attaching a family's 8 or 18 individual clauses to every place-channel of a multi-place recipe exhausts that ceiling fast — a consolidated (any) rule is the escape hatch: one attachment instead of a whole family's worth. See multi-place combo steps for the channel ceiling in context.
Rule 5 (any)
Matches any Rule 5 step — all eight rule-5:* clauses, addition and subtraction, ORed together. Seeded as RULE-59.
(current_value > 0 AND formula = 1 AND digitBefore IN (4))
OR (current_value > 0 AND formula = 2 AND digitBefore IN (3, 4))
OR (current_value > 0 AND formula = 3 AND digitBefore IN (2, 3, 4))
OR (current_value > 0 AND formula = 4 AND digitBefore IN (1, 2, 3, 4))
OR (current_value < 0 AND formula = 1 AND digitBefore IN (5))
OR (current_value < 0 AND formula = 2 AND digitBefore IN (5, 6))
OR (current_value < 0 AND formula = 3 AND digitBefore IN (5, 6, 7))
OR (current_value < 0 AND formula = 4 AND digitBefore IN (5, 6, 7, 8))Rule 10 (any)
Matches any Rule 10 step — all eighteen rule-10:* clauses, addition and subtraction. Seeded as RULE-60.
(current_value > 0 AND formula = 1 AND digitBefore IN (9))
OR (current_value > 0 AND formula = 2 AND digitBefore IN (8, 9))
OR (current_value > 0 AND formula = 3 AND digitBefore IN (7, 8, 9))
OR (current_value > 0 AND formula = 4 AND digitBefore IN (6, 7, 8, 9))
OR (current_value > 0 AND formula = 5 AND digitBefore IN (5))
OR (current_value > 0 AND formula = 6 AND digitBefore IN (4, 9))
OR (current_value > 0 AND formula = 7 AND digitBefore IN (3, 4, 8, 9))
OR (current_value > 0 AND formula = 8 AND digitBefore IN (2, 3, 4, 7, 8, 9))
OR (current_value > 0 AND formula = 9 AND digitBefore IN (1, 2, 3, 4, 6, 7, 8, 9))
OR (current_value < 0 AND formula = 1 AND digitBefore IN (0))
OR (current_value < 0 AND formula = 2 AND digitBefore IN (0, 1))
OR (current_value < 0 AND formula = 3 AND digitBefore IN (0, 1, 2))
OR (current_value < 0 AND formula = 4 AND digitBefore IN (0, 1, 2, 3))
OR (current_value < 0 AND formula = 5 AND digitBefore IN (0))
OR (current_value < 0 AND formula = 6 AND digitBefore IN (0, 5, 6, 7, 8, 9))
OR (current_value < 0 AND formula = 7 AND digitBefore IN (0, 1, 5, 6, 7, 8, 9))
OR (current_value < 0 AND formula = 8 AND digitBefore IN (0, 1, 2, 5, 6, 7, 8, 9))
OR (current_value < 0 AND formula = 9 AND digitBefore IN (0, 1, 2, 3, 5, 6, 7, 8, 9))Combo (any)
Matches any Combo step — all eight combo:* clauses, addition and subtraction. Seeded as RULE-61.
(current_value > 0 AND formula = 6 AND digitBefore IN (5, 6, 7, 8))
OR (current_value > 0 AND formula = 7 AND digitBefore IN (5, 6, 7))
OR (current_value > 0 AND formula = 8 AND digitBefore IN (5, 6))
OR (current_value > 0 AND formula = 9 AND digitBefore IN (5))
OR (current_value < 0 AND formula = 6 AND digitBefore IN (1, 2, 3, 4))
OR (current_value < 0 AND formula = 7 AND digitBefore IN (2, 3, 4))
OR (current_value < 0 AND formula = 8 AND digitBefore IN (3, 4))
OR (current_value < 0 AND formula = 9 AND digitBefore IN (4))Plain (any)
Matches any Plain step — all eighteen plain:* clauses, addition and subtraction. Seeded as RULE-62.
(current_value > 0 AND formula = 1 AND digitBefore IN (0, 1, 2, 3, 5, 6, 7, 8))
OR (current_value > 0 AND formula = 2 AND digitBefore IN (0, 1, 2, 5, 6, 7))
OR (current_value > 0 AND formula = 3 AND digitBefore IN (0, 1, 5, 6))
OR (current_value > 0 AND formula = 4 AND digitBefore IN (0, 5))
OR (current_value > 0 AND formula = 5 AND digitBefore IN (1, 2, 3, 4))
OR (current_value > 0 AND formula = 6 AND digitBefore IN (0, 1, 2, 3))
OR (current_value > 0 AND formula = 7 AND digitBefore IN (0, 1, 2))
OR (current_value > 0 AND formula = 8 AND digitBefore IN (0, 1))
OR (current_value > 0 AND formula = 9 AND digitBefore IN (0))
OR (current_value < 0 AND formula = 1 AND digitBefore IN (1, 2, 3, 4, 6, 7, 8, 9))
OR (current_value < 0 AND formula = 2 AND digitBefore IN (2, 3, 4, 7, 8, 9))
OR (current_value < 0 AND formula = 3 AND digitBefore IN (3, 4, 8, 9))
OR (current_value < 0 AND formula = 4 AND digitBefore IN (4, 9))
OR (current_value < 0 AND formula = 5 AND digitBefore IN (6, 7, 8, 9))
OR (current_value < 0 AND formula = 6 AND digitBefore IN (6, 7, 8, 9))
OR (current_value < 0 AND formula = 7 AND digitBefore IN (7, 8, 9))
OR (current_value < 0 AND formula = 8 AND digitBefore IN (8, 9))
OR (current_value < 0 AND formula = 9 AND digitBefore IN (9))