Commit Graph

4 Commits

Author SHA1 Message Date
Claude aadb347b84 feat(nests): adopt deployed nostrnests schema (streaming/auth/live + paired 10112)
The deployed nostrnests reference (NestsUI v2 + moq-auth + moq-rs)
emits a different on-the-wire schema than the previous EGG-01 / EGG-09
drafts and Quartz writers. Verified by reading the production
NestsUI bundle. The deployed schema is now canonical:

kind:30312 (room event)
  - relay URL → ["streaming", url]   (was ["endpoint", url])
  - auth URL  → ["auth",      url]   (was ["service",  url])
  - live status → ["status", "live"]   (was "open")
  - ended status → ["status", "ended"] (was "closed")
  - room name → ["title", name]        (was ["room", name])

kind:10112 (user MoQ-server list)
  - 3-element entries: ["server", relay, auth]
  - first-element name "relay" accepted as a synonym (legacy)
  - 2-element entries: derive auth host by replacing leading "moq."
    with "moq-auth.", or prepending "moq-auth." otherwise

Implementation
- ServiceUrlTag.TAG_NAME = "auth", LEGACY_TAG_NAME = "service"
- EndpointUrlTag.TAG_NAME = "streaming", LEGACY_TAG_NAME = "endpoint"
- StatusTag enum: PLANNED/LIVE/PRIVATE/ENDED with code "live"/"ended";
  legacy "open"/"closed" still parsed on read
- NestsServersEvent: emit/read 3-element [server, relay, auth] tags
  with the legacy-shape tolerances above; expose a NestsServer pair
- Account.nestsServers.flow now produces List<NestsServer> pairs
- NestsServersScreen: rewritten edit-field asks for both URLs,
  recommended row shows the nostrnests pair, list rows show both URLs
- NestsScreen first-time setup writes the nostrnests pair, not a
  single URL; gate the create FAB on both URLs being parseable
- CreateNestViewModel: drop the resolveServerPair hardcoded mapping —
  the saved pair is now authoritative; defaults stay correct for an
  empty kind-10112 list

Specs
- EGG-01 rewritten to canonical streaming/auth/live/ended with a
  legacy-spelling table; example uses the real nostrnests pair
- EGG-02 references "auth" tag throughout; error taxonomy says "ended"
- EGG-09 rewritten to 3-element server tag with derivation fallback
- New nestsClient/specs/nip-53-proposed.md — a single self-contained
  proposed update to upstream NIP-53 covering kind 30312 + kind 10112
  with the deployed schema and the JWT-mint flow

All existing unit tests adjusted; quartz:jvmTest, amethyst:testPlayDebugUnitTest,
and nestsClient:jvmTest pass.
2026-04-29 19:32:53 +00:00
Claude fd03122206 docs(nestsClient/specs): close hosting-side ambiguities
Define the host-side flow that was previously implicit. A new-room
implementer can now go from "I want to start broadcasting" to first
audio frame without reading our source.

README — new "Hosting a new room" section:
- 8-step ASCII walkthrough symmetrical to "Joining sequence".
- Covers service/endpoint selection, kind:30312 compose + publish, JWT
  mint with publish:true, WT/Setup, Announce, presence, Opus stream.
- Lists ongoing host duties (add speaker, kick, edit, close, recording).

EGG-01 — two new behavior rules:
- Rule 12 "Publish-before-mint ordering": peers MUST publish the
  kind:30312 to relays BEFORE requesting a JWT for it, since the auth
  sidecar reads the most-recent event by (pubkey, kind, d) to validate
  existence / status. 410 unknown_room → retry 1s/2s/4s. Closes the
  silent footgun where a host could mint a token before their event
  has propagated.
- Rule 13 "Service/endpoint selection (host-side guidance)": pre-fill
  from kind:10112 first entry, fall back to client default with user
  override, both MUST be https://.

EGG-07 — new "Audio publish authorisation" section:
- Spells out who gets a publish:true JWT: host (by authorship,
  implicitly — no need for ["p", _, _, "speaker"] on the host's own
  p-tag), explicit "speaker" role, or "admin" role. All others 403
  publish_forbidden per EGG-02.
- Relay does NOT re-read kind:30312; demoting a speaker mid-session
  does NOT terminate their stream — host MUST kick (kind:4312) to
  end an active broadcast.

https://claude.ai/code/session_01RDpuki4t8StSg1CZcXnV5b
2026-04-27 13:05:49 +00:00
Claude bd12d5ef72 docs(nestsClient/specs): close interop gaps surfaced in spec review
Edits across all 13 EGGs to remove implementer guesswork. After this an
implementer can build a listener and speaker without reading our source.

README:
- Conventions section: hex casing rule (lowercase, 64 chars, no 0x),
  NIP-01 foundations, `a`-tag form, created_at tie-break, JSON / time.
- Joining sequence: numbered end-to-end walkthrough from `kind:30312`
  to first audio frame, referencing each EGG.

EGG-01 (room event):
- `relays` tag is one tag with multiple values (not multi-tag).
- `service` URL trailing-slash normalization.
- `private` status: gate is implementation-defined, not "render as open".
- `d`-tag charset locked to [A-Za-z0-9._-] so it interpolates safely
  into the moq-auth namespace.
- Relay-discovery rule: publish to `relays` tag ∪ NIP-65 outbox.
- Tie-break on identical created_at via smallest event id.

EGG-02 (auth):
- JWT signing pinned: ES256 over P-256, JWKS at /.well-known/jwks.json,
  5-minute relay cache.
- NIP-98 tags pinned: u / method / payload, base64 RFC 4648 standard
  (not base64url).
- Error taxonomy: full HTTP status + `error` slug table for /auth, plus
  WebTransport CONNECT 200/401/403/404 table.

EGG-03 (audio):
- Pin moq-lite Lite-03 to kixelated/moq-rs `rs/moq-lite/src/lite/`.
- One Opus packet per moq Frame (no container, no timestamp).
- Pubkey hex casing reaffirmed at the suffix / broadcast slots.
- AnnouncePlease prefix="" for speaker discovery.
- Mute = stop publishing (not silence frames, not Announce Ended).
- Mid-stream join: discard pre-skip per RFC 7845.

EGG-04 (presence):
- Heartbeat jitter ±5 s required (anti-thundering-herd).
- "0"/"1" are strings, not booleans.
- Single-room rule via replaceable-event semantics.

EGG-05 (chat): 8 KB suggested, 64 KB hard cap, 3 msg/s render rate.
EGG-06 (reactions): 30s window measured against created_at, drop-on-arrival
                    if already stale.
EGG-07 (moderation): replay protection — dedupe kicks by id within 120 s.
EGG-08 (scheduling): planned rooms MUST 403 at the auth sidecar.
EGG-10 (theming): bg image caps (1 MB / 4096 px soft, 8 MB / 8192 px hard).

Deferred (per review): EGG-00 (Conventions as a standalone spec), EGG-13
(capability advertisement), EGG-14 (discovery), test vectors corpus.
The "Conventions" section in README covers EGG-00's most urgent content
inline.

https://claude.ai/code/session_01RDpuki4t8StSg1CZcXnV5b
2026-04-27 12:31:19 +00:00
Claude 5c40e27fde docs(nestsClient/specs): EGG-00..EGG-12 — Extensible Gossip Guidelines
Wire-protocol specs for nostrnests-style audio rooms, in the
style of Nostr NIPs and Blossom BUDs. Each spec documents one
self-contained capability that a client or relay can implement;
two compliant peers implementing the same set of EGGs round-trip
without further coordination.

Layout:

  README.md            cover, status table, conformance levels
  EGG-01.md  Room event (kind:30312)              required
  EGG-02.md  Auth + WebTransport handshake        required
  EGG-03.md  Audio plane (moq-lite)               required
  EGG-04.md  Presence (kind:10312)                required
  EGG-05.md  In-room chat (kind:1311)             optional
  EGG-06.md  Reactions (kind:7)                   optional
  EGG-07.md  Roles & moderation (kind:4312)       optional
  EGG-08.md  Scheduling (status=planned)          optional
  EGG-09.md  User server list (kind:10112)        optional
  EGG-10.md  Theming (c/f/bg tags)                decorative
  EGG-11.md  Recording                            decorative
  EGG-12.md  Catalog track (catalog.json)         optional

Conformance levels (Listener / Speaker / Host) defined in the
README so a deployment can declare "we implement EGG-01..EGG-04"
and other peers know exactly what to expect.

Each spec follows the same shape (Summary / Wire format /
Behavior numbered MUST/SHOULD/MAY rules / Example /
Compatibility) and fits on a single printed page. Wire formats
are documented exactly as nostrnests + amethyst implement them
on this branch — no hypothetical capabilities, no "future" tags
without an EGG number.
2026-04-27 03:54:45 +00:00