A durable execution runtime in Rust for high-consequence systems.
ObzenFlow is durable execution expressed as a typed stream-processing topology. Each stage is a supervised, event-sourced finite-state machine backed by an ordered journal, and the compiler checks every edge connecting them. Together, those journals preserve the facts, decisions, and effect outcomes required to reconstruct, verify, or resume the entire flow.

Built for high-consequence systems.
A high-consequence system is one where being wrong costs something real. A payment captured twice, an order lost mid-fulfilment, a compliance export that cannot be defended, a model decision nobody can explain. ObzenFlow was built for exactly these systems, and correctness is the constraint the rest of the design bends around.
A charge or a shipment must happen exactly once, and the decision trail has to survive the process that made it.
Balances are folds over facts. Projection and audit derive from the same journal, so disagreement is detectable and repairable.
An export is only as defensible as its provenance. When an export is derived from journaled facts, the journal preserves the causal path that produced it.
Long-running, interruptible, and contested later. Resume protects the work; replay defends the outcome.
When prompts, outputs, and costs are captured as journaled facts, a model-assisted decision can be reconstructed and questioned from the record.
What Is Durable Execution?
The four guarantees of durable execution.
Durable execution is primarily a safety contract. Any framework claiming to provide it owes you four guarantees. They are the foundation on which resilient and correct systems are built.
ObzenFlow’s real value is combining those guarantees with a small typed vocabulary, idiomatic Rust handlers, first-class effects, built-in resilience, sensible integrations, and an operational substrate that ships in the same binary. You build durable software like an application and operate it like a service, without adopting a separate orchestration platform.
Deterministic reconstruction
Exactly-once effects
Durable progress
Resume over restart
Durable execution without infrastructure lock‑in or coupling.
ObzenFlow’s journal is a port in the domain core, not a dependency on a disk format, database, or storage SDK. The built-in disk implementation provides durable execution from a single binary, while another backend can implement the same contract without changing how runs are reconstructed, replayed, or resumed. Rust and Cargo enforce that boundary, keeping correctness independent of the infrastructure that stores the journal.
Show me the code
ObzenFlow combines a concise DSL for wiring typed stages into a durable graph with ordinary Rust handlers for your business logic. Sketch the flow with placeholders, fill in each stage one at a time, and let ObzenFlow add supervision, journaling, and replay without changing the code inside.
The blueprint
You sketch the whole flow with placeholder handlers, then fill in real logic one stage at a time. Every stage models one business decision and enumerates every outcome.
flow! {
name: "order_flow",
journals: disk_journals(journal_root),
stages: {
// Sources and sinks take I/O adapter values.
orders = source!(Order => orders_feed());
// Logic stages take your handler types.
validate = transform!(
Order -> { ValidOrder, RejectedOrder } => Validate
);
authorize = effectful_transform!(
ValidOrder -> { Authorized, Declined } => Authorize,
effects: [AuthorizePayment with [gateway_resilience]]
);
paid = sink!(Authorized => fulfillment());
},
topology: {
orders |> validate;
validate |> authorize;
authorize |> paid;
}
}Everything right of => is a plain Rust value. Validate and Authorize are your handler structs; orders_feed() and fulfillment() build the I/O adapters. The valid path crosses the declared AuthorizePayment effect under gateway_resilience, and the |> block wires the typed stages into the executable graph.
Your handler
The handler classifies each input and returns one of the declared outcomes as a plain Rust value, in the lineage of value-oriented programming.
// A handler is ordinary Rust: a struct, a trait,
// a decision. Unit-test it like any other function.
#[derive(Debug, Clone, StageOutputFacts)]
pub enum ValidationOutcome {
Valid(ValidOrder),
Rejected(RejectedOrder),
}
pub struct Validate;
impl TypedTransformHandler for Validate {
type Input = Order;
type Output = ValidationOutcome;
fn process(&self, order: Order)
-> Result<Self::Output, HandlerError>
{
if order.amount_cents == 0 {
return Ok(ValidationOutcome::Rejected(RejectedOrder {
order_id: order.order_id,
reason: RejectionReason::ZeroAmount,
}));
}
Ok(ValidationOutcome::Valid(ValidOrder::from(order)))
}
}This is the Validate the blueprint names. ObzenFlow wraps supervision, journaling, and replay around it at runtime, and a plain #[test] exercises it without any of them.
Build a durable workflow in Rust, step by step.
Follow one runnable payment example from a typed placeholder sketch through declared effects, journaled facts, verified replay, and safe resume.