Markdown source for agents: https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/core/04-how-to-design.md

Nostr Agent Onboarding · start here · index · source: Nostr-exp/core/04-how-to-design.md · snapshot 2026-10-10

How to design for Nostr

Part 4 of the core synthesis: the design methodology — events, kinds, tags, communities, money, and trust, plus the principles that arbitrate every trade-off. Sources: Building Nostr chs. 2, 6, 7; the nostr-dev design-synthesis.md and kind cheatsheet; nostrdesign.org.

Designing on Nostr = two artifacts

You are never designing "a system." The runtime is whatever relays exist. You are designing:

  1. An event schema — kind(s) + tag set + content shape, and
  2. A routing strategy — which relays each kind goes to and is read from (02-how-it-should-work.md).

Every other decision is downstream. Take them in this order:

Decision 1 — the schema

Decision 2 — the event class

Default regular; regular events keep history, keep referential transparency (id = content hash), and degrade gracefully. Escalate only with a written justification of what you're discarding and why:

                one-current-value-per-user?
                   /                \
                 yes                 no
                  |                   |
       keyed by a d-tag?        instantaneous signal?
          /        \                /        \
        yes        no             yes         no
         |          |              |           |
  ADDRESSABLE  REPLACEABLE     EPHEMERAL    REGULAR ← default
  30000–39999  10000–19999    20000–29999

Smell tests: a settings event that accumulates → replaceable. A "current location" stream → ephemeral. An edited blog post → addressable. An editable comment → wrong, comments are accountable: regular + NIP-09 tombstone. A draft → addressable. Remember what replaceability costs: history gone, race conditions in, and only a social (not technical) resolution when two writes collide.

Decision 3 — routing per kind

For every kind you define: who reads this, with what query, and which relays must therefore hold it? Write the heuristic into the spec. A kind without a routing heuristic is an incomplete design (the geocache/topic-tag lesson: events whose natural query has no relay-selection story end up on hard-coded relays — centralization — or unfindable).

Decision 4 — the failure and abuse model

Duplicates, gaps, reordering, lying relays, race-prone replaceables — plus: who can spam this? impersonate in it? what leaks? An event schema is not done until you can answer "what does a hostile pubkey do with this?" (spam → WoT/PoW/paid relays; impersonation → WoT validation, never NIP-05 alone — addresses locate users, they do not authenticate them) and "what does this reveal?" (Nostr is publicity technology; metadata is data).

Kind allocation, concretely

  1. Search the NIPs registry table (vendored: ../sources/nips-readme-kinds.md).
  2. nak nip <n> for the relevant NIPs; read them.
  3. Probe the live network — nak req -k <kind> -l 5 against big relays; undocumented-but-occupied kinds are common, and colliding with one hurts both parties.
  4. Fit an existing kind if you honestly can; match its schema exactly.
  5. Else pick a free number in the correct class range, document it in-repo, ship, and NIP-PR it once a second implementation exists.

Designing privacy: encryption vs. relay policy

Two mechanisms give confidentiality, with opposite trade-offs:

Choose by threat model, and be honest in your spec about which you chose. Gift-wrapped events deliberately hide kind, author, and timestamp from relays; remember that even then, traffic metadata (who talks to which relay, when) still leaks — say so in your privacy story.

Two more honesty checks from the practitioners. Group encryption past roughly twenty members is theater — "you'll either have a mole or an asshole in there" (Gigi); don't pay heavy cryptography costs for an assurance the social layer can't deliver, and consider Martti Malmi's alternative: use Nostr as the lookup substrate (publish your Signal/SimpleX handles on your profile) rather than forcing every private medium onto relays. And deletion is make-believe everywhere, not just here: "computers are copying machines… all deletions in a networked world are pinky-promise deletions." NIP-09/62 are courtesy requests; design as if nothing can be unpublished, because nothing can.

Designing communities

Building Nostr ch. 7's taxonomy — five community shapes, each wanting a different architecture. Naming which one you're serving is half the design:

Shape Nature Architecture fit
Social cluster emergent, open, graph-defined broadcast social + outbox; no membership machinery at all
Group chat small, every-member-trusted, quadratic intimacy encrypted (NIP-17 pairwise; MLS for scale); doesn't scale socially past trust, don't pretend it does
Discussion forum open, topic-defined, needs moderation not gatekeeping relay-based groups (NIP-29) or moderation-as-user-preference; forkable by design — same group on two relays merges in the client
Owned community exists for/by a central figure (creator, company) centralized control is a feature; NIP-29 relay owned by the owner; interop is the value-add
Commons member-owned, politically self-organized the hard one: roles, gradated membership, partitions by identity/topic/content-type; design with the community, not for it

Lessons paid for in the wild: NIP-72's require-moderator-approval design killed its forums (moderation must be added under load, not a precondition for content to exist); moderation policy generally belongs to users and relays, not frozen into the event spec; missing data is not a bug when the user's own filters caused it — partition tolerance is also a social feature. And know which value applies where — Constant on NIP-29: a group "is a house, you are a guest, and the fact that you can be yeeted out is a feature, not a bug. In this context, censorship resistance does not make sense." Demanding broadcast-network values inside a community context is a category error in both directions.

The generalization of all this is Constant's TEPP formula: Nostr is "a permissionless system for the creation of permissioned environments." Permission lists over the protocol's own primitives — people (npubs), places (relays), things (kinds/events) — enforced redundantly at signer, client, and relay, extensible through webs of trust. Child-safe internet (Kidstr) is the flagship case, but the pattern covers any curated, bounded, or supervised space you might need to design.

Designing for value-for-value

Money is a first-class design material on Nostr, and its semantics are patronage, not trade: digital content has ~zero marginal cost, so payment buys future production plus identity/belonging — leaderboards, boosts with messages, in-group signaling. Design for those dynamics, not for a store.

Trust and reputation as design material

There is no global truth on Nostr, so reputation is always relative to a starting point. Design rules:

The principles that arbitrate

When two design options tie, these break the tie (nostrdesign.org guiding principles + the synthesis of everything above):

  1. User sovereignty over identity — keys never leave the user; no design may require an intermediary that can impersonate.
  2. User sovereignty over relays — never hard-code, never hide; relay selection is user-facing UI, not an implementation detail.
  3. Modularity over monoliths — the smaller and sharper your piece, the more the ecosystem carries it.
  4. Filter, don't censor — clients give users filtering tools (WoT, PoW, mute, relay choice) instead of deciding for them; moderation is relay- and user-policy, not client fiat.
  5. Interoperability over features — a feature that breaks other clients' reading of shared data is a bug with good PR.
  6. Trust users, trust developers, keep specs simple — write NIPs a human reads in five minutes; complexity is capture surface.
  7. Embrace compromise — Nostr is "good enough" by design; perfect protocols with no users lose to messy protocols with them. Protocol work is politics in the Aristotelian sense: a community building the place it intends to inhabit. Participate accordingly.
  8. State your trade-offs out loud — the No Solutions rule ("no solutions, only trade-offs"). Mints can rug you: that's the design, keep pocket change there. Zapstore dials decentralization down for credible exit, and says so. The characteristic newcomer failure is refusing to accept a trade-off — and thereby smuggling a central authority back in (Passkeys, home servers, global registries, "smart" proxies, DRM). A design document that names what it gives up is the mark of someone who understood the protocol.