A runtime rules engine for airline retailing — and any other domain whose business logic lives in a directed graph of filters, lookups, mutations and sub-rule calls. Sub-millisecond hot path, traces on demand, sibling project to DocumentForge.
Most rule engines lock business logic inside code or behind a heavyweight BPMN runtime. RuleForge takes a different bet: rules are JSON documents — directed graphs of small, well-typed nodes — that anyone with the right admin app can author, version, and pin per environment. The engine reads them at boot, caches aggressively, and evaluates each request in microseconds.
Each rule is an immutable snapshot. Environments pin a specific version. The engine resolves endpoint + method → ruleId → version → snapshot with all three steps cached.
~70µs p50 for an 8-node rule (filters, AND, product, two mutators, calc). 73,000 req/s on 16 workers. The brief targets <5ms; the engine clears it by 70×.
input · output · filter (string / number / date) · logic (and / or / xor / not) · product · mutator (set / lookup-replace) · calc · constant · ruleRef + subRuleCall.
Any node can invoke another rule. inputMapping builds the sub-request, outputMapping writes back into parent ctx or onto the host node's output. onError: skip|fail|default handles non-apply outcomes.
The lookup-and-replace mutator pulls a row from a versioned referenceSets doc and writes one column onto the upstream object. Price matrices, FX tables, country codes, all live in DocumentForge.
Add ?debug=true or X-Debug: true and the envelope carries a per-node trace plus a wall-clock durationMs. Production mode skips both.
Every evaluation produces the same envelope shape: a ruleId, the evaluated version, a decision (apply | skip | error), the rule-specific result, and an optional trace. The decision tells the caller what to do; the result is the rule's payload.
// POST /v1/ancillary/bag-policy?debug=true { "ruleId": "rule-bag-policy", "ruleVersion": 7, "decision": "apply", "evaluatedAt": "2026-04-27T10:14:04.614Z", "result": { "code": "BAG", "weightKg": 23, "currency": "AED", "fee": 517.5, "pieces": 3 }, "trace": [/* per-node, only in debug mode */], "durationMs": 47 }
RuleForge is the runtime. It does not author rules — that's a job for the admin app of your choice (we built one called AERO; you can build your own). The engine consumes the JSON output of whatever editor you have, evaluates against an inbound request, and emits the envelope. Authoring concerns like locked-paths, friendly labels, and template hierarchies are stripped away by publish time.
The result: an engine you can run anywhere — Render, k8s, a single VM, or alongside DocumentForge as a co-located sidecar where the cold-path is 2.5ms instead of 1500ms across the public internet.
Models, evaluators, DAG walker, JSONPath subset, rule + reference-set source interfaces. Zero ASP.NET dependency.
Thin HTTP client + IRuleSource / IReferenceSetSource implementations. Caches rule snapshots indefinitely (immutable per version).
ASP.NET Core entrypoint with auto-binding. Reads every endpoint from the rule source at boot and registers it. X-AERO-Key auth on top.
One binary with four verbs: run, publish, mirror, bench. Run a rule in-process or against a deployed engine; publish to DocumentForge; copy collections between instances; benchmark.