FlowNodeDescriptor<TContext> Descriptor { get; }
Source
Gets the public descriptor executed for this node.
Internal, prevalidated node view used by runners to avoid repeated graph-routing lookups.
TContext
Instances are created only by FlowDefinition{TContext}
after the public node dictionary has been copied and validated. The public API remains FlowDefinition{TContext}.Nodes
; this type exists only to keep execution routing internal and fail-closed.
void SetNextNodes(IReadOnlyDictionary<string, FlowExecutionNode<TContext>> nextNodes)
Assigns the prevalidated next-node map once all execution nodes have been created.
nextNodes
FlowNodeDescriptor<TContext> Descriptor { get; }
Source
Gets the public descriptor executed for this node.
IReadOnlyDictionary<string, FlowExecutionNode<TContext>> NextNodes { get; set; }
Source
Gets the prevalidated next-node targets keyed by allowed target id.
Describes an external event or timeout that resumed a waiting flow node.
FlowResumeEvent Timeout(string eventName)
Creates a timeout resume event for the supplied wait event.
eventName
A timeout resume event.
string EventName { get; }
Source
Gets the event name.
object? Payload { get; }
Source
Gets the optional event payload.
bool IsTimeout { get; }
Source
Gets a value indicating whether this event represents a timeout.
Registers the AppSurface Flow core services.
The module is passive: it adds the one-node transition evaluator, in-memory runner, definition registry, and options used by local tests and host-specific adapters. It does not start background workers, create storage, schedule timers, execute activities, or replace AppSurface startup composition.
Stores AppSurface Flow definitions by context type, flow id, and version.
void Register<TContext>(FlowDefinition<TContext> definition)
Registers a flow definition.
TContext
definition
ArgumentException
bool TryGet<TContext>(string flowId, string version, out FlowDefinition<TContext>? definition)
Tries to resolve a registered flow definition.
TContext
flowId
version
definition
true
when a matching definition exists.
FlowDefinition<TContext> GetRequired<TContext>(string flowId, string version)
Resolves a registered flow definition or throws a diagnostic exception.
TContext
flowId
version
The matching definition.
FlowDefinitionException
Thread-safe in-memory implementation of IFlowDefinitionRegistry
.
Describes a typed, stable activity callsite in a Flow definition.
TWork
TResult
A callsite id and its contract versions are durable identifiers. Do not change them while nonterminal Flow instances can reference the callsite. Expected business failures belong in TResult
; exhausted technical failures and ambiguous provider outcomes are host-level suspension concerns.
FlowActivityWorkResult<TResult> CreateResult(TResult result)
Creates the typed result used to resume this callsite's Flow node.
result
A result carrying this callsite's identity and result contract version.
ArgumentNullException
result
is null.bool TryGetResult(FlowActivityWorkResult? workResult, out TResult result)
Attempts to read a resumed activity result for this exact callsite and result contract.
workResult
result
true
when the result belongs to this callsite; otherwise, false
.
A mismatched result is not coerced. Durable hosts should normally prevent mismatches by validating the persisted wait registration before evaluating the node. Nodes can use this method to distinguish initial execution from activity resumption without casting or reflection.
TResult GetResult(FlowActivityWorkResult? workResult)
Reads a resumed activity result for this exact callsite and result contract.
workResult
The typed activity result.
FlowDefinitionException
string CallsiteId { get; }
Source
Gets the stable callsite identifier.
int WorkContractVersion { get; }
Source
Gets the serialized work contract version.
int ResultContractVersion { get; }
Source
Gets the serialized result contract version.
Provides non-generic activity request metadata to durable Flow hosts.
TContext
The metadata is intentionally exposed without reflection so a host can select registered codecs from the declared CLR types and contract versions. The interface does not authorize execution or serialize values itself.
FlowActivityWorkResult CreateResult(object result)
Wraps a decoded result in this request's typed callsite contract.
result
ResultType
.A typed work result suitable for resuming the Flow node.
ArgumentNullException
result
is null.ArgumentException
result
has the wrong CLR type.InvalidOperationException
This method lets a host bridge a registered non-generic codec back into the typed Flow result without reflection. Implementations must wrap the exact decoded value supplied by the host and preserve the request's callsite id, declared result type, and result contract version.
string CallsiteId { get; }
Source
Gets the stable callsite identifier.
Type WorkType { get; }
Source
Gets the declared work CLR type.
int WorkContractVersion { get; }
Source
Gets the serialized work contract version.
Type ResultType { get; }
Source
Gets the declared result CLR type.
int ResultContractVersion { get; }
Source
Gets the serialized result contract version.
object Work { get; }
Source
Gets the typed work value through a non-generic host boundary.
TContext Context { get; }
Source
Gets the Flow context to persist atomically with the activity command.
Validates and snapshots activity requests supplied through extensible public host boundaries.
A request snapshot preserves the metadata, work value, and context that a host must persist atomically. The work and context contracts themselves should be immutable or serialized immediately; this helper does not deep-clone application values.
IFlowActivityRequest<TContext> Snapshot<TContext>(IFlowActivityRequest<TContext> activity, string parameterName)
Creates an immutable, validated activity-request wrapper.
TContext
activity
parameterName
A request whose metadata cannot change after validation.
Base contract for a decoded activity result supplied when a waiting node resumes.
Results contain safe application contracts, not provider response bodies or credentials. Durable hosts validate the callsite, CLR type, and result contract version against the persisted activity wait before node evaluation.
string CallsiteId { get; }
Source
Gets the activity callsite that produced the result.
Type ResultType { get; }
Source
Gets the declared result CLR type.
int ResultContractVersion { get; }
Source
Gets the serialized result contract version.
object Result { get; }
Source
Gets the decoded result through a non-generic host boundary.
Carries a decoded, typed activity result for node resumption.
TResult
TResult Value { get; }
Source
Gets the typed decoded result.
Describes a timeout requested by a flow wait outcome.
The core in-memory runner returns timeout metadata to callers; durable hosts are responsible for turning it into a durable timer and racing that timer against the external event.
TimeSpan Duration { get; }
Source
Gets the timeout duration.
Builds and validates typed AppSurface Flow graphs.
TContext
The builder validates declared transitions before returning a definition. Every target passed to AddNode(string, IFlowNode{TContext}, string[])
must exist in the final graph. Cycles are allowed because long-running business processes often revisit a review, remediation, or wait step.
FlowGraphBuilder<TContext> Create(string flowId, string version = "1")
Creates a new builder.
flowId
version
1
.A new builder instance.
FlowGraphBuilder<TContext> AddNode(string nodeId, IFlowNode<TContext> node, params string[] nextNodeIds)
Adds a node and declares the node ids it may return from a FlowNext{TContext}
outcome.
nodeId
node
nextNodeIds
FlowNext{TContext}.NodeId
targets.The current builder.
ArgumentException
FlowGraphBuilder<TContext> StartAt(string nodeId)
Sets the node id used for new flow instances.
nodeId
The current builder.
FlowDefinition<TContext> Build()
Validates and creates an immutable flow definition.
The validated definition.
FlowDefinitionException
Describes one node in a flow definition.
TContext
string NodeId { get; }
Source
Gets the stable node id.
IFlowNode<TContext> Node { get; }
Source
Gets the executable node implementation.
IReadOnlySet<string> NextNodeIds { get; }
Source
Gets the allowed next-node targets.
Stable fault codes shared by the built-in transition evaluator and runners that translate its decisions.
Input for one host-neutral Flow node evaluation.
TContext
string NodeId { get; }
Source
Gets the current node id.
TContext Context { get; }
Source
Gets the current Flow context.
FlowResumeEvent? ResumeEvent { get; }
Source
Gets the optional external event or timeout that resumed the node.
FlowActivityWorkResult? ActivityResult { get; }
Source
Gets the optional typed activity result that resumed the node.
Host-neutral decision produced by evaluating exactly one Flow node.
TContext
Inspect Kind
before reading kind-specific properties. A durable host commits this decision before evaluating another node. It must atomically persist an FlowTransitionKind.Activity
decision, its activity command, and the waiting context.
FlowTransition<TContext> Next(string nodeId, string nextNodeId, TContext context)
Creates a next-node transition carrying the declared target and persisted context.
nodeId
nextNodeId
context
A transition whose target and context are populated.
FlowTransition<TContext> Waiting(string nodeId, string eventName, IFlowEventCallsite? eventCallsite, TContext context, FlowTimeout? timeout)
Creates a wait transition carrying the event contract, persisted context, and optional timeout.
nodeId
eventName
eventCallsite
context
timeout
A transition whose event, context, and timeout fields are populated.
FlowTransition<TContext> TimedOut(string nodeId, string eventName, TContext context)
Creates a timeout transition carrying the expired event name and resulting context.
nodeId
eventName
context
A transition whose event name and context are populated.
FlowTransition<TContext> Completed(string nodeId, TContext context)
Creates a terminal completion transition carrying the final context.
nodeId
context
A transition whose context is populated.
FlowTransition<TContext> Faulted(string nodeId, FlowFault fault)
Creates a fault transition carrying only the process-level fault.
nodeId
fault
A transition whose fault is populated and whose context is absent.
FlowTransition<TContext> ActivityRequested(string nodeId, IFlowActivityRequest<TContext> activity)
Creates an activity transition carrying the activity request and its persisted context.
nodeId
activity
A transition whose activity and context are populated.
FlowTransitionKind Kind { get; }
Source
Gets the transition kind.
string NodeId { get; }
Source
Gets the node that produced the transition.
TContext? Context { get; }
Source
Gets the context carried by non-fault transitions.
string? NextNodeId { get; }
Source
Gets the declared target for a FlowTransitionKind.Next
transition.
string? EventName { get; }
Source
Gets the event name carried by wait and timeout transitions.
IFlowEventCallsite? EventCallsite { get; }
Source
Gets the exact typed event contract for a wait, or null for an explicit no-payload wait.
FlowTimeout? Timeout { get; }
Source
Gets the optional timeout carried by a wait transition.
FlowFault? Fault { get; }
Source
Gets the process-level fault carried by a fault transition.
IFlowActivityRequest<TContext>? Activity { get; }
Source
Gets the typed request metadata carried by an activity transition.
Evaluates exactly one Flow node and maps its outcome to a host-neutral transition.
TContext
This is the shared semantic boundary for in-memory, Durable Task, and PostgreSQL hosts. It does not loop through FlowNext{TContext}
transitions, persist state, validate serialization, schedule timers, or execute activities. Nodes can be evaluated again when a process dies before the host commits the returned transition, so they must be side-effect-free and must receive nondeterministic inputs through explicit context or resume contracts. Transition creation is package-owned so every runner observes the same mapping and validation semantics. External implementations should decorate and delegate to FlowTransitionEvaluator{TContext}
for concerns such as telemetry; they cannot manufacture alternative transitions. Express custom process behavior through node outcomes instead of replacing the evaluator's transition semantics.
ValueTask<FlowTransition<TContext>> EvaluateAsync(FlowDefinition<TContext> definition, FlowTransitionInput<TContext> input, CancellationToken cancellationToken = default)
Evaluates one declared node.
definition
input
cancellationToken
One mapped transition. Missing nodes, undeclared next targets, and unsupported outcomes become fault transitions; caller argument errors, cancellation, and node exceptions propagate.
ArgumentNullException
definition
or input
is null, or when the selected node returns a null outcome. OperationCanceledException
cancellationToken
is canceled before or during node execution. string EvaluatorId { get; }
Source
Gets the stable, host-independent evaluator identity used by durable execution manifests.
string EvaluatorVersion { get; }
Source
Gets the evaluator semantics version used by durable execution manifests.
Default host-neutral implementation of IFlowTransitionEvaluator{TContext}
.
TContext
Describes one AppSurface Flow node execution.
TContext
FlowId
Version
NodeId
State
ResumeEvent
The context is an immutable value-type snapshot so in-process runners can pass it to synchronous nodes without allocating a new reference object for every step. Runners always populate all members before invoking a node. Avoid using default
instances as real execution contexts because value types can be default-created without the required flow, version, node, or state values.
FlowActivityWorkResult? ActivityResult { get; init; }
Source
Gets the optional typed activity result that resumed the node.
This property is null during initial execution and external-event resumption. Use the activity's FlowActivityCallsite{TWork,TResult}
to validate and unwrap a result. A runner never supplies both ResumeEvent
and this property for one evaluation.
Runs AppSurface Flow definitions until the next external-event wait, typed activity, or terminal outcome.
TContext
ValueTask<FlowRunResult<TContext>> RunAsync(FlowDefinition<TContext> definition, TContext initialContext, CancellationToken cancellationToken = default)
Starts a new flow instance at the definition's start node.
definition
initialContext
cancellationToken
The result after execution pauses or ends.
ValueTask<FlowRunResult<TContext>> ResumeAsync(FlowDefinition<TContext> definition, string nodeId, TContext context, FlowResumeEvent resumeEvent, CancellationToken cancellationToken = default)
Resumes a waiting node with an external event or timeout.
definition
nodeId
context
resumeEvent
cancellationToken
The result after execution pauses or ends.
ValueTask<FlowRunResult<TContext>> ResumeActivityAsync(FlowDefinition<TContext> definition, string nodeId, TContext context, FlowActivityWorkResult activityResult, CancellationToken cancellationToken = default)
Resumes a node that is waiting for one typed activity result.
definition
nodeId
context
activityResult
cancellationToken
The result after execution pauses or ends.
NotSupportedException
The default implementation preserves compatibility for custom v1 runners and reports that activity resumption is unsupported. Runners that surface FlowRunStatus.ActivityPending
must override this method.
Represents an invalid flow definition or an attempt to execute a node transition that the definition does not allow.
Definition errors are deterministic authoring mistakes. They are surfaced as exceptions so tests and startup validation fail loudly before a durable instance is started.
Runs AppSurface Flow definitions in memory for local development and tests.
TContext
This runner does not persist state, create durable timers, or buffer external events. It executes synchronously through FlowNext{TContext}
outcomes and stops at FlowWait{TContext}
, FlowActivity{TContext,TWork,TResult}
, FlowComplete{TContext}
, FlowTimedOut{TContext}
, or FlowFaultOutcome{TContext}
. It reports activities to the caller; it never executes external work itself.
Describes a typed AppSurface Flow graph.
TContext
A definition is immutable after construction. Nodes are identified by stable string ids so local and durable hosts can store the current node without serializing executable code. Flow ids and versions should remain stable once durable instances have been started.
string FlowId { get; }
Source
Gets the stable flow identifier.
string Version { get; }
Source
Gets the graph version.
string StartNodeId { get; }
Source
Gets the node id where new instances start.
IReadOnlyDictionary<string, FlowNodeDescriptor<TContext>> Nodes { get; }
Source
Gets all node descriptors keyed by node id.
IReadOnlyDictionary<string, FlowExecutionNode<TContext>> ExecutionNodes { get; }
Source
Gets the internal execution view keyed by node id.
The execution view is built from the copied and validated node dictionary. It preserves the public Nodes
graph view while giving runners pre-resolved next-node targets.
FlowExecutionNode<TContext> StartExecutionNode { get; }
Source
Gets the pre-resolved start node used by in-process runners.
Configures local AppSurface Flow execution behavior.
These options affect the in-memory runner only. Durable hosts should keep replay, persistence, external events, and timer policy in their durable orchestration layer and use this package's contracts for typed graph behavior.
int MaxStepsPerRun { get; set; }
Source
Gets or sets the maximum number of synchronous node transitions allowed during one in-memory run.
The default value, 1000, protects local tests and examples from accidental infinite loops. Set a higher value for intentionally dense local workflows. Values less than 1 are treated as configuration errors when a runner starts.
Describes a typed external-event wait without exposing CLR type names to durable storage.
This interface describes manifest metadata only. A durable host validates an authorized event against its persisted wait registration, selects an allowlisted codec through ContractName
and ContractVersion
, validates the decoded value against PayloadType
, and only then invokes the Flow evaluator. The evaluator does not authorize, decode, or deduplicate external events.
string EventName { get; }
Source
Gets the exact case-sensitive event name.
Type PayloadType { get; }
Source
Gets the expected event payload CLR type for allowlisted codec lookup.
string ContractName { get; }
Source
Gets the exact durable payload contract name.
string ContractVersion { get; }
Source
Gets the exact durable payload contract version.
Declares the exact typed payload contract accepted by one external Flow event wait.
TPayload
The event name and contract identity are durable manifest values. Change them only with a new Flow definition version. Values are preserved exactly and compared ordinally by durable hosts; there is no trimming, case folding, or normalization. TPayload
is runtime codec metadata rather than a durable wire identifier. Use the string-based Wait
overload when an event intentionally carries no payload.
Validates and snapshots event-callsite metadata at public host boundaries.
IFlowEventCallsite
is extensible, so implementations can expose mutable or inconsistent getters. Capturing each value once prevents later mutation from changing an already-created wait or durable decision.
IFlowEventCallsite Snapshot(IFlowEventCallsite eventCallsite, string parameterName)
Creates an immutable, validated copy of an event callsite.
eventCallsite
parameterName
Immutable event metadata safe to retain.
Marks a partial type as the generated authoring specification for an AppSurface Flow.
Use generated authoring when a flow should be declared as typed transformer nodes with compile-time validation of outcome coverage. Use FlowGraphBuilder{TContext}
directly when a host needs dynamic graph construction, low-level runtime control, or compatibility with hand-authored nodes. The annotated type must be a non-generic partial class. Record and nested generated flow specifications are not supported. Generated authoring is additive: the generator lowers the annotated specification into the existing FlowDefinition{TContext}
runtime contract without changing low-level flow APIs. Avoid mixing generated definition helpers with manual low-level node registration for the same flow because that makes mapping ownership unclear.
string FlowId { get; }
Source
Gets the stable flow identifier used by generated definitions.
string Version { get; set; }
Source
Gets or sets the stable graph version. Defaults to 1
.
Marks a partial nested type as a generated-authoring flow node.
Apply this attribute to a partial class nested inside a FlowAuthoringAttribute
flow type. The node class must implement IFlowTransformerNode{TInput,TOutcome}
where TInput
matches InputContextType
and TOutcome
is the generated outcome union for that node.
string NodeId { get; }
Source
Gets the stable node identifier.
Type InputContextType { get; }
Source
Gets the context type consumed by the node.
Marks one generated-authoring node as the flow start node.
Exactly one node per generated flow must be marked with FlowStartAttribute
. If a flow declares zero or multiple start nodes, the generator reports diagnostic ASFLOWA004
and does not produce the generated definition helpers for that invalid flow.
Declares one generated outcome case a transformer node can return.
Outcome contexts are nominal ports used by the generated graph validator. FlowOutcomeKind.Next
must carry the input context type of exactly one target node. FlowOutcomeKind.Wait
and FlowOutcomeKind.TimedOut
resume the current node, so they must carry that node's input context type. FlowOutcomeKind.Fault
must carry FlowFault
. FlowOutcomeKind.Complete
is terminal and does not require a target node. FlowOutcomeKind.Activity
uses the five-argument constructor to declare work and result contracts, and its output context must match the current node input context.
string Name { get; }
Source
Gets the stable outcome name.
FlowOutcomeKind Kind { get; }
Source
Gets the outcome kind.
Type OutputContextType { get; }
Source
Gets the context type carried by this outcome.
Type? WorkType { get; }
Source
Gets the activity work contract type, when this is an FlowOutcomeKind.Activity
declaration.
Type? ResultType { get; }
Source
Gets the activity result contract type, when this is an FlowOutcomeKind.Activity
declaration.
string? CallsiteId { get; set; }
Source
Gets or sets an explicit stable activity callsite id.
When omitted, generated authoring uses <node-id>.<outcome-name>
. Either form is a durable identifier within a Flow definition and must not change while nonterminal instances reference it.
int WorkContractVersion { get; set; }
Source
Gets or sets the positive serialized activity work contract version. Defaults to one.
int ResultContractVersion { get; set; }
Source
Gets or sets the positive serialized activity result contract version. Defaults to one.
Describes one generated graph mapping method for analyzer validation.
Do not apply this attribute manually. The generator emits it on generated GraphBuilder
mapping methods so analyzers can validate explicit BuildDefinition
lambda coverage. Manually applying it can make graph coverage diagnostics misleading. This attribute is emitted by generated authoring code. Application code should use FlowOutcomeAttribute
to declare outcomes instead of applying this attribute manually.
string NodeId { get; }
Source
Gets the stable source node identifier.
string OutcomeName { get; }
Source
Gets the stable outcome name.
Type OutputContextType { get; }
Source
Gets the context type carried by this outcome.
Executes one generated-authoring transformer node.
TInput
TOutcome
Implementations receive a FlowTransformerContext{TInput}
and must return a non-null generated outcome case. The generated adapter lowers that case into the v1 runtime contract and the runner enforces the non-null outcome requirement. Exceptions thrown by an implementation propagate to the caller; use FlowOutcomeKind.Fault
with FlowFault
for expected process failures that should be represented as flow results. Nodes should honor cancellation and must not perform externally visible side effects; return FlowOutcomeKind.Activity
so a durable host can commit the command before executing work. A node may be evaluated more than once when a process dies before the returned transition commits.
ValueTask<TOutcome> ExecuteAsync(FlowTransformerContext<TInput> context, CancellationToken cancellationToken = default)
Executes the node and returns a generated outcome case.
context
cancellationToken
A generated outcome case.
Describes one generated-authoring transformer execution.
TInput
FlowId
Version
NodeId
State
ResumeEvent
FlowId
, Version
, and NodeId
identify the current definition and node being executed. State
is the typed input context unwrapped from the generated envelope; the record does not validate it, and generated adapters assume it is non-null. ResumeEvent
is null for initial execution and non-null when a node resumes after an external event or timeout. ActivityResult
is non-null only when a typed activity resumes the node; runners never populate both resume forms at once.
FlowActivityWorkResult? ActivityResult { get; init; }
Source
Gets the optional typed activity result that resumed this transformer node.
Use the generated outcome callsite's TryGetResult
or GetResult
method instead of casting FlowActivityWorkResult.Result
. The property is null on initial and external-event execution.
Executes one typed step in an AppSurface Flow graph.
TContext
Nodes should be deterministic, idempotent where practical, and explicit about process outcomes. Durable hosts may replay orchestration decisions around node execution, so avoid hidden global side effects in nodes and keep external I/O behind durable activity boundaries.
ValueTask<FlowNodeOutcome<TContext>> ExecuteAsync(FlowExecutionContext<TContext> context, CancellationToken cancellationToken = default)
Executes the node.
context
cancellationToken
A discriminated outcome that tells the runner how to continue.
Result returned by a flow runner after executing until the next pause or terminal outcome.
TContext
FlowRunResult<TContext> Waiting(string nodeId, string eventName, TContext context, FlowTimeout? timeout = null)
Creates a waiting result.
nodeId
eventName
context
timeout
ArgumentException
nodeId
or eventName
is empty. ArgumentNullException
context
is null.
Inspect Status
before reading wait-specific properties. timeout
is optional and remains null for waits without a timeout.
FlowRunResult<TContext> Waiting(string nodeId, IFlowEventCallsite eventCallsite, TContext context, FlowTimeout? timeout = null)
Creates a waiting result with an exact typed payload contract.
nodeId
eventCallsite
context
timeout
A waiting result that preserves immutable event metadata.
ArgumentException
nodeId
or callsite text metadata is empty. ArgumentNullException
eventCallsite
, its payload type, or context
is null. FlowRunResult<TContext> Completed(string nodeId, TContext context)
Creates a completed result.
nodeId
context
ArgumentException
nodeId
is empty.ArgumentNullException
context
is null.
A completed result does not carry wait, timeout, or fault details. Inspect Status
before reading status-specific properties.
FlowRunResult<TContext> TimedOut(string nodeId, string eventName, TContext context)
Creates a timed-out result.
nodeId
eventName
context
ArgumentException
nodeId
or eventName
is empty. ArgumentNullException
context
is null.
A timed-out result means timeout handling ran; it is distinct from a waiting result that carries a future timeout. Inspect Status
before reading timeout-specific properties.
FlowRunResult<TContext> Faulted(string nodeId, FlowFault fault)
Creates a faulted result.
nodeId
fault
ArgumentException
nodeId
is empty.ArgumentNullException
fault
is null.
Faulted results do not carry a context. Inspect Status
before reading fault-specific properties.
FlowRunResult<TContext> ActivityPending(string nodeId, IFlowActivityRequest<TContext> activity)
Creates a result that pauses local execution for one typed external activity.
nodeId
activity
An activity-pending result.
ArgumentException
nodeId
or activity metadata is empty, a contract version is invalid, or the work value does not implement its declared type. ArgumentNullException
activity
or one of its required values is null.
The in-memory runner does not execute activities. Execute the work through a test or host boundary, construct a result with the request's typed callsite, and call IFlowRunner{TContext}.ResumeActivityAsync
.
FlowRunStatus Status { get; }
Source
Gets the runner status.
TContext? Context { get; }
Source
Gets the latest context when the result carries one.
string? NodeId { get; }
Source
Gets the node id where execution paused or ended.
string? WaitingEventName { get; }
Source
Gets the event name awaited by a waiting result.
IFlowEventCallsite? EventCallsite { get; }
Source
Gets the immutable typed event contract for a waiting result, or null
for a string wait.
The runner preserves this metadata so a host can select an allowlisted payload codec. The result does not authorize, decode, or deduplicate event delivery.
FlowTimeout? Timeout { get; }
Source
Gets the optional timeout associated with a waiting result.
string? TimedOutEventName { get; }
Source
Gets the event whose timeout branch completed.
FlowFault? Fault { get; }
Source
Gets the fault details for a faulted result.
IFlowActivityRequest<TContext>? Activity { get; }
Source
Gets the typed activity request when Status
is FlowRunStatus.ActivityPending
.
Describes a fault returned by a flow node or adapter.
Faults are flow results, not exceptions. Use them for expected process failures that should be visible to callers or durable orchestration logs. Use exceptions for invalid definitions, host configuration errors, and programmer bugs.
string Code { get; }
Source
Gets the stable machine-readable code.
string Message { get; }
Source
Gets the human-readable diagnostic message.
Represents the discriminated outcome returned by a flow node.
TContext
The sealed derived records form a stable discriminated-union style API that works on current C# compilers. Future native union syntax can be layered on as authoring sugar without changing the runtime contract.
FlowNext<TContext> Next(string nodeId, TContext context)
Creates an outcome that moves execution to another declared node.
nodeId
context
A next-node outcome.
FlowWait<TContext> Wait(string eventName, TContext context, FlowTimeout? timeout = null)
Creates an outcome that waits for an external event before executing this node again.
eventName
context
timeout
A wait outcome.
FlowWait<TContext> Wait<TPayload>(FlowEventCallsite<TPayload> callsite, TContext context, FlowTimeout? timeout = null)
Creates an outcome that waits for an external event carrying one exact typed payload contract.
TPayload
callsite
context
timeout
A typed external-event wait outcome.
ArgumentNullException
callsite
or context
is null. FlowTimedOut<TContext> TimedOut(string eventName, TContext context)
Creates an outcome indicating the node handled a timeout branch.
eventName
context
A timed-out outcome.
FlowComplete<TContext> Complete(TContext context)
Creates a successful completion outcome.
context
A completion outcome.
FlowFaultOutcome<TContext> Fault(string code, string message)
Creates a fault outcome.
code
message
A fault outcome.
FlowActivity<TContext, TWork, TResult> Activity<TWork, TResult>(FlowActivityCallsite<TWork, TResult> callsite, TWork work, TContext context)
Creates an outcome that schedules one typed external activity and pauses the Flow node for its result.
TWork
TResult
callsite
work
context
An activity outcome.
ArgumentNullException
callsite
, work
, or context
is null.
Returning this outcome does not execute work
. A durable host records the transition and activity command atomically, executes the work through its provider-safe worker boundary, and resumes this same node with FlowActivityWorkResult{TResult}
. Nodes must not perform the external effect themselves.
Moves execution to another node in the same flow definition.
TContext
string NodeId { get; }
Source
Gets the target node id.
TContext Context { get; }
Source
Gets the context to pass to the target node.
Pauses execution until a named external event or timeout is delivered by the host.
TContext
string EventName { get; }
Source
Gets the external event name.
IFlowEventCallsite? EventCallsite { get; }
Source
Gets the exact typed event contract, or null
when this wait explicitly accepts no payload.
TContext Context { get; }
Source
Gets the context to persist while waiting.
FlowTimeout? Timeout { get; }
Source
Gets the optional wait timeout.
Reports that a timeout branch has been handled by a node.
TContext
string EventName { get; }
Source
Gets the event whose wait expired.
TContext Context { get; }
Source
Gets the context after timeout handling.
Completes a flow instance successfully.
TContext
TContext Context { get; }
Source
Gets the final context.
Fails a flow instance with a process-level fault.
TContext
FlowFault Fault { get; }
Source
Gets the fault details.
This member intentionally hides the static fault factory on FlowNodeOutcome{TContext}
.
Schedules one typed external activity and pauses the current Flow node until its result is available.
TContext
TWork
TResult
The generic properties are convenient for node tests. Durable hosts should consume IFlowActivityRequest{TContext}
to read declared CLR types, versions, work, and context without reflection.
FlowActivityCallsite<TWork, TResult> Callsite { get; }
Source
Gets the stable typed callsite.
TWork Work { get; }
Source
Gets the typed work value.
TContext Context { get; }
Source
Gets the Flow context to persist atomically with the activity command.
Identifies the host-neutral decision produced by evaluating exactly one Flow node.
Numeric values are a compatibility contract for durable hosts and telemetry. Do not reorder, renumber, remove, or reuse values. Append new transition kinds with explicit numeric values.
Runtime outcome kinds supported by generated AppSurface Flow authoring.
The numeric values are part of the public compatibility contract. Do not renumber or reorder existing values.
Identifies the terminal or pause status returned by an AppSurface Flow runner.
The numeric values are part of the public compatibility contract for logs, persisted state, and tests. Do not reorder, renumber, remove, or reuse values. Add new statuses only at the end with explicit numeric values and a migration/versioning plan.