hotato 0.4.0
Hotato 0.4.0
Released 2026-07-08.
0.4.0 turns Hotato from a one-call scorer into a monitoring loop: connect a stack once, pull recent recordings, rank the candidate turn-taking moments across them, then carry a labeled fix to a paste-ready patch and a before/after proof.
Highlights
hotato connect/pull/sweep.connect <stack>runs a live auth check and stores credentials locally at~/.hotato/connections.json(mode 0600), sent nowhere but the vendor's own API.pullbulk-fetches recent recordings through each platform's verified list endpoint.sweeprunspulland then the zero-configanalyzeover the pulled folder, writing one self-contained offline dashboard of ranked candidate moments. Only verified endpoints are used; Retell pulls by explicit--call-id, and that limitation is documented rather than papered over.hotato analyze <folder>, zero-config folder analysis. Point it at a folder of dual-channel recordings and it ranks candidate turn-taking moments across all of them by measured salience, no scenarios, labels, onsets, or flags. Top moments embed the real audio inline with a playhead synced to the timeline, so you press play and hear the bug land where the chart marks it.--format jsonemits the ranked candidates for an agent to drive. Everything is framed as measured candidates you review and label; never a pass/fail, a failure count, or an intent claim.hotato patch/verify/loop, the closed loop.patch <fixplan.json>renders a fix plan into a literal, paste-ready artifact per platform: a JSON merge-patch body plus a ready curl for the platform's real config endpoint, or the exact constructor-kwarg source edit where config lives in agent code. It produces the change and never applies it.verify --before --afterreports battery-scale movement ("N of M fixtures that used to fail now pass, K of L hold fixtures still pass"), refuses the headline claim under low n, and reports coincidence, never causation.looporchestrates the whole cycle with state across runs and never auto-labels or auto-applies.hotato ingest, the passive on-ramp. Wire a platform webhook to invoke it and each completed call is fetched and scanned for candidate moments automatically. Discovery only: webhook payloads are treated strictly as untrusted data, exit 0 means it ran, and nothing is auto-labeled, auto-fixtured, or auto-tuned. Per-stack recipes indocs/INGEST.md.hotato describe, the generated capability manifest. One call (json or text) built from the live parser: every subcommand, argument, and exit code, so an agent learns the whole CLI without scraping--helpacross 18 subparsers. Exit-code epilogs are now uniform across every subcommand, anddoctor --format jsonemits the machine envelope.- Five more stacks behind
--allow-mono. Bland, ElevenLabs, Synthflow, Millis, and Cartesia capture and pull with exact verified endpoints. These platforms record one combined track, so scoring is degraded, gated behind the flag, and labeled indicative only.
Changed
hotato demoscores two real recorded calls. The packaged battery replaces synthetic audio with two operator-recorded probe calls against a scripted assistant on a provider's default interruption settings: a missed interruption (0.25 s talk-over) and a false stop on a soft backchannel. Full provenance and attestation ride in the scenario metadata, the only human voice is the recording operator's own, and two runs remain byte-identical.
Fixed
- Atomic writes for recording downloads, the sweep dashboard, and every
--out, so an interrupted run cannot truncate a previously good artifact. - Every JSON emitter refuses NaN and Infinity; a non-finite value surfaces as a clean exit 2, never invalid JSON.
.hotato/loop-state.jsonis validated on load; an incomplete or hand-edited state file is a clean error, never a KeyError.- Malformed WAV headers, identical caller/agent channels, invalid onsets, and bad flags are refused up front with plain reasons, and one bad file never aborts an
analyzeorloopbatch. - Wording in
docs/WHY.mdandREADME.mdsoftened where a frequency claim had no source.
Security
- Default-deny SSRF blocking on every vendor download URL: loopback, private, link-local, and reserved hosts are refused, re-checked on every redirect, and credential headers are stripped on cross-host redirects.
HOTATO_ALLOW_PRIVATE_URLSis the explicit opt-out. - MCP server input paths are sandboxed, mirroring the existing report-path sandbox.
ingestlocal recording paths requireHOTATO_INGEST_DIRand fail closed, so a forged payload cannot point the scanner at an arbitrary file.- Scenario ids are validated as safe path segments, closing a crafted-pack path that could read or exfiltrate an arbitrary local WAV.
CI and docs
- A new sdist guard job builds the sdist, installs only the extracted tree into a fresh venv, and runs the full suite from inside it, catching the green-wheel-broken-sdist failure mode that shipped unguarded in 0.2.3 and 0.3.0.
server.jsonMCP registry manifest,docs/MCP.mdwith copy-paste client configs,docs/CONNECT.md, an honest rewrite ofdocs/ADAPTER-STATUS.md,llms.txtreconciled to the real command surface, the new concatenatedllms-full.txt, andCITATION.cff.