Document why wrapping QuinnTransport with EncryptingTransport using the
pairwise client↔relay key cannot work for an SFU (recipient has a different
key than sender). Propose two valid paths: MLS group keys (true E2E) or
hop-by-hop relay re-encryption (relay-trusted). Recommend hop-by-hop first.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Blockers 4 & 5: browser getUserMedia → JPEG IPC → Rust I420 pipeline;
remote video strip renders decoded frames via canvas; EncryptingTransport
wraps QuinnTransport so WZP AEAD is applied to all media (C2 fix).
Test fixes: HandshakeResult.session destructuring across relay/client/crypto
integration tests; video_codecs field added to all CallOffer/CallAnswer
structs; wzp-video pipeline_roundtrip integration tests added.
PRD docs: five Kimi-ready specs for E2E encryption, Android NDK 0.9 migration,
quality upgrade flow, wire-format hardening, and clippy debt.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add emit_call_debug events at every step of the Android connect/audio
path so failures are visible in the Settings debug log without needing
adb logcat:
- connect:handshake_start/done/failed (with timing)
- connect:android_audio_preflight (wzp_native loaded + RECORD_AUDIO
permission check via new has_record_audio_permission() JNI helper)
- connect:audio_stop_start/done
- connect:audio_mode_start/done/failed
- connect:audio_start_start/failed/panic/done (with oboe error code)
- connect:reuse_endpoint (endpoint reuse diagnostic)
Also adds has_record_audio_permission() to android_audio.rs — used in
the preflight event to confirm the OS has granted mic access before
wzp_oboe_start is called.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- oboe_bridge.cpp: return -6 (instead of silent 0) when streams do not
reach Started within the 2s poll deadline; also clean up streams on
that path so a retry can succeed
- main.ts: shared connectWithTimeout() so room-join and direct-call
auto-connect both get the 15s JS timeout; shared errorMessage() so
Tauri error objects don't show as [object Object] in toasts
- docs/bugs/001-android-join-voice-hang.md: comprehensive bug report
with root cause chain, evidence, return code table, and next steps
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Audit:
- docs/AUDIT-2026-05-25.md: full protocol audit covering 8 findings
(4 critical, 2 high, 5 medium, 4 low) with code references and fix
effort estimates
- vault/Audit/Tasks.md: Obsidian Tasks plugin file tracking all audit
items with priorities, due dates, and per-step checklists
Architecture docs updated for Wire format v2 and Wave 5/6 features:
- ARCHITECTURE.md: adds wzp-video to dependency graph and project
structure; wire format updated to v2 (16B header, 5B MiniHeader);
relay concurrency section corrected (DashMap+RwLock is current, not
a future optimization); test count 571→702; Android note
- PROGRESS.md: Wave 5 and Wave 6 sections appended; test count 372→702;
current status and open blockers as of 2026-05-25
- ROAD-TO-VIDEO.md: implementation status table inserted (✅/🟡/🔴/🔲
per phase); 6-step critical path to first video call
- WZP-SPEC.md: MediaHeader updated to v2 (16B byte-aligned); MiniHeader
updated to 5B with seq_delta; codec IDs 9-12 added (H.264/H.265/AV1);
version negotiation section added
Obsidian vault (vault/):
- 114 files across Architecture/, PRDs/, Reports/, Android/,
Reference/, Audit/ with YAML frontmatter
- 00 - Home.md index note with wiki links
- .obsidian/app.json config
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>