Before the action
waitFor checks role, prerequisites, thread state, and transitions, then atomically
claims an invocation. Do not execute if it rejects or times out.
The next report for that step on the same thread instance carries the invocation
ID automatically. Permission does not imply success or validate future content.
After reporting the outcome
.failed('Reason', { waitFor: true }). The response waits for
that event’s worker validation without polling. It cannot undo an action.
If a report was accepted but the validation wait timed out, the error carries
stepId. Resume the wait without recording a duplicate:
Fresh approval for every attempt
Use this complete repeatable workflow when each refund attempt needs its own approval:Recovery
Cancel a grant you will not use withawait grant.cancel(). Cancellation does
not restore its consumed approval. If a permission response is lost, recover
using its invocationId rather than claiming another invocation:
Go and Python
Go usesthread.WaitFor(ctx, name, &threadify.WaitOptions{Timeout: 10 * time.Second})
and threadify.ReportOptions{WaitFor: true}. Python uses
await thread.wait_for(name, WaitOptions(timeout=10)) and success(wait_for=True).
JavaScript timeouts are milliseconds; Go uses durations and Python uses seconds.
See the Go and Python examples.
Existing OpenTelemetry instrumentation
After obtaining permission, setthreadify.thread_id, threadify.step_name, and
threadify.invocation_id on the individual operation span. Its exporter can report
the outcome instead of duplicating it with an SDK step report. Use the same
identity that obtained the grant. Passive OTLP export alone cannot gate execution.
Protocol details and failure behavior