Direction
Roadmap
Wyrd grows around three capabilities: simulate the future, replay the past, and run the present.
Spike
AvailableThe process model as data, with two syntaxes building the same model.
- DoneProcess model as data (Process, StepNode, AwaitNode) with structural equality
- DoneFluent syntax, and the opt-in pipe syntax (>>)
- DoneExtension member literals such as 15.Minutes and 3.Times
- DoneResult<TOk, TError>, the [Union] marker, Mermaid rendering
Runnable core
AvailableSlices with pure decisions and a deterministic in-memory runtime.
- DoneSlices with a static pure Decide, and state via IState
- DoneExplicit correlation with StartOn and Await
- DoneDeterministic InMemoryRuntime with a virtual clock: retries, reverse compensation, timeouts, duplicates, correlation
- Donesamples/Shop and library scaffolding (CI on 3 operating systems)
Messages done right
AvailableCommands, domain events and integration events as different things, enforced at build time.
- DoneMessage taxonomy, contracts split from slices, explicit publication mapping
- DoneRuntime rules: one owner per command, only integration events published from outside
- DoneAnalyzers WYRD0001 to WYRD0004, contract snapshots with breaking-change detection (WYRD0200 to WYRD0204) and a code fix
- DoneMulti-version publishing and upcasters for subscribers
Distributed-shaped core, in memory
AvailableA message-driven engine that behaves like a distributed system while staying deterministic.
- DoneSteps as command messages with Accepted / Rejected / Faulted replies; everything crosses the queue as JSON
- DoneOne transaction per message (state, inbox, outbox, timers) behind a storage port, with an in-memory store
- DoneRetries with backoff, early events parked, projections with redelivery protection
- DoneProcess outcomes as commands (.OnCompensated), Wyrd.Testing Given/When/Then
- DoneSource-generated JSON with analyzers WYRD0300 to WYRD0302, and Native AOT checked in CI
Skuld — simulate the future
AvailableFailure simulation with shrinking, explicit retry semantics, suspension, the structure fingerprint, steps that read earlier events and ordered read models.
- DoneSkuld.SimulateAsync: seeded futures with faults, redelivery and reordering, invariants, replay by seed
- DoneEngine fixes found by Skuld: attempt-aware replies, unknown-outcome steps compensated, thread-safe type registry
- DoneTyped invokers in the pipe syntax; only steps that read earlier events are invoked dynamically (Native AOT-compatible)
- DoneAnalyzers WYRD0011 (how a step is undone), WYRD0012 (await without .Within), WYRD0013 (process style), WYRD0020 (exhaustive union switch)
- DoneRetry semantics: every step declares .Retry(...) or .NoRetry("why") (WYRD0014); undos and the outcome always insist; WYRD0010 removed
- DoneSuspend instead of guessing, with ResumeAsync / CompensateAsync and opt-in .OrCompensate()
- DoneProcess structure fingerprint per instance: a changed definition suspends in-flight instances
- DoneSteps that read the events of earlier steps (and awaited events), checked before the first message
- DoneOrdered projections per stream
- DoneShrinking: reduce a failing future to the fewest perturbations that still break the invariant
Urd — replay the past, and the dotnet wyrd tool
AvailableCapture in-memory instance histories and replay them against today’s process definition with Urd.
- Donedotnet wyrd asyncapi
- Donedotnet wyrd diagram
- DoneProcess instance history capture
- Donedotnet wyrd replay <history.json> --as-test
Verdandi — run the present
DoneThe durable runtime, the only place with real I/O, and services that talk over a broker.
- DoneIntegrations (Integration<TCommand, TEvent, TError>): the only I/O, with idempotency keys and recorded outcomes
- DoneIWyrdRuntime and IWyrdBuilder<T>: the same application code and modules on every host
- DoneEF Core host (PostgreSQL, SQL Server): state, inbox, outbox, timers and read models in one transaction, the database as the queue
- DoneOne retry layer, operators (resume, compensate) and a hardened queue with health metrics
- DoneExplicit retention for everything a host keeps, and a history archive
- DoneRabbitMQ transport between services (Wyrd.RabbitMq)
- DoneOpenTelemetry with process-level traces
- DoneCatching up a projection added to a store that already has data
Documentation & adoption
ContinuousTeaching the mental model matters as much as the code.
- DoneGuide: From classic DDD to Wyrd
- DoneGuidance on shared invariants living on the state or in pure domain policies
- DoneRich aggregate in samples/Shop (Order, OrderLine, Money)
- DoneGuide: modelling read models for screens and reports
- DoneGuide: running durable, with retention and operators
- DoneDocs site with the mental model first, API reference second
Production ready
PlannedEverything needed to run Wyrd with confidence.
- OpenProcess versioning: a snapshot of every process, with breaking changes failing the build until in-flight instances are migrated
- DoneNative AOT verified end to end
- Donedotnet wyrd CLI and an MCP server for agents
Later
- Event Modeling to code and back
- Live process dashboard
- Azure Service Bus and Kafka transports, and community adapters (Wolverine, MassTransit)
Open decisions
- State persistence: state-stored, event-sourced, or both
- The full rules catalog (what "correct" means, rule by rule)