Captura, picker, preview, crop e upload de fotos. EXIF strip ON por default; widgets KoderImagePicker / KoderImagePreview / KoderImageCropper.
Transcrição
Contrato cross-surface para transcrição (speech-to-text) em apps Koder. Regra central: **on-device-first** — a transcrição DEVE funcionar offline e por padrão no próprio dispositivo (whisper/sherpa embarcado); o backend remoto (Koder AI Voice, `services/ai/voice`) é **enhancement opt-in** (mais acurácia/diarização/ áudio longo), nunca a dependência crítica. Privacidade-by-default: o áudio não sai do device sem confirmação. Gate de release via teste TTS→transcrever→assert (koder-stack#187). Realização de referência no Dek: dek#149 (local-first resilience) + dek#155 (fallback on-device).
Especificação completa
Media — Transcription (STT) — on-device-first — v0.1
Normative cross-surface. Onde um app Koder transcreve fala em texto (recorder, memo, legendas, interview capture), vale este contrato. Engine on-device via whisper/sherpa embarcado; engine remota = Koder AI Voice (
services/ai/voice, self-hosted). Os dois são Koder — a decisão aqui é resiliência + privacidade, não Koder-vs-externo (esse é oself-hosted-first.kmd, já satisfeito).
1 — MUST: on-device-first (o piso)
- R1 — Default on-device. A transcrição DEVE rodar no próprio dispositivo por padrão e funcionar offline. Abrir uma gravação e transcrever NÃO PODE depender de rede nem de um backend alcançável.
- R2 — Remoto é enhancement opt-in. O Koder AI Voice remoto só entra quando o usuário opta (mais acurácia, diarização, sumarização, áudio longo) e há rede. Nunca é o caminho crítico; sua indisponibilidade não quebra a transcrição.
- R3 — Degradação graciosa. Backend remoto gated/401/403/offline/timeout →
cair pro on-device com aviso inline claro ("Sem conexão — transcrevendo neste
dispositivo"), NUNCA uma tela de erro terminal. (Antipadrão observado:
DEK-AUT-003/DEK-NET-001viravam "Falha na transcrição" sem fallback efetivo.)
2 — MUST: privacidade-by-default
- Transcrever on-device mantém o áudio no device — alinha com
audio.kmd §3("NUNCA auto-upload sem confirmação"). Enviar o áudio pro backend remoto exige o opt-in da R2 (consentimento), não pode ser silencioso. - O modelo on-device e seus assets ficam embarcados/baixados localmente; nenhum
conteúdo (transcrição, áudio, hash) vaza em telemetria (
voice/wake-word.kmd §obs).
3 — MUST: empacotamento do engine on-device
- A lib nativa de STT embarcada (ex.:
libwhisper.so) DEVE respeitar os gates de empacotamento da plataforma — em Android, 16 KB page-alignment (-Wl,-z, max-page-size=16384), senão o gate strict de release reprova (dek#137/#155). - Modelo embarcado/baixável versionado via model catalog/registry (dek#149 + modelreg).
4 — MUST: teste de corretude (gate de release)
Todo componente com transcrição DEVE ter o TDD gerado pela categoria transcription
do /k-test (koder-stack#187): TTS sintetiza uma frase canônica conhecida em
N idiomas (piper) → roda pela função de transcrição (on-device E, se configurado,
remoto) → assert fuzzy (contains/WER ≥ limiar) por idioma. Reprova a release se a
transcrição (no piso on-device) não devolver o texto esperado — teria pego o backend
gated antes de publicar.
5 — Adoption checklist (per app)
- Transcrição funciona offline (R1) — testar com rede desligada.
- Remoto é opt-in (R2); sua falha cai pro on-device com aviso (R3).
- Áudio não sai do device sem consentimento (privacidade §2).
- Lib STT nativa 16 KB-aligned (§3) — passa o gate de release Android.
- TDD
transcription(koder-stack#187) no gate de release.
Non-normative — referências
- Realização de referência: Dek —
dek#149(local-first resilience + model catalog),dek#150(connectivity-aware + fallback local + aviso inline, DONE),dek#155(fallback on-device),dek#137(16 KB gate). - Engine remota:
services/ai/voice(Koder AI Voice). Engine on-device: whisper/sherpa viawhisper_ggml_plus. - Teste:
koder-stack#187. Privacidade:audio.kmd §3. Resiliência:always-on.kmd.
Outras capabilities de mídia
Gravação, playback e screen-capture. Recording indicator obrigatório; codecs via engines/kodec; widgets KoderVideoPlayer / KoderVideoRecorder / KoderScreenCapture.
Memos, podcast, attachments e ringtones — áudio genérico, separado de voice/wake-word. Widgets KoderAudioPlayer / KoderAudioRecorder.
Pick, preview e OCR de PDF/DOCX/MD/TXT. OCR local-first (tesseract); fallback services/ai/ocr. Widgets KoderDocumentPicker / KoderOcrButton.