Skip to content

Await-Condition Steps

Sovereign
Sovereign tier required. Await-condition steps keep long-running work synchronized without manual polling or reconstructed handoffs.

Use an await_condition step when a workflow must pause until an expected outcome arrives from an agent session, review, or authorized callback.

Configuration

- key: await_executor
  name: Await Executor
  kind: await_condition
  needs: [launch_executor]
  waitsFor:
    kind: workflow_input
    expected: [executor_completed, executor_blocked]
    authorizedHandles: ["${workflow.inputs.executorHandle}"]
    sourceSessionUlid: "${steps.launch_executor.outputs.sessionUlid}"
  outputs:
    outcome: "$.normalized.input.outcome"
FieldRequiredPurpose
waitsFor.kindYesUse workflow_input for authored waits
waitsFor.expectedYesOutcomes this step accepts
waitsFor.authorizedHandlesCallback modeAgents or operators allowed to satisfy a callback-authorized wait
waitsFor.sourceSessionUlidDepends on modeRecommended for callback mode; required for an exact-turn join
waitsFor.sourceTurnClientRequestIdExact-turn modeBinds the wait to one turn from the same detached producer
outputsNoNamed accepted values for later steps

Keep expected outcomes narrow and non-empty. Strict validation rejects an empty list. Callback-authorized waits need at least one authorized handle; exact-turn waits derive authority from the detached producer and must not add authorizedHandles.

Bind the wait to its source

For agent work, map the session identity from the launch step and use it as sourceSessionUlid. For review work, use the reviewer session identity and expect only review verdicts:

waitsFor:
  kind: workflow_input
  expected: [review_approved, review_changes_requested]
  authorizedHandles: ["${workflow.inputs.reviewerHandle}"]
  sourceSessionUlid: "${steps.launch_review.outputs.reviewerSessionUlid}"

This prevents unrelated sessions or reviews from advancing the workflow.

Join one detached turn

Use an exact-turn wait when a Session or Review step dispatches work with detached: true. Export both identifiers from that producer, then bind the wait to the same pair:

- key: launch_executor
  name: Launch Executor
  kind: session
  detached: true
  session:
    action: launch_task
    taskKey: "${workflow.inputs.taskKey}"
    agentHandle: "${workflow.inputs.executorHandle}"
    launcherConfigKey: "${workflow.inputs.launcherConfigKey}"
  outputs:
    sessionUlid: "$.normalized.session.sessionUlid"
    turnClientRequestId: "$.normalized.session.turnClientRequestId"

- key: await_executor
  name: Await Executor
  kind: await_condition
  needs: [launch_executor]
  waitsFor:
    kind: workflow_input
    expected: [executor_completed, executor_blocked]
    sourceSessionUlid: "${steps.launch_executor.outputs.sessionUlid}"
    sourceTurnClientRequestId: "${steps.launch_executor.outputs.turnClientRequestId}"
  outputs:
    outcome: "$.normalized.input.outcome"

Both values must come from the same detached producer. Do not add callback-authority fields to an exact-turn wait.

Interpret structured session output

Put a session-output gate on the producing Session or Review step when that step starts and waits, or on a Session input step. An await_condition cannot carry gates. See Session Steps for the supported placement and example.

Review-backed waits rely on published review evidence; do not use an agent’s JSON response to manufacture a review verdict.

Outputs and routing

Map the accepted outcome:

outputs:
  outcome: "$.normalized.input.outcome"

Later steps can route on ${steps.await_executor.outputs.outcome} with when checks or an Outcome route.

In Valdr UI

The run inspector shows what the step is waiting for, its linked session or review, accepted evidence, and any available operator action. The Workflow Builder exposes expected outcomes, authorized handles, source-session selection, and output mappings.

Next step

Use a Outcome route to route the accepted outcome, or a Human-Gate Step when the next transition requires an operator decision.