Skip to content

feat(voice): on-device voice input (Chrome local recognition, never the cloud) - #100

Merged
linxule merged 6 commits into
mainfrom
feat/device-voice
Oct 10, 2026
Merged

linxule merged 6 commits into
mainfrom
feat/device-voice

Conversation

@linxule

@linxule linxule commented Oct 10, 2026

Copy link
Copy Markdown
Owner

Adds a fourth per-study voice mode, device: desktop Chrome turns speech into text on the participant's computer (SpeechRecognition.processLocally). Decision record: the on-device voice spike (GO for Chrome local recognition; NO-GO for self-hosted Whisper and Moonshine).

Privacy invariant. A device recognizer starts only if processLocally exists on it and reads back true after being set. There is no fallback to cloud dictation or server transcription. language-not-supported, service-not-allowed, a failed install, or a missing API hide the mic for the session; participants type instead. /api/transcribe still accepts only installation.

Consent. Locality is worded as the browser's claim, not ours: the browser "turns your speech into text on this computer and says the recording stays there; this study receives only the text you choose to send." This is in all six languages. The five translations are drafts pending review.

Verified in real Chrome 155 (macOS): available() returns downloadable for all six tags (en-US, zh-CN, fr-FR, ja-JP, ko-KR, es-ES; zh-CN confirmed), and install() succeeds for en-US (~5–30 s). Not verified: recognition of real speech. A fake-microphone clip produced no-speech, so a manual check by speaking in desktop Chrome is required before participants use it.

Rollback. The mode is a study-config field bound to the revision. No schema change, but a 5.3 build refuses studies saved with device (save 400, links 409, canonical load 503). Before rolling back, set those studies to Off on 5.4 and reissue links.

Reviews: Kimi approved with no blockers. Its two minor findings were fixed after checking them against the code: a language change reset installation/browser voice state, and the Spanish register was inconsistent.

npm run check:cloudflare: 20/20 lanes on a clean tree at the head commit.

Inspired by Yinghua's voice-input work in her fork, credited in ACKNOWLEDGMENTS as in 5.1.0.

🤖 Generated with Claude Code

linxule and others added 6 commits October 10, 2026 14:41
…tion

'device' is accepted wherever 'browser' is: validation, drafts, hosted rules
and follow-up copies. /api/transcribe still accepts only 'installation'.
Changing the mode advances the study revision (shared contract scenario).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… the cloud

Device mode gates the mic on SpeechRecognition.available({processLocally}),
installs the language pack on first press while typing stays available, and
starts only recognizers that have the processLocally attribute and accept
true. language-not-supported and service-not-allowed hide the mic for the
session. There is no fallback to cloud dictation or server transcription.

Consent presents locality as the browser's promise: the browser turns speech
into text on this computer and says the recording stays there; the study
receives only the text the participant sends. zh-CN verified as accepted by
Chrome 155 (available() for all six tags).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ut; Spanish tú register

The device availability effect re-ran for every mode on a language change,
resetting state and stopping an active browser dictation. Device detection
is now its own effect that returns early outside device mode (regression
test). The Spanish device lines used usted; the file uses tú. Both from the
Kimi review.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Gemini, Kimi and Grok reviewed the five device-voice translations as the
5.1 strings were. No promise was strengthened or weakened; fixes are term
and register consistency in ja, zh and ko. Decisions recorded in
docs/translations/REVIEW-2026-10.md.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@linxule
linxule merged commit 27072b7 into main Oct 10, 2026
6 checks passed
@linxule
linxule deleted the feat/device-voice branch October 10, 2026 13:28
menotbobbybrown pushed a commit to menotbobbybrown/openinterviewer that referenced this pull request Oct 11, 2026
On-device voice input (linxule#100), analysis files in the study export (linxule#101),
OpenNext 1.20.10 / wrangler 4.148.0 with Next held at 16.3 (linxule#98), provider
SDKs (linxule#95). Code-only release; rollback to 5.3 refuses device-mode studies.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant