3.9 KiB
3.9 KiB
Clio - Architecture Overview
Purpose
Multi-device audio recording system with end-to-end encryption. Records continuously on phone and portable devices, encrypts immediately, syncs to central server, transcribes with GPU, and provides a web interface for search and highlights.
Components
| Repository | Purpose | Deployment Target |
|---|---|---|
| clio-api | FastAPI server, recordings DB, highlights | Server (10.0.0.45) |
| clio-android | Android recording app | Phone (manual APK) |
| clio-ui | React viewer frontend | Server (10.0.0.45) |
| clio-ai | Whisper transcription, wake word detection | Desktop (10.0.0.130) |
| clio-infra | Deployment configs, docs, NixOS modules | All |
Security Model
Phone (has: server public key) Server (has: private key)
───────────────────────────── ────────────────────────
Record audio → temp.ogg
Encrypt with public key →
recording_*.ogg.enc
│
└──── HTTP POST ────────→ Receive encrypted file
Decrypt with private key
Store as .ogg in recordings/
- Sealed box encryption: X25519 key exchange + XSalsa20-Poly1305
- Forward secrecy: Each encryption uses ephemeral keys
- Phone never stores unencrypted: Temp file deleted immediately after encryption
- If no public key configured: Recordings are deleted (security-first design)
File Format (SREC)
Encrypted files use a chunked format for streaming large files:
[4 bytes: "SREC" magic]
[1 byte: version (1)]
[4 bytes: chunk count, big-endian]
For each chunk (64KB max):
[4 bytes: encrypted length, big-endian]
[N bytes: sealed box ciphertext]
Data Flow
1. Recording
Phone/Pi → temp.ogg → encrypt → recording_*.ogg.enc
2. Sync
Phone/Pi → HTTP POST → Server decrypts → recordings/YYYY/MM/DD/*.ogg
3. Transcription (async, on desktop)
Desktop pulls recordings → Whisper → JSON segments → POST to server
4. Viewing
Browser → clio-ui → clio-api → recordings + transcripts + highlights
API Endpoints (clio-api)
| Endpoint | Method | Description |
|---|---|---|
/health |
GET | Health check |
/api/v1/public-key |
GET | Server public key (Base64) |
/api/v1/recordings/upload |
POST | Upload encrypted file |
/api/v1/recordings |
GET | List recordings with transcripts |
/api/v1/recordings/{id} |
GET | Recording details |
/api/v1/recordings/{id}/audio |
GET | Stream audio file |
/api/v1/import/transcription |
POST | Import transcription JSON |
/api/v1/highlights |
GET/POST | Manage highlights |
/api/v1/sources |
GET | List recording sources |
Database Schema
recordings: id, source_name, audio_path, duration, language, recorded_at, transcribed_at segments: id, recording_id, start_time, end_time, text, confidence highlights: id, recording_id, start_seconds, end_seconds, tag, note, created_at
Sync Modes (Android)
| Mode | Behavior |
|---|---|
| Never | No sync, files stay on phone |
| LAN Only | Sync only when IP matches subnet (e.g., 10.0.0.) |
| WiFi Only | Sync on any WiFi network |
| Any Network | Sync on WiFi or mobile data |
Hosts & Paths
Server (10.0.0.45)
- Code:
/work/hosting/recordings - Audio:
/media/external/Hosting/Recordings - Database:
/work/hosting/recordings/data/recordings.db - Frontend:
/var/www/recordings-viewer - Domain:
recordings.hallocks.xyz
Desktop (10.0.0.130)
- Transcription scripts
- Real-time wake word detection
- GPU: RTX 3090
Dependencies
clio-api (Python)
- fastapi, uvicorn
- pynacl (libsodium)
- aiofiles
- sqlite3
clio-android (Kotlin)
- lazysodium-android
- androidx.work
- okhttp3
clio-ai (Python)
- faster-whisper
- torch, torchaudio
- sounddevice
- webrtcvad
- scikit-learn