Human-in-the-loop agent workflows
The reliable division of labor for agent automation: the agent proposes, a human approves, and OrchStep executes. A prompt step makes the approval a real gate, not a vibe.
Full autonomy sounds great until the agent promotes the wrong build to production at 4pm on a Friday. Full manual sounds safe until you're the bottleneck on every routine task and the agent's value evaporates.
The division of labor that actually works sits between them: the agent proposes — it figures out what to do and stages it — a human approves the one decision that carries risk, and the tool executes deterministically once the yes lands. The trick is making the approval a real gate, not a Slack message someone thumbs-up out of habit. OrchStep's prompt step is that gate, baked into the workflow.
Propose, approve, execute
name: release-train
defaults:
version: "3.2.0"
target: production
tasks:
# `orchstep run promote`
promote:
steps:
- name: stage
func: shell
do: echo "staged {{ vars.version }}, ready to promote to {{ vars.target }}"
- name: review
func: prompt
args:
message: "Promote {{ vars.version }} to {{ vars.target }}?"
type: confirm
default: false
- name: decision
if: '{{ eq steps.review.value "true" }}'
then:
- name: promote
func: shell
do: echo "promoting {{ vars.version }} to {{ vars.target }}"
- name: announce
func: shell
do: echo "{{ vars.version }} live in {{ vars.target }}"
else:
- name: defer
func: shell
do: echo "promotion deferred by reviewer"Read the shape: stage is the agent's proposal — it's done the work to get a build ready. review is the human gate. decision is the execution, and it only takes the promote branch when steps.review.value is "true". The agent can run everything up to review on its own; it physically cannot promote without the answer.
Why a prompt beats a chat approval
A "yeah ship it" in chat approves something — but what, exactly? The version the agent had in mind when it asked, or the one it has now? The prompt step closes that gap. The message renders the actual variables — Promote 3.2.0 to production? — so the human approves the concrete action, not a vague intent. And the approval is in the execution path: there is no promote step that runs without review returning true. The gate isn't a social convention, it's control flow.
The default that keeps CI honest
default: false is doing quiet, important work. The same workflow runs in two places: a human's terminal, where the prompt asks and waits, and a non-interactive context like CI, where nobody is there to answer. In the second case the step resolves to its default — false — and the workflow takes the defer branch. It does not silently promote because no one said no.
That means one workflow is safe in both worlds. You don't keep a "manual" version and an "automated" version that drift apart. You keep one, and the gate behaves correctly whether a person or a pipeline runs it.
Let the human see what they're approving
Pair the prompt with a dry-run and the approval gets even sharper. The human can preview the full resolved plan before the run that will ask them:
orchstep run promote --dry-runThey see exactly which steps the then branch contains and which variables resolved to what — so when the real run asks "Promote 3.2.0 to production?", they're saying yes to something they've already read. Full tour: Previewing with Dry Run.
What you gained
| Concern | Chat approval | OrchStep prompt gate |
|---|---|---|
| Approving the actual action | ambiguous | message renders real vars |
| Enforced before execution | by convention | by control flow |
| Safe when nobody answers | accidental ship | default: false defers |
| One workflow for human + CI | two that drift | one, gate behaves per context |
| Reviewable before the yes | — | --dry-run |
The point isn't to slow the agent down everywhere — it's to put exactly one deliberate human decision in front of the one step that's expensive to get wrong, and let the agent own everything else.
Where to go next
- LLM Agent Integration — how agents propose and run workflows
- Previewing with Dry Run — review before you approve
- Variables & Outputs — how
steps.review.valueflows - Error Handling — what happens when a step fails
Want a human in the loop without becoming the bottleneck? Add one prompt step in front of the irreversible action — orchstep init gives you the starting shape.
curl -fsSL https://orchstep.dev/install.sh | sh