|
| 1 | +DMN-Style Decision Tables |
| 2 | +========================= |
| 3 | + |
| 4 | +Nested ``AC_if_var`` chains get unreadable fast. A decision table externalizes |
| 5 | +branching into rows of ``conditions -> outputs`` evaluated by a **hit policy** — |
| 6 | +the DMN way to keep business rules data-driven and reviewable. |
| 7 | + |
| 8 | +Each cell condition is a wildcard (``None`` / ``"-"`` / ``"*"``), a literal |
| 9 | +(equality), or ``{"op": "ge", "value": 18}`` using the project's standard |
| 10 | +comparators (``eq/ne/lt/le/gt/ge/contains/startswith/endswith`` — reused from the |
| 11 | +executor, not duplicated). Pure standard library; imports no ``PySide6``. |
| 12 | + |
| 13 | +Hit policies |
| 14 | +------------ |
| 15 | + |
| 16 | +================ =================================================== |
| 17 | +Policy Behavior |
| 18 | +================ =================================================== |
| 19 | +``UNIQUE`` Exactly one rule may match (raises if more do). |
| 20 | +``FIRST`` The first matching rule wins. |
| 21 | +``PRIORITY`` Same as FIRST — first match in rule order. |
| 22 | +``COLLECT`` All matching rules' outputs (a list). |
| 23 | +================ =================================================== |
| 24 | + |
| 25 | +Headless API |
| 26 | +------------ |
| 27 | + |
| 28 | +.. code-block:: python |
| 29 | +
|
| 30 | + from je_auto_control import evaluate_table |
| 31 | +
|
| 32 | + spec = { |
| 33 | + "inputs": ["age", "country"], |
| 34 | + "hit_policy": "FIRST", |
| 35 | + "rules": [ |
| 36 | + {"conditions": {"age": {"op": "lt", "value": 18}}, |
| 37 | + "outputs": {"tier": "minor"}}, |
| 38 | + {"conditions": {"age": {"op": "ge", "value": 18}, "country": "US"}, |
| 39 | + "outputs": {"tier": "us-adult"}}, |
| 40 | + {"conditions": {"age": {"op": "ge", "value": 18}}, |
| 41 | + "outputs": {"tier": "adult"}}, |
| 42 | + ], |
| 43 | + } |
| 44 | + evaluate_table(spec, {"age": 30, "country": "DE"}) # -> {"tier": "adult"} |
| 45 | +
|
| 46 | +``evaluate_table`` returns the matched outputs dict (or ``{}`` if none) for |
| 47 | +single-hit policies, and a list for ``COLLECT``. The ``DecisionTable`` class |
| 48 | +(``from_dict`` / ``evaluate``) is available for reuse. |
| 49 | + |
| 50 | +Executor command |
| 51 | +---------------- |
| 52 | + |
| 53 | +``AC_decision_table`` takes ``spec`` and ``context`` (each a dict or JSON |
| 54 | +string) and returns ``{result}``. The same operation is exposed as the MCP tool |
| 55 | +``ac_decision_table`` and as a Script Builder command under **Flow**. |
0 commit comments