guardrail-sim
byJeff Green

Constraints

Rules that policies enforce

Constraints

In guardrail-sim, constraints are implemented as policy rules using json-rules-engine. Each rule defines conditions that must be satisfied for a discount to be approved.

Default Constraints

The default policy includes these constraint rules:

Margin Floor

Ensures minimum margin is maintained after discount.

{
  name: 'margin_floor',
  conditions: {
    all: [{
      fact: 'calculated_margin',
      operator: 'lessThan',
      value: 0.15  // 15% minimum margin
    }]
  },
  event: {
    type: 'violation',
    params: { message: 'Margin falls below 15% floor' }
  }
}

Maximum Discount

Caps the total discount percentage.

{
  name: 'max_discount',
  conditions: {
    all: [{
      fact: 'proposed_discount',
      operator: 'greaterThan',
      value: 0.25  // 25% maximum
    }]
  },
  event: {
    type: 'violation',
    params: { message: 'Discount cannot exceed 25%' }
  }
}

Volume Tier

Requires minimum quantity for larger discounts.

{
  name: 'volume_tier',
  conditions: {
    all: [
      { fact: 'quantity', operator: 'lessThan', value: 100 },
      { fact: 'proposed_discount', operator: 'greaterThan', value: 0.10 }
    ]
  },
  event: {
    type: 'violation',
    params: { message: 'Discount >10% requires quantity >= 100' }
  }
}

Creating Custom Constraints

Add new constraint rules to your policy:

import type { PolicyRule } from '@guardrail-sim/policy-engine';
 
// Customer segment constraint
const goldOnlyRule: PolicyRule = {
  name: 'gold_tier_discount',
  conditions: {
    all: [
      { fact: 'proposed_discount', operator: 'greaterThan', value: 0.15 },
      { fact: 'customer_segment', operator: 'notEqual', value: 'gold' }
    ]
  },
  event: {
    type: 'violation',
    params: { message: 'Discounts over 15% require Gold tier' }
  }
};

Condition Logic

ALL Conditions (AND)

All conditions must be true for the rule to trigger:

conditions: {
  all: [
    { fact: 'quantity', operator: 'lessThan', value: 50 },
    { fact: 'proposed_discount', operator: 'greaterThan', value: 0.20 }
  ]
}
// Triggers only if quantity < 50 AND discount > 20%

ANY Conditions (OR)

At least one condition must be true:

conditions: {
  any: [
    { fact: 'customer_segment', operator: 'equal', value: 'new' },
    { fact: 'quantity', operator: 'lessThan', value: 10 }
  ]
}
// Triggers if customer is new OR quantity < 10

Nested Conditions

Combine ALL and ANY for complex logic:

conditions: {
  all: [
    { fact: 'proposed_discount', operator: 'greaterThan', value: 0.20 },
    {
      any: [
        { fact: 'customer_segment', operator: 'notEqual', value: 'platinum' },
        { fact: 'order_value', operator: 'lessThan', value: 10000 }
      ]
    }
  ]
}
// Discount > 20% AND (not platinum OR order < $10k)

Available Operators

OperatorDescriptionExample
equalExact match{ fact: 'segment', operator: 'equal', value: 'gold' }
notEqualNot equal{ fact: 'segment', operator: 'notEqual', value: 'new' }
lessThanLess than{ fact: 'margin', operator: 'lessThan', value: 0.15 }
lessThanInclusiveLess than or equal{ fact: 'discount', operator: 'lessThanInclusive', value: 0.25 }
greaterThanGreater than{ fact: 'quantity', operator: 'greaterThan', value: 100 }
greaterThanInclusiveGreater than or equal{ fact: 'value', operator: 'greaterThanInclusive', value: 5000 }
inValue in array{ fact: 'segment', operator: 'in', value: ['gold', 'platinum'] }
notInValue not in array{ fact: 'category', operator: 'notIn', value: ['clearance'] }
containsArray contains value{ fact: 'tags', operator: 'contains', value: 'vip' }

Constraint Evaluation Order

Constraints are evaluated by rule priority (higher numbers first). Use priorities to:

  1. Fail fast: Check time/eligibility constraints first
  2. Layer logic: Apply volume tiers before final caps
  3. Ensure order: Run margin checks before stacking rules

On this page