# Live handoff verification (deployed lab) Produced by `ops/e2e/live-handoff.mjs` (Playwright chromium, run 2026-10-24 ~11:47-11:49 UTC) against https://chatwoot-bot.railsfanatics.com and https://chatwoot.railsfanatics.com (Chatwoot v4.19.0). Final run: conversation display id 5. Conversations 1-4 are earlier runs of the same script made while fixing selectors in the script; each of those runs reached the same handoff, they are not separate evidence. All JSON here is sanitized (tokens, secrets, non-example.com emails redacted; no secret values found by a post-run scan; the only match is the public bot URL in the `referer` field). ## What was observed 1. Visitor page and widget opened in a real browser; native pre-chat form filled (name Lab Visitor, email lab-visitor+@example.com, issue "Dishwasher will not drain", message "I need to book a repair appointment"). The pre-chat "Message" field is the first incoming message (no separate send needed). 2. Polled by API (HUMAN_AGENT_TOKEN). First observation (~2.3 s after submit): status `pending`, assignee_type `AgentBot`, waiting_since null (`02-state-trace.json`). About 1.2 s later: status `open`, team scheduling (id 1), assignee_type null, waiting_since set. Messages: public ack from AgentBot (id 26) created before the private summary note (id 27); both in `02-messages.json`. The first incoming message therefore did arrive pending. Operator runs page (`03-operator-runs.png`): run handed_off, action log verify_pending, ack, note, recheck_before_handoff, assign_team, open_status, readback all ok; no error rows. 3. Second visitor message sent in the widget; after 22 s: no new bot or outgoing message, run still handed_off, no extra run/action rows, conversation still open in team 1 (`04-second-message-readback.json`). 4. Replayed duplicate message_created webhook (real first incoming message, fresh timestamp, valid HMAC signature, new delivery id): HTTP 200 `{"status":"duplicate_event"}`, no new messages, no new run/action rows. A bad-signature POST returned 401 (`05-duplicate-webhook.json`). Note: the replay payload was built by the script from API data in Chatwoot's webhook shape; it is a synthetic replay, not a captured delivery. 5. SCRIPTED AGENT-USER REPLY (posted with the human agent user's API token, not a human response): "Scripted agent-user reply (posted via API token, not a human response)". It appeared in the visitor widget (`07-widget-scripted-agent-user-reply.png`) and waiting_since went from set to 0/cleared (`06-after-scripted-agent-user-reply.json`). No human replied at any point. 6. Dashboard screenshot after UI login as the lab admin: team "scheduling" queue, Unassigned tab (`09-dashboard-scheduling-team-queue.png`), listing the lab conversations as open. ## Where pre-chat values landed - Email and name: contact (`meta.sender`). Issue: conversation custom_attributes `issue` (contact custom_attributes empty). The bot's note reproduced name, email and issue from them. The message body was the first incoming message. ## Files Screenshots 01, 02, 03, 07, 09; JSON 02-08; `summary.json` (per-check pass/fail, 25 of 25 pass).