GoRules Version 2 is here - redesigned, now with managed cloud.GoRules Version 2 is here!
Watch the launch videoWatchSwitch from Decisions.com to GoRules.
A step-by-step guide to moving your Statement Rules, Truth Tables, Rule Tables, Matrix Rules, and Rule Sets to GoRules: document each rule, rebuild with the AI copilot, validate in parallel, and cut over.
What you get with GoRules
Where your rules land: the parts of GoRules most relevant to this migration.
AI copilot for authoring and conversion
The copilot converts uploaded rule files into decision graphs, edits tables from plain-language instructions, generates test cases, and explains what a decision did on a given input. Deploys and releases stay explicit human actions.
One expression language everywhere
Decision table cells, expression nodes, and switch conditions all use Zen - a single expression language with 60+ built-in functions (sum, avg, filter, map, date, duration, matches). For logic beyond expressions, functionNode runs sandboxed JavaScript with zod, big.js, dayjs, and http imports.
Visual editor for developers and business users
Rules are modeled as decision graphs in a web editor: decision tables, expressions, switches, and functions on one canvas. Business users and developers edit the same graph, with changes tracked per release.
Native SDKs across languages
The same Rust core ships as @gorules/zen-engine for Node.js, zen-engine for Python and Rust, zen-go for Go, io.gorules:zen-engine for JVM (Java and Kotlin), GoRules.ZenEngine for .NET, plus Swift, Android, and browser or Lambda via WASM.
The migration path
A step-by-step route from your current setup to running your rules on Zen Engine.
1. Inventory your Decisions rules
GoRules has no importer for Decisions project ZIPs (<ProjectName>-MMDDYYYY-HHMMSS.zip) or Repository Server exports. Before migration, walk the Studio and document each Rule Type in scope: input/output data definitions, condition trees for Statement Rules, columns/rows for Truth Tables and Rule Tables, axes for Matrix and Tree Rules, fact flows for Rule Chains, and members for Rule Sets. Capture verb names exactly (String List Contains Five Of, Greater Than In Percents, Equals Without Decimal) - these drive the Zen translation in step 3.
2. Map Decisions Rule Types to GoRules nodes
Statement Rule with True/False outcomes maps to a switchNode with Zen boolean expressions; if the rule produces output values per outcome, add an expressionNode per branch. Truth Table and External Data Truth Table map to decisionTableNode with hitPolicy: "first" (each row is AND-of-columns, returns first match). Rule Table (cells = Statement Rules) flattens to a decisionTableNode whose cells contain Zen unary tests. Matrix Rule and Tree Rule (axes are nested Rules) map to chained switchNodes, or to a single decisionTableNode if both axes flatten cleanly to columns. Rule Set with Inclusion Rule Control = Run All maps to a decisionTableNode with hitPolicy: "collect"; Stop on First True / Stop on First False map to hitPolicy: "first" with rows ordered by your Properties > SETTINGS > Rule Set > Order values. Rule Engine Extension (anchor-typed custom verbs) becomes either an expressionNode (for verbs that are pure Zen) or a functionNode (for verbs backed by custom logic).
3. Translate Decisions verbs to Zen expressions
Most verbs map directly: Is → ==, Is Not → !=, Greater Than → >, Greater Than Or Equal To → >=, Less Than → <, Between → x in [a..b], In List → x in ["a","b","c"], Contains → contains($, "..."), Starts With → startsWith($, "..."), Ends With → endsWith($, "..."), Is Empty → len(x) == 0, Is Not Empty → len(x) > 0, Regex Match → matches(x, "pattern"). Length Equals → len(s) == n. The verbose count-of verbs (List Contains Five Of, List Contains Three Of) become len(filter(list, # == target)) == 5. Numeric specials: Equals Without Decimal → floor(a) == floor(b); Greater Than In Percents → value > (other * percent / 100). List quantifiers (Contains All / Contains Any / Does Not Contain Any) → all(list, # condition) / some(list, # condition) / none(list, # condition). Date verbs map onto Zen d() and its date methods (durations are expressed as duration strings). The Each List Item Name scoped iteration variable becomes the # self-reference inside Zen quantifier functions.
4. Use the AI copilot to author from natural language
Because there is no file importer, the practical migration path is to describe each rule in the GoRules AI copilot rather than upload a file. For a Statement Rule, paste the condition tree (verbs, AND/Either-Or grouping, outcomes) into the chat panel - the copilot generates an expressionNode or switchNode. For a Truth Table, describe the input columns, output columns, hit policy, and the row matrix - the copilot produces a decisionTableNode with Zen unary tests. For a Rule Chain that does not depend on backward chaining, describe the rule sequence - the copilot wires decisionNodes and intermediate expressionNodes. Iterate by pasting your sample inputs and expected outputs and asking the copilot to adjust until simulation matches.
5. Redesign constructs that have no GoRules equivalent
Rule Chains with backward chaining ("derive only the facts I asked for") cannot be represented in a static DAG. Restructure as smaller decisions called conditionally by the application, or as a switchNode that gates which branches of the graph execute. Rule Sets that mix Rules and Flows split into two pieces: the rule logic moves to GoRules (decisionTableNode or chained nodes); the Flow members move to the calling application. Rule Engine Extensions with anchor-type dispatch have no equivalent - GoRules does not type-anchor verbs; rewrite the verb logic as a functionNode and have the calling application route the right inputs. Champion/Challenger A/B testing has no in-engine primitive; deploy two releases (or two decisions) and split traffic at the calling application or via a feature flag system. Interceptor Rules and Learning Rules adaptive validation move to the ingress layer of the application. Processes, Flows, Forms, Pages, Reports, Dashboards, and Assignments are out of scope for a decision engine - they need a separate platform or application surface.
6. Swap the API integration
Replace your per-Rule API configuration (Integration Type = API Service, Reference Type, Data Format, Configure HTTP Methods) with a single endpoint pattern. The call POST <BasePortalURL>/Primary/restapi/Rule/<id> with Authorization: Basic (or a SessionID from /Primary/REST/AccountService/LoginUser, or Bearer <JWT>) becomes POST /projects/:projectId/evaluate/<decision-path> with header x-access-token: <project-access-token> and body { "context": { ... }, "trace": false }. The response shape changes from JSON / XML / Raw (per your configured Data Format) to a uniform { performance, result, trace } envelope. For per-environment or per-release isolation, use the variants POST /projects/:projectId/environments/:environmentId/evaluate/* or POST /projects/:projectId/releases/:releaseId/evaluate/*. For embedded use without a REST hop, swap to a native SDK (GoRules.ZenEngine on NuGet for .NET, io.gorules:zen-engine on Maven Central for JVM, @gorules/zen-engine for Node, zen-engine for Python, zen-go for Go).
7. Validate against your Decisions baseline
Run identical inputs through both engines and compare outputs. GoRules simulation returns a per-node trace - each node reports its input, output, and execution time - so divergences localize quickly. Once outputs match, publish the decision documents and release them to the target environment, then cut traffic over.
Let the copilot do the translation.
GoRules has no importer for Decisions project ZIPs or Repository Server exports, so unlike DMN-based migrations the AI copilot does not parse a source file here; you describe each rule to it instead. In tested conversions, this works well for Statement Rule condition trees (paste the verbs, AND/Either-Or grouping, and outcome values - the copilot generates expressionNode or switchNode), for Truth Table and Rule Table matrices (describe columns, rows, and hit policy - the copilot generates a decisionTableNode with Zen unary tests), and for verb translation (Is → ==, Greater Than → >, In List → in [...], Contains → contains($, "..."), Between → x in [a..b], Is Empty → len(x) == 0, count-of verbs like List Contains Five Of → len(filter(list, # == target)) == 5). Constructs that need manual redesign: Rule Chains with forward/backward chaining (no equivalent in a static DAG - restructure as sequential decisions or as conditional switchNode branches), Rule Sets that mix Rules and Flows (split rule logic into GoRules nodes; move Flow members to the calling application), and Rule Engine Extensions with anchor-type dispatch (rewrite as functionNode since GoRules has no type-anchored dispatch). What the copilot cannot migrate at all: C# SDK custom Rule Verbs (rewrite as functionNode JavaScript with the sandboxed zod / big.js / dayjs / http / zen imports); Champion/Challenger A/B testing (no built-in primitive - handle traffic split in the calling application or a feature flag system); Interceptor Rules and Learning Rules adaptive validation (move validation to the application ingress); and the process and UI surface (Processes, Flows, Forms, Pages, Reports, Dashboards, Assignments) which is out of scope for a decision engine entirely.
Other migration guides
View all guidesSwitch from Drools
A step-by-step guide to moving your DRL rules, DMN models, and spreadsheet decision tables to GoRules: export, convert with the AI copilot, validate in parallel, and cut over.
GuideSwitch from IBM ODM
A step-by-step guide to moving your BAL rules, decision tables, and ruleflows to GoRules: export, convert with the AI copilot, validate in parallel, and cut over.
GuideSwitch from FICO Blaze Advisor
A step-by-step guide to moving your SRL rulesets, decision tables, ruleflows, and score models to GoRules: map the BOM to JSON, convert with the AI copilot, validate in parallel, and cut over.
Leave the build step
behind.
Bring your Decisions.com rules over, run both engines in parallel, and cut over when the outputs match.