Skip to content

UWS — Udon Workflow Specification

UWS logo

UWS is a compact, execution-oriented workflow specification that sits directly on top of source documents such as OpenAPI, Google Discovery, AWS Smithy, AsyncAPI, GraphQL, OpenRPC, Protocol Buffers, and OData. A UWS document describes how to orchestrate API, RPC, and event operations that source documents already describe without duplicating methods, paths, channels, messages, schemas, servers, or security schemes.

Source documents own the API or event contract. UWS owns the workflow overlay.

This is what distinguishes UWS from full client-side workflow tools such as Arazzo and IaC engines such as OpenTofu and Terraform. Arazzo describes full client-side action sequences and treats each step as a bespoke client action. OpenTofu and Terraform act as full client-side workflow engines for infrastructure: each resource and provider call is described in the client configuration and resolved against a provider plugin at apply time. Neither approach assumes the underlying operations are already defined by a server contract. UWS takes the opposite position: server actions are pre-defined by the source document, and UWS workflows reference those operations by ID rather than re-describing them. The result is a much smaller overlay: UWS does not duplicate request/response shapes, does not redeclare endpoints, and does not encode anything the source document already specifies.

UWS 1.13.0 is the latest specification release. It adds the verified HCL presentation/deprecation contract without changing the 1.12 wire or execution rules. The separate byte-based codec and lossless conformance corpus are implemented; M08 qualifies both root and codec releases after whole review 3. Legacy HCL input stays available. UWS 1.12 added optional operation effect classification (read, write, or unknown) and non-executable pending step contracts with recursive object-root input/output schemas. Pending-only planning documents may have an empty operations array; structural and semantic validation accepts valid pending contracts, while executable validation rejects them before runtime calls. UWS 1.11 added version-gated response-body dot-walks, loop-only $batchIndex, numeric wait/batchSize literals, terminal root-scoped goto, and corrected forEach merge records. UWS 1.10's portable execution rules and expression-addressable declaration names remain in force for 1.10 and later; earlier UWS versions retain their own semantics and schemas. Browser 1.10 is the current opt-in separate browser profile and adds typed CSS selector match counts; empty profile-schema lookup retains Browser 1.8 as its compatibility default. Missing sourceDescription.type defaults to openapi; legacy OpenAPI selectors remain valid for OpenAPI sources. The ansible-module source type added in 1.6 was removed in 1.7 without a replacement UWS-owned Ansible profile.

Why UWS?

Many API providers already publish OpenAPI. Once those documents exist, a workflow layer should stay focused on workflow concerns:

  • which operations participate
  • how they depend on each other
  • how values flow between them
  • which structural constructs shape control flow
  • which triggers start execution
  • which semantics are portable across runtimes

UWS answers exactly those questions and nothing else.

Beyond document shape, UWS also defines a normative execution model: a clean split between an orchestrator that owns structural workflow execution (dependency resolution, control flow, retry, output propagation) and a bound runtime that owns leaf execution (API/event calls, expression evaluation, item resolution). This split is what makes UWS portable — any compliant runtime shares the same orchestration semantics while bringing its own transport, credentials, and extension-profile logic.

UWS 1.9.1 and later also offer an explicit content-trust analyzer. It recovers core data flow, accepts profile-specific channel contracts from resolvers, and reports provenance/capability findings without changing validation or execution. See Content Trust.

For non-source leaf work, UWS keeps the core document narrow. Extension-owned operations declare x-uws-operation-profile; the public uws.runtime.1.0 supplement optionally adds a small x-uws-runtime payload with a required non-HTTP type selector such as fnct, cmd, sql, or llm. HTTP and event calls still use source binding fields, not x-uws-runtime.

The separate Mock Fixture Format 1.0 provides deterministic response fixtures keyed by operation ID and a canonical request digest. The public mockruntime package includes a pure runtime that replays those fixtures through the UWS orchestrator, uses caller-supplied examples or bounded deterministic schema synthesis, and records resolved would-be requests without network calls or automatic persistence. Its separately enabled hybrid adapter delegates only declared UWS 1.12+ reads to a caller-supplied hook; writes and unknown effects remain mocked.

A Minimal Document

{
  "uws": "1.12.0",
  "info": { "title": "Weather Report", "version": "1.1.0" },
  "sourceDescriptions": [
    { "name": "weather_api", "url": "./weather.openapi.yaml", "type": "openapi" },
    { "name": "gmail_api",   "url": "./gmail.openapi.yaml",   "type": "openapi" }
  ],
  "operations": [
    {
      "operationId": "current_weather",
      "sourceDescription": "weather_api",
      "sourceOperationId": "getCurrentWeather",
      "request": { "query": { "q": "Los Angeles", "units": "imperial" } },
      "outputs": { "summary": "$response.body.summary" }
    },
    {
      "operationId": "send_report",
      "sourceDescription": "gmail_api",
      "sourceOperationId": "sendMessage",
      "dependsOn": ["current_weather"],
      "request": { "body": { "userId": "me", "text": "$steps.get_weather.outputs.summary" } }
    }
  ],
  "workflows": [
    {
      "workflowId": "main",
      "type": "sequence",
      "steps": [
        { "stepId": "get_weather", "operationRef": "current_weather" },
        { "stepId": "send_email",  "operationRef": "send_report" }
      ]
    }
  ]
}

No HTTP method, no path, no server URL, no response schema — those live in the referenced source documents. UWS points at the operations and describes how the workflow uses them.

Executing a Document

A UWS document is not just a description — it is executable. Bind a runtime, call Execute, and UWS core orchestrates the entire workflow:

doc.SetRuntime(rt)          // bind your source/extension runtime
if err := doc.Execute(ctx); err != nil {
    log.Fatal(err)
}
records := doc.ExecutionRecords()  // inspect what ran

The orchestrator owns all structural concerns: dependency resolution, parallel scheduling, conditional branching, loop iteration, retry counting, and trigger routing. The bound runtime owns only leaf work: making the actual source operation call, evaluating expressions, and resolving iteration items. This split gives compliant runtimes the same orchestration semantics while leaving transport and provider behavior runtime-owned.

Reference

Start Authoring

If you need to hand-write a workflow, start with the practical workflow authoring guide. It shows the minimal YAML shape, operation binding, request values, output flow, workflow steps, triggers, extensions, and a validation checklist before the full specification. Authors of browser account-creation profiles should also review the registration authoring boundaries, including the current 1.2 verification contract and private-input rules.

The 10 Major Features

# Feature Summary
1 Source Operation Binding Strict binding to OpenAPI, Google Discovery, AWS Smithy, AsyncAPI, GraphQL, OpenRPC, gRPC/protobuf, OData, browser profiles, or extension-owned operations
2 Six Structural Constructs sequence · parallel · switch · loop · merge · await
3 Runtime Expression Grammar Normative ABNF expression language for value flow
4 Triggers and Route Dispatch Typed entry points with output-based routing
5 Structural Results Named outputs linked back to their source construct
6 Success Criteria and Actions Inline retry, goto, end with per-criterion scoping
7 Execution Model Orchestrator/runtime split for portable semantics
8 Extension Profiles Non-HTTP operations via x-uws-operation-profile
9 Validation Two-layer structural + semantic validation
10 Interchange Formats JSON, YAML, and HCL with round-trip guarantees