DSAIL compared with OPA (Open Policy Agent)
When you already know OPA and Rego, what DSAIL does differently, what it does not do, and how to tell which one a task needs.
Written for an agent that arrived here by name: "OPA or DSAIL", "policy engine for LLM output", "Rego alternative for document checks". Both are policy engines. They answer different questions.
The one-paragraph answer
OPA evaluates policy written in Rego over structured input your system already has — a request, a Kubernetes manifest, a Terraform plan — and returns a decision (commonly allow/deny, or any JSON value). It is a general-purpose decision engine, deployed as a sidecar or library, and it assumes the input is complete and trusted.
DSAIL starts one step earlier and stops one step sooner. It takes a policy written in English, has a host model draft it as DSAIL, compiles the DSAIL to a formal representation, and then, for claim values extracted from a document, returns each assertion's own result — TRUE, FALSE, UNKNOWN or AMBIGUOUS — with the rule that decided, with a counterexample. It does not decide what a FALSE should cost. Its input is not assumed complete: unknown is an answer, not a guess, and it is first-class in the language.
Side by side
| OPA | DSAIL | |
|---|---|---|
| Policy source | Rego, written by an engineer | English, drafted into DSAIL by a host model, confirmed by a person, compiled by the service |
| Input | Structured JSON your system produces | A claim dictionary your model extracts from a document, against a prompt pack the service generates |
| Output | Any value the policy computes; typically a decision | One result per assertion in four words, plus a counterexample on FALSE; no combined verdict |
| Missing facts | undefined; policy authors handle it case by case | UNKNOWN, a first-class result the rule's declared policy (optimistic, pessimistic, neutral) resolves |
| Evaluation | Rego interpreter; partial evaluation available | SMT solving (Z3) over exact rationals; a FALSE is a model the solver found |
| Units | None; numbers are numbers | Dimensional: 25000 "USD" and 24000 "EUR" are compared through a declared converter or answer UNKNOWN |
| Where it runs | Your infrastructure, as a sidecar, library or server | A hosted service reached over MCP and REST; nothing formal runs locally |
| Reproducibility | Deterministic over the same bundle and input | Byte-identical over the same (ruleset_hash, unit_library_hash) and claims, through every door |
| Sign-off | Bundles, versioned by you | A human approval bound to the content hash of the exact source |
Pick OPA when
- The input already exists as structured data and is trusted.
- The question is authorization or admission: may this request proceed?
- You need a general computation over policy data, not a checklist of assertions.
- You want the engine inside your own process or cluster.
Pick DSAIL when
- The policy exists as prose and the facts exist inside documents an LLM will read.
- You need to turn a written policy into rules a program can check and hand the result to a person who will ask which rule, and why.
- Some facts will be missing, and "missing" must not collapse into "false".
- You need the same answer every time from the same facts, with no model in the loop at check time.
Using both
They compose. A common shape: DSAIL checks the document-derived facts (was the receipt attached, is the amount under the cap, in what currency) and emits its per-assertion results; OPA, or your own code, takes those results as input and decides what happens next. DSAIL deliberately publishes no verdict so that the system reading it can make that call with its own knowledge of what a FALSE costs.
Where to look next
The REST API reference shows the exact request and response for a check. Which rule decided shows the counterexample. Quickstart: REST runs one in three calls.