Success path deletes both the upload and the WAV; failures are typed and still
delete the audio; a shutdown mid-job leaves the row for the start-up sweep
(it is not a transcription failure); a hung endpoint is failed by the job
timeout, never an eternal spinner; strictly one job at a time (two long jobs on
iguana were never measured); stopping deletes queued audio and refuses new jobs.
Red: uploads.Worker is undefined.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Bounded read (cap+1 byte tells 'at the limit' from 'over'); a file that fails
validation creates no row; a prober fault is our error, not the user's bad
file; a row whose job cannot be submitted is failed, never left queued.
Mutation-checked: cap off-by-one, missing cleanup and deleting the handed-over
file each turn a test red.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Video is checked first so it is always refused as video; limits and reasons
are typed so callers and tests branch on Reason, not message text.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Probe-based, not extension-based: a Teams voice-only export is typically an
.mp4 with no video stream, indistinguishable from video by name (ADR-033).
Red: package uploads does not exist.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>