Neutron Workflow
A durable execution engine. Every step is an event on Nucleus; on restart the engine replays the log to reconstruct state and continue. Workflows suspend for an event, an approval, or a timer — and resume days later, exactly where they stopped.
Durable, event-sourced workflows — suspend for days, survive restarts, resume exactly where you left off.
The primitive Next.js and Astro don't have.
Web frameworks give you a request and a response. They have no answer for "run this, then wait three days for the customer to reply, then continue" — that's where you reach for a queue, a cron job, a state table, and a lot of glue. Neutron Workflow is a durable execution primitive built in. You write a plain async function; the engine makes it survivable.
Every step is recorded as an event. When a process restarts — a crash, a deploy, a scale-down — the engine replays the event log from the top, feeds completed steps their recorded results instead of re-running them, and continues from the first step that never finished. State is reconstructed, not persisted by hand.
import { workflow } from "@neutron-build/workflow";
export const onboarding = workflow("onboarding", async (ctx, userId: string) => {
// step() runs once, records the result, and replays it forever after.
const user = await ctx.step("load-user", () => db.users.get(userId));
await ctx.step("welcome-email", () => sendEmail(user.email, "welcome"));
// Suspend for three days. No process stays alive; the scheduler wakes it.
await ctx.sleep("3d");
if (!(await ctx.step("did-activate", () => hasActivated(userId)))) {
await ctx.step("nudge-email", () => sendEmail(user.email, "nudge"));
}
return { onboarded: true };
});ctx.step() runs once, records its result as an event, and replays that result on every later pass. The event log is the source of truth.sleep parks on a timer, waitForEvent parks until a payload arrives. No thread, no process — the run is durable state, woken later.ctx.now() and ctx.random() are recorded like steps, and a NondeterminismError catches replay drift. All I/O goes inside step().NucleusEventStore persists the log to Nucleus streams; MemoryEventStore runs the same semantics in tests. Same engine, swappable backing.Scheduler over a RunIndex picks up runs that are due or parked — a slept timer fired, a retry delay elapsed — and drives them forward.Wait for the outside world, then continue.
A workflow can suspend until an external event arrives — a webhook, a human approval, a payment confirmation. The run parks as durable state; when you deliver the event, it wakes and continues with the payload in hand. The waiting costs nothing, and it can last days.
import { workflow } from "@neutron-build/workflow";
export const expense = workflow("expense", async (ctx, claim: Claim) => {
await ctx.step("record", () => db.claims.insert(claim));
// Suspend until deliverEvent(runId, "decision") supplies a payload.
const decision = await ctx.waitForEvent<{ approved: boolean }>("decision");
if (decision.approved) {
await ctx.step("reimburse", () => pay(claim.userId, claim.amount));
}
return { status: decision.approved ? "paid" : "denied" };
});Run it, park it, wake it.
executeRun drives a run against an event store until it completes or suspends. A suspended run returns to the store as durable state. Later — when a timer fires or an event lands — the scheduler or an explicit deliverEvent resumes it. Same engine, whether it runs for ten milliseconds or ten days.
import { executeRun, deliverEvent, NucleusEventStore } from "@neutron-build/workflow";
const store = new NucleusEventStore(nucleus.streams);
// First pass: runs until the workflow suspends on waitForEvent.
await executeRun({ workflow: expense, runId: "claim-91", store, input: claim });
// ...minutes or days later, from a webhook handler:
await deliverEvent(store, "claim-91", "decision", { approved: true });
// The scheduler picks the run back up and continues from the wait.What it's for
Multi-day business processes — onboarding drips, approval chains, subscription lifecycles. Sagas that coordinate several services and need to unwind cleanly on failure. Retry-heavy jobs where a delayed retry should park for free rather than hold a worker. Anything that has to wait on a human or an external system and then reliably pick up where it stopped. And it's the substrate under Neutron Agents and Teploy Ship — an agent turn is a durable workflow.
Why durable execution?
Because the alternative is a queue plus a state table plus a cron job plus reconciliation logic, reinvented per feature and wrong in a different way each time. Event sourcing gives you the audit log for free: every run's history is the exact sequence of steps that happened. Deterministic replay means the same inputs always reconstruct the same state, so a resumed run is indistinguishable from one that never stopped.
Part of a bigger system
Neutron Workflow is the durability layer the rest of the stack stands on. Neutron Agents turns an agent turn into a workflow so it survives restarts and pauses for approval. The AI SDK's tool loop becomes durable through agentStep. The event log lives in Nucleus, alongside everything else — one database, one contract, one system.