ETDL — Event Tree Definition Language Compiler
Compile reliability models into code. ETDL (Event Tree Definition Language) is a declarative, design-time domain-specific language (DSL) that turns event tree analysis (IEC 62502) and fault tree analysis (IEC 61025) into a single .etdl document — and compiles that document into production-ready Rust, fully generated, with probability-driven SLAs, retry policies, and chaos injection built in.
No central workflow engine. No orchestration servers. No runtime interpreters. Your event tree becomes your code.
Why ETDL?
Most event-driven systems describe what should happen (topics, channels, message schemas) but never why, when, and with what reliability the system must respond. Failures are discovered in production, under load, by pager alerts.
ETDL moves reliability engineering to design time:
| Concern | Typical approach | ETDL |
|---|---|---|
| Failure sequences | Implicit in code, scattered across services | Explicit event trees (IEC 62502) |
| Failure probability | Guessed, or measured after incidents | Exact fault trees (IEC 61025), resolved at compile time |
| SLA behavior | Hand-rolled retry/timeout/backoff in every service | Generated RetryPolicy + SLA tracker |
| Failure injection | Custom scripts, feature flags, breakage in prod | Declared chaos probability, scoped per event tree |
| Contract drift | AsyncAPI docs rot, code diverges | AsyncAPI 3.0 references resolved at compile time |
| Process flow | BPMN diagrams no one reads | Causal event trees that are the code |
ETDL vs. alternatives
| ETDL | Temporal / Cadence | Camunda / BPMN | AWS Step Functions | Hand-rolled sagas | |
|---|---|---|---|---|---|
| Central runtime engine | None — compiles to code | Yes (workers + server) | Yes (engine) | Yes (AWS-managed) | N/A |
| Reliability modeling | First-class (fault trees) | Manual | Manual | Manual | Manual |
| IEC standards | 61025 + 62502 | No | No | No | No |
| Probability-driven SLAs | Compile-time constant | No | No | No | No |
| Deployable | Anywhere (library code) | Temporal cluster | Camunda cluster | AWS | — |
| Type-checked contracts | AsyncAPI + ECEL at build | Runtime | Runtime | Runtime | No |
ETDL follows the Smart Endpoints, Dumb Pipes philosophy: the intelligence lives in your services (as generated, testable Rust functions), not in a centralized brain that becomes a single point of failure.
How it works
An .etdl document declares event trees (causal sequences of barriers, operations, and consequences) and fault trees (how basic events combine into a top-level failure). The compiler validates everything — including probabilistic math, ECEL conditions, and AsyncAPI references — and emits a single Rust function per initiating event.
flowchart LR
A[".etdl document<br/>(event trees + fault trees)"] --> B["etdl parse<br/>(etdl-parser)"]
B --> C["etdl validate<br/>(etdl-compiler)"]
C --> D["fault tree resolution<br/>top-event probability"]
D --> E["code generation<br/>(etdl-compiler)"]
E --> F["Generated Rust<br/>+ etdl-core runtime"]
A -.-> G["AsyncAPI 3.0<br/>(YAML/JSON)"]
G --> B
style F fill:#4caf50,color:#fff
What a fault tree becomes at build time
In order-fulfillment.etdl, the top event PaymentGatewayFailure is an OR of two basic events. The compiler computes the exact probability:
// Computed from faultTrees.PaymentGatewayFailure.topEvent at build time (Section 5.16)
const PROCESS_PAYMENT_OPERATION_FAILURE_PROBABILITY: f64 = 0.012987;
What an event tree becomes at run time
pub async
Quick Start
# 1. Install the CLI
# 2. Write an .etdl document (or clone the example below)
# 3. Compile it to Rust
# 4. Validate without generating code
A complete example
etdl: "1.0.0"
info:
title: "Order Fulfillment Event Tree"
version: "2.0.0"
domain: "FulfillmentContext"
asyncapi_imports:
orders_api: "./asyncapi/orders.yaml"
payment_api: "./asyncapi/payments.yaml"
eventTrees:
OrderFulfillment:
initiatingEvent:
id: OrderPlacedTrigger
message: "orders_api#/components/messages/OrderPlaced"
next: InventoryCheckBarrier
nodes:
InventoryCheckBarrier:
type: barrier
branches:
- outcome: SUCCESS
condition: "message.payload.items[*].qty > 0"
probability: 0.95
next: ProcessPaymentOperation
- outcome: FAILURE
condition: "default"
probability: 0.05
next: OutOfStockConsequence
ProcessPaymentOperation:
type: operation
action: execute
handler: "stripe_charge_handler"
emits: "payment_api#/components/messages/PaymentProcessed"
next: FulfillmentConsequence
onFailure: PaymentFailedConsequence
onFailureProbabilitySource: "#/faultTrees/PaymentGatewayFailure/topEvent"
retryPolicy:
maxAttempts: 3
backoffMs: 250
backoffStrategy: exponential
timeoutMs: 5000
FulfillmentConsequence:
type: consequence
operation: send
channel: "orders_api#/channels/FulfillmentChannel"
message: "payment_api#/components/messages/PaymentProcessed"
faultTrees:
PaymentGatewayFailure:
topEvent:
id: PaymentCaptureFailed
rootCause: GatewayUnavailableOrRejected
gates:
GatewayUnavailableOrRejected:
type: OR
inputs:
- GatewayUnreachable
- ChargeRejected
basicEvents:
GatewayUnreachable:
probability: 0.008
ChargeRejected:
failureRate: 0.00021
missionTime: 24
Run:
This validates the document, resolves PaymentGatewayFailure to 0.012987, and emits a handle_order_placed_trigger async function that retries with exponential backoff, tracks branch probabilities in a BranchMonitor, and routes failures to a dead-letter channel.
Concepts
Event Trees (IEC 62502)
A tree of barriers (decision gates), operations (side-effecting actions with retry/backoff/timeout), and consequences (outcomes). Every barrier branch carries a probability, and every operation can reference a fault tree for its failure probability. ETDL event trees mirror the event tree analysis method used in nuclear safety, aerospace, and process industry risk assessment — applied to event-driven software.
Fault Trees (IEC 61025)
A Boolean model of how basic events combine through gates (AND, OR, NOT, XOR, VOTING) into a top event. Basic events carry probability or failureRate + missionTime (exponential failure model). The compiler evaluates the tree exactly at build time, so failure probabilities are constants in your generated code — no runtime estimation, no surprises.
ECEL — Event-tree Condition Expression Language
Conditions on barrier branches are written in ECEL, a typed expression language (inspired by CEL) over the AsyncAPI message payload. The compiler type-checks expressions against resolved schemas at build time, catching qty > "three" before it ships.
Probability-linking
onFailureProbabilitySource: "#/faultTrees/PaymentGatewayFailure/topEvent" connects an operation's failure to a fault tree. The generated code records the resolved probability against the actual failure in the BranchMonitor, enabling SLA anomaly detection and chaos injection with declared, deterministic probabilities.
Runtime (etdl-core)
| Component | Purpose |
|---|---|
BranchMonitor |
Tracks taken branches, probabilities, and failures per event tree |
RetryPolicy |
Async retry with exponential/fixed backoff and max attempts |
SlaTracker |
Detects anomaly rates vs. declared probabilities (ETDL_SLA_WINDOW, ETDL_SLA_THRESHOLD) |
ChaosController |
Declared, seeded, scoped failure injection (disabled in production via ETDL_ENV) |
| Telemetry | inject_traceparent W3C trace context propagation |
Crates
Documentation
- ETDL Specification v1.0.0 — the formal spec (CC BY 4.0)
- Getting Started — install, first document, compile, run
- Concepts — event trees, fault trees, ECEL, probability linking
- Comparison — ETDL vs Temporal, Camunda, Step Functions, sagas
- Architecture — compiler pipeline and codegen contract
- API docs —
etdl-core,etdl-parser,etdl-compiler
Editor support
- VS Code extension — syntax highlighting, live validation (Rust → WASM, no CLI needed), and interactive IEC 62502/61025 event-tree + fault-tree diagrams.
npm run packageineditors/vscode/builds a.vsix.
Examples
- Order Fulfillment — the spec's Section 13 worked example, with AsyncAPI stubs
Roadmap
- Additional code generation targets (TypeScript, Go) via the
CodeGeneratortrait - Minimal cut-set reporting CLI (
enumerate_minimal_cut_sets) - AsyncAPI 3.0 operation generation (asyncapi-codegen integration)
- Editor language support (syntax highlighting, schema validation)
Contributing
Contributions are welcome! Open an issue or pull request. See CONTRIBUTING.
License
Apache 2.0 — see LICENSE.