Login

SESL Product Overview

This guide provides a comprehensive overview of SESL's product capabilities. You'll learn how to use the CLI in both online and batch modes, understand the structure and syntax of the SESL language, leverage linting tools to catch errors before runtime, and visualize rule dependencies through graph generation. Whether you're building compliance systems, automating decision logic, or integrating SESL with AI platforms, this guide covers the essential concepts and workflows.

SESL (Simple Expert System Language) is a deterministic, rule-based expert system designed to turn documents, policies, and business logic into executable, auditable decision models. Unlike probabilistic AI systems that may produce different outputs from the same inputs, SESL guarantees consistent, repeatable results with full explainability—showing exactly which rules fired, why they fired, and how conclusions were reached.

– Deterministic

SESL uses a forward-chaining inference engine that evaluates rules in priority order, applying them to a fact base until no more rules can fire (convergence). The same inputs always produce the same outputs—no randomness, no hallucinations, no probabilistic variation. This determinism is critical for compliance-sensitive domains (finance, healthcare, legal) where decisions must be repeatable, auditable, and defensible. SESL integrates seamlessly with AI platforms like ChatGPT and Claude via the Model Context Protocol (MCP), allowing LLMs to draft rules from documents or natural language descriptions while SESL enforces strict execution and traceability.

– Explainable

SESL provides comprehensive explainability through multiple trace mechanisms: the support trace shows which rules fired in which iteration and what they wrote; the monitor trace provides a human-readable, step-by-step execution log with rule reasons; the driver tree visualizes the dependency chain showing how each conclusion was derived from input facts and intermediate rules. This multi-layered transparency is essential for regulatory compliance, business review, and debugging complex logic. You can run models with RUN DESCRIBE to get full traces, or use RUN DRIVER or RUN REASON for focused explanations.

– Readable and Extensible

SESL models are written in structured YAML, a widely understood, human-readable format that doesn't require specialized training to read or modify. Rules are expressed in natural constructs: if conditions (boolean logic), then actions (fact assignments), let formulas (computed values), priorities (execution order), and because explanations (human-readable reasons). This syntax scales from simple decision trees to enterprise-grade systems with thousands of rules, multiple scenarios, and complex interdependencies. SESL supports modular design through constants, reusable rule templates, and scenario-based testing, making it easy to extend and maintain large rule sets over time.

How to Use SESL

Using SESL with an LLM

SESL integrates with ChatGPT, Claude, and other LLMs via the Model Context Protocol (MCP), a standardized interface for AI tools. When you connect SESL as an MCP server, the LLM can invoke SESL commands directly: loading models, adding rules, editing scenarios, running inference, and retrieving results. The LLM acts as a conversational interface for SESL, translating natural language requests ("add a rule that checks age", "run this scenario") into SESL commands. Critically, SESL models execute on SESL's own server, not inside the LLM. The LLM receives only the final results (facts, traces, errors), ensuring that decision logic remains deterministic and auditable. This architecture lets you leverage LLMs for rule drafting, model exploration, and natural language queries while maintaining SESL's strict execution guarantees.

Screenshot of SESL generating rules

Generate rules

Screenshot of SESL editing a scenario

Build a scenario

Screenshot of SESL evaluating results

Evaluate results

Run SESL Locally

SESL runs natively on Windows, macOS, and Linux as a standalone executable. You can work with SESL models using the command-line interface (CLI) in online mode (interactive session with prompt, history, and multiline editing) or batch mode (non-interactive, scripted execution). Models are plain YAML files, so you can edit them in any text editor (VS Code, Sublime, Notepad++, vim) with syntax highlighting and version control (Git). The CLI provides commands for creating, loading, saving, editing, linting, graphing, and running models. Local execution means no network dependencies, no cloud costs, and full control over your data and logic.

Screenshot of SESL running in a Windows command prompt Screenshot of SESL in a vs-code editor

SESL Language

Structure of a SESL program

A SESL model is a structured YAML file that defines rules, facts (scenarios), and optional constants. Providing a simple structure for allowing decision logic, inputs, and shared values to stay organised and easy to maintain.

The rules section contains each rule’s name, conditions (if), actions (then), optional LET formulas, priorities, explanations, and an optional stop flag; rules fire in priority order using forward-chaining so one rule’s output can influence another.

