adr 0019 neura openai voice - Alshival-Ai/neural-labs GitHub Wiki
ADR 0019: Scope Alshival voice by private and team chat boundaries
Design history: for current instructions, see AI accounts and models. See the decision index for amendments and related records.
- Status: Accepted
- Date: 2026-09-04
Context
Alshival needs voice input in two different privacy scopes. A private chat calls for a low-latency, two-way assistant conversation, while a Team Chat needs a durable voice memo that teammates can replay and that Alshival can understand. Giving a browser a standard provider API key, treating a memo as a live team call, or keeping a transcript outside channel history would violate those boundaries.
Decision
Private voice uses WebRTC between the authenticated browser and OpenAI
Realtime. The workspace server accepts a same-origin SDP offer, adds a bounded
server-owned Alshival session configuration, exchanges it at the fixed OpenAI
endpoint with OPENAI_API_KEY, and returns only the SDP answer. It does not
relay live audio or return the key. Sessions are capped at five minutes.
Team voice uses MediaRecorder. The authenticated browser posts a supported
audio blob of at most 25 MB to a same-origin transcription endpoint. The
workspace server sends it to the fixed OpenAI transcription endpoint. After a
successful transcription, the browser uploads the original memo to the shared
team-uploads/ folder and posts both the attachment and visible transcript to
the originating channel as context, with invokeAgent: false. Mention or skill
tokens inside a transcript cannot automatically summon Alshival. A separate user
message containing @Alshival or a skill command creates a run
with recent channel transcripts in its bounded context. Existing channel membership
and agent-run authorization remain authoritative; the optional invocation flag can
only suppress normal trigger detection, not bypass it or grant access.
The unified composer switches between Send and Voice. Private calls expose a microphone mute and tap/hold modes. Team delivery uses the authenticated, CSRF- protected message POST with a stable request ID and waits for persistence before discarding local audio. Failed recordings are memory-only and can be downloaded, retried, sent without transcription, or discarded; no provider key or recording is persisted in browser localStorage.
The workspace derives an HMAC safety identifier from the stable Neural Labs user ID and an existing server secret. The raw user ID and provider errors are not forwarded to the client, and the provider key remains only in the ignored deployment environment.
Consequences
- Private audio flows directly over the negotiated WebRTC session; only SDP crosses the Neural Labs server.
- Team memo audio is disclosed to OpenAI for transcription and stored in the shared workspace, whose file tree is intentionally not a per-channel ACL.
- Team transcripts are durable channel history and ordinary bounded Alshival context for later explicit invocations, not automatic agent commands.
- Voice fails closed until an operator configures
OPENAI_API_KEY; personal ChatGPT OAuth remains isolated and is not repurposed for Realtime or transcription API calls.