Files
amethyst/nestsClient/specs/EGG-12.md
T
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

117 lines
4.2 KiB
Markdown

# EGG-12: Catalog track (`catalog.json`)
`status: draft`
`requires: EGG-03`
`category: optional`
## Summary
A speaker MAY publish a sibling `catalog.json` track on the same moq-lite
broadcast as their `audio/data` track. The catalog carries codec
metadata: format, sample rate, channel count, bitrate, etc. It exists so
clients can render a "speaker is broadcasting Opus 48 kHz mono" tooltip
without parsing audio frames, and so future codec migrations can be
negotiated client-side.
## Wire format
### Track convention
A speaker MUST publish the catalog on the SAME broadcast as their audio
track:
```
SUBSCRIBE broadcast=<speaker pubkey hex> track="catalog.json"
```
### Payload
Each `Group` carries a single JSON document encoded as UTF-8. The
publisher emits a fresh group whenever the catalog changes (e.g. codec
swap on mute / unmute). Receivers SHOULD read only the most recent
group.
Document shape:
```json
{
"version": 1,
"audio": [
{
"track": "audio/data",
"codec": "opus",
"sample_rate": 48000,
"channel_count": 1,
"bitrate": 32000
}
]
}
```
Field reference:
| field | type | required | meaning |
|-----------------|--------|----------|--------------------------------------|
| `version` | int | required | Schema version. Currently `1`. |
| `audio` | array | required | One entry per audio track. May be empty. |
| `audio[].track` | string | required | Track name; matches the moq-lite track this catalog describes (typically `"audio/data"`). |
| `audio[].codec` | string | optional | Lower-case codec id (`opus`, `aac`, …). |
| `audio[].sample_rate` | int | optional | Sample rate in Hz. |
| `audio[].channel_count` | int | optional | 1 = mono, 2 = stereo. |
| `audio[].bitrate` | int | optional | Target bitrate in bits per second. |
Unknown fields MUST be tolerated: parsers MUST ignore keys they do not
recognise rather than rejecting the document. New keys are added without
incrementing `version` unless they change the meaning of an existing key.
## Behavior
1. Publishing a catalog is OPTIONAL. A speaker that omits the
`catalog.json` track MUST still be playable per EGG-03 (which already
pins the audio parameters).
2. A subscriber MUST tolerate the absence of a catalog. A `Subscribe`
response of `Drop`/error on the `catalog.json` track is benign — the
subscriber falls back to the EGG-03 default parameters.
3. A subscriber MUST tolerate malformed JSON, missing `version`, and
unknown fields. Failure to parse means "no catalog metadata" — render
the default tooltip.
4. A publisher MUST NOT use the catalog track to deliver authoritative
stream parameters that contradict EGG-03. The catalog is INFORMATIVE,
not normative: a listener MUST be able to decode `audio/data` without
reading the catalog.
5. Subscribers SHOULD limit how often they re-render the catalog tooltip:
at most once per second, even if catalogs are published more
frequently.
6. Hosts MAY use the catalog to detect non-conformant publishers (e.g. a
broadcaster claiming `aac` when EGG-03 mandates `opus`) for
moderation purposes. The actual moderation flow is out of scope for
this EGG.
## Example
A speaker comes onstage with default Opus parameters:
```
SUBSCRIBE broadcast="speakerA" track="catalog.json"
← GROUP sequence=0
← FRAME {"version":1,"audio":[{"track":"audio/data","codec":"opus","sample_rate":48000,"channel_count":1,"bitrate":32000}]}
```
The same speaker bumps to 64 kbit/s:
```
← GROUP sequence=1
← FRAME {"version":1,"audio":[{"track":"audio/data","codec":"opus","sample_rate":48000,"channel_count":1,"bitrate":64000}]}
```
## Compatibility
EGG-12 is purely additive on top of EGG-03. A receiver that does not
support EGG-12 MUST still subscribe to `audio/data` directly (EGG-03)
and decode at the parameters EGG-03 mandates.
A future EGG MAY widen the catalog schema to describe multiple audio
quality tiers, video tracks, or speaker-side hints (e.g. push-to-talk
state). Those additions MUST keep `version: 1` working for existing
parsers; breaking changes ship as `version: 2` with a separate EGG.