Predicator

CIcodecovHex.pm VersionHex DownloadsHex Docs

Predicator is a secure, non-evaluative condition engine for end-user boolean predicates. A user-authored expression like score > 85 AND active compiles to a flat instruction list run by a small stack VM - there is no eval, no Code.eval_string, and no dynamic code execution anywhere in the pipeline, so untrusted input can never become code.

The language covers comparisons, arithmetic, logical operators, dates and durations, lists and objects, nested data access, and both builtin and custom functions.

Installation

Add predicator to your list of dependencies in mix.exs:

def deps do
[
{:predicator, "~> 3.8"}
]
end

Quick Start

iex> Predicator.evaluate!("score > 85 AND active", %{"score" => 92, "active" => true})
true
iex> {:ok, instructions} = Predicator.compile("score > threshold")
iex> Predicator.evaluate!(instructions, %{"score" => 95, "threshold" => 80})
true
iex> Predicator.evaluate("score > 85", %{"score" => 92})
{:ok, true}

Documentation

Migrating from =

Using = for equality still works but is deprecated: parsing one now emits a warning, and Predicator 4.0 makes expression-position = a parse error - = is reserved for assignment in the forthcoming statement grammar. Migrate to == before upgrading, or silence the warning with config :predicator, deprecation_warnings: false. See ADR-0002 for the reasoning.

Cross-Language Siblings

Predicator has sibling implementations in Ruby and JavaScript, in the riddler/predicator monorepo. The instruction list, not the expression string, is the interchange format between them; the divergences (including the = break above) are described in docs/architecture.md.

Development

See CLAUDE.md for the contributor workflow and docs/architecture.md for the quality-check commands.

License

MIT - see LICENSE.