Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ruler Laravel Package

hoa/ruler

Hoa/ruler is a PHP rule engine for defining and evaluating business rules with a dedicated, expressive language. It supports stateless production rules, rule manipulation, proposition evaluation, and integration into PHP applications. Use it to model conditions and make declarative decisions.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. hoa/ruler is a framework-agnostic business rule engine: you hand it a rule string (logged(user) and user.age > 18) plus a context array/object, and it returns a boolean (Ruler::assert($rule, $context)). That is a legitimate fit for eligibility checks, pricing/discount logic, feature gating, and routing rules that business stakeholders want to change without a deploy. It is not a decision-table or workflow engine — no rule persistence, no versioning, no authoring UI, no evaluation audit trail, no explainability output. Every one of those capabilities is a layer we would build and own around the library. Treat it as a parser + evaluator, not a rules platform.

Integration feasibility. Installable via Composer, but it drags in the full Hoa dependency tree (hoa/compiler, hoa/ustring, hoa/visitor, hoa/stream, hoa/consistency, hoa/zformat, hoa/exception). Hoa bootstraps a custom hoa:// stream wrapper and constants at autoload time — a side effect we would be introducing into a Laravel request lifecycle. There is no service provider, facade, config, or container awareness; the adapter is entirely ours to write. Context hydration (mapping Eloquent models, guards, and request data into the evaluator's array shape) remains the bulk of the integration work. The latest release, 2.17.05.16 (2017-05-16), marginally reduces that work: the Asserter can now visit array-like dimensions, meaning context objects exposing ArrayAccess-style offsets (Eloquent models, ArrayObject, some value objects) can be traversed directly instead of being flattened into plain arrays first. Useful, but incremental — it does not eliminate the need for a normalisation layer, since guards, DTOs, and relations still have heterogeneous shapes.

Technical risk. High. The repository is archived, the last release is 2017-05-16, and the Hoa project itself is disbanded. The 2.17.05.16 note confirms rather than changes this: a single-commit feature release from May 2017 is the terminal state of the project, not evidence of renewed maintenance. There is no security response process, no PHP 8.x maintenance, and transitive dependencies (hoa/compiler, hoa/ustring) that are known to trip on deprecations and removals introduced in PHP 8.1+. The 619 stars / 0 listed dependents combination is a weak ecosystem-validation signal for a modern Laravel stack. Licensing (BSD-family — verify) permits a fork, but not free maintenance. Secondary risk: rules are configuration authored by humans, so parse failures surface at runtime unless we validate at write time. The array-dimension capability also introduces a new failure surface — behaviour when a dimension is absent, or when an ArrayAccess implementation throws — that is undocumented and must be pinned by tests before we rely on it.

Key questions.

  • Which PHP version and Laravel major are we targeting, and is there an Octane requirement (static bootstrap + stream wrapper conflict)?
  • Is a DSL genuinely required, or would decision tables in JSON/config cover 90% of cases with less risk?
  • Who authors rules — engineers in PRs, or business users in an admin UI? That determines the validation and UX investment.
  • Do we need per-evaluation auditability or "why did this match" explanations for compliance?
  • What is the evaluation latency budget and expected call volume?
  • Does direct ArrayAccess traversal change our context contract, and what is the defined behaviour for missing dimensions?
  • Who owns an internal fork, and for how long?

Integration Approach

Stack fit. Define our own RuleEngine contract (evaluate / validate / explain), bind it in a service provider, expose a thin facade, and put the Hoa calls behind it. Keep the DSL surface in config (allowed functions, allowed context keys, comparison operators) so we can swap the underlying engine without touching call sites. This interface-first framing is the single most important decision — it converts an abandoned dependency into a replaceable implementation detail. Given 2.17.05.16, define the context contract in terms of plain arrays first and treat ArrayAccess traversal as an optional optimisation the adapter may exploit, so the contract does not become coupled to a Hoa-specific behaviour.

Migration path. If we proceed, do not depend on hoa/ruler directly from Packagist. Fork it into our VCS, pin a patch branch, add PHP 8 compatibility fixes and a test suite, and consume it as a path/VCS repository. Capture 2.17.05.16 as the exact baseline commit so the array-dimension behaviour is reproducible. In parallel, spike symfony/expression-language as the primary comparator: it is maintained, PHP 8-ready, has an explicit sandbox for untrusted expressions, supports attribute access on arrays and objects, and its syntax (and/or/not, registered functions) is close enough that most rules translate mechanically. The honest recommendation is still to adopt Symfony's engine behind the same adapter and skip Hoa unless the spike proves otherwise.

Compatibility. Verify Composer constraints against Laravel 10/11 and PHP 8.1+. Watch for conflicts between pinned hoa/* versions and Symfony components Laravel already ships — that is a realistic install-time blocker. The 2.17.05.16 feature is behaviourally additive, so it introduces no migration obligation for existing rules, but it does mean any previously flattened context can now be passed through — adopt that deliberately, not implicitly.

Sequencing.

  1. Two-day spike: install on the target PHP, encode 10 representative production rules, measure parse/eval cost, confirm no deprecation noise.
  2. Build-vs-fork decision gate against symfony/expression-language.
  3. Adapter + golden-file rule corpus as a regression harness (this corpus is the migration insurance), explicitly including array-like/ArrayAccess context cases and missing-dimension cases so the 2.17.05.16 behaviour is locked down.
  4. Rule persistence, versioning, and a compiled-rule cache.
  5. Authoring surface (admin UI or config-PR workflow) with schema validation at save time.
  6. Observability: per-rule evaluation counts, error rates, and shadow-mode rollout before enforcement.

Operational Impact

Maintenance. We become the maintainer. That means PHP upgrade churn on a codebase nobody on the team wrote, plus the ongoing cost of an abandoned dependency appearing in SCA reports and slowing down procurement/audit reviews. Budget it as an owned internal component, not a third-party library. The 2.17.05.16 release changes nothing here — it is the last thing upstream shipped, and it shipped in 2017.

Support. No upstream, no CVE feed, no issue triage. Community answers are five-plus years stale and predate modern PHP. Internal documentation and tests are the only support surface.

Scaling. Evaluation is CPU-bound: grammar compilation dominates, then AST traversal. Compiling the rule string on every request is the default and is wasteful at volume — cache the parsed/compiled artifact keyed by rule hash, and memoize per-request when evaluating the same rule across a collection. Throughput is fine for per-request decision points; it is a poor fit for tight loops over large datasets without pre-compilation. Passing live ArrayAccess objects into evaluation can trigger lazy loading or query fan-out if those objects are Eloquent-backed — resolve hydration eagerly and pass plain structures at high volume.

Failure modes.

  • Runtime parse errors from human-authored rules — validate on save, fail closed on evaluate.
  • Missing function or context key raising an exception mid-request — wrap and convert to a typed domain error.
  • Missing or null array-like dimension under the new traversal path — undefined upstream; must be an explicit, tested decision.
  • Silent mis-evaluation from loose type comparison, null handling, and float precision — encode these as explicit test cases in the golden corpus.
  • Bootstrap/stream-wrapper side effects surfacing under Octane or in queued workers.
  • No built-in "why" output, so debugging a false result is manual tracing.

Ramp-up. The DSL itself is small — a competent developer is productive in a day. The real ramp is the surrounding discipline: context shaping, rule testing, versioning, and safe rollout. Business users cannot safely author raw rule strings without a validating UI, so plan for an engineering-mediated authoring flow in v1.

Verdict. Conditional no-go for greenfield adoption, unchanged by release 2.17.05.16. The array-dimension support in Asserter is a small, welcome ergonomics gain for hydrating Eloquent- and collection-shaped context, but it arrives four years after the project was abandoned and does not alter the maintenance, security, or PHP 8 exposure. Adopt symfony/expression-language behind an internal rule-engine abstraction, or buy a managed rules product; fork hoa/ruler only if the spike proves it clean and the rule corpus is small, stable, and owned by a team prepared to maintain it indefinitely.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle