Home / Incident

The agent kept speaking 1,810 ms after the caller interrupted.

One recording, one command, one incident: a measured moment where the call went wrong, with a timestamp and an id you can hand to someone who does not trust you. This is what hotato autopsy writes for the example in the repo, and for yours. How the number is validated →

the command that produced everything below
$ hotato autopsy examples/autopsy/audio/autopsy-01-barge-in-say-do.example.wav
incident apx-cc33f46fad58#2 · autopsy-01-barge-in-say-do.example.wav
CRITICAL BARGE-IN apx-cc33f46fad58#2

The agent kept speaking for 1,810 ms after the caller interrupted.

barge-in · overlap 1.81s dead air 1.94s 0s 2s 4s 6s 8s 10s 12s caller takes the floor · t=2.99s
observed
t=2.99s into a 12.0s call, 2 channels, stereo
measured
overlap 1.81 s; the agent did not go silent within the 3.0 s limit
evidence
dual-channel audio: caller and agent on separate channels
pin
apx-cc33f46fad58, this call's id; #1..#2
The same fields land in the self-contained HTML report each run writes to hotato-output/.

What the run printed.

Every line names an incident kind, the second it happened, and the number that made it one.

hotato autopsy: autopsy-01-barge-in-say-do.example.wav  (12.0s, 2 channels, stereo)
  [CRITICAL] BARGE-IN       t=2.99s  overlap=1.81s  agent did not go silent within 3.0s
      the caller took the floor and the agent kept talking over them for 1.81 s without going quiet within 3.0 s
  1 incident: 1 critical, 0 warning
  report: hotato-output/autopsy-apx-cc33f46fad58.html
  pin: apx-cc33f46fad58  (incidents apx-cc33f46fad58#1..#1)

Generated from Hotato 1.20.0 on the example recording in the repo. Timing comes from audio energy over time, one channel per party, so each number recomputes from the waveform. What every verdict rests on →

Reported in the wild

The same moment, filed by other people.

The builders living this are already asking for the missing layer in public. Every link below is someone else’s report, on their own stack, of the failure this page measures.

  • A LiveKit community thread on 2026-07-09 asks how teams profile per-turn latency: user-stop through playback, every tool call in between, p50 and p95 across runs (LiveKit community: per-turn latency).
  • A separate report describes instrumenting ASR, LLM, and TTS, watching the services total under one second, and still hearing a three to four second gap before the agent speaks (LiveKit community: services 1s, reply 3-4s).
  • One HN comment describes a barged-in appointment confirmation that still triggered the downstream booking pipeline: the caller cut in to stop it, and the booking went through anyway (Hacker News: a barge-in that booked anyway).
  • One production report estimates an agent interrupting itself through its own echo in about ten percent of calls, where lowering the sensitivity risks the agent never yielding to the caller (Retell community: an agent echoing itself).
  • One developer reports 1,242 calls with zero conversions, blames a three to four second response gap, and wants sub-second replies to recover the funnel (Retell community: no conversions). Another reports prospects hanging up during a three second silence before the agent speaks (Retell community: opening silence).

The turn-taking is the product surface, and right now it is the untested one.

And the other half: what the agent said it did.

One commenter states the constraint: judges “can’t reliably judge LLM outputs without access to the environment where those actions are executed” (Hacker News: judging without the environment).

Why it lands hereWhen the agent’s word is the only record, a wrong action and a right one look identical. The incident above is the same moment with a timestamp, an id and a number on it.

Send it. Then pin it.

Both start from the printed id, apx-cc33f46fad58.

  1. 01 / SHARE

    One file, whoever owns the fix

    The run writes this report as a self-contained HTML file. Attach it to the ticket and the timeline travels with it.

  2. 02 / PIN

    The incident becomes a check

    hotato pin apx-cc33f46fad58#2 writes a portable .hotato bundle: the audio, the timing evidence, the check.

  3. 03 / PROVE

    CI reads the exit code

    hotato prove --contracts contracts/ re-runs the stored checks and fails closed: 0 pass, 1 fail, 2 could not tell.

How the timing is measured → · how say-do is graded → · full walkthrough →

The payoff

The transcript passed. The call failed.

Every voice team has shipped this call. The transcript reads clean, the tool log says success, the dashboard is green, and the customer got the wrong outcome. Here is the walk from a call to a gate.

You start with one recording:

console
$ hotato investigate ./call.wav
hotato investigate [run 1]: call.wav
  input health: eligible for scan
  verdict path: eligible (a labeled event here can carry a yield/hold verdict)
  most likely failure (top-ranked candidate):
    [1] t=7.63s agent_stop_no_caller  trailing_silence_sec=0.37, caller_proximity_sec=0.5
  next: label it (use --expect hold instead if the agent was right to keep talking):
    hotato investigate label '.hotato/investigate-state.json#1' --expect yield

The scan ranks the candidate moments, marks the top one, and prints the command that comes next. You label that moment as a yield the agent owed or a hold it was right to keep, and that writes a contract named by its evidence hash:

console
$ hotato investigate label '.hotato/investigate-state.json#1' --expect yield
created hotato contract: call-8s-yield
  dir:      contracts/call-8s-yield.hotato
  expect:   yield
  passed:   False
  measured: did_yield=False seconds_to_yield=n/a talk_over=0.00s
next:
  hotato contract verify contracts

Then the gate scores the stored evidence, deterministically, in CI:

console
$ hotato contract verify contracts
hotato contract verify: contracts (1 contract)
  [FAIL] call-8s-yield (expect yield): did_yield=False seconds_to_yield=n/a talk_over=0.00s | integrity: intact
  0/1 contracts pass; exit_code=1
  These contracts pin known failures. Each stays red until you fix the agent and recapture the call, the same way a snapshot test stays red until you update the snapshot.
  Path to green: fix the agent, then recapture with `hotato drive <bundle>` (vapi/twilio), or the manual path in docs/RECAPTURE.md.

That exit 1 is the part worth slowing down on. A committed contract is a pinned bad call, and it is meant to stay red. The frozen audio never changes, so the gate goes green only after you fix the agent and recapture the call, the same way a snapshot test stays red until you update the snapshot. The red names the contract, its expectation, and the numbers. Nothing recaptures automatically: the recorded behavior is the source of truth in CI, and updating it is a deliberate, local, reviewed act.

Say-do is what turns a green transcript into a red gate. A tool_call assertion counts only the spans in your ingested trace, so an agent’s words claiming a tool ran do not count. An outcome assertion combines those spans with a query against your system of record, so a refund the agent announced is checked against whether a refund row exists.

hotato prove folds the checks you ran into one release proof, green only if all pass. Wire the gate into CI →

Run it on your recording.

One call in, every measured incident out, with the report already written.

$ hotato autopsy ./call.wav

pip install hotato is the whole setup. Get started →