CLIENT + BACKEND / VOICE
Speak first. Review before submit.
Voice is an input adapter for the same food workflows as typed text. Capture, processor choice, transcription, transcript review, and final submission stay separate so convenience does not erase consent or control.
heyfood log --voiceRust release status
The hardened Python v0.3 client shipped --voice for onboarding, agent questions, and meal logging, plus device and capture preferences. Native v0.4.1 intentionally removed that runtime while the client moved to Rust. Its public Rust voice crate currently defines the target-gated audio boundary but does not implement capture or activate --voice. The backend transcription contract and audio:transcribe authorization remain implemented, dark by default unless enabled for a deployment.
One reviewed voice turn
- 01
Authorize before capture
Verify an authenticated session and the narrow audio:transcribe scope before opening a microphone. An older grant must be expanded before any recording begins.
- 02
Capture in memory
Record a short, device-qualified PCM stream and encode one bounded WAV. Cancellation closes the microphone immediately; the voice adapter does not persist local audio or transcripts.
- 03
Transcribe through a bounded endpoint
Upload once over HTTPS. The service validates the multipart envelope and WAV independently, rate-limits fail closed, and holds audio in memory rather than using a disk-spooling upload abstraction.
- 04
Review the transcript
Accept, edit, record again, type instead, or cancel. Dropped or truncated capture cannot be accepted unchanged for a saved profile or meal mutation.
- 05
Enter the normal turn path
Only reviewed text reaches onboarding, meal logging, or the hosted agent. Voice and typed input converge before business logic, safety evaluation, and write confirmation.
Processor changes require consent
| Capture path | Trust boundary |
|---|---|
| Native microphone | Audio is sent to hello.food's authenticated transcription endpoint and its configured transcription subprocessor. |
| Browser speech recognition | The browser vendor processes audio. Automatic fallback requires an explicit disclosure and defaults to no. |
| Typed input | No microphone or speech processor. Always remains available as the final fallback. |
An explicitly selected native path never opens a browser. SSH, headless sessions, missing devices, denied permissions, and unavailable audio dependencies degrade to a clear typed path rather than hanging.
Transcription is deliberately narrow
POST /v1/audio/transcriptions
scope audio:transcribe
purpose onboarding | ask | log
input mono 16-bit PCM WAV · 8–48 kHz · max 120s
output transcript · duration · language? · opaque model version- Audio bytes are never written to disk, logged, or persisted by the endpoint.
- Logs contain operational metadata, never audio or transcript content.
- The service validates request and audio-size ceilings separately.
- Provider failures remain generic at the client boundary.
- Capture is never automatically retried after an uncertain network outcome.
Target TUI interaction
Ctrl+Space start or stop capture
F8 fallback voice binding
/voice start, stop, or explain unavailable support
Esc cancel and close the microphone
RECORDING → TRANSCRIBING → REVIEW → SUBMITThe transcript appears in the composer for review. Accepted text then follows the same streaming agent turn and presentation path as typed input. Spoken-agent responses are a separate capability and are not claimed by this Rust TUI contract.