Capture features
Meeting capture and acoustic diarization — identity-free by design.
The Capture plane joins meetings and produces who spoke when + what they said — with no identity. It is stateless and holds nothing persistent. Everything here is built and merged.
Two capture paths
- Online bot (recato-bot) — a headless browser / Zoom-SDK bot joins Meet / Teams / Zoom and captures per-participant audio (structural diarization, no ML), with Silero VAD, a confirmation buffer, hallucination filtering, per-speaker language lock, DOM speaker names, and authenticated warmed accounts.
- In-person single-mic (the flagship) —
WS /v1/inperson/stream→ diart live acoustic diarization → NEAR Whisper ASR per span → Redis publish, while buffering the recording for the authoritative post-pass.
A runtime-api orchestrates bot containers (idle auto-stop, crash reconciliation, exit webhooks with retry, per-user concurrency, hot-reload profiles).
Diarization engines
| Engine | Role | Placement |
|---|---|---|
| diart | Live streaming preview | CPU |
| DiariZen | Authoritative post-pass | GPU (stateless, swappable by URL) |
| remote | torch-free caller → external GPU box | — |
| mock | deterministic test double | — |
Selected via CAPTURE_DIARIZER; lazy import keeps the core torch-free. DiariZen uses 15-minute
windowing with an ephemeral CAM++ linker that stitches windows in memory and persists
nothing. See Diarization.
The identity seam (load-bearing)
Capture emits {start, end, local_speaker} only — no
voiceprint id, no name, no store import. This is test-locked against identity leaks
(diarize_only.py). The ephemeral linker reuses CAM++ math but keeps nothing. Identity
is a separate, consented step in VFTE.
Durable jobs & orchestration
- Durable queue (
#16) — Redis-Streamsdiarize_jobswith XAUTOCLAIM reclaim + dead-letter. - Option-A HTTP-claim — an off-CVM GPU worker claims via
:443only (claim / heartbeat / result), no Redis or SSH on the box, fetching audio by reference (by token, not through Redis). - Meeting-end — upload recording → meeting-completed webhook → fire-and-forget authoritative
post-pass.
store_audio=falseskips the upload but keeps the transcript.
API & TEE
POST /v1/diarize · WS /v1/diarize/stream · WS /v1/inperson/stream · GET /health ·
GET /attestation. Bearer-token auth (constant-time), ?token= for browsers. TDX attestation is
quote-only, no sealed key — the box holds nothing. Offline models, no runtime egress.
Source: FEATURE-SPEC.md §3, capture/README.md.