Skip to content

ZEN Decision Tables -- Personality Variants & Hit Policies

Demonstrates ZEN JSON Decision Model (JDM) evaluation through three scenarios: a maze-navigating rat with interchangeable personality variants, a potion recipe selector using collect hit policy, and a food truck planner combining decision tables with expression nodes. This is the first nxusKit example built on the ZEN decision engine.

Evaluate business decision tables in Go, Rust, and Python using the ZEN engine — from pricing rules to eligibility checks, with first-hit and collect hit policies.

Scenarios: maze-rat · potion · food-truck

Pro — requires a Pro (or trial) entitlement for ZEN evaluation APIs.

Difficulty: Starter 🟢 · ZEN

  • Summary: ZEN decision table evaluation via nxusKit SDK
  • Scenario: Evaluate business decision tables using the ZEN engine
  • tech_tags in manifest: ZEN — example id zen-decisions in conformance/examples_manifest.json.
  • SDK: Use an installed SDK tree (NXUSKIT_SDK_DIR, NXUSKIT_LIB_PATH as needed); test-examples.sh resolves Go/Rust/Python deps from that tree only — see README.md, scripts/setup-sdk.sh, and scripts/test-examples.sh.
  • Languages in this example: go, rust (paths under this directory; Python may live under a sibling python/ or shared reference per Language Implementations).
FeatureDescriptionRustGo
ZEN EvaluateStateless JDM evaluationnxuskit_zen_evaluate()nxuskit-go.ZenEvaluate()
First Hit PolicyReturn first matching rule"hitPolicy": "first""hitPolicy": "first"
Collect Hit PolicyReturn all matching rules"hitPolicy": "collect""hitPolicy": "collect"
Expression NodesComputed fields in pipelineexpressionNodeexpressionNode
Personality VariantsSame input, different modelsMultiple JDM filesMultiple JDM files
Result FreeingMemory management for resultsnxuskit_zen_free_result()Automatic (Go wrapper)

Pricing rules, eligibility determination, policy evaluation.

ZEN

┌──────────────────┐
│ cautious JDM │──> action: sniff_around
└──────────────────┘
┌───────────┐ ┌──────────────────┐
│ Input │──┬──>│ greedy JDM │──> action: go_right
│ (shared) │ │ └──────────────────┘
└───────────┘ │ ┌──────────────────┐
└──>│ explorer JDM │──> action: go_right
└──────────────────┘
┌───────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Input │──>│ Decision Table │──>│ All Matching │
│ │ │ (collect policy) │ │ Recipes │
└───────────┘ └──────────────────┘ └──────────────────┘

Food Truck (Decision + Expression Pipeline)

Section titled “Food Truck (Decision + Expression Pipeline)”
┌───────────┐ ┌──────────────────┐ ┌──────────────────┐ ┌──────────┐
│ Input │──>│ Decision Table │──>│ Expression Node │──>│ Output │
│ │ │ (location/price) │ │ (menu/restock) │ │ │
└───────────┘ └──────────────────┘ └──────────────────┘ └──────────┘

Attach an installed SDK (NXUSKIT_SDK_DIR). See the repository README.md and scripts/test-examples.sh.

Terminal window
# From `/examples/integrations/zen-decisions`:
cd rust && cargo build
cd go && make build
Terminal window
cd rust
cargo run -- --scenario maze-rat
cargo run -- --scenario potion --verbose
cargo run -- --scenario food-truck --step
Terminal window
cd go
make build
./bin/zen-decisions --scenario maze-rat
./bin/zen-decisions --scenario potion --verbose
./bin/zen-decisions --scenario food-truck --step

Or directly:

Terminal window
cd go
go run . --scenario maze-rat

A maze-navigating rat with three interchangeable personality variants, each encoded as a separate JDM file. All share the same input schema but produce different actions.

Input fields: scent_strength (1-10), dead_ends_nearby (0-5), hunger_level (1-10)

Output fields: action (go_left, go_right, backtrack, sniff_around, rest), confidence (0.0-1.0)

PersonalityStrategyKey Trait
CautiousAvoids dead ends, backtracks when riskyHigh dead_ends triggers backtrack
GreedyAlways follows scent, ignores dead endsStrong scent always means go_right
ExplorerSeeks new paths, ignores scentPrefers go_left to explore unknown areas

With the default input (scent_strength=7, dead_ends_nearby=2, hunger_level=4):

  • Cautious: sniff_around (0.60 confidence) — strong scent but hesitant
  • Greedy: go_right (0.95 confidence) — immediately follows strong scent
  • Explorer: go_right (0.80 confidence) — few dead ends, worth exploring right

A potion recipe selector that returns all matching recipes using the collect hit policy. Multiple recipes can match the same ingredients and desired effect.

Input fields: ingredients (comma-separated list), desired_effect (healing, strength, invisibility, speed), caution_level (low, medium, high)

Output fields: recipe_name, recipe_steps, warnings

With the default input (ingredients=mushroom,moonstone, desired_effect=healing, caution_level=medium):

  • Healing Tonic (mushroom + healing matches)
  • Unknown Brew (default catch-all also matches under collect policy)

A food truck location and menu planner that chains a decision table with an expression node. The decision table selects location and base pricing; the expression node computes menu adjustments.

Input fields: time_of_day, weather, nearby_events, inventory_level

Output fields: location, price_multiplier, menu_adjustment, restock_alert

With the default input (time_of_day=lunch, weather=sunny, nearby_events=large, inventory_level=medium):

  • Location: Main Street Park (lunch + sunny + large event)
  • Price multiplier: 1.3 (premium for large event)
  • Menu: full menu (medium inventory)
  • Restock alert: false
PolicyBehaviorUse Case
firstReturn the first matching rulePrioritized rules, fallback chains
collectReturn all matching rulesMultiple recommendations, audit trails

With first hit policy, rule order matters — the first match wins. With collect, all matching rules are returned as an array.

Expression nodes compute derived fields using simple expressions:

{
"type": "expressionNode",
"content": {
"expressions": [
{"key": "output_field", "value": "input_field"},
{"key": "computed", "value": "if condition then 'a' else 'b'"}
]
}
}

Expressions support:

  • Field references: field_name passes through a value
  • Conditionals: if condition then value1 else value2
  • Comparisons: ==, !=, >, <, >=, <=
  • String literals: 'single quoted'
AspectCLIPS (Rule Engine)ZEN (Decision Tables)
Model format.clp rule files.json JDM files
EvaluationForward-chaining inferenceTable lookup + expressions
StateWorking memory (facts)Stateless per evaluation
ComplexityArbitrary rule logicStructured table/expression
Best forComplex reasoning chainsConfiguration-driven decisions
Hit policiesN/A (all matching rules fire)first, collect
Session managementRequired (create/destroy)None (stateless)

The JDM format follows the GoRules specification:

{
"contentType": "application/vnd.gorules.decision",
"edges": [
{"id": "e1", "sourceId": "input", "targetId": "dt1", "type": "edge"}
],
"nodes": [
{"id": "input", "type": "inputNode", ...},
{"id": "dt1", "type": "decisionTableNode", "content": {...}},
{"id": "output", "type": "outputNode", ...}
]
}
TypeDescription
inputNodeEntry point; passes input data to connected nodes
outputNodeExit point; returns the final result
decisionTableNodeEvaluates input against rules with configurable hit policy
expressionNodeComputes derived fields from expressions
switchNodeRoutes to different branches based on conditions

Note: functionNode (JavaScript) is not supported by the nxusKit ZEN provider.

  • Comparison operators: > 30, <= 10, >= 7, == 5, != 0
  • String values (in outputs): "\"cool\"" (double-quoted inside JSON)
  • Numeric values: 0.85, 1.3
  • Boolean values: true, false
  • Empty field: "" (matches any value / wildcard)
Terminal window
# Verbose mode -- show raw JSON results
cargo run -- --scenario maze-rat --verbose # Rust
go run . --scenario maze-rat --verbose # Go
# Step mode -- pause at each step with explanations
cargo run -- --scenario potion --step # Rust
go run . --scenario potion --step # Go
# Combined mode
cargo run -- --scenario food-truck --verbose --step
go run . --scenario food-truck --verbose --step

Or use environment variables:

Terminal window
export NXUSKIT_VERBOSE=1
export NXUSKIT_STEP=1
Terminal window
# Rust
cd rust && cargo test
# Go
cd go && go test -v

Each scenario includes an expected-output.json that describes expected results for regression testing.