Project 9: Pricing Rules DSL

Build a safe pricing-expression language with temporal conditions, margin guards, and full execution traces.

Quick Reference

Attribute Value
Difficulty Level 4 (Expert)
Time Estimate 3-4 weeks
Main Programming Language Python (Alternatives: TypeScript, Kotlin, Scala)
Coolness Level Level 4
Business Potential 4. Open Core Infrastructure
Prerequisites Projects 3 and 8, expression evaluation fundamentals
Key Topics Safe eval, temporal logic, traceability, publish gates

1. Learning Objectives

  1. Design a constrained expression language for pricing logic.
  2. Sandbox execution with strict limits and allowlisted functions.
  3. Generate per-rule execution traces for audit replay.
  4. Integrate DSL runtime with pricing and approval workflows.

2. All Theory Needed (Per-Concept Breakdown)

Concept A: Safe Expression Runtime

Fundamentals Pricing DSLs must be expressive enough for analysts but constrained enough to prevent unsafe behavior and margin leakage.

Deep Dive into the concept Use an allowlisted function set, operation budgets, and static checks before runtime. Keep expressions pure and side-effect free. Emit deterministic traces for every applied rule.

How this fit on projects Primary here; integrates with P03-pricing-engine-core.md and P10-visual-rule-builder.md.

Definitions & key terms

  • Expression budget
  • Function allowlist
  • Trace span

Mental model diagram

Pricing DSL -> Parse -> Validate -> Sandbox Eval -> Pricing Delta + Trace

How it works

  1. Parse expression rule.
  2. Validate allowed operators/functions.
  3. Execute under budget.
  4. Emit delta and trace.

Minimal concrete example

when segment == "Enterprise" then discount = min(0.12, margin_guard(0.22))

Common misconceptions

  • “Pricing DSL can expose general-purpose scripting.” This is dangerous and unnecessary.

Check-your-understanding questions

  1. Why enforce operation budgets?
  2. Why keep expression runtime pure?

Check-your-understanding answers

  1. To prevent runaway complexity.
  2. To keep outputs reproducible and auditable.

Real-world applications Promotion engines, dynamic discounts, contract adjustments.

Where you’ll apply it This project and P03-pricing-engine-core.md.

References

  • Oracle CPQ pricing scripting docs.
  • RFC 8259 JSON contracts.

Key insights A pricing DSL is valuable only when it stays safe and explainable.

Summary Constrained runtime + strong traces enable frequent business updates without code deploys.

Homework/Exercises to practice the concept Create one rule that fails static validation and one that fails budget checks.

Solutions to the homework/exercises Add validator for disallowed functions and max expression depth.

3. Project Specification

3.1 What You Will Build

A pricing DSL compiler/runtime that evaluates rule packs and emits deterministic deltas plus traces.

3.2 Functional Requirements

  1. Parse pricing expressions and conditions.
  2. Validate rule safety and compatibility.
  3. Evaluate expressions with bounded runtime.
  4. Emit rule traces and approval triggers.

3.3 Non-Functional Requirements

  • Performance: <300ms evaluation for 200 rules on medium quote.
  • Reliability: deterministic output for fixed fixtures.
  • Usability: analyst-readable rule errors.

3.4 Example Usage / Output

$ cpq pricing-dsl run --quote fixtures/quote_medium.json --rules pricing_rules.dsl
net=29990 approval_required=true

3.5 Data Formats / Schemas / Protocols

  • PricingRule(id, condition, expression, priority, effectiveRange)
  • RuleTrace(ruleId, matched, delta, runningTotal, durationMs)

3.6 Edge Cases

  • Circular variable references.
  • Out-of-range date logic.
  • Conflicting promotions.

3.7 Real World Outcome

3.7.1 How to Run (Copy/Paste)

$ cpq pricing-dsl validate pricing_rules.dsl
$ cpq pricing-dsl run --quote fixtures/quote_medium.json --rules pricing_rules.dsl

3.7.2 Golden Path Demo (Deterministic)

Rule pack + quote fixture yields same net and identical trace ordering every run.

3.7.3 If CLI: exact transcript

$ cpq pricing-dsl run --quote Q-2026-0120 --rules pricing_rules.dsl
[trace] R_PROMO_Q4 matched delta=-1500
[trace] R_SEGMENT_ENT matched delta=-1710
[trace] R_MARGIN_GUARD triggered approval=true
[result] net=29990

4. Solution Architecture

4.1 High-Level Design

DSL Parser -> Safety Validator -> Runtime Evaluator -> Trace Export -> Pricing Engine

4.2 Key Components

| Component | Responsibility | Key Decisions | |———–|—————-|—————| | Validator | static safety checks | allowlist + depth limits | | Evaluator | bounded expression runtime | deterministic context loading | | Trace Exporter | explainability output | per-rule span records |

4.4 Data Structures (No Full Code)

EvalContext { quote, customerSegment, dates, costbook }
EvalResult { netDelta, approvalTriggers, traces[] }

4.4 Algorithm Overview

  1. Compile rules to IR.
  2. Build quote context.
  3. Evaluate prioritized rules.
  4. Persist traces and results.

5. Implementation Guide

5.1 Development Environment Setup

$ cpq seed --scenario pricing-dsl
$ cpq test --suite pricing-dsl

5.2 Project Structure

pricing-dsl/
  src/
    grammar/
    validator/
    runtime/
    tracing/

5.3 The Core Question You’re Answering

“Can pricing policy changes move at business speed without opening security or margin risk?”

5.4 Concepts You Must Understand First

  • Expression parsing
  • Runtime sandboxing
  • Temporal policy logic

5.5 Questions to Guide Your Design

  • Which operators are allowed initially?
  • How do you cap evaluation cost?

5.6 Thinking Exercise

Model a maliciously expensive expression and design runtime containment.

5.7 The Interview Questions They’ll Ask

  1. How do you sandbox a business-authored expression engine?
  2. How do you guarantee auditability of dynamic pricing?
  3. How do you handle promotions with overlapping date windows?

5.8 Hints in Layers

  • Hint 1: no side-effect functions.
  • Hint 2: static checks before runtime.
  • Hint 3: trace every rule application.

5.9 Books That Will Help

| Topic | Book | Chapter | |——-|——|———| | DSL runtime patterns | “Language Implementation Patterns” | Ch. 6-8 | | Defensive engineering | “The Pragmatic Programmer” | Ch. 8 |

5.10 Implementation Phases

  • Phase 1: grammar + parser.
  • Phase 2: safe runtime.
  • Phase 3: traces and approval integration.

5.11 Key Implementation Decisions

| Decision | Options | Recommendation | Rationale | |———-|———|—————-|———–| | Execution model | unrestricted, sandboxed | sandboxed | safety | | Trace granularity | summary only, per-rule | per-rule | auditability |

6. Testing Strategy

6.1 Test Categories

| Category | Purpose | Examples | |———-|———|———-| | Unit | operator/function checks | valid/invalid expressions | | Integration | runtime with pricing engine | net + triggers | | Security | abuse attempts | deep nesting, bad funcs |

6.2 Critical Test Cases

  1. Allowed rule with deterministic output.
  2. Disallowed function blocked at validation.
  3. Budget overflow gracefully handled.

6.3 Test Data

pricing_rules_valid.dsl, pricing_rules_unsafe.dsl, quote_fixture.json.

7. Common Pitfalls & Debugging

7.1 Frequent Mistakes

| Pitfall | Symptom | Solution | |———|———|———-| | unbounded eval | latency spikes/timeouts | operation budgets | | weak traces | cannot explain deltas | per-rule trace schema |

7.2 Debugging Strategies

  • Re-run with trace-level logging.
  • Compare trace snapshots across rule pack versions.

7.3 Performance Traps

Avoid repeated context fetches during per-line rule eval.

8. Extensions & Challenges

8.1 Beginner Extensions

  • Add expression lint warnings.
  • Add rule tags and grouping.

8.2 Intermediate Extensions

  • Backtest new rule packs against historic quotes.
  • Add “what changed” diff between rule versions.

8.3 Advanced Extensions

  • Policy canary rollouts by segment.
  • Cost-aware optimization hints for analysts.

9. Real-World Connections

9.1 Industry Applications

  • Dynamic enterprise discounting.
  • Promotion governance programs.

9.3 Interview Relevance

Shows language tooling and safe policy execution in revenue-critical systems.

10. Resources

10.1 Essential Reading

  • Oracle CPQ pricing updates.
  • DSL and parser engineering references.

10.2 Video Resources

  • Dynamic pricing system design talks.

10.3 Tools & Documentation

  • Tracing tools and schema docs.

11. Self-Assessment Checklist

  • I can explain runtime safety controls for pricing DSL.
  • I can replay pricing outcomes from traces.
  • I can prove guardrail violations trigger approvals.

12. Submission / Completion Criteria

Minimum Viable Completion:

  • Parsing and safe execution works for core rules.

Full Completion:

  • Trace output and approval integration complete.
  • Regression tests for rule updates pass.

Excellence (Going Above & Beyond):

  • Historical backtesting and canary policy rollout tooling.