Manual triggers and webhooks

Every trigger starts the same root <steps>. Its normalized input becomes context.payload. Multiple triggers may exist, but WOML v1 does not route each trigger to a different entry node.

<manual>

WOML
<manual id="start" />

Only id is accepted. woml run stays active and creates a run when the operator presses Enter. A keyboard run currently receives {} as its payload. Select a particular manual trigger with --trigger <id> when necessary.

<webhook>

WOML
<webhook
  id="newOrder"
  path="/webhooks/orders"
  method="POST"
  auth="bearer"
  secret="{{secrets.ORDER_WEBHOOK_TOKEN}}"
>
  <schema>
    {
      "type": "object",
      "required": ["orderId"],
      "properties": { "orderId": { "type": "string" } },
      "additionalProperties": false
    }
  </schema>
</webhook>
AttributeRequiredMeaning
idYesTrigger identity.
pathYesStatic absolute route. Parameters, wildcards, repeated slashes, and /_woml are forbidden.
methodNoDefaults to POST; executable v1 ingress uses POST.
authYesbearer or explicitly insecure none.
secretWith bearerExact {{secrets.NAME}}; forbidden with auth="none".

<schema> is optional and may occur once. It contains JSON Schema Draft 2020-12. Invalid source schema prevents activation. An invalid request returns HTTP 400 with WOML_TRIGGER_SCHEMA_INVALID and creates no run. Accepted requests return HTTP 202 with a durable run ID; execution continues asynchronously. The body limit is 1 MiB and the CLI prints a copyable curl request at startup.