Skip to main content

vector_core/community/v2/
mod.rs

1//! Concord v2 (the upstream CORD specs — `github.com/concord-protocol/concord`).
2//!
3//! Vector's second-generation community protocol, carried ALONGSIDE v1 (the
4//! sibling `community::` modules) for a migration window. v2 keeps v1's control
5//! plane engine verbatim — the edition hash, fold, roster, and authority algebra
6//! are shared by import, not copied — and replaces the envelope (CORD-01 Private
7//! Streams: group-key-signed kind-1059 wraps addressed by `authors`), the owner
8//! anchor (a self-certifying `community_id`), the invite system (CORD-05), and
9//! adds the Guestbook plane (CORD-02 §5).
10//!
11//! Nothing in here touches v1 state: a `Community` is one protocol or the other
12//! (`protocol` discriminator), and the two stacks share only pure logic.
13//!
14//! Frozen wire constants live in two places: the derivation labels in
15//! [`derive`], and the kind registry below (CORD-02 Appendix B). A retired
16//! number is burned forever, never reused.
17
18pub mod chat;
19pub mod community;
20pub mod control;
21pub mod derive;
22pub mod dissolution;
23pub mod guestbook;
24pub mod inbound;
25pub mod invite;
26pub mod list;
27pub mod list_frag;
28pub mod pin_keys;
29pub mod pins;
30pub mod realtime;
31pub mod volley;
32pub mod rekey;
33pub mod roles;
34pub mod service;
35pub mod stream;
36pub mod streamauth;
37
38/// Inner rumor kinds (CORD-02 Appendix B). The *outer* event is always a wrap
39/// ([`stream::KIND_WRAP`] / [`stream::KIND_WRAP_EPHEMERAL`]); these ride inside.
40pub mod kind {
41    /// Chat message (NIP-C7 shape: content = text; a `q` tag = an INLINE quote).
42    pub const MESSAGE: u16 = 9;
43    /// Threaded reply (NIP-22 comment, CORD-03 §3): uppercase `K`/`E`/`P` pin the
44    /// thread root, lowercase `k`/`e`/`p` the immediate parent — all rumor ids.
45    /// Deliberately distinct from a kind-9 inline quote.
46    pub const COMMENT: u16 = 1111;
47    /// Reaction (NIP-25 shape: `e`/`p`/`k` tags name the target — `k` is the
48    /// target's kind, `9` or `1111`).
49    pub const REACTION: u16 = 7;
50    /// Delete (NIP-09 shape: `e` names the author's own rumor id).
51    pub const DELETE: u16 = 5;
52    /// Message edit (fields unpinned upstream; Vector: `e` = own message rumor id,
53    /// content = replacement text).
54    pub const EDIT: u16 = 3302;
55    /// Rekey blobs (CORD-06).
56    pub const REKEY: u16 = 3303;
57    /// Guestbook join/leave (content = the verb).
58    pub const JOIN_LEAVE: u16 = 3306;
59    /// Control edition, sub-kinded by `vsk` (shared grammar with v1 — `community::edition`).
60    pub const CONTROL: u16 = 3308;
61    /// Guestbook kick (admin-signed, `p` target, `vac` citation).
62    pub const KICK: u16 = 3309;
63    /// WebXDC peer signal (payload opaque to the protocol).
64    pub const WEBXDC: u16 = 3310;
65    /// Guestbook snapshot (refounder-signed, chunked 400/event).
66    pub const SNAPSHOT: u16 = 3312;
67    /// Direct invite rumor — rides a STANDARD NIP-59 giftwrap to a person,
68    /// never a stream wrap (CORD-05 §6).
69    pub const DIRECT_INVITE: u16 = 3313;
70    /// Typing indicator (ephemeral tier — 21059 wrap, never stored).
71    pub const TYPING: u16 = 23311;
72    /// Voice presence heartbeat (ephemeral tier; CORD-07 — deferred in Vector,
73    /// constant reserved so nothing else claims it).
74    pub const VOICE_PRESENCE: u16 = 23313;
75    /// Public invite bundle — bare addressable event signed by the per-link
76    /// keypair at an empty `d` (CORD-05 §2). Outside the wrap.
77    pub const INVITE_BUNDLE: u16 = 33301;
78    /// A member's self-encrypted Community List (replaceable). Outside the wrap.
79    /// RETIRED by the fragmented form below — a replaceable kind holds one event
80    /// per pubkey, so it cannot shard, and the List outgrew what relays accept.
81    pub const COMMUNITY_LIST: u16 = 13302;
82    /// The fragmented Community List (CORD-02 §8): addressable, one event per
83    /// fragment at `d` = the fragment index in decimal. Outside the wrap.
84    pub const COMMUNITY_LIST_FRAG: u16 = 33302;
85    /// A creator's self-encrypted Invite List (replaceable). Outside the wrap.
86    pub const INVITE_LIST: u16 = 13303;
87}
88
89/// Control-plane `vsk` sub-kinds (CORD-02 Appendix B). Identical numbering to
90/// v1 (`community::roster`) — that is deliberate, the registry is shared. 7 is
91/// retired upstream (the v1 owner attestation, obsoleted by the self-certifying
92/// community id); 11 is claimed by Vector for the v1-side migration pointer and
93/// never appears on the v2 wire.
94pub mod vsk {
95    pub const COMMUNITY_METADATA: &str = "0";
96    pub const ROLE: &str = "1";
97    pub const CHANNEL_METADATA: &str = "2";
98    pub const GRANT: &str = "3";
99    pub const BANLIST: &str = "4";
100    // "5" reserved (role ordering), "6"/"9" claimed by the 33301 invite marker,
101    // "7" retired, "8" = invite-link registry, "10" = dissolved tombstone.
102    pub const INVITE_LINKS: &str = "8";
103    pub const INVITE_LIVE: &str = "6";
104    pub const INVITE_REVOKED: &str = "9";
105    pub const DISSOLVED: &str = "10";
106    /// One Pin List per Channel at `pins_locator` (CORD-04 §7).
107    pub const PINS: &str = "11";
108}