1. Registry Overview
874 total rules across 15 rule types, 11 formula functions, 6 engine rule classes, and 5 use case domains.
2. Formula Language Specification
The Wormwood formula language is a deterministic, sandboxed expression language parsed by FormulaParser. It supports two modes: standalone (direct attribute paths) and legacy Excel (cell references with mappings). All formula evaluation is side-effect-free: no loops, no I/O, no mutable state. The same input always produces the same output.
2.1 Operator Precedence (Lowest to Highest)
| Level |
Operators |
Associativity |
Description |
| 1 |
? : |
Right |
Ternary conditional |
| 2 |
\ |
\ |
|
Left |
Logical OR |
| 3 |
&& |
Left |
Logical AND |
| 4 |
== != > < >= <= |
Left |
Comparison |
| 5 |
+ - |
Left |
Addition, subtraction |
| 6 |
/ |
Left |
Multiplication, division |
| 7 |
^ |
Right |
Exponentiation |
| 8 |
! NOT |
Unary |
Boolean negation |
| 9 |
() |
n/a |
Grouping |
2.2 Built-in Functions
| Function |
Signature |
Description |
Example |
SUM |
SUM(a, b, ...) |
Sum of non-null arguments |
SUM(capex.racks, capex.ups, capex.gen) |
ROUNDUP |
ROUNDUP(value [, decimals]) |
Ceiling round; optional precision |
ROUNDUP(power.it_load_kw) |
ROUND |
ROUND(value [, decimals]) |
Standard rounding; default 0 decimals |
ROUND(score.total, 2) |
MAX |
MAX(a, b, ...) |
Maximum of non-null arguments |
MAX(score.a, score.b) |
MIN |
MIN(a, b, ...) |
Minimum of non-null arguments |
MIN(budget.low, budget.high) |
IF |
IF(cond, true_val, false_val) |
Conditional value selection |
IF(entity.status == 'Active', 1, 0) |
ABS |
ABS(value) |
Absolute value |
ABS(delta.variance) |
SQRT |
SQRT(value) |
Square root |
SQRT(power.total_kw) |
IN |
IN(value, opt1, opt2, ...) |
Membership test against value list |
IN(entity.material, 'Carbon Steel', 'Duplex') |
REGEX_MATCH |
REGEX_MATCH(text, pattern) |
Regex match against pattern |
REGEX_MATCH(entity.tag, '^[A-Z]{2}-') |
TOPK_AVG |
TOPK_AVG(k, v1, v2, ...) |
Average of top-K non-null values |
TOPK_AVG(3, s.a, s.b, s.c, s.d) |
2.3 Literals and Data Types
| Type |
Syntax |
Internal Representation |
| Number |
42, 3.14, 0.615385 |
Python float |
| String |
'fixed' or "negotiable" |
Python str |
| Boolean |
TRUE, FALSE |
1.0 / 0.0 |
| Null |
null |
Python None |
| Attribute path |
entity.tag, budget.amount |
Dot-path resolution against context dict |
| Cell reference |
$C83, I57 |
Legacy mode only; resolved via cell_mappings |
2.4 Expression Modes
Standalone Mode (Current Standard)
Formulas use direct attribute paths: assumptions.rack_cost rack.total_racks 1000. The parser resolves paths against the calculation context dictionary. This is the mode used by all NSD rulesets.
Legacy Excel Mode (Backward Compatibility)
Formulas use cell references with an explicit mapping: =C75 I57 1000 with cell_mappings = {"C75": "assumptions.rack_cost", "I57": "rack.total_racks"}. This mode exists for Pyrometrix TCO rules imported directly from Excel spreadsheets. New rulesets MUST NOT use this mode.
3. Engine Rule Classes
The RuleEngine (wormwood/core/rule_engine.py) classifies rules into six execution classes, each with a default priority band. Rules execute in descending priority order within a calculation pass.
| Class |
Enum Value |
Default Priority |
Purpose |
Execution Phase |
| Validation |
VALIDATION |
200+ |
Check inputs, enforce constraints, flag errors |
First -- reject bad data before calculations |
| Consolidation |
CONSOLIDATION |
150+ |
Apply baseline fixes, resolve defaults, normalise |
Second -- clean data for downstream rules |
| Calculation |
CALCULATION |
100+ |
Core business logic: CAPEX, OPEX, power, scoring |
Third -- primary value computation |
| Adjustment |
ADJUSTMENT |
50+ |
Technology-specific tweaks, overrides, modifiers |
Fourth -- refine calculation results |
| Escalation |
ESCALATION |
10+ |
Time-based escalation (year-over-year growth, decay) |
Fifth -- apply temporal factors |
| Aggregation |
AGGREGATION |
1 |
Final summing, total computation, report output |
Last -- produce final results |
Why Six Classes?
Each class represents a logical phase in the calculation pipeline. Validation must run before Calculation so that invalid inputs fail early. Consolidation normalises data (e.g., applying default material for valves without one specified). Adjustments apply after core calculations so technology-specific modifiers do not pollute the base logic. Escalation applies last because it multiplies already-computed values by time factors. Aggregation sums everything. This order is deterministic and guaranteed regardless of rule registration order.
4. Rule Type Registry
Each JSON rule file declares a type field that classifies the rule into a domain. The following 15 rule types exist across 25 JSON files in wormwood/rules/.
4.1 Infrastructure Domain (Pyrometrix TCO)
| Type |
Directory |
Count |
Description |
Technologies |
capex |
capex/ |
65 |
Capital expenditure calculations: racks, cooling, UPS, generators, electrical, site prep, engineering |
traditional, dlc, rdhx, grc |
opex |
opex/ |
148 |
Operational expenditure: power, maintenance, staffing, PUE factors, year-over-year escalation |
traditional, dlc, rdhx, grc |
power |
infrastructure/ |
8 |
Electrical power chain: IT load, cooling, UPS, total DC power |
all |
infrastructure |
infrastructure/ |
3 |
Rack counts, floor space, power density |
all |
energy |
infrastructure/ |
4 |
Energy efficiency: PUE, annual consumption, carbon |
all |
tco |
tco/ |
10 |
Total cost of ownership: year summation, NPV, 10-year horizon |
traditional, dlc, rdhx, grc |
4.2 EDR Domain (Entity Data Registry)
| Type |
Directory |
Count |
Description |
Entity Classes |
edr_validation |
edr/ |
19 |
Tag format, valve size, pressure rating, power rating, material standard, safety classification, voltage, instrument range, completeness scoring, quality tier |
Valve, Pipeline, Equipment, Electrical, Instrument, Safety |
validation |
edr/ |
12 |
Consolidation and cross-entity validation: duplicates, orphan detection |
All |
4.3 Nesto Domain (Worker Compliance)
| Type |
Directory |
Count |
Description |
Countries |
nesto_compliance |
nesto/ |
17 |
Passport, nationality, visa type, emirate, sponsor, medical fitness, biometrics, occupation code, contract dates, salary range, accommodation type, insurance, WPS, bank, labour card, MOHRE approval, Emirates ID |
UAE, KSA, BH |
4.4 Freelance Pipeline Domain
| Type |
Directory |
Count |
Description |
scoring |
freelance/ |
10 |
Job opportunity scoring: budget clarity, competition level, deadline pressure, scope clarity, tech stack match, client history, rate fit, recency, portfolio relevance, final composite |
policy |
freelance/ |
11 |
Pricing policy: minimum hourly rate, project floor, platform fee adjustment, currency normalisation, rush surcharge, complexity multiplier |
assignment |
freelance/ |
4 |
Tier assignment: gold/silver/bronze based on composite score thresholds |
4.5 PFP Domain (Product Fit Profile)
| Type |
Directory |
Count |
Description |
pfp_clearance |
pfp/ |
537 |
Product clearance rules: compliance checks, compatibility matrices, regulatory clearance per jurisdiction |
pfp_selection |
pfp/ |
9 |
Product selection logic: technology matching, priority ordering |
pfp_validation |
pfp/ |
17 |
Profile input validation: required fields, range checks, format validation |
5. Rule JSON Schema
Every rule in wormwood/rules//.json follows this schema. Fields marked Required are mandatory for all rule types. Fields marked Domain are present in specific domains.
| Field |
Type |
Status |
Description |
id |
string |
Required |
Unique rule identifier. Convention: {domain}_{category}_{seq}_{slug} |
name |
string |
Required |
Human-readable rule name |
type |
string |
Required |
Rule type from Section 4 registry |
priority |
integer |
Required |
Execution priority (higher = runs first) |
technology |
string |
Required |
Technology scope: traditional, dlc, rdhx, grc, edr, nesto, pipeline, or all |
formula |
string |
Required |
Wormwood formula expression (Section 2) |
output |
string |
Required |
Dot-path where result is stored in context |
description |
string |
Required |
Human-readable description of what the rule does |
enabled |
boolean |
Required |
Whether the rule is active |
excel_source |
string |
Domain |
Pyrometrix only: original Excel cell reference |
severity |
string |
Domain |
EDR/Nesto: ERROR, WARNING, INFO |
applies_to |
string |
Domain |
EDR: entity class filter (Valve, Pipeline, All) |
countries |
array |
Domain |
Nesto: ISO country codes where rule applies |
edr_source |
string |
Domain |
EDR: source table or property reference |
validation |
object |
Domain |
Expected range, baseline value, tolerance percentage, test cases |
6. Technology Scoping
Rules are scoped to a technology via the technology field. When the engine evaluates rules for a given technology context, only rules matching that technology (or all) are executed.
| Technology |
Domain |
Description |
traditional |
Pyrometrix |
Air-cooled data centre (baseline comparison) |
dlc |
Pyrometrix |
Direct liquid cooling |
rdhx |
Pyrometrix |
Rear-door heat exchanger |
grc |
Pyrometrix |
Green Revolution Cooling immersion |
edr |
EDR |
Entity Data Registry (Wormwood core) |
nesto |
Nesto |
Worker compliance, UAE/KSA/BH jurisdictions |
pipeline |
Freelance |
Job scoring and pricing pipeline |
all |
Cross-domain |
Infrastructure and power rules shared across all technologies |
7. Registry Versioning
This registry is versioned independently from other Nexus documents. The NSD references the registry version it was built against. If a new rule type or formula function is added, the registry version increments and all NSD references must be updated.
| Version |
Date |
Changes |
| RR-1.0 |
2026-05-02 |
Initial registry: 874 rules, 15 types, 11 functions, 6 engine classes. Extracted from codebase implementation. |
Referencing This Registry
The NSD rulesets section references registry version via: "rule_registry_version": "RR-1.0". The DevOps Service validates that all rule types used in the NSD are declared in the referenced registry version. Undeclared rule types cause deployment rejection.