Deterministic rule engine for agent systems
Rune is a language for encoding decision logic as deterministic finite state machines. It is designed to sit between LLM reasoning and real-world actions — guaranteeing that the same inputs always produce the same outcome.
Rune policies take typed inputs and always terminate. There are no loops, no side effects, no ambiguity.
LLMs reason probabilistically. Real-world actions (approvals, rejections, escalations) must be deterministic. Rune is the layer that enforces this — a tiny, auditable runtime where business rules are explicit, testable, and version-controlled.
- Determinism — same inputs, same terminal. Always.
- Type safety —
number,boolean,string, andenuminputs - Lint + type checker — catches structural and semantic errors before runtime
- Spec format — define policies as JSON (
.runespec.json) and compile to.rune - LLM extraction — extract policies from natural language documents using an LLM
npm install
npm run buildRun the CLI:
npm run rune -- <command> [options]Or directly:
node packages/cli/dist/index.js <command> [options]Create policy.rune:
version "0.1"
input risk_score: number
input has_docs: boolean
initial review
state review {
when risk_score > 80 && has_docs == false then reject
when risk_score <= 30 then approve
else manual_check
}
state manual_check {
when has_docs == true then approve
else reject
}
terminal approve
terminal reject
| Command | Description |
|---|---|
lint <file> |
Validate a .rune policy file |
eval <file> |
Evaluate a policy against a JSON input |
spec:check <file> |
Validate a .runespec.json schema |
spec:lint <file> |
Semantic lint of a .runespec.json |
spec:compile <file> |
Compile a .runespec.json to .rune |
compile [file] |
Compile a document into a policy using an LLM |
npm run rune -- lint policy.runenpm run rune -- eval policy.rune --input input.jsonOutput:
Terminal approve
Path review -> manual_check -> approve
Steps 3
npm run rune -- compile recipe.txt --provider openai --api-key $OPENAI_API_KEY --out policy.rune
npm run rune -- compile --text "approve if score < 50, else reject" --provider deepseek --api-key $DEEPSEEK_API_KEYUse --draft-dir .rune/drafts/my-policy to write a full analysis package:
policy.rune— the extracted policyreport.md— human-readable extraction reportwarnings.json— structured warningstrace.json— document → rule mapping
Rune is designed to embed cleanly inside any existing repo. Add it as a dependency, drop your policies alongside your code, and use the CLI to compile, lint, and test them.
npm install @rune/core @rune/cli<your-project>/
policies/ ← versioned .rune files (check these in)
refund.rune
access-control.rune
tests/ ← gsi-generated test cases (check these in too)
refund.test.json
access-control.test.json
recipes/ ← source documents that policies are compiled from
refund.txt
access-control.md
.rune/ ← tool output — add to .gitignore
drafts/
refund/ ← full draft package from `rune compile`
Add .rune/ to your .gitignore:
# .gitignore
.rune/
1. Write or compile a policy
# From a document (interactive wizard):
rune compile recipes/refund.txt
# The wizard defaults draft output to .rune/drafts/refund/
# Move the finished policy to policies/ when satisfied:
cp .rune/drafts/refund/policy.rune policies/refund.rune2. Lint
rune lint policies/refund.rune3. Generate test cases
rune gsi policies/refund.rune
# → writes policies/tests/refund.test.json automatically4. Evaluate
rune eval policies/refund.rune --input '{"amount": 450, "customer_tier": "gold", "has_receipt": true}'import { parse, evaluate } from "@rune/core";
import { readFileSync } from "node:fs";
const policy = parse(readFileSync("policies/refund.rune", "utf-8"));
const result = evaluate(policy, { amount: 450, customer_tier: "gold", has_receipt: true });
// result.terminal → "approve" | "reject" | "escalate"The policies/, recipes/, and .rune/ directories follow established conventions:
.rune/mirrors.git/,.next/,.turbo/— tool artifacts live in a dot-dir, gitignoredpolicies/tests/mirrors Jest__tests__/, dbttests/— test cases co-located with what they testrecipes/mirrorsprisma/,migrations/— source inputs that produce compiled artifacts
packages/
core/ Parser, validator, type checker, evaluator, spec compiler
cli/ Command-line interface
ingestion/ LLM-based policy extraction
test-suite/ Integration tests and fixtures
spec/ Language specification
See HANDBOOK.md for the full language reference, grammar, error codes, and the spec format.
Rune was extracted from production work on an AI-driven document validation platform processing ~1,000 documents daily. It is the layer that makes the final decision deterministic inside an otherwise probabilistic agent system.
MIT — LICENSE
Built by Marcel Scognamiglio