Nothing sends. Nothing pays. Until a human signs off.

The dangerous moment in an agent workflow is not the work. It is the irreversible step after it: the email sent, the payment released, the order placed, each taken on the agent's own summary that the work is ready. Put a human decision in the record between the work and that step, and make the agent read the record before it acts. Zambo is the verifiable work layer for AI, and its handover acceptance is exactly that checkpoint: a decision recorded by the client side, readable by software as one small JSON record.

See the pattern first: the live demo runs one real call and hands you its verifiable receipt, no signup. For $0.99, put a human sign-off in front of your agent's next consequential action, so nothing runs on a claim alone: get the Day Pass

Published October 17, 2026. The acceptance states quoted below were read live from zambo.dev on the day this page was written. Updated October 17, 2026. Written against AER-1, IETF Internet-Draft revision 23: draft-zambo-aer1-23. AER-1 is an IETF Internet-Draft, not a finalized standard.

The step that needs a gate

Most agent workflows end with an action the world cannot take back. A summary that says "ready" is produced by the same system that did the work, with the same blind spots, and a workflow that acts on it has no checkpoint at all, just momentum. Human-in-the-loop diagrams usually draw the checkpoint as a chat message or a dashboard button, which means the approval lives in a thread, detached from the work it approved, and the agent has no reliable way to read it at the moment of action.

The gate that works is a record: the delivery itself carries a decision field that starts at hold, the human moves it, and the acting step reads it fresh. Approval stops being a message about the work and becomes part of the work's own record.

The gate, step by step

  1. The work runs as recorded calls. The agent does the job through Zambo, so every step leaves a verifiable receipt: the tool, the inputs, the saved output, the time.
  2. The job is handed over as one link. The handover gathers the session's receipts, redacts emails, phone numbers, and keys, and publishes one page: every step, what was not checked, and a summary receipt closing the set. The reviewer needs no account to open it.
  3. A human reviews, then decides. The reviewer presses Verify all to re-check every step in the browser, then accepts or flags the delivery. A flag requires a reason. The answer mints its own receipt, pinned to the handover's original Merkle root.
  4. The agent reads, then acts. Before the send or the payment, the acting step fetches /handover/<id>/acceptance.json and reads release_hint. It reads hold while the handover is pending, and still reads hold when the work is flagged. It reads ok_to_release only after a client has accepted, with decided_by: "client" and the time in decided_at. No ok_to_release, no action.

The full mechanics are documented at zambo.dev/docs/handover, including the respond API at /api/v2/handover/<id>/respond.

Two live handovers, the two states of the gate

Hold: no human decision yet

Handover bd7e5325 was created on October 16, 2026 at 14:34 UTC and holds five steps. Its not_checked list names two steps that did not complete successfully. Nobody has accepted or flagged it. Its acceptance record reads status "pending", decided_by null, decided_at null, release_hint "hold". An agent gated on this record waits, correctly: there is no sign-off to act on, and the record even shows one reason a reviewer might hesitate.

Released: a client decided, on the record

Handover 45434a17 carries four steps, each with its own verifiable receipt. Its acceptance record reads status "accepted", decided_by "client", decided_at 2026-10-16T14:31:51Z, release_hint "ok_to_release", 4 steps checked and 0 unchecked. The accept behind it is an event in the handover's JSON twin with its own receipt (14cb8b21), pinned to the original Merkle root. An agent reading this record proceeds, and can show exactly which decision it proceeded on.

Both pages are public and live. The difference between the two records is the entire pattern.

The agent cannot approve its own work

A gate the gated party can lift is decoration, so the record refuses the shortcut. Ask through the MCP handover_accept tool from the session that created the handover and the call is refused with a forbidden error: "Creator authority cannot accept this handover." The web respond path under creator authority returns HTTP 403 with the same refusal. The approval record export states the rule in plain words: "The acting agent cannot approve its own handover." The decision has to come from the client side, and the record keeps which side decided in decided_by. A workflow can still be fully automated around the gate: what it cannot do is quietly approve itself and keep the paperwork looking human.

The record after the decision

Sign-off that evaporates is worth little, so the decision is kept where auditors and clients later look for it. After an accept or a flag, the receiver's client link for the handover offers the approval record as a PDF or JSON download: who decided as entered, decided_at, the decision, the note or the flag reason, and the per-step list with each step's AI label, checked state, and receipt link. The public handover page withholds the export; the record travels with the client, not the crowd. The approval record page walks one real acceptance field by field.

What the gate does not do

The gate is a read, and your workflow enforces it. Zambo does not reach into your agent and block its other tools, does not hold the payment while anyone decides, and does not release or reverse funds. The pattern works because the acting step checks the record first; wiring that check in is the integration, and it is a small one.

The record is also honest about what a decision proves. The acceptance record prints its own scope: check_scope reads "Receipt bytes only; not accuracy or human review of every step." And the accept event on handover 45434a17 carries the notice verbatim: "Logged by Zambo on behalf of the visitor. Not identity-verified." A verifiable receipt shows the saved result has not changed since it was recorded; it does not prove the result was right. What the gate proves is narrower and, at the moment of an irreversible action, exactly what you need: a decision was recorded, by the client side, at a stated time, over a stated set of steps, and it has not been edited since.

Questions, answered

How do I get human sign-off before an agent sends or pays?

Put the delivery in a Zambo handover and gate the action on its acceptance record. The agent does the work as receipted steps and hands it over; the send or the payment step reads GET /handover/<id>/acceptance.json first. While the record reads status pending with release_hint hold, nothing proceeds. Only a client-side Accept flips it to status accepted with release_hint ok_to_release, and only then does the agent send or pay. The full mechanics are documented at zambo.dev/docs/handover.

Can the agent approve its own work to get past the gate?

No. The acting agent cannot approve its own handover. An accept attempted from the creating session through the MCP handover_accept tool is refused with a forbidden error, and the web respond path under creator authority returns HTTP 403. The status stays pending and the release_hint stays hold. Sign-off has to come from the client side, and the record shows which side decided: decided_by reads client.

What exactly does the agent check, and when?

One small JSON record, readable with no account: status (pending, accepted, or flagged), decided_by, decided_at, the step totals, and release_hint. The agent reads it at the moment of action, not when the work finished, because a flag can land after delivery. The record also prints its own scope honestly: check_scope reads Receipt bytes only; not accuracy or human review of every step. The gate certifies that a decision was recorded, not that the work is correct.

What if the human flags the work instead of approving it?

The record says flagged, the release_hint stays hold, and the objection is kept: a flag requires a reason (submitting without one returns HTTP 400), and the reason is carried in the approval record. The agent waits or escalates to a person; it does not proceed. Nothing about the delivery can be quietly edited in the meantime, because every step and the flag itself are verifiable receipts.

Where does the record of the decision live afterward?

On the client link for the handover. After an accept or a flag, the receiver can download the approval record as PDF or JSON: who decided as entered, when, the decision, the note or flag reason, and the per-step list with receipt links. The public page withholds the export. If the money itself is the thing being gated, the proof-before-payment page covers the release pattern from the payer side. Zambo never holds the funds while any of this happens.