Turn judgments into decisions.
An open-source decision engine. Models and scores tell you what is going on. Ordo decides what to do about it,
with rules that have tests and versions, and shows which decisions a change moves before you ship it.
English · 简体中文 · Website · Quick start
if jev.confidence > 0.85:
refund(order)That line decides who gets money back. It was written once, without review or a test. When the model is updated, 0.85 starts to mean something else, and nothing tells you.
Decision models like Jev are good at reading a customer's message and answering "is this a refund request?" with a confidence. They don't know your refund window, your amount limits, or how sure is sure enough to pay out without a person looking. That part is a decision, and it is what Ordo is for.
The same goes for discounts, credit limits and risk thresholds, which usually end up as if/else branches spread across dozens of files. Ordo keeps all of these decisions in their own rule files:
- Rules are JSON or YAML, in git next to your code. You can review them and diff them.
- The expression language is bounded: no loops, no side effects. Rules written by people and rules written by AI can both be checked.
- Money is exact decimal. Inputs are declared with types, and bad input is rejected before any rule runs.
- Every ruleset carries its own tests.
ordo testruns them locally and in CI, with no server. - Your application asks one question, such as "what do we do with this refund request?", and stays the same when the rules change.
If one person writes and changes the decision logic, and it already has tests, Ordo adds little.
It helps most when:
- Thresholds change often, and the people changing them are not the ones who wrote the code.
- The same judgment lives in several places and the numbers have drifted apart, such as 0.7 in one file and 0.75 in another.
- The model gets upgraded, and you need to know which decisions change before you switch.
- Decisions move money: refunds, credit, blocked payments. When one is wrong, you need to say which rule made it and why.
npm i -g @ordo-engine/cli
git clone https://github.com/Ordo-Engine/Ordo
cd Ordo/examples/rule-packs/jev-routing
ordo test
ordo trace refund-routing --input '{"jev":{"intent":{"choice":"refund","confidence":0.97},
"urgency":{"score":0.43},"chargeback":{"noul":0.04}},
"order":{"amount":"129.00","days_since_delivery":1},"customer":{"refunds_90d":0}}'code: AUTO_REFUND
message: Refund issued without review
output: {
"amount": 129,
"jev_confidence": 0.97,
"priority": "normal"
}
path: escalation -> intent -> priority -> route -> dispatch -> auto_refund
These are real Jev answers. The customer wrote "the blender is louder than the video showed, not sure it is for me, what are my options?" They only asked a question, but Jev was 0.97 sure it was a refund request, so the rules paid out 129 EUR without anyone reading the message. Jev reads text well, but its confidence is not a probability, and TypeSafe says there is no universal threshold. trace lists every step a run took, so "why was this refunded without a person looking?" has an answer, and the fix is a rule change you can test. The pack's route.mjs asks Jev for you, and uses the recorded answers when no API key is set.
Support is swamped, and someone proposes auto refunding from 0.80 instead of 0.85. After the edit, all 12 tests still pass. ordo impact runs the edit next to the last commit, over the test cases, real inputs you provide and probe inputs on both sides of every threshold:
$ ordo impact refund-routing
impact refund-routing (HEAD → working tree)
309 inputs: 12 tests, 0 captured, 297 boundary probes
LLM_DRAFT → AUTO_REFUND 18 inputs
LLM_DRAFT → HUMAN_REVIEW 3 inputs
CHANGED probe:jev.intent.confidence=0.84 {... "order":{"amount":"129.00",
"days_since_delivery":1} ...}
code: LLM_DRAFT → AUTO_REFUND
message: "An LLM drafts the reply, an agent approves it" → "Refund issued without review"
…
21 changed · 288 unchanged
The tests did not notice, but 18 inputs that used to wait for a person now get their money back without anyone reading the message. Run it with --inputs last-week.jsonl and the count is real customers, before the change ships.
Add --fail-on-change to stop surprise changes in CI, or --json to feed the result to other tools. Coding agents get the same check through ordo mcp, so an agent can look at the effect of its own rule edit before a person reviews it.
ordo impact needs CLI 0.7.0 or later, and --model and ordo decisions need 0.8.0 (release). See the CLI docs.
ordo-server can sit between your application and Jev. Your code keeps calling Jev, each answer comes back with Ordo's decision attached, and every call goes to a decision log.
mkdir -p decisions && chmod 777 decisions # the container user writes the log here
docker run -p 8080:8080 -e ORDO_DECIDE_API_KEY=<your OpenRouter key> \
-v "$PWD/decisions:/decisions" \
ghcr.io/ordo-engine/ordo:latest \
--rules-dir /app/rule-packs/jev-routing/rulesets \
--decide-upstream https://openrouter.ai/api \
--decide-log-dir /decisions --decide-log-requests
# from examples/rule-packs/jev-routing
curl localhost:8080/systemone/v1/systemone \
-H 'content-type: application/json' -d @request.jsonThe response is Jev's answer plus an ordo field with the decision (code, message, output). In your application, set TYPESAFE_BASE_URL=http://localhost:8080/systemone and add the ordo field with your ruleset and order facts. If your app already sends its facts to Jev in a JSON state, it needs no change at all: use TYPESAFE_BASE_URL=http://localhost:8080/systemone/rulesets/<ruleset> and the rules read the fields of state. ordo decisions decisions/ sums up what was decided.
Before you switch models, ask the new model the real requests in the log and see which decisions change:
$ ordo impact refund-routing --inputs decisions/decisions-2026-10-13.jsonl \
--model cloudflare/clef-flash --repeat 3
model: typesafe/jev-1.13-20260917 → cloudflare/clef-flash
24 logged requests asked again, 3 times each
AUTO_REFUND → ESCALATE 1 input
AUTO_REFUND → LLM_DRAFT 3 inputs
HUMAN_REVIEW → ESCALATE 1 input
ROUTE_TEAM → HUMAN_REVIEW 2 inputs
No rule changed, only the model, and 7 of 24 requests would be handled differently. In two of three asks, a customer whose jacket was too small would be sent to a senior agent as a chargeback threat. See the decision model gateway docs.
Common business decisions, already written and tested. Copy one and change the numbers to your own policy.
| pack | decides |
|---|---|
| jev-routing | what to do with a refund request after Jev has read the customer's message |
| credit-approval | approve, send to manual review, or decline a personal loan |
| promo-stacking | which promotions apply at checkout, how far they stack, and what the customer pays |
| fraud-scoring | allow, challenge or block a card payment |
A rule pack is a plain Ordo project. Rules your team writes can be shared the same way.
# ordo-server, over HTTP or gRPC
docker run -p 8080:8080 ghcr.io/ordo-engine/ordo:latest
curl localhost:8080/api/v1/execute/<ruleset> \
-H 'content-type: application/json' -d '{"input": {...}}'
# Embedded in a Rust program
cargo add ordo-core --git https://github.com/Ordo-Engine/Ordo
# In the browser, as WASM
npm install @ordo-engine/wasmFrom your services, call the HTTP or gRPC API. Client SDKs for Go, Python and Java are in sdk/ and are not on the package registries yet.
The engine is written in Rust: a bytecode VM, plus a Cranelift JIT for hot numeric expressions. A rule run takes 1.63 µs on the VM, numeric expressions take 50–80 ns after JIT, and a single HTTP thread serves about 54k QPS. See the benchmarks.
Studio draws the same rules as a flow and as a decision table, so people who don't write code can read the logic, run tests and request releases. Engineers keep working with files and git, and the CLI pushes and pulls between the two.
![]() |
![]() |
- One ruleset, shown as a flow or as a decision table
- Run tests in Studio and compare expected and actual results
- Field catalog, decision contracts, version history and release approvals
See the Studio docs.
The same engine also keeps coding agents in bounds. Before Claude Code, Codex CLI or Cursor runs a command, it goes through your local rules: allow, deny, or ask you first.
npx @ordo-engine/cli guard initThe policy is an Ordo project in .ordo-guard/, with tests (ordo guard test) and a log (ordo guard log). See the Guard docs.
| Ordo | OPA | Drools | json-rules-engine | |
|---|---|---|---|---|
| JIT compilation | ✅ Cranelift | ❌ | ❌ | ❌ |
| Authoring model | Rule files (JSON/YAML), visual flow and decision table | Rego policy code | DRL / DMN + Business Central | JSON rule DSL |
| Built-in web workbench | ✅ Studio | Playground / APIs | ✅ Business Central | ❌ |
| Browser / Wasm target | ✅ Native | ✅ Policy-to-Wasm | ❌ | ✅ Browser JS |
| Deployment | Single binary or hosted platform | Binary, sidecar, or service | JVM app, KIE Server, Business Central | JS library for Node/browser |
The comparison covers first-party documented authoring and deployment capabilities, not cross-project benchmark claims.
ordo/
├── crates/
│ ├── ordo-core/ # Rule engine, bytecode VM, JIT compiler
│ ├── ordo-server/ # HTTP / gRPC API server
│ ├── ordo-platform/ # Orgs, projects, releases, testing
│ ├── ordo-cli/ # CLI: init, validate, test, trace, impact, mcp, guard
│ ├── ordo-wasm/ # WebAssembly bindings
│ ├── ordo-proto/ # gRPC definitions
│ └── ordo-derive/ # TypedContext derive macro
├── ordo-editor/
│ ├── packages/ # @ordo-engine/editor-{core,vue,react,wasm}
│ └── apps/
│ ├── studio/ # Studio (Vue 3 + TDesign)
│ ├── playground/ # Live demo
│ └── docs/ # Documentation site
├── examples/
│ └── rule-packs/ # jev-routing, credit-approval, promo-stacking, fraud-scoring
└── sdk/ # Go / Python / Java clients
MIT. See LICENSE.




