WinstonRedGuard local-first deterministic rule evaluation engine (formerly rule-lab on PyPI, republished under WRG namespace)
Project description
wrg-rule-lab
💡 Found this useful? ⭐ Star the repo (helps others find it) and subscribe to weekly detection-engineering writeups at Detection Frontier.
Replace your scattered
if/elsepolicy logic with auditable JSON rules. Zero dependencies. Stdlib only. Deterministic by design.
A Python library + CLI for defining decision rules as JSON data, evaluating them against arbitrary contexts, detecting conflicts, and simulating outcomes — built for AI release gating, compliance enforcement, and any decision engine where reproducibility matters.
Why this exists
Most production Python apps eventually grow a tangle of if score > 80 and not banned and ... policy logic. The problems compound:
- Hard to audit — reviewers cannot tell what changed in a 50-line conditional cascade
- Hard to test — every branch needs a fixture; coverage decays fast
- Hard to evolve — adding a new condition risks breaking 3 others
- Hard to explain — non-engineers (compliance, product, risk) cannot read or propose changes
wrg-rule-lab moves that logic out of code and into JSON data. Same outcomes, but every evaluation is traceable, every change is a diff, and the rules can live anywhere your config does.
Use cases
- AI release gating — block LLM outputs before they ship (e.g.,
if hallucination_score > 0.7 and no_citations) - Compliance-as-code — KVKK/GDPR/SOC2 rules expressed as data, evaluated per request
- Decision engines — replace hardcoded approval/rejection logic with JSON rules
- Feature flag combinators — combine multiple conditions without touching application code
- Audit trails — every rule evaluation produces a structured, reproducible result for after-the-fact review
Quick start
pip install wrg-rule-lab
from rule_lab import load_rules_from_dict, evaluate_rules
ruleset = {
"rules": [
{
"rule_id": "block_high_risk",
"name": "Block high-risk transactions",
"conditions": [
{"field": "risk_score", "op": "gt", "value": 80},
{"field": "country", "op": "neq", "value": "US"}
],
"action": "block",
"priority": 10
}
]
}
rules = load_rules_from_dict(ruleset)
result = evaluate_rules(rules, context={"risk_score": 95, "country": "RU"})
print(result.matched_count) # 1
print(result.results[0].action) # block
Before / after
Before — scattered if/else, hard to audit:
def should_block(transaction):
if transaction.risk_score > 80 and transaction.country != "US":
return True
if transaction.amount > 10000 and not transaction.kyc_verified:
return True
if transaction.user.flags and "fraud_history" in transaction.user.flags:
return True
# 30 more lines...
After — same logic as data, auditable + diffable + testable:
{
"rules": [
{"rule_id": "high_risk_geo", "conditions": [
{"field": "risk_score", "op": "gt", "value": 80},
{"field": "country", "op": "neq", "value": "US"}
], "action": "block"},
{"rule_id": "large_amount_no_kyc", "conditions": [
{"field": "amount", "op": "gt", "value": 10000},
{"field": "kyc_verified", "op": "eq", "value": false}
], "action": "block"},
{"rule_id": "fraud_history", "conditions": [
{"field": "user.flags", "op": "contains", "value": "fraud_history"}
], "action": "block"}
]
}
Same call site: evaluate_rules(rules, context=transaction.to_dict()).
CLI
# Validate a rule file
rule-lab validate --rules rules.json
# Simulate rules against a list of contexts
rule-lab simulate --rules rules.json --contexts contexts.json
# Detect conflicting rules (same conditions, different actions)
rule-lab diff --rules rules.json
How it compares
| Project | Engine type | Dependencies | Format | Conflict detection | Best for |
|---|---|---|---|---|---|
| wrg-rule-lab | Imperative actions on conditions | Zero (stdlib only) | JSON | Yes (built-in diff) |
Python apps needing simple, auditable policy logic |
| Drools | Forward-chaining rules engine | JVM ecosystem | DRL (custom DSL) | Yes | Enterprise Java with complex inference chains |
| py-rules-engine | Boolean expression evaluator | pyparsing |
Python-ish expression strings | No | Embedded boolean checks in larger apps |
| JSON Schema | Declarative validation | jsonschema |
JSON | N/A (validation only) | Data shape validation (not decisions) |
| Pydantic validators | Compile-time type validators | pydantic |
Python class methods | N/A | Type-safe data parsing (not runtime policy) |
When to reach for wrg-rule-lab
- Your app has 20+ branches of
if/elsepolicy logic that compliance or non-engineers need to read or change - You need an audit trail showing exactly which rule matched which input
- You want JSON rules you can hot-reload, version-control, and diff in PRs
- Zero dependency footprint matters (sandboxes, CI minutes, supply chain hygiene)
Where wrg-rule-lab loses today (honest delta)
- No forward-chaining inference — Drools and similar engines support rules that fire other rules in cascades; wrg-rule-lab is a single-pass evaluator
- Limited condition vocabulary — 10 operators (eq, neq, gt, gte, lt, lte, contains, not_contains, exists, not_exists); no regex / no custom Python predicates
- No streaming evaluation — built for single-context evaluations, not continuous stream rule matching
- No GUI / rule authoring UX — rules are hand-written JSON; no visual builder (use a JSON Schema in your editor for autocomplete)
- Newer than alternatives — Drools (20+ years), pyparsing-based engines (10+ years) have much larger communities
If any of those is your primary need, reach for the project that owns it. Reach for wrg-rule-lab when you want a small, local, zero-dep policy evaluator that fits in any Python sandbox.
API Reference
| Function | Description |
|---|---|
load_rules_from_file(path) |
Load rules from a JSON file |
load_rules_from_dict(data) |
Load rules from a dict |
load_rules_from_list(rules) |
Load rules from a list |
evaluate_rule(rule, context) |
Evaluate a single rule |
evaluate_rules(rules, context) |
Evaluate a list of rules |
simulate(rules, contexts) |
Simulate multiple contexts |
Rule format
{
"rules": [
{
"rule_id": "unique-id",
"name": "Human readable name",
"conditions": [
{"field": "score", "op": "gt", "value": 50}
],
"action": "approve",
"priority": 10,
"tags": ["finance", "v1"],
"metadata": {}
}
]
}
Supported operators
The op field in a condition accepts these 10 operators (canonical set in src/rule_lab/core/conditions.py):
| Operator | Purpose | Example |
|---|---|---|
eq |
Equality | {"field": "status", "op": "eq", "value": "active"} |
neq |
Not equal | {"field": "status", "op": "neq", "value": "banned"} |
gt |
Greater than (numeric) | {"field": "score", "op": "gt", "value": 50} |
gte |
Greater than or equal (numeric) | {"field": "score", "op": "gte", "value": 50} |
lt |
Less than (numeric) | {"field": "age", "op": "lt", "value": 18} |
lte |
Less than or equal (numeric) | {"field": "age", "op": "lte", "value": 18} |
contains |
Substring match | {"field": "email", "op": "contains", "value": "@example.com"} |
not_contains |
Substring absent | {"field": "tags", "op": "not_contains", "value": "blocked"} |
exists |
Field present in context | {"field": "user_id", "op": "exists"} |
not_exists |
Field absent | {"field": "ban_reason", "op": "not_exists"} |
Design principles
- Zero dependencies — stdlib only, no surprise installs
- Deterministic — same input always produces same output
- Local-first — no network calls, no cloud required
- Testable — every rule is independently verifiable
Sister WRG-11 packages
Part of the WRG-11 PyPI portfolio:
instinct-mcp— Self-learning memory for AI coding agents (MCP server)wrg-devguard— Developer-first AI safety: prompt-policy lint + secret scanning + log scanning with PII detectionwrg-mcp-server— MCP bridge for the WinstonRedGuard monorepo (60+ security/threat-intel tools)ai-security-toolkit— Offensive + defensive AI/LLM security tools, labs, CTF writeups, research
Migration note
Previously published as rule-lab on PyPI. The original publisher account became inaccessible; releases continue here as wrg-rule-lab under the WRG namespace. The Python import path rule_lab is unchanged, so existing code continues to work — only the pip install name differs.
License
MIT — built by WinstonRedGuard.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wrg_rule_lab-0.1.7.tar.gz.
File metadata
- Download URL: wrg_rule_lab-0.1.7.tar.gz
- Upload date:
- Size: 29.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7c3fffb4cb4ba022049c101fc8173770bf0009a630b5ea562074ab928b5c87d1
|
|
| MD5 |
97001dcfb01398e9a017be38dcd5f61e
|
|
| BLAKE2b-256 |
054ebf17880008b40602c14e8ffdfc07fdf4666db8f079e9df1f017c10050a8f
|
Provenance
The following attestation bundles were made for wrg_rule_lab-0.1.7.tar.gz:
Publisher:
publish.yml on WRG-11/wrg-rule-lab
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wrg_rule_lab-0.1.7.tar.gz -
Subject digest:
7c3fffb4cb4ba022049c101fc8173770bf0009a630b5ea562074ab928b5c87d1 - Sigstore transparency entry: 1705062305
- Sigstore integration time:
-
Permalink:
WRG-11/wrg-rule-lab@fa39596de571565037a75a9a3947dd33a35b1fe3 -
Branch / Tag:
refs/tags/v0.1.7 - Owner: https://github.com/WRG-11
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fa39596de571565037a75a9a3947dd33a35b1fe3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file wrg_rule_lab-0.1.7-py3-none-any.whl.
File metadata
- Download URL: wrg_rule_lab-0.1.7-py3-none-any.whl
- Upload date:
- Size: 17.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e97e1f51e8f1a26f9a0a31157a3ee8549e4173ad1cddc7d3889e5b6ec4dd5ceb
|
|
| MD5 |
e5062ec1153c7cc083f7514118cfeaf2
|
|
| BLAKE2b-256 |
09d13871666741058e33acbfe1dd2688ecb656bc525caf5714a6cf0ab0d0ca10
|
Provenance
The following attestation bundles were made for wrg_rule_lab-0.1.7-py3-none-any.whl:
Publisher:
publish.yml on WRG-11/wrg-rule-lab
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wrg_rule_lab-0.1.7-py3-none-any.whl -
Subject digest:
e97e1f51e8f1a26f9a0a31157a3ee8549e4173ad1cddc7d3889e5b6ec4dd5ceb - Sigstore transparency entry: 1705062359
- Sigstore integration time:
-
Permalink:
WRG-11/wrg-rule-lab@fa39596de571565037a75a9a3947dd33a35b1fe3 -
Branch / Tag:
refs/tags/v0.1.7 - Owner: https://github.com/WRG-11
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fa39596de571565037a75a9a3947dd33a35b1fe3 -
Trigger Event:
push
-
Statement type: