A general-purpose rules engine for Go supporting multiple rule types, sequential evaluation, and config-driven rule definitions.
- Five Rule Types: Assignment, Formula, Allocation, Lookup, Buildup
- Expression DSL: Simple expressions for config-driven formulas
- Thread-Safe: Concurrent-safe evaluation context
- Observable: Pluggable logging, metrics, and tracing
- Zero Dependencies: stdlib only
go get github.com/kolosys/cortexpackage main
import (
"context"
"fmt"
"math"
"github.com/kolosys/cortex"
)
func main() {
engine := cortex.New("payroll", cortex.DefaultConfig())
// Register lookup table
engine.RegisterLookup(cortex.NewRangeLookup("tax_brackets", []cortex.RangeEntry[float64]{
{Min: 0, Max: 50000, Value: 0.10},
{Min: 50000, Max: 100000, Value: 0.22},
{Min: 100000, Max: math.Inf(1), Value: 0.35},
}))
// Add rules
engine.AddRules(
cortex.MustAssignment(cortex.AssignmentConfig{
ID: "salary", Target: "salary", Value: 75000.0,
}),
cortex.MustLookup(cortex.LookupConfig{
ID: "rate", Table: "tax_brackets", Key: "salary", Target: "tax_rate",
}),
cortex.MustFormula(cortex.FormulaConfig{
ID: "tax", Target: "tax", Expression: "salary * tax_rate",
}),
cortex.MustAllocation(cortex.AllocationConfig{
ID: "split", Source: "salary", Strategy: cortex.StrategyPercentage,
Targets: []cortex.AllocationTarget{
{Key: "dept_eng", Amount: 60},
{Key: "dept_ops", Amount: 40},
},
}),
)
// Evaluate
evalCtx := cortex.NewEvalContext()
result, _ := engine.Evaluate(context.Background(), evalCtx)
fmt.Printf("Success: %v, Rules: %d\n", result.Success, result.RulesEvaluated)
tax, _ := evalCtx.GetFloat64("tax")
fmt.Printf("Tax: $%.2f\n", tax) // Tax: $16500.00
}Set values directly on the context:
cortex.MustAssignment(cortex.AssignmentConfig{
ID: "set-salary",
Target: "salary",
Value: 75000.0,
})Calculate values using expressions or Go functions:
// Expression-based
cortex.MustFormula(cortex.FormulaConfig{
ID: "calc-tax",
Target: "tax",
Expression: "salary * tax_rate",
})
// Function-based
cortex.MustFormula(cortex.FormulaConfig{
ID: "calc-bonus",
Target: "bonus",
Formula: func(ctx context.Context, e *cortex.EvalContext) (any, error) {
salary, _ := e.GetFloat64("salary")
return salary * 0.10, nil
},
})Distribute values across targets:
cortex.MustAllocation(cortex.AllocationConfig{
ID: "split",
Source: "budget",
Strategy: cortex.StrategyPercentage,
Targets: []cortex.AllocationTarget{
{Key: "eng", Amount: 50},
{Key: "ops", Amount: 30},
{Key: "admin", Amount: 20},
},
})Strategies: StrategyPercentage, StrategyFixed, StrategyWeighted, StrategyEqual, StrategyRatio
Retrieve values from lookup tables:
// Map lookup
engine.RegisterLookup(cortex.NewMapLookup("status", map[string]int{
"active": 1, "inactive": 0,
}))
// Range lookup (tax brackets)
engine.RegisterLookup(cortex.NewRangeLookup("rates", []cortex.RangeEntry[float64]{
{Min: 0, Max: 50000, Value: 0.10},
{Min: 50000, Max: 100000, Value: 0.22},
}))
cortex.MustLookup(cortex.LookupConfig{
ID: "get-rate",
Table: "rates",
Key: "income",
Target: "rate",
})Accumulate values (running totals):
cortex.MustBuildup(cortex.BuildupConfig{
ID: "add-total",
Buildup: "running_total",
Operation: cortex.BuildupSum,
Source: "amount",
Target: "current_total",
})Operations: BuildupSum, BuildupMin, BuildupMax, BuildupAvg, BuildupCount, BuildupProduct
Supported in config-driven formulas:
Arithmetic: +, -, *, /, %
Comparison: ==, !=, <, >, <=, >=
Logical: &&, ||, !
Functions: min, max, abs, floor, ceil, round, if, sqrt, pow
Examples:
"base_salary * tax_rate"
"if(age >= 65, senior_discount, 0)"
"round(total * 0.0825, 2)"
import "github.com/kolosys/cortex/parse"
json := `{
"version": "1.0",
"name": "payroll",
"rules": [
{"id": "salary", "type": "assignment", "config": {"target": "salary", "value": 75000}},
{"id": "tax", "type": "formula", "config": {"target": "tax", "expression": "salary * 0.22"}}
]
}`
parser := parse.NewParser()
engine, _ := parser.ParseAndBuildEngine("payroll", []byte(json), nil)ModeFailFast(default): Stop on first errorModeCollectAll: Evaluate all rules, collect errorsModeContinueOnError: Log errors, continue evaluation
MIT