DMN and FEEL
TinyConductor evaluates DMN decisions and FEEL expressions inside the engine. DMN (Decision Model and Notation) is the standard for decision tables. FEEL is its expression language, which BPMN models also use.
Evaluation is deterministic. The same expression, the same variables and the same point in time always give the same result. This is what lets the engine replay a process’s history exactly.
- Decision tables: all hit policies, and decision requirement (DRD) evaluation — a decision may require other decisions and business knowledge models.
- Literal expressions: supported.
- Business knowledge models: supported, including invocation from decisions. A business knowledge model whose logic is a decision table is not supported.
- Decision services: single-output decision services can be invoked by id or name. Multi-output decision services, and calling a decision service from FEEL, are not supported.
- Business rule tasks (
tc:calledDecision) evaluate the deployed decision in the engine; no worker is involved. Deploy the DMN resource before the BPMN that calls it. The decision-evaluation record lists every evaluated decision, including required ones, with its evaluated inputs and matched rules. - Past evaluations of business rule tasks and of the evaluation API are
searchable (
POST /v2/decision-instances/search, by decision, process instance, state and evaluation time) and readable one by one with their inputs and matched rules (GET /v2/decision-instances/{key}), in the console under Decisions, Evaluations. They age out with the tenant’s history: a business rule task’s with its process instance, an API evaluation once it is older than the tenant’s history retention. - Deployed decisions and requirements graphs are searchable
(
POST /v2/decision-definitions/searchandPOST /v2/decision-requirements/search, by id, name, version and key) and readable by key, with the DMN file each was deployed from (GET /v2/decision-requirements/{key}and…/{key}/xml; one decision’s file withGET /v2/decision-definitions/{key}/xml), in the console under Decisions, Decisions and Requirements graphs. A user whose read access names only some decisions sees a requirements graph only when every decision of it is among them.
The sample order-decisions.dmn (see Examples) is a
FIRST-hit decision table that requires a business knowledge model.
Conformance
Section titled “Conformance”TinyConductor is tested against the public DMN Technology Compatibility Kit (TCK), the standard DMN test suite, at compliance level 3. The TCK has 3,369 assertions in 118 test files.
Every release must reach at least 3,133 passed, 6 failed, 230 unsupported. That is 99.81% of the supported features and 92.99% overall. The most recent run, which does not block releases, measured 3,137 passed, 12 failed and 220 unsupported.
- The 6 failures are XML Schema extended years (up to ±999,999,999), which exceed the date range of the engine’s value model (±262,143 years).
- The unsupported assertions are features outside the supported subset: external Java functions, DMN imports, multiple iteration contexts, decision tables as business-knowledge-model logic, some boxed invocation and relation shapes, FEEL comments, and XPath regular-expression constructs.
The FEEL implementation covers decimal, boolean and string expressions; lists,
contexts and ranges; path, filter and index navigation; if, for and
quantified expressions; unary tests; temporal values; and the standard list,
string, numeric and context functions.
The following compatibility helper functions are available: is defined,
nested get value, context put, context merge, extract, trim,
to base64, is blank, duplicate values, is empty, partition,
from json and to json. Only these names are provided; alternative
spellings of them are not.
Also available:
| Function | Notes |
|---|---|
number(from, grouping separator) and number(from, grouping separator, decimal separator) | Parse numbers with explicit separators |
fromAi(value, …) (one to five arguments) | Returns its first argument unchanged. The description, type, schema and options arguments are metadata for the consuming integration; they are type-checked and must be literals |
date and time with an offset plus an agreeing time zone | For example +02:00[Europe/Berlin] |
is defined with zero arguments is an error.
Limits
Section titled “Limits”Every evaluation of an expression has a budget, so that one expression can neither slow down nor stop the engine for other processes and tenants:
- Work: 100,000 evaluation steps. A tenant’s
feelBudgetquota changes this number (see Tenant quotas). - Memory: 4 MiB for everything the expression builds. The text a
function returns counts (for example the result of
replace,string join,splitorextract), and so do lists built byfor, by a list literal or by list functions such asconcatenateandunion, the entries of a context, joined strings and the variables a function definition keeps. A result that would not fit is refused before it is built. - Nesting: an expression may be nested at most 128 levels deep: brackets,
operators, function calls, paths,
if,forand the other constructs, counted together. A deeper expression is refused when the model is deployed. While an expression runs, its nesting and the functions it calls, including a function calling itself, may reach 256 levels.
An expression that goes over its budget fails like any other failing expression: the element raises an incident whose message starts with “FEEL evaluation exceeded”, and the rest of the engine carries on.
In a decision model, a decision or business knowledge model may require other ones in a chain at most 64 long; a longer chain fails the evaluation with an incident.
Deliberately absent: uuid()
Section titled “Deliberately absent: uuid()”uuid() is not provided. When the engine replays history, it evaluates each
expression again and must get the same value. A random result would break that.
uuid() can only be added once the engine stores the random value in the
history.
Where FEEL is used in BPMN
Section titled “Where FEEL is used in BPMN”FEEL appears wherever a BPMN attribute starts with =: input and output
mappings, conditions, timer definitions, correlation keys, job types and
retries, called process ids, and multi-instance collections. Task headers are
the exception: they are passed to workers exactly as written, including a
leading =. Element-by-element support is listed in
BPMN coverage.