Metadata-Version: 2.4
Name: wrg-rule-lab
Version: 0.1.7
Summary: WinstonRedGuard local-first deterministic rule evaluation engine (formerly rule-lab on PyPI, republished under WRG namespace)
Author: WinstonRedGuard
License-Expression: MIT
Project-URL: Homepage, https://github.com/WRG-11/wrg-rule-lab
Project-URL: Repository, https://github.com/WRG-11/wrg-rule-lab
Project-URL: Documentation, https://github.com/WRG-11/wrg-rule-lab#readme
Project-URL: Issues, https://github.com/WRG-11/wrg-rule-lab/issues
Project-URL: Changelog, https://github.com/WRG-11/wrg-rule-lab/blob/main/CHANGELOG.md
Project-URL: Author, https://github.com/WRG-11
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: OS Independent
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: pytest>=9.0.3; extra == "dev"
Dynamic: license-file

# wrg-rule-lab

> 💡 **Found this useful?** ⭐ Star the repo (helps others find it) and subscribe to weekly detection-engineering writeups at [Detection Frontier](https://detection-frontier.kit.com/subscribe).

[![PyPI version](https://img.shields.io/pypi/v/wrg-rule-lab.svg)](https://pypi.org/project/wrg-rule-lab/)
[![Python 3.11+](https://img.shields.io/pypi/pyversions/wrg-rule-lab.svg)](https://pypi.org/project/wrg-rule-lab/)
[![CI](https://github.com/WRG-11/wrg-rule-lab/actions/workflows/ci.yml/badge.svg)](https://github.com/WRG-11/wrg-rule-lab/actions/workflows/ci.yml)
[![CodeQL](https://github.com/WRG-11/wrg-rule-lab/actions/workflows/codeql.yml/badge.svg)](https://github.com/WRG-11/wrg-rule-lab/actions/workflows/codeql.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Coverage](https://img.shields.io/badge/coverage-92%25-brightgreen)](#)

> **Replace your scattered `if/else` policy 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

```bash
pip install wrg-rule-lab
```

```python
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:

```python
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:

```json
{
  "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

```bash
# 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](https://www.drools.org/) | Forward-chaining rules engine | JVM ecosystem | DRL (custom DSL) | Yes | Enterprise Java with complex inference chains |
| [py-rules-engine](https://pypi.org/project/rule-engine/) | Boolean expression evaluator | `pyparsing` | Python-ish expression strings | No | Embedded boolean checks in larger apps |
| [JSON Schema](https://json-schema.org/) | Declarative validation | `jsonschema` | JSON | N/A (validation only) | Data shape validation (not decisions) |
| [Pydantic validators](https://docs.pydantic.dev/) | 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/else` policy 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

```json
{
  "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`](https://pypi.org/project/instinct-mcp/) — Self-learning memory for AI coding agents (MCP server)
- [`wrg-devguard`](https://pypi.org/project/wrg-devguard/) — Developer-first AI safety: prompt-policy lint + secret scanning + log scanning with PII detection
- [`wrg-mcp-server`](https://pypi.org/project/wrg-mcp-server/) — MCP bridge for the WinstonRedGuard monorepo (60+ security/threat-intel tools)
- [`ai-security-toolkit`](https://github.com/WRG-11/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](https://github.com/WRG-11).
