Skip to content

PyRulesEngine Architecture

PyRulesEngine is built with an enterprise-grade focus on performance, scalability, and strict safety guardrails. It embraces SOLID principles and relies on asynchronous I/O and non-blocking abstractions.

Core Component Diagram

graph TD
    API[FastAPI / App Layer] --> Engine[RulesEngine]
    Engine --> Storage[StorageManager]
    Storage --> FileProvider[FileStorageProvider]
    Storage --> DBProvider[Custom Storage Providers]
    Engine --> Evaluator[Evaluator]
    Engine --> Actions[Action Registry]
    Evaluator --> Context[ActionContext]
    Actions --> |Triggers|Engine

The Storage Layer

A decoupled storage architecture ensures workflows are environment-agnostic.

  1. BaseStorageProvider: The abstract layer. Providers must implement parsing methods returning Workflow objects.
  2. FileStorageProvider: Bundled native provider that scans directories for .yaml (preferred) and .json JDM files.
  3. StorageManager:
  4. Acts as an intelligent in-memory cache proxy.
  5. Indexes files dynamically by (WorkflowName, Version).
  6. Thread-safe (asyncio.Lock protected caching).
  7. Allows live-reloading of modifications without application restarts using .reload().

SemVer "Latest" Resolution

When you request execution via execute_all_rules_async("MyWorkflow", inputs, version="latest"), the Storage Manager intelligently scans the cached index, executes native Semantic Versioning (semver) comparisons against all registered formats, and automatically routes the request to the highest tagged version.

The Execution Engine

The central RulesEngine leverages a synchronous AST traversal embedded in an asynchronous orchestrator wrapper.

Execution Flow: 1. Global Input sanitization. 2. Namespace instantiation (combining global inputs with local mapped parameters). 3. Evaluator dispatch (e.g., recursive branch iterations like AND, OR). 4. Action Hooks dispatch (triggers asynchronous side-effects on success/failure).

Short-Circuit Optimization: Operators like AndAlso and OrElse natively return preemptive WasSkipped results if their parent conditions establish an early logical conclusion, protecting system resources against expensive database calls inside deeper expression queries.

Security & Resilience (OWASP Hardened)

By design, expression evaluators in dynamic engines represent extremely high-risk attack surfaces (RCE - Remote Code Execution vectors).

  • No Unsafe Execution: PyRulesEngine entirely avoids eval() and insecure AST-based evaluators. It uses Google's Common Expression Language (CEL) via the celpy library. CEL is intentionally limited and non-Turing complete, preventing arbitrary code execution and infinite loops.
  • NLQ Validation Gate: LLM-generated rules undergo a mandatory CEL Syntax Validation phase. If a generated rule contains syntax errors, the MCP server automatically triggers a self-healing refinement loop to correct the JDM schema before deployment.
  • Stack Exhaustion Prevention: Complex JDM branches or nested files are natively bounded by deterministic limits.
  • max_chain_depth: Stops circular action loops (e.g., Workflow A -> B -> A).
  • max_nesting_depth: Rejects configuration schemas with recursively malicious branch depth.
  • Safe Unboxing: CEL evaluation results are "unboxed" into standard Python primitives (bool, int, float, str) only after successful validation, ensuring consumer-side type safety.
  • Sanitized Exceptions: Unhandled failures (e.g., missing dictionary keys) are caught and scrubbed. Only safe high-level error reasons are returned to prevent stack trace leakage (OWASP A9).