Workflow Anatomy

A runnable WOML file has one <woml> document root and one <workflow>. The document separates reusable dependencies, workflow identity, activation, business flow, operational policy, and lifecycle observation so each concern has one visible home.

Minimal structure

WOML
<woml>
  <imports>
    <module name="pricing" from="./modules/pricing.ts" />
  </imports>

  <workflow
    id="orders"
    name="Process orders"
    description="Validate, price, and confirm incoming orders."
    version="1.0.0"
  >
    <config concurrency="4" timeout="5m" queue="orders" />

    <triggers>
      <manual id="start" />
    </triggers>

    <steps>
      <step id="calculate" name="Calculate price">
        <script>
          return pricing.calculate(context.payload);
        </script>
      </step>
    </steps>

    <lifecycle>
      <on-error>
        <script>
          console.error("Order workflow failed", lifecycle.failure);
        </script>
      </on-error>
    </lifecycle>
  </workflow>
</woml>

<imports> is optional and belongs outside the workflow because imported code and reusable definitions are document dependencies, not workflow steps. The order of <config>, <triggers>, <steps>, and <lifecycle> inside <workflow> does not change their meaning. WOML recognizes those singleton sections by tag name.

The document root

<woml> accepts no attributes. A file has one of three profiles:

  • A runnable document contains <workflow>.
  • A reusable step document contains <props> and <step>.
  • A reusable notification document contains <props> and <provider kind="notification">.

Only the runnable profile can be activated with woml run. Reusable definitions are imported by runnable workflows and do not create independent run instances.

Workflow metadata

id is the stable machine identity used by durable storage, workflow calls, logs, and runtime management. Choose it carefully and keep it stable across compatible edits.

name and description are human-facing metadata. They appear in terminal output and make operational history understandable without reading source.

version belongs to your workflow definition. It does not choose the WOML grammar. Increase it when your team considers a workflow change meaningful for deployment, auditing, or compatibility.

WOML
<workflow
  id="customer-onboarding"
  name="Customer onboarding"
  description="Create the account, request approval, and send the welcome message."
  version="2.1.0"
>

Executable structure

<triggers> describes how new runs enter the system. Multiple triggers may activate the same root flow, and every normalized trigger input becomes context.payload.

<steps> is required and contains the business graph. Its direct children execute in document order unless a control-flow primitive explicitly introduces concurrency or routing.

<config> controls workflow-wide admission and deadlines. It is not a business step and does not return data.

<lifecycle> observes workflow and step events. Hooks are useful for logging and notification, but they cannot repair a failed step, change a route, or replace the workflow result.

Call-only workflows

A workflow may omit <triggers> when it should run only through services.workflows.call() or services.workflows.start(). Do not write an empty <triggers />; either declare at least one trigger or omit the section.

Validate the structure

Run:

Terminal
woml check workflows/

WOML reports duplicate sections, misplaced imports, unknown attributes, invalid IDs, empty steps, and unsupported document profiles before any script runs.

Use Tag Reference for exact placement and attributes.