Durable Waits and External Signals
A durable wait pauses a run without keeping a script worker alive. WOML records the wait and can resume the same run after a runtime restart. Choose a timer for time-based work or an external signal for a callback from another system.
Choose a wait
| Need | Flow item |
|---|---|
| Pause for a duration | <wait id="pause" duration="10m" /> |
| Resume at an instant | <wait-until id="window" at="..." /> |
| Wait for a matching callback | <wait-for id="result" signal="..." correlation="..." /> |
Each item belongs inside <steps> and publishes its result under context.steps.<id>.
Wait for a callback
An earlier step can supply a correlation value:
<step id="dispatchBuild">
<script>return { buildId: crypto.randomUUID() };</script>
</step>
<wait-for
id="buildResult"
signal="ci.build.succeeded"
correlation="{{context.steps.dispatchBuild.buildId}}"
timeout="1h"
on-timeout="fail"
>
<schema>{ "type": "object", "required": ["commit"], "properties": { "commit": { "type": "string" } }, "additionalProperties": false }</schema>
</wait-for>The callback must match the exact run, wait, signal, correlation, schema, and a unique idempotency key. This prevents a callback for one build from waking another. Do not use a JavaScript promise or sleep loop for a long wait.
Deliver and inspect a signal
External HTTP signal ingress requires a dedicated token and a protected endpoint. For local operator delivery, use the owner-authenticated CLI:
woml get <run-id>
woml signal ci.build.succeeded --run <run-id> --wait buildResult --correlation <build-id> --id ci-run-123 --payload ./result.jsonValidate signal payloads before delivery and use TLS plus an authenticating reverse proxy when exposing callback ingress beyond a trusted host. Timeouts, cancellation, duplicate delivery, and restart recovery are settled by the durable runtime.