Input
- Question it answers
- What starts this Process?
- Approval example
- A customer identity and the reason approval was requested.
Building Blocks
Coordinate entity changes, requests, events, waits, and longer-running business workflows using familiar asynchronous C#.
A Process coordinates work that spans more than one decision, entity, participant, or moment in time. It can read information, invoke entity Transitions, request work from another capability, wait for an event or deadline, and return a typed outcome.
Cohesive.Processes lets you write that coordination with async, await, local variables, conditionals, and pattern matching. The source remains recognizable C#, while the Process runtime can pause, persist progress, resume after external input, and avoid repeating completed work.
This Process reads a customer, requests a document review, and invokes the customer's approval Transition when the review succeeds:
[GenerateProcessDefinition(nameof(Run))]
public static partial class ApproveCustomerProcess
{
static async ProcessTask<ApproveCustomerResult> Run(
ProcessContext process,
ApproveCustomerInput input)
{
var customer = await process.Read<Customer>(
relation: CustomerById,
input: input.CustomerId);
if (customer.Status == CustomerStatus.Suspended)
return new(customer.Id, ApprovalStatus.NotEligible);
var review = await process.Effect<DocumentReviewResult>(
contract: RequestDocumentReview,
outcome: ReviewCompleted,
input: new DocumentReviewRequest(
customer.Id,
input.Reason));
if (!review.Approved)
return new(customer.Id, ApprovalStatus.Rejected);
await process.Transition(
transition: ApproveCustomer,
subject: customer.Id,
input: new CustomerApproval(input.Reason));
return new(customer.Id, ApprovalStatus.Approved);
}
}CustomerById, RequestDocumentReview, and ApproveCustomer identify definitions supplied by the surrounding domain model. The code focuses on the business flow: obtain the customer, stop when approval is not allowed, wait for the review obligation to complete, apply the entity decision, and return the Process result.
The guided walkthrough installs the Process package and analyzer, authors a small asynchronous Process, and then adds a durable event-or-deadline wait. It introduces persistence and compilation only after the workflow itself is clear.
Open the Getting Started guide →
A Process reads like an asynchronous application method, but each awaited operation represents durable business progress:
The ProcessContext does not expose arbitrary services. Its operations name the reads, entity changes, requests, events, child Processes, and temporal behavior that form the workflow. This keeps the coordination visible instead of hiding it behind injected callbacks.
An ordinary async method is easy to write, but its call stack and local variables disappear when the process stops. Applications then rebuild durability through job records, status columns, retry flags, message handlers, and recovery scripts. Cohesive asks you to make the workflow explicit so those concerns can work from the same Process definition.
A caller starts a Process with typed input. The Process execution environment advances the definition until it reaches an operation or wait. Relation adapters perform reads, entity adapters execute Transitions, and interaction adapters deliver requests or accept events. Their typed results become the values used by the next part of the workflow.
When execution cannot continue immediately, the durable runtime commits a checkpoint containing the current continuation, accepted inputs, completed operation receipts, outgoing interactions, and control state. A later result, event, deadline, or control command starts another activation from that checkpoint.
This environment owns storage, scheduling, delivery, retries, time, and recovery. The authored C# method describes the coordination and is not kept alive as a running async method. Capability diagnostics report when a configured runtime cannot preserve the guarantees the Process requires.
A Process can coordinate several forms of interaction:
The Process can wait for one interaction, or race several typed events and deadlines. It can state how simultaneous matches are resolved and what happens to late, stale, duplicate, or misdirected input. The overview example uses the simplest form: continue when the selected ReviewCompleted outcome arrives.
Some workflows need several branches to make progress together. Fork and Join can require every branch, choose the first eligible result, or continue after a required number completes. Concurrency and item limits remain explicit so a runtime cannot silently turn a bounded workflow into unbounded work.
A parent Process can start a child Process for an independently meaningful piece of work. It can also process a bounded partition of items or repeat work across activations under a declared limit. Compensation and reconciliation remain named purposes rather than hidden exception callbacks.
These constructs support patterns such as sagas without pretending that a long-running workflow provides ACID rollback across independent participants.
A customer or employee onboarding Process can span several entities and wait for human or external-system outcomes.
Cohesive.Entities owns the state, invariants, and Transitions invoked as steps in a Process.Cohesive.Relations supplies reusable reads and queries without making the Process responsible for data-access logic.Cohesive.Storage persists Process checkpoints, operation receipts, accepted inputs, control state, and outgoing interactions.Cohesive.Api can expose start, status, control, and explain operations.Cohesive.Presentation can project progress, outcomes, and human tasks from the same runtime evidence.Durable coordination introduces questions that normal async code does not answer: how source becomes a restorable definition, how continuation identities survive revisions, how competing events are arbitrated, how completed operations replay, and what must commit together.
The Internals page covers source generation, canonical Process documents, compilation, identity and compatibility, wait policies, durable checkpoints, replay evidence, and runtime control.