dfdf07269d
Adds Fix #6 (L2 — SubscribeOk narrowing), Fix #7 (L3 — subscriber-driven Probe API), and Fix #8 (L1 — version-aware Lite-03/04 codec + ALPN negotiation) to the compliance audit document. Updates the gap matrix (L1/L2/L3 → ✅) and the TL;DR (now reads "nine shipped fixes + M6 closed; every gap is now resolved, no items remain deferred"). The "what's deliberately deferred" section now lists only the external follow-up — a `kixelated/moq` feature request suggesting per-deployment tuning of moq-rs's per-subscriber forward-queue starvation behavior. That's an upstream-relay concern, not a moq-lite gap. Updates the audio-rooms completion-plan pointer to reflect the shipped count and the absence of remaining deferrals. Audit doc title acknowledges Lite-04 alongside Lite-03 since the codec now speaks both. https://claude.ai/code/session_012TGfo99Ugz7fcCPv85a8Tq
4.7 KiB
4.7 KiB
Audio rooms — completion plan
STATUS (2026-04-26 PM): Listener and speaker paths are both live end-to-end on moq-lite Lite-03, the create-space flow ships, and the kind-10112 host-server list lives in Settings. What remains is hardening (reconnect / leave cleanup / per-speaker level metering), Nests-feature parity (chat, hand-raise approval, recordings — see the integration audit), and Desktop / iOS targets.
:nestsClient:jvmTest(~140 unit tests) is green; integration tests behind-DnestsInterop=truework against a real Docker'd nostrnests stack.
Implementation state
Transport + protocol
| Surface | Status | Notes |
|---|---|---|
:quic v1 + HTTP/3 + WebTransport |
✅ done | RFC 9000 + 9220; auditor passes |
| moq-lite Lite-03 codec (announce / subscribe / group) | ✅ done | moq/lite/, full unit suite |
| moq-lite session (listener + publisher) | ✅ done | MoqLiteSession.client(...) |
WebTransportSession.incomingBidiStreams + openUniStream |
✅ done | needed for publisher |
IETF draft-ietf-moq-transport-17 codec |
✅ done | reference impl, no production caller |
:nestsClient
| Surface | Status | Notes |
|---|---|---|
HTTP /auth JWT mint (NIP-98 → ES256 JWT) |
✅ done | OkHttpNestsClient.mintToken |
connectNestsListener → MoqLiteNestsListener |
✅ done | path = /<namespace>?jwt=<token> |
connectNestsSpeaker → MoqLiteNestsSpeaker |
✅ done | publishes audio/data track |
AudioRecordCapture + MediaCodecOpusEncoder |
✅ done | Android actuals |
MediaCodecOpusDecoder + AudioTrackPlayer |
✅ done | Android actuals |
AudioRoomMoqLiteBroadcaster + AudioRoomPlayer |
✅ done | encode / decode pumps |
| Interop harness (Docker compose nostrnests stack) | ✅ done | NostrNestsHarness, 4 test classes |
Amethyst (Android UI)
| Surface | Status | Notes |
|---|---|---|
AudioRoomsScreen feed of kind-30312 events |
✅ done | from followed users |
AudioRoomJoinCard → launches AudioRoomActivity |
✅ done | passes service / endpoint / hostPubkey |
AudioRoomActivity (full screen + PIP) |
✅ done | lifecycle anchor |
AudioRoomViewModel (listener + speaker state) |
✅ done | commons/.../viewmodels/ |
Foreground service (AudioRoomForegroundService) |
✅ done | listening + microphone variants |
| Mute / unmute / hand-raise UI | ✅ done | drives BroadcastHandle.setMuted + presence |
| Kind-10312 presence heartbeat | ✅ done | 30 s + debounced state-change publish |
"Start space" FAB → CreateAudioRoomSheet |
✅ done | publishes kind-30312 with caller as host |
| Settings → Audio-room servers (kind 10112) | ✅ done | replaceable list, defaults to nostrnests.com |
Pending
| Item | Phase | Effort |
|---|---|---|
| Reconnect / retry on listener Failed | M8 | 1 d |
| Per-speaker level meters (RMS from decoder output) | M8 | 1 d |
| Connection-failure UX copy (typed reasons → strings) | M8 | 0.5 d |
| Desktop audio capture + playback | future | gated on Compose Desktop AudioInput API |
| iOS audio capture + playback | future | new iosMain actuals |
| Nests-feature parity (chat, mod, recordings, …) | see integration audit | varies |
Pointers
- moq-lite wire spec + IETF gap:
nestsClient/plans/2026-04-26-moq-lite-gap.md - moq-lite Lite-03/04 compliance audit (2026-05-09):
nestsClient/plans/2026-05-09-moq-lite-rfc-compliance.md— no 🔴 wire-incompatibilities found; nine spec tightenings shipped end-to-end: AnnouncePlease prefix-mismatch, Subscribe broadcast validation, trackPriority bit-pack matching kixelated'sPriorityHandle, publishers-list freshness on inbound bidi dispatch, RESET_STREAM with typed code on Drop replies, STOP_SENDING(SUBSCRIPTION_GONE) on dead group uni, SubscribeOk narrowing ofstartGroupto publisher'snextSequence, subscriber-driven Probe API (MoqLiteSession.probe()), and full Lite-04 codec + ALPN negotiation (MoqLiteVersionenum,wt-protocolparsing, dual-version advertisement). M6 (Goaway body) closed via spec verification (no body in Lite-03/04). No items remain deferred. - Nostrnests integration audit (gaps + roadmap): see most recent doc in
nestsClient/plans/ - QUIC stack status:
quic/plans/2026-04-26-quic-stack-status.md - Audio-rooms NIP draft (needs refresh after the moq-lite findings):
docs/plans/2026-04-22-nip-audio-rooms-draft.md - Listener entry:
nestsClient/src/commonMain/kotlin/com/vitorpamplona/nestsclient/NestsConnect.kt - Speaker entry: same file (
connectNestsSpeaker) - Create-space sheet:
amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/audiorooms/create/ - Servers settings:
amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/nestsServers/