Skip to main content

Human-in-the-loop — the pipeline waits for you

Advanced ⏱ 15 min approvals · hitl · governance

You will build: the review seam every acting pipeline needs — drafts pause in an approval queue, a reviewer approves or rejects (CLI, or the link in a Slack/WhatsApp/email notification), and the resolved draft is emitted onto a topic the next stage consumes. Approve → the action proceeds. Reject → it doesn't. Every decision is audit-logged with who and when.

stage drafts → approval queue (pipeline pauses) → pulse approvals approve/reject → resolved topic → next stage acts

Prerequisites

  • A deployed app whose acting stage routes through the human-approval plugin (the MCP tutorial's acting pipeline is the natural base — templates that use it ship with HumanApprovalPlugin wired).
  • pulse approvals requires Pulse ≥ the build carrying B-199 (check: pulse approvals --help).

1 · See what's waiting on you

pulse approvals list
2 approval(s):
ap-7c1… pending via slack 2026-07-14T09:02:11Z
Draft reply to ticket #4821 exceeds the refund threshold
ap-8d0… pending via email 2026-07-14T09:05:37Z

2 · Read the draft the pipeline paused on

pulse approvals show ap-7c1…

The full draft the stage produced, the channel that notified, and the resolvedTopic the verdict will land on.

3 · Decide

pulse approvals approve ap-7c1… --feedback "refund justified, customer is right"
# or
pulse approvals reject ap-8d0… --feedback "tone — escalate to a human agent"
approved ap-7c1… status=approved → emitted on drafts.resolved

The moment you respond, the plugin emits the draft (with your verdict and feedback attached) onto its resolved topic — the paused pipeline resumes on the next stage. The same responder powers the notification links, so CLI and Slack reviewers share one queue.

4 · Verify the resume and the audit trail

pulse events tail --topic drafts.resolved
pulse audit --limit 5 # APPROVAL_GRANTED / APPROVAL_REJECTED, with reviewer and timestamp

What just happened

The human is a stage, not a spectator: the pipeline's own topology enforces that nothing acts without a verdict, the queue survives restarts (it's a persisted table, not a callback), and governance gets what it actually asks for — who approved what, when, with what reasoning — as data, not screenshots.

Next