# Review Steps
{{< tier level="sovereign" note="Review steps make independent evaluation an explicit part of the delivery process." >}}

Use a `review` step after implementation to launch a registered reviewer against the source agent session and its work.

## Configuration

```yaml
- key: launch_review
  name: Launch Reviewer
  kind: review
  needs: [launch_executor]
  review:
    action: launch_reviewer
    taskKey: "${workflow.inputs.taskKey}"
    sourceSessionUlid: "${steps.launch_executor.outputs.sessionUlid}"
    reviewId: "${workflow.inputs.reviewId}"
    assignmentId: "${workflow.inputs.assignmentId}"
    agentHandle: "${workflow.inputs.reviewerHandle}"
    launcherConfigKey: "${workflow.inputs.reviewerLauncherConfigKey}"
  waitsFor:
    kind: workflow_input
    expected: [review_approved, review_changes_requested]
  outputs:
    reviewerSessionUlid: "$.normalized.session.sessionUlid"
    outcome: "$.normalized.input.outcome"
```

| Field | Required | Purpose |
| --- | --- | --- |
| `review.action` | Yes | Use `launch_reviewer` |
| `taskKey` | Yes | Task being reviewed |
| `sourceSessionUlid` | Yes | Implementation session whose work is reviewed |
| `reviewId` | When dispatching | Existing review record receiving the verdict |
| `assignmentId` | When dispatching | Exact reviewer assignment receiving the verdict |
| `agentHandle` | Yes | Registered reviewer assigned to this launch |
| `launcherConfigKey` | Yes | Launcher preset used for the reviewer |
| `run` | No | Dispatch immediately by default; set `false` to create the reviewer session only |
| `outputs` | No | Named values, usually the reviewer session identity |

For a dispatched review, create or load the review and assignment before this step. Valdr freezes the exact `reviewId` and `assignmentId` correlation before the reviewer runs, keeping the published verdict attached to the intended review and work.

## Choose an execution mode

- **Start and wait:** Leave `run` unset, include `reviewId`, `assignmentId`, and `waitsFor`, and let the Review step own its verdict wait.
- **Detached:** Leave `run` unset, set `detached: true`, and join that exact reviewer turn later with an [Await-Condition Step](../await-condition/).
- **Create only:** Set `run: false` without `waitsFor`. This creates the reviewer session but sends no initial review turn; a later Session step can prompt it after the artifact is ready. Review and assignment IDs are not required until a dispatched turn needs to publish a verdict.

## Review outcomes

| Outcome | Meaning |
| --- | --- |
| `review_approved` | The supported review evidence approved the work |
| `review_changes_requested` | The reviewer requested another implementation pass |

These values are different from the `approved` and `rejected` choices used by a human gate.

## Route requested changes

Use an [Outcome route](../condition/) to send `review_changes_requested` back to implementation within a bounded loop. Review then runs again against the revised work before the workflow can advance.

## Next step

Continue with [Await-Condition Steps](../await-condition/) for callback-authorized waits and exact-turn joins.

