lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README | LICENSE

commit 41e20a14d30416d13d9864ed2cc2f415d9a8e6ea
parent 9e60a154c607ee31bd108f751e1bb1fe64259314
Author: triesap <tyson@radroots.org>
Date:   Fri, 12 Jun 2026 02:33:24 -0700

spec: add social event contract

- define the public social event substrate and approved event families
- record strict comment, reaction, file metadata, listing draft, and relay-list decisions
- document social conformance requirements for future codec vectors
- keep curated social operations deferred until implementation-backed vectors exist

Diffstat:
Mspec/README.md | 16++++++++++++++++
Mspec/conformance/README.md | 15+++++++++++++++
Mspec/operations.toml | 4++++
Aspec/social-events.md | 110+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 145 insertions(+), 0 deletions(-)

diff --git a/spec/README.md b/spec/README.md @@ -46,6 +46,22 @@ envelope. They are outside the `rr-rs` event-contract boundary unless a future contract slice explicitly promotes them into a curated SDK operation surface with matching conformance vectors and language export mappings. +## Public Social Event Substrate + +Public social events are represented as event and codec substrate in +`radroots_events`, `radroots_events_codec`, and `radroots_events_codec_wasm`. + +The active social-event contract is defined in `spec/social-events.md`. It covers +ordinary posts, comments, reactions, articles, public generic file metadata, +calendar events, reposts, reports, listing drafts through `RadrootsListing`, and +NIP-65 relay lists through `RadrootsList`. + +The social surface is substrate-first. MVP social builders and parsers may be +promoted into curated SDK operation metadata only after their Rust models, +codecs, wasm helpers where needed, and deterministic conformance vectors exist. +Production-v1 repost, report, calendar collection, and RSVP behavior remains +available through event and codec APIs by default. + ## Rust Crate Tiers The public Rust story is tiered explicitly. diff --git a/spec/conformance/README.md b/spec/conformance/README.md @@ -16,3 +16,18 @@ Each fixture must be deterministic and machine-readable. - vectors are generated from canonical rust implementations. - every contract behavior change must update vectors in the same change. - language sdk test harnesses must validate vectors without local overrides. + +## social event vectors + +Social event vectors are required for every new social codec and every existing +codec whose public behavior changes under `spec/social-events.md`. + +The social vector set must cover valid, invalid, and round-trip behavior for the +approved public social event families. It must include strict NIP-22 comment +targets, empty-content NIP-25 reactions, public NIP-94 generic file metadata, +NIP-99 listing `published_at`, NIP-65 relay-list `r` tags, and private Field +business-document isolation. + +Social event vectors must be deterministic, synthetic, and repo-owned. They must +not depend on relay databases, application runtime state, external services, or +fixture roots outside this repository. diff --git a/spec/operations.toml b/spec/operations.toml @@ -6,6 +6,10 @@ source = "rust" [public] domains = ["profile", "farm", "listing", "trade"] +# Public social events are substrate-first during the active social refactor. +# Curated social operations are intentionally added only after their models, +# codecs, wasm helpers, and conformance vectors exist. + [shared_types] public = [ "WireEventParts", diff --git a/spec/social-events.md b/spec/social-events.md @@ -0,0 +1,110 @@ +# Public Social Event Substrate + +Status: active implementation contract + +Scope: public Radroots social Nostr event models, codecs, wasm builders, and deterministic +conformance vectors in this repository. + +## Purpose + +The public social event substrate extends the Radroots event family beyond profile, farm, listing, +and trade workflows while keeping relay runtime behavior, application projections, moderation +services, and private Field business documents outside this repository's event-contract boundary. + +The target implementation is standards-first and Radroots-named. Event models live in +`radroots_events`, canonical encode/decode behavior lives in `radroots_events_codec`, optional JSON +to tags helpers live in `radroots_events_codec_wasm`, and deterministic fixtures live under +`spec/conformance`. + +## Source Inventory + +The current repository already contains partial public social support for kind `1` +`RadrootsPost`, kind `1111` `RadrootsComment`, kind `7` `RadrootsReaction`, generic +`RadrootsList` entries, and listing draft kind `30403` through `RadrootsListing`. + +The current gaps before the social refactor are: + +- missing model and codec coverage for articles, public generic file metadata, calendar date events, + calendar time events, reposts, generic reposts, calendar collections, RSVP events, and reports +- incomplete kind and tag constants for the approved NIP surface +- `RadrootsPost` does not yet preserve optional social metadata +- `RadrootsComment` still accepts legacy `e_root` and `e_prev` fallback tags in canonical decode +- `RadrootsReaction` currently rejects empty content even though empty content is a valid NIP-25 like +- `RadrootsListing` needs explicit optional `published_at` metadata for NIP-99 parity +- NIP-65 relay-list behavior needs explicit validation evidence through `RadrootsList` +- conformance vectors and canonical-event witnesses do not yet cover every new or upgraded social + event family + +## Approved Event Families + +The MVP public social substrate includes: + +- `RadrootsPost` for ordinary NIP-01 kind `1` notes plus optional Radroots social metadata +- `RadrootsArticle` for NIP-23 kind `30023` long-form content +- generic public `RadrootsFileMetadata` for NIP-94 kind `1063` +- `RadrootsCalendarDateEvent` for NIP-52 kind `31922` +- `RadrootsCalendarTimeEvent` for NIP-52 kind `31923` + +The production-v1 public social substrate includes: + +- `RadrootsRepost` for NIP-18 kind `6` +- `RadrootsGenericRepost` for NIP-18 kind `16` +- `RadrootsCalendar` for NIP-52 kind `31924` +- `RadrootsCalendarEventRsvp` for NIP-52 kind `31925` +- `RadrootsReport` for NIP-56 kind `1984` +- listing draft kind `30403` validation through `RadrootsListing` +- relay-list kind `10002` validation through `RadrootsList` + +## Contract Decisions + +`RadrootsPost` remains compatible with ordinary kind `1` text notes. Content-only notes must remain +valid. Optional farm or address references, media metadata, geohash, topics, and quote references +must be preserved when present and must use serde defaults so existing simple JSON fixtures remain +valid. + +`RadrootsComment` uses strict NIP-22 semantics. The target and scope model must support event-id, +address, and external roots or parents through `E`/`e`, `A`/`a`, and `I`/`i` tags with matching +`K`/`k` kind metadata. Canonical decode must reject legacy `e_root` and `e_prev` fallback tags. + +`RadrootsReaction` uses strict NIP-25 semantics. Empty content, `+`, `-`, emoji, and custom reaction +content are valid when the target tags are valid. Missing targets remain invalid. + +`RadrootsReport` intentionally tightens NIP-56 for the Radroots type: a reported pubkey `p` tag is +required for a valid report, including event and file or blob reports. + +Generic public `RadrootsFileMetadata` remains separate from private `RadrootsFarmFileMetadata` even +though both use kind `1063`. The public generic model must cover the current simple NIP-94 tags, +including URL, MIME type, SHA-256 hash, original hash, size, dimensions, blurhash, thumbnail, image, +summary, alt text, fallback, `magnet`, `i`, and `service`. + +`RadrootsListingDraft` and `RadrootsRelayList` are not separate model types in the target contract. +Listing draft kind `30403` is represented through `RadrootsListing`, and NIP-65 relay metadata kind +`10002` is represented through `RadrootsList`. + +## Exclusions + +This substrate does not include `RadrootsFeedItem`, `RadrootsMapPin`, NIP-72 community events, +checkout or payment events, or public task, harvest, work-session, approval, or other Field business +document event types. + +Task records, work sessions, harvest records, approvals, and similar Field business objects remain +CRDT document semantics carried inside the CRDT change envelope unless a later contract explicitly +promotes them. + +## SDK Boundary + +The public social surface is event and codec substrate first. Curated SDK operation metadata may +promote MVP social builders and parsers only after the corresponding Rust models, codecs, wasm +helpers where needed, and conformance vectors exist. Production-v1 repost, report, calendar +collection, and RSVP behavior remains substrate-visible by default unless a consumer proves that it +should be promoted into the curated operation surface. + +## Conformance Boundary + +Every new social codec and every upgraded existing social codec must have deterministic valid and +invalid conformance vectors before closeout. Upgraded vectors must include the strict comment, +reaction, listing, farm, list, and list-set behavior whose public contract changes during the +refactor. + +Social vectors are repo-owned and synthetic. They must not depend on application relay state, local +databases, external services, root fixture catalogs, or ambient machine state.