Skip to content

Core Philosophy

Vyuh Workflows separates orchestration, side effects, history, and storage. The executable source is a Dart function or a constrained JSON document. The runtime never stores a Dart stack frame.

Replay, Not Tokens

A run is history plus the current command projection. After every durable fact the runtime invokes the same versioned workflow from its entry point:

Completed awaits return recorded results. Unresolved awaits emit a command and mark the run blocked. running means a new fact is ready to reduce, not that a Dart isolate is parked.

Side Effects Belong in Activities

Workflow code may use if, switch, and loops over recorded values. It must not:

  • call a network or database;
  • read the wall clock or generate randomness;
  • mutate globals;
  • use Future.wait or unregistered futures.

Those belong in versioned ActivityHandlers that receive a stable idempotencyKey. Human work is a userTask. External events are signals. Time is sleep.

One Vocabulary, Two Authoring Surfaces

ConceptDartJSONRuntime record
IdentityWorkflowRef(code, version)code + versionversion plus run
Automated workflow.serviceTaskserviceTaskactivity command
Assigned workflow.userTaskuserTaskuser-task command
External eventflow.waitForSignalsignalsignal history
Timeflow.sleeptimertimer command
Branch / loopDart control flowswitch, joinsreplay decisions

JSON compiles to an executable definition. Arbitrary Dart cannot be converted losslessly back into a graph.

Identity Is Immutable

code + version is the public identity. The fingerprint/digest is an integrity check. A run stores all three. Changing behavior requires a new version. Workers refuse to replay history against a different digest.

Storage Is the Coordinator

Correctness comes from:

  • append-only history;
  • unique (run, operationKey, attempt) commands;
  • optimistic run revisions;
  • leases and claim-generation fencing;
  • atomic join and continue-as-new transactions.

Process affinity is not a correctness mechanism. API, decider, activity, and recovery roles can share a process or run separately.

Products Talk to the Service

Product Flutter apps and product APIs do not embed deciders or hold a service-role key. They call vyuh_workflow_service. cdx_feature_workflows renders inbox state. cdx_workflow_templates supplies the canonical approval definition.

The graph LegacyWorkflowEngine remains only so existing ELOG and DocsIQ runs can finish on the engine that started them.

See Also