ADR 0002: Embedded runtimes first, a central engine second
Status: accepted
Status: accepted
Context
The engine must be highly available and scale with the applications that use it, on the backend and in the browser.
Decision
The primary way to enforce rules is a runtime library inside the application. A stateless rule server exists for callers that cannot embed one. Rules are distributed as immutable, checksummed files (since ADR 0005, compiled bundles); evaluation is a pure function.
Why
A central decision service is on the critical path of every request of every application. It needs its own capacity planning, adds a network hop to each decision, and when it fails, everything fails together. An embedded runtime has none of those properties: it is as available as its host and as fast as a function call.
The usual objection to embedding is drift between implementations. The conformance suite removes it: every runtime must return the same result, field for field, for the same input.
Consequences
- Changing rules means rolling out a new file, not flipping a switch in one place. Rollouts are slower than a central toggle and far safer.
- Each supported language needs a runtime. Four exist as libraries: Python (the reference), TypeScript, Java and Go. Every other language runs the same engine as a command or a WebAssembly module (ADR 0007).
- The browser cannot be trusted, so the server always evaluates again.