Turn your Event Models into Verified Contracts.
Stop translating sticky notes. Start compiling domain logic.
Eliminate the gap between business intent and software execution. Weltenwanderer compiles .ddd specifications into a formally verified domain kernel. No more implementation drift or AI-generated guesswork: your code is proof-checked against the model, not just unit-tested.
Open Source · Codeberg
context Shopping {
type CartId = String
type ProductId = String
type Quantity = Integer
command AddItem {
cartId: CartId
productId: ProductId
quantity: Quantity
validate quantity > 0
else "Quantity must be positive"
}
event ItemAdded {
cartId: CartId
productId: ProductId
}
decider ShoppingCart {
commands: AddItem
events: ItemAdded
state: Empty | Active | CheckedOut
decide(AddItem, Active) {
require items.length < 50
else reject "Cart is full"
-> [ItemAdded { cartId, productId }]
ensure items.length == old.items.length + 1
}
evolve(Active, ItemAdded)
-> Active { items: items + item }
}
} "Domain language is specification. Everything else is infrastructure."
You leave the EventStorming session with a wall of sticky notes and a shared understanding. Then the translation begins — and meaning gets lost.
You've seen it before: the model in code drifts from the model on the wall. Domain experts stop recognizing their own language. Developers build what they understood, not what was meant.
Teams that invest in collaborative design deserve a single source of truth — not a game of telephone between whiteboards, JSON schemas, and generated code.
The AI-assisted variant is faster but not better: paste a JSON schema into an LLM, review the output, fix the hallucinations, repeat. The RALPH loop burns tokens on translation that a compiler does deterministically in milliseconds.
Without a compiler, every team member maintains their own mental model. The models diverge. The system diverges. The bugs follow.
Why trust Weltenwanderer
We've been in that room
We've sat in those sessions. We've seen the gap between what the team designed and what got shipped.
Formal foundation
Built on proven computation theory (DynPROP, Schwentick). Not heuristics — theorems.
Deterministic compilation
No LLM in the loop. .ddd → verified TypeScript. Same input, same output, every time.
One file, every stakeholder
Domain experts read it. Developers compile it. The compiler enforces it.
How it works
Three steps from design to code
Model your domain
Write commands, events, and state machines in .ddd syntax that reads like the language from your design session.
Compile and verify
The compiler checks exhaustiveness, guard consistency, and postconditions. Structural bugs die here.
Generate and ship
Get typed TypeScript code, smart constructors, and framework wiring. Switch targets without rewriting your domain.
Your next EventStorming session could produce running, verified code
Not sticky notes that fade. Write your domain once, verify it at compile time, and generate code for any target platform.
Get notified when static verification ships.
No spam. One email when the feature lands.
What changes
After Weltenwanderer
Domain experts review .ddd files directly — no translation meetings
AI coding assistants use the .ddd file as context — no JSON schema, no RALPH loop, 10× fewer tokens
New team members read the domain model on day one — it’s the spec AND the program
Platform migration means changing a compiler flag, not rewriting the domain
See the language
One file. Domain experts and developers both read it.
This is what a domain expert and a developer both read. One file. The compiler does the rest.
-
Four constraint layers
- Types, validations, business rules, and postconditions — each verified at the right scope.
-
Smart constructors
- validate will generate private constructors with Result types. Invalid commands cannot be instantiated.
-
Atomic event sequences
- Multiple events from one decision are folded left-to-right and committed atomically.
Why can a compiler verify this?
The evolve function is a catamorphism (left-fold). When the state type is a finite algebraic data type, the projection is a finite automaton. All properties — equivalence, minimality, reachability, confluence — are decidable.
This is not an approximation. Gelade, Marquardt, and Schwentick (2012) proved that dynamic maintenance with propositional updates captures exactly the regular languages.
context Ordering {
type ItemList = Item[]
type Reason = String
command PlaceOrder {
items: ItemList
}
command CancelOrder {
reason: Reason
}
command ShipOrder {
trackingId: String
}
event OrderPlaced {
items: ItemList
total: Number
}
event OrderCancelled {
reason: Reason
}
event OrderShipped {
trackingId: String
}
decider Order {
commands: PlaceOrder, CancelOrder, ShipOrder
events: OrderPlaced, OrderCancelled, OrderShipped
state: Draft | Placed(items: ItemList) | Shipped | Cancelled
initial: Draft
terminal: Shipped, Cancelled
decide(PlaceOrder, Draft) {
require items.length > 0
else reject "Order must have items"
require total >= 10.00
else reject "Minimum order: 10 EUR"
-> [OrderPlaced { items, total }]
}
decide(CancelOrder, Placed) {
require not shipped
else reject "Already shipped"
-> [OrderCancelled { reason }]
}
decide(ShipOrder, Placed)
-> [OrderShipped { trackingId }]
evolve(Draft, OrderPlaced) -> Placed { items: items }
evolve(Placed, OrderCancelled) -> Cancelled
evolve(Placed, OrderShipped) -> Shipped
}
}Comparison
Compiler vs. Runtime Frameworks
Weltenwanderer is not a replacement for runtime frameworks — it generates code that targets them. The comparison shows what static analysis adds.
Approach
- Runtime Frameworks
- Library you code against
- Weltenwanderer
- Compiler that generates code
Correctness
- Runtime Frameworks
- Discovered at runtime
- Weltenwanderer
- Proven at compile time
Domain model
- Runtime Frameworks
- Spread across code files
- Weltenwanderer
- Single .ddd source of truth
Platform lock-in
- Runtime Frameworks
- Tied to one framework
- Weltenwanderer
- Generates for any target
Documentation
- Runtime Frameworks
- Manual, drifts from code
- Weltenwanderer
- Generated from source
AI Coding
- Runtime Frameworks
- Paste JSON + fix hallucinations
- Weltenwanderer
- .ddd file IS the prompt — deterministic output
Project Status
Where we are today
- VS Code extension
- Living documentation
- Schema evolution
- Flow analysis
- Event Model construct
- DSL mutation testing
- Data classification and GDPR compliance
- Modular compiler architecture
- Source map support
- Extended compile targets
- Lazy / JIT artifact generation
- MCP server
- Try-it-online playground
- Domain-level debugger
- Runtime architecture strategy
- Value type factory functions
- Additional CLI delivery formats
Your next EventStorming session could produce running, verified code
Not sticky notes that fade. Write your domain once, verify it at compile time, and generate code for any target platform.
Get notified when static verification ships.
No spam. One email when the feature lands.