Drop in one recording. Get the moment it went wrong, with a timestamp.
An autopsy is a whole-call scan of a two-channel recording: every barge-in, talk-over, dead air and latency incident, each with its position in the call and its measured magnitude, plus a self-contained HTML report.
# zero config; --demo reads the stereo call bundled in the install $ hotato autopsy call.wav $ hotato autopsy --demo
ffmpeg when it is on PATH. The report is written under hotato-output/, named by the content-derived autopsy id.What it measures
Four incident kinds, each a timing fact.
Deterministic on a two-channel recording: caller on one channel, agent on the other, byte-identical on every run of the same input.
| Incident | The timing fact behind it | Two-channel |
|---|---|---|
| barge-in | The caller became active while the agent was active, and the agent’s response to that is measurable. | required |
| talk-over | Overlapping activity with a measured overlap length. Attribution needs the channels separated. | required |
| dead air | A silence long enough to surface, timed from the end of caller activity. | best-effort on mono |
| latency spike | A response gap after the caller finished, above the threshold you set with --min-gap. | best-effort on mono |
A mono recording is analysed best-effort: silence timing with a measured confidence per finding. Talk-over and barge-in attribution comes from a two-channel export, which is what stack capture exists to get you.
$ hotato trust --stereo call.wav $ hotato trust --stereo call.wav --format json
- exit 0 · eligible for scan
- exit 2 · NOT SCORABLE, with the reason
- never a yield/hold verdict
A bad export gets refused before it can produce a confident, meaningless verdict.
Identical channels, a silent required channel, and a mono file handed to the two-channel path all exit 2 — naming the specific reason and the next step, rather than scoring anyway.
The same gate runs inside autopsy and inside investigate, so an unusable recording is caught at the same place every time. trust never labels intent and never emits a pass/fail: that separation is the point — it tells you whether a verdict would mean anything, and stops there.
Candidate moments are timing events. You supply the intent.
scan --stereo walks the caller and agent activity tracks across the whole recording and lists overlap onsets, agent starts during caller activity, and long response gaps.
This tool cannot know whether a caller sound was “mhm” or “stop”. So it ranks the moments, prints the label command for the top-ranked one, and waits. You decide the expected behaviour; the label is what makes the moment a check.
investigate adds one thing on top: it authenticates where the recording came from — a previously-frozen fixture clip, a fetch from the stack’s own API for a named call id, or a local file you asserted. A suspected channel swap or crosstalk refuses the verdict path outright and shows the candidates as advisory until you confirm the mapping.
# one recording: ranked candidate moments $ hotato scan --stereo full-call.wav --top 5 # a folder: the health report over every recording in it $ hotato scan ./calls # every candidate as JSON, for whatever reads it next $ hotato scan --stereo full-call.wav --format json --out candidates.json
Cost lines render only from figures you supply.
Hotato ships no default dollar figure. Pass --cost-config with your own per-incident numbers and the estimate lines appear; without it they stay off.
{"currency": "USD", "per_incident": {"dead-air": 3.0, "barge-in": 2.0}}