# AI-to-human handoff test checklist

A handoff passes when the caller reaches a useful, verified human or fallback state. A transfer API returning success is not enough.

Run each required route during open, closed, busy, no-answer, rejected, and media-failure conditions. Use test accounts and approved staff. Remove or protect personal data in recordings, transcripts, context briefs, and tickets.

## Test setup

- Workflow: `[name]`
- Agent version: `[version]`
- Route/queue: `[destination]`
- Hours and timezone: `[schedule]`
- Transfer mode: `[warm/blind/callback/ticket/other]`
- Caller and human fixtures: `[non-production IDs]`
- Context fields allowed to cross: `[minimum necessary list]`
- Evaluation owner: `[role]`
- Operations owner: `[role]`

## 1. Trigger and permission

- [ ] Caller-requested handoff is recognized without unnecessary resistance.
- [ ] Policy-required escalation triggers at the right point.
- [ ] Authority boundaries send consequential or unsupported actions to the approved route.
- [ ] Tool or model failure triggers handoff only when that is the approved recovery.
- [ ] A false trigger does not expose context or place the caller in a queue.

Record: trigger event, policy source, expected route, actual route, and result.

## 2. Caller explanation and consent

- [ ] The agent explains why a handoff is happening in plain language.
- [ ] The destination and expected next step are accurate.
- [ ] Expected wait, callback, or ticket behavior is not invented.
- [ ] Consent is requested before sharing context when required.
- [ ] The caller can decline and receives the approved alternate path.

Record the exact caller-facing message and the event that proves consent or decline.

## 3. Route and availability

- [ ] Open queue reaches the intended team, region, language, and skill.
- [ ] Closed hours follow the configured timezone and holiday calendar.
- [ ] Busy and full queues use the approved alternate route.
- [ ] No answer has a bounded timeout and visible recovery.
- [ ] Rejected transfer returns control to a useful caller-facing state.
- [ ] Reconnect or retry cannot create two active transfers or tickets.

Evidence: route decision, queue event, timestamps, retry count, and terminal state.

## 4. Context briefing and data minimization

- [ ] The human receives the caller's goal and verified facts once.
- [ ] Corrections replace stale values in the brief.
- [ ] Failed or unverified claims are labeled, not presented as facts.
- [ ] Sensitive data not needed by the human is excluded.
- [ ] The brief contains no internal prompt, hidden policy, or unrelated history.
- [ ] The caller does not need to repeat information that safely crossed the boundary.

Evidence: sanitized brief, human receipt, and caller repetition count.

## 5. Media and AI exit

- [ ] Caller and human can hear each other after connection.
- [ ] The introduction does not clip the caller or human greeting.
- [ ] Hold audio and silence stay inside the approved behavior.
- [ ] The AI stops speaking, generating, and calling tools after the human takes control.
- [ ] A one-way-audio or media drop is detected and recovered.
- [ ] The AI cannot silently remain as an active third participant unless explicitly designed and disclosed.

Evidence: participant events, audio channels, playback/generation state, and tool timeline.

## 6. Verified outcome and recovery

- [ ] Successful connection records the correct human receipt and disposition.
- [ ] Callback captures approved contact details, time window, ownership, and confirmation.
- [ ] Ticket fallback creates one ticket with the right priority and context.
- [ ] Failed handoff returns to the caller with an accurate explanation and useful option.
- [ ] The final system state matches what the caller was told.
- [ ] Critical route, privacy, or silent-limbo failures block release.

## Run record

| Case | Condition | Expected useful state | Actual state | Evidence | Result | Owner | Next action | Release impact |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| HND-001 | `[open/closed/busy/no answer/rejected/media drop]` | `[connected/callback/ticket/safe end]` | `[state]` | `[run ID]` | `[pass/fail]` | `[role]` | `[action]` | `[ready/caution/blocked]` |

## Worked fictional example

This is an invented case. A fictional travel-support agent routes a caller to the baggage team. The transfer service says `connected`, but the human receives one-way audio and the AI has already left. The caller hears silence for 40 seconds and hangs up.

The API result passed. The handoff failed. The expected recovery is to detect the missing human media, return to the caller, explain the problem, and offer an approved callback or ticket. No real caller or staff data is used in this example.

## Release decision

- Required cases run: `[count/total]`
- Critical failures: `[count and IDs]`
- Untested queues, languages, hours, or failure modes: `[list]`
- Decision: `[ready/caution/blocked]`
- Decision owner: `[role]`
- Follow-up date: `[date]`

Voxeval's release rule: no caller should be left in silent limbo, and no successful status should be accepted without a verified useful next state.
