Blog  Post

Blog Post

Forward-Chaining Inference: Rules That React to Their Own Results

Jul 18, 2026   

We have added forward-chaining inference to AI Rule Engine. It is the capability that separates a rule list from a rule engine: rules that re-fire as their actions change the facts other rules read, cascading a set of small decisions into a final one — without you scripting the order.

This is the execution model that classic production rule engines like Drools are known for. What has usually been missing from that world is authoring you would actually enjoy. You get both here: turn inference on with a single dropdown, keep the decision-table editor you already use, and let the engine work out the sequence.

The limit of single-pass matching

In classic mode, a RuleSet makes one pass. Every rule is evaluated against the inputs, the matching ones fire, and the run is done. That is exactly right for most rulesets, and it stays the default.

It falls short when one rule’s output should feed another. Say a rule sets tier to “gold” based on spend, and a second rule grants free shipping when tier is “gold”. In a single pass, the second rule reads the original context and never sees the tier the first rule just wrote. You end up flattening the logic into one giant rule, or ordering conditions by hand and hoping the arrangement holds. Inference removes that ceiling.

A decision table with Inference turned on in the execution toolbar, showing per-rule salience badges on the rules.

Turn it on from the toolbar

The execution toolbar sits above your rules in both the Table and List views. Open the match-policy dropdown and you will see four options: First match, First N…, All matching, and Inference. Choosing Inference switches the set into forward-chaining mode; the badge reads Inference. Every other single-pass policy leaves classic behavior exactly as it was. It is opt-in, per RuleSet, and reversible.

One rule at a time, in salience order

Under inference, the engine does not fire everything at once. Eligible rules line up in a queue ordered by salience — highest first — with ties falling back to the rule’s position in the set. The engine fires the top rule, applies its actions to the context, and then looks again.

Salience is a per-rule integer, default 0, in the range −10000 to 10000. Set it from the per-rule settings overlay (the gear on a decision-table row) or in the List-view rule editor; any non-zero value shows a small badge on the row like S5. It is ignored entirely outside inference, so adding salience never changes a classic set. Highest salience fires first; when two rules tie, rule order breaks the tie.

Re-firing — only when inputs actually changed

Here is what makes it an engine rather than a loop. After a firing changes the context, the engine re-evaluates only the rules that read the keys that changed. A rule untouched by the change is not reconsidered. And a rule will not re-fire unless the values it reads have actually changed since the last time it fired.

That single guarantee is what keeps runs safe. It is why an A→B→A value oscillation halts instead of spinning: once the values settle back, nothing re-fires. The run ends when the engine reaches a stable state — the banner reads “Reached a stable state — no more rules to fire.” — and you get a deterministic, repeatable result.

An activation cap you control

As a backstop against a genuine write/read loop, every inference run has a Max activations cap on total firings. The default is 500; you can override it per set to anything from 1 to 10000, or leave it blank to use the default. If a run ever hits the cap it stops and warns “Stopped at the activation cap (possible write/read loop)” so you can look at what kept re-firing. In normal use you will never see it.

What still works, and what does not

Inference composes with most of the editor. Shuffle still applies — it becomes the tie-breaker within equal salience. Nested RuleSets and every action type work as before. Two single-pass concepts don’t carry over: the parallel toggle is disabled (forward chaining fires rules one at a time, so one rule’s output can feed the next), and First match / First N limits are cleared, since “how many rules to match” is a single-pass idea.

One run, one metered run

An inference cascade might fire twenty rules across five iterations. It still counts as one metered run — you are billed for the execution, not the firings. AI-prompt conditions get the same treatment: a rule whose AI condition inputs have not changed is not re-billed when it is re-examined. Cascades stay predictable, both in behavior and on your invoice.

You can also turn on Record run traces to capture a full, viewable, AI-explainable account of every firing for production runs — but that deserves its own post.

Open any RuleSet, pick Inference from the match-policy dropdown, and let your rules chain.

Visit RuleEngine.ai to try it.

The AI Rule Engine Team