Rule Cascade
ReferenceExample READMEs

Batch recipe

Evaluate a file of thousands of operations against one ruleset, with any runtime, and write one decision per line.

Evaluate a file of thousands of operations against one ruleset, with any runtime, and write one decision per line. Useful to re-check stored records after a rule change, to screen an import, or to compare what two versions of a ruleset decide.

batch.py (examples/batch/batch.py) needs only the Python standard library. It starts an engine once, loads the bundle once and streams every request through the JSON Lines engine protocol (specification section 13). One thread writes requests while another reads answers, so the engine never waits for the script and memory stays flat.

python examples/batch/batch.py examples/batch/transfers.csv
{"line": 1, "id": "t-1", "decision": "allow", "blocking": [], "findings": [], "commands": []}
{"line": 3, "id": "t-3", "decision": "deny", "blocking": ["ORG-TRF-001"], "findings": [{"code": "ORG-TRF-001", "severity": "error", "status": "open", "message": "Transfers to KP are not permitted."}], "commands": []}
...
7 request(s): 3 allowed, 4 denied, 0 refused as malformed

Any engine

--engine takes the command line of any engine. The decisions are the same whichever you choose; the test checks that for every engine that is built.

Engine--engine
Python (default)"python -m rule_cascade engine" with packages/python/src on PYTHONPATH
Go command"rule-cascade engine"
TypeScript"node packages/typescript/dist/cli.js engine"
Java"java -cp packages/java/target/classes io.github.yarlisaisolutions.rulecascade.Main engine"
WebAssembly"node packages/go/wasi/run.mjs packages/go/dist/rule-cascade.wasm engine"

--bundle names the compiled ruleset (default: the payments example's bundle in conformance/bundles), --channel the manifest (default server) and -o the output file.

Input

  • .jsonl: one evaluation request per line, as in requests.jsonl (examples/batch/requests.jsonl): entity, operation, data, and optionally original, actor, resolutions.
  • .csv: one entity per row, as in transfers.csv (examples/batch/transfers.csv). Dotted column names build nested objects (beneficiary.country); actor.id and actor.roles (separated by ;) become the actor. Cells that are JSON numbers or true/false become numbers and booleans; empty cells are left out. --entity and --operation name the operation (default Transfer, create).

Output and exit status

One JSON object per input line, in input order: decision, the codes of the blocking findings, every finding with its severity, status and message, and the commands with their idempotency keys. A request the engine refuses as malformed gives {"line": n, "error": "..."} instead.

The exit status is 0 when every request was evaluated, whatever the decisions; 1 when any request was refused as malformed; 2 when the engine could not be started or broke the protocol.

Test

python -m unittest discover -s examples/batch -v

The Python engine always runs. The TypeScript, Go and Java engines run when they are built; set BATCH_REQUIRE_ENGINES=python,node,go,java to fail rather than skip when one is missing (CI requires python,node,go).

On this page