# Human-in-the-Loop Approval Gate

> Let agents draft freely but require explicit human approval before any irreversible or external action.

Category: AI Agent Workflows  
Tags: safety, approval, side-effects  
Setup time (estimate): 2-4 hours  
Estimated cost: No model cost added; cost is reviewer time.  
Last verified: not yet independently verified

Classify every tool as **read**, **reversible write**, or **irreversible/external** (send email, payment, delete, publish). Only the last class needs approval.

## Steps

1. Tag each tool with a `risk` level in its registry entry.
2. When the agent calls a high-risk tool, do not execute. Persist the pending call (tool, args, reason) with an ID.
3. Notify a human with a readable summary and approve/reject actions.
4. On approve, execute exactly the stored args (never re-generate them). On reject, return the rejection reason to the agent as the tool result.
5. Expire pending actions after a timeout.

## Tool registry

```json
{
  "search_docs":   {"risk": "read"},
  "create_draft":  {"risk": "reversible"},
  "send_email":    {"risk": "external", "requires_approval": true},
  "delete_record": {"risk": "irreversible", "requires_approval": true}
}
```

## Gate logic

```python
def dispatch(call):
    meta = REGISTRY[call.name]
    if meta.get("requires_approval"):
        pid = store_pending(call)
        notify_human(pid, summarize(call))
        return f"PENDING_APPROVAL id={pid}. Wait; do not retry."
    return execute(call)
```

## Failure modes

- Approval fatigue: reviewers rubber-stamp when every action needs approval.
- Approved action differs from what executes if arguments are not frozen at approval time.
- Pending approvals that never expire block workflows or run stale actions.
