Files
amethyst/nestsClient/specs/EGG-04.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

3.6 KiB

EGG-04: Presence (kind:10312)

status: draft requires: EGG-01 category: required

Summary

Each participant in a room periodically broadcasts a kind:10312 event declaring their state: which room they are in, whether their hand is raised, whether they are muted, whether they are actively pushing audio, and whether they currently hold a stage seat.

Presence is the source of truth for the audience-side participant grid, the hand-raise queue, the listener counter, and the home-screen "live" bubble.

Wire format

kind:10312 is a NIP-01 replaceable event with a fixed d-tag (one presence-state per pubkey, regardless of how many rooms a user joins; see "Behavior" below).

{
  "kind": 10312,
  "pubkey": "<participant pubkey hex>",
  "tags": [
    ["a", "30312:<host pubkey hex>:<room d>", "<relay hint>"],
    ["hand",       "0" | "1"],
    ["muted",      "0" | "1"],
    ["publishing", "0" | "1"],
    ["onstage",    "0" | "1"],
    ["alt", "Room Presence tag"]
  ],
  "content": "",
  ...
}

The a tag is REQUIRED and points at the room defined in EGG-01.

Behavior

  1. A participant MUST emit a kind:10312 event:
    • on entering the room,
    • every 30 s while in the room,
    • immediately when any flag (hand, muted, publishing, onstage) changes,
    • one final time on leaving, with publishing="0" and onstage="0".
  2. Receivers MUST treat a participant as departed if no presence has been observed in > 6 minutes. (One missed heartbeat plus a 5 minute tolerance window.)
  3. The hand flag is the participant's request-to-speak. Hosts and admins read it to populate a queue (EGG-07).
  4. The muted flag is set ONLY by speakers who are also publishing. Pure audience members SHOULD omit it.
  5. The publishing flag means "I currently have an open audio/data broadcast on the relay" (EGG-03). It MUST be 0 whenever the speaker has stopped publishing, regardless of mute state.
  6. The onstage flag means "I currently hold a speaker slot in the room's p-tag list (EGG-01) AND I have not voluntarily stepped off". A speaker who steps off the stage without losing the role tag MUST emit onstage="0".
  7. The d-tag MUST be the FIXED string nests-room-presence (chosen so that one presence event represents a participant's CURRENT room across all clients). A participant MUST NOT be in two rooms simultaneously.
  8. Every flag MUST be present in every emitted event. Receivers MAY assume omitted flags default to 0, but emitters that omit are non-conformant.
  9. Hosts and clients displaying the participant grid MUST hide presences from kind:10312 events whose created_at is older than the staleness window in rule (2).

Example

{
  "kind": 10312,
  "pubkey": "def...co",
  "created_at": 1714003231,
  "tags": [
    ["a", "30312:abchost:office-hours-2026-04", "wss://relay.example"],
    ["hand", "0"],
    ["muted", "0"],
    ["publishing", "1"],
    ["onstage", "1"],
    ["alt", "Room Presence tag"]
  ],
  "content": "",
  "id": "...",
  "sig": "..."
}

Compatibility

EGG-07 (moderation) reads hand to drive the host's promote queue. EGG-03 (audio plane) is the source of truth for whether a speaker IS broadcasting; presence's publishing flag is a Nostr-side reflection that clients use as a hint when they cannot subscribe to the audio plane (e.g. listeners on weak networks rendering the home bubble).

The kind:10312 shape here intentionally mirrors kind:10311 from NIP-53 streaming so that a generic Nostr client can render audience indicators for both protocols without code-paths.