The facts section provides one or more scenarios—each with input data, an optional name, a result object (where outputs are written), and automatically injected constants. The constants section stores shared configuration values accessible to all rules. Finally, all outputs are written into the scenario’s result object, which may also include engine metadata such as starting facts, LET dumps, monitoring traces, and support tracking, keeping all conclusions and debugging information in one place.


const:
  MIN_ADULT_AGE: 16

rules:

  - rule: check_age
    priority: 10
    if:
      - applicant.age < MIN_ADULT_AGE
    then:
      result.eligible: false
    because: "Applicant is under the required adult age."

  - rule: check_nationality
    priority: 20
    if:
      - applicant.nationality != "British"
    then:
      result.eligible: false
    because: "Applicant is not a British national."

  - rule: check_previous_passport
    priority: 30
    if:
      - applicant.has_previous_passport == true
    then:
      result.eligible: false
    because: "Applicant has already had a UK passport."

  - rule: verify_documents
    priority: 40
    if:
      all:
        - docs.birth_certificate == true
        - docs.identity_evidence == true
        - docs.photo_ok == true
    then:
      facts.docs_ok: true
    because: "All required documents are provided."

  - rule: final_decision
    priority: 100
    if:
      - facts.docs_ok == true
      - result.eligible != false
    then:
      result.eligible: true
    because: "All requirements satisfied."

facts:
  - name: Scenario1
    applicant:
      age: 22
      nationality: "British"
      has_previous_passport: false
    docs:
      birth_certificate: true
      identity_evidence: true
      photo_ok: true

          


In summary, a SESL model cleanly separates rule logic, scenario data, and shared constants while providing a dedicated result structure for outputs. This organisation makes SESL models easy to read, easy to test, and highly maintainable, while supporting powerful reasoning features like LET formulas, priority handling, and truth-maintenance tracking.

How SESL processes rules

The rules engine starts by loading the rules you wrote in YAML. Each rule has conditions (the “IF”), actions (the “THEN”), optional LET formulas, and a priority. The engine turns each rule’s conditions into a logic structure (like a tree of AND/OR/NOT blocks) so it can evaluate them quickly and consistently. LET expressions are also prepared in advance so the engine can compute temporary values for each rule during processing.

When the engine runs a scenario, it enters a loop that keeps applying rules until nothing changes anymore. For each rule, the engine first calculates the LET values for that rule, then tests whether the rule’s conditions are true using the current facts. If the conditions match, the rule is allowed to fire. The engine also keeps track of which parts of the data changed so it doesn’t waste time re-evaluating conditions unnecessarily.

If a rule fires, the engine performs its actions—which means it writes new values into the scenario facts (usually inside the result section). If a higher-priority rule has already written to the same output, the lower-priority rule is skipped for that specific value. The engine also uses a simple “truth maintenance system” to record which rules are supporting each result; if a rule later stops being true, the results depending on that rule can automatically be removed.

The engine keeps looping through all rules until it reaches a stable state—meaning no rule changed anything during that iteration. When this happens, it stops and returns the final results. If a monitor is turned on, the engine also produces a step-by-step explanation showing which rules were evaluated, which ones fired, which actions were taken, and why. This makes it easy to understand exactly how the engine arrived at its final answer.

The engine uses a forward-chaining approach where it repeatedly applies rules to the current facts until no more changes occur, gradually building up conclusions step by step. Unlike a RETE engine—which builds an optimized network of condition nodes for extremely fast pattern-matching across large rule sets—this engine uses a simpler but more transparent evaluation cycle: each rule is checked in priority order, with dependency tracking to avoid unnecessary re-evaluation, LET expressions for per-rule computed values, and a truth-maintenance system to ensure results remain logically consistent when rules stop applying. This design trades RETE’s heavy optimisation structures for clarity, easier debugging, and deterministic behaviour, while still achieving efficient re-runs by only re-evaluating conditions linked to recently changed parts of the fact set.

SESL Online and Batch tools

The SESL tool can operate in two distinct execution styles—online mode and batch mode—each designed for a different workflow. Both modes use the same underlying SESL rule engine, but they differ in how users interact with models, how commands are processed, and whether the tool behaves conversationally or automatically. Understanding the difference between these two modes helps users choose the workflow best suited to development, debugging, automation, or testing.

Online Mode

In online mode, the SESL tool enters a fully interactive environment where the user types commands one at a time and receives immediate feedback. This mode is designed for hands-on exploration: you can load or create models, edit rules and scenarios, inspect their contents, and run inference repeatedly as you iterate. Online mode also includes conveniences like tab-completion, colorized output, option substitution, and confirmation prompts. It behaves like a live workspace where the model evolves continuously based on user input.

Example (starting online mode):

$ sesl --online
SESL> LOAD my_model.sesl
SESL> LIST
SESL> RUN DESCRIBE
        

During interactive execution, online mode supports rich debugging tools. Running scenarios with RUN DESCRIBE reveals the rule-firing trace, detailed summaries, support structures, and explanations of the final results. Errors are surfaced immediately, and because the session preserves the model in memory, users can fix issues and retry quickly. This makes online mode ideal for building, experimenting with, and refining SESL models.

Example (editing and re-running a scenario interactively):

SESL> ADD FACT DemoScenario temperature=15
SESL> RUN SCENARIO DemoScenario DESCRIBE
SESL> DELETE FACT DemoScenario temperature
SESL> RUN
        

Batch Mode

In contrast, batch mode is completely non-interactive. It executes a sequence of SESL commands automatically, with all confirmations answered “yes” behind the scenes. Commands are provided as a single --batch string, which may contain multiple semicolon-separated instructions. Batch mode is built for automation—running tests, transforming models, validating files, or processing SESL logic inside scripts or pipelines.

Example (batch mode with multiple commands):

$ sesl model.sesl --batch "LIST; RUN; LINT ERRORS"
        

Batch mode’s behavior is entirely deterministic: it never pauses for input, never asks questions, and only prints the results of executing the commands. It can load a file at the start or begin with an empty model. This makes it well suited for CI systems, automated workflows, regression testing, and other scenarios where SESL logic must run unattended. While online mode is optimized for interactive editing and debugging, batch mode is optimized for repeatable and scripted execution.

Example (batch mode used in automation):

$ sesl --batch "NEW; ADD RULE myrule: {...}; SAVE out.sesl"
        

SESL Linter

The SESL Linter performs static analysis on your SESL models to detect mistakes before you run them. It inspects rules, conditions, LET expressions, constants, and scenarios to catch structural issues, missing references, impossible conditions, and unused fields. This ensures your SESL model is clean, correct, and predictable before it reaches execution.

The linter checks for a wide range of issues, including:

  • Unknown fact or result paths referenced in conditions
  • Unknown CONST references or LET dependencies
  • Impossible or invalid rule conditions
  • Rules that never fire (dead rules)
  • Unused constants or unused scenario fields
  • Conflicting rules writing to the same result path
  • Duplicate rule names
  • Empty scenarios or scenarios with never-read facts
  • LET expressions with invalid syntax or obvious runtime errors (e.g., divide by zero)

These rules come directly from the SESL linter core, ensuring strict consistency with SESL’s execution semantics. The linter enforces strict identifier rules, requiring that unquoted tokens in conditions and actions refer to known facts, LET names, result fields, or constants. This prevents subtle runtime bugs caused by typos or missing quotes. :contentReference[oaicite:2]{index=2}

Example (run the linter):

$ sesl model.sesl --batch "LINT ERRORS"
    

Rule Dependency Graph

SESL can generate a visual GraphViz dependency graph showing how rules relate to each other. This graph helps you understand the flow of logic: which rules depend on which facts, which rules produce results that other rules consume, and how data moves through your SESL model.

The graph generator reads every rule's conditions, LET expressions, and result writes to build a map of:

  • Rule → Fact dependencies
  • Rule → Rule dependencies via result.x reads
  • Fact nodes referenced by conditions
  • Priority-based color coding for rules

Each rule is displayed as a rectangular node, colored based on its priority, while facts become oval nodes. Edges between rules reveal how data flows and where dependencies exist. The result is a clear, visual way to see the structure of your rule system—especially useful for large models with many interacting rules. :contentReference[oaicite:3]{index=3}

Example (generate a graph):

$ sesl model.sesl --batch "GRAPH DEPENDENCIES > graph.dot"
$ dot -Tpng graph.dot -o graph.png