5.2 KiB
Channel subscriber counts — feature scope
Status: Scoped; not implemented · Created 2026-07-26
Goal
Show a useful subscriber/follower count on public BitVid channel profiles without misrepresenting an estimate as a global Nostr fact or weakening private subscriptions.
Constraint that determines the design
BitVid subscriptions are encrypted, private NIP-51 lists. Relays cannot answer "how many people subscribe to this creator?" from those lists. Querying public follow lists, where they exist, would be incomplete, expensive, sybil-prone, and would encourage users to make private follows discoverable. Therefore this feature must not derive a global count by scanning followers' events.
Recommended product definition
Ship a clearly labelled BitVid followers count, not an unqualified global "Subscribers" count. It should count only voluntary, public follow attestations that BitVid can verify and should remain an estimate of the BitVid-visible audience. Keep the existing private subscription feature private and do not use it as a counting source.
Before implementation, make one explicit product decision:
- Public attestation count (recommended): a viewer may opt in to publish a public, signed follow attestation; BitVid counts valid unique authors for a creator. This has a real verifiable numerator but is necessarily partial.
- Creator-reported count: creator publishes a signed number. This is cheap, but is self-reported and must be labelled as such.
- No public count: retain private subscriptions only. This is the strongest privacy option.
Do not silently fall back from option 1 to option 2.
Proposed implementation slice (option 1)
Data model and protocol
- Research existing Nostr follow/interest conventions first; reuse an interoperable event if one supports a public creator follow without exposing the private BitVid list.
- If no suitable convention exists, write a small BitVid event proposal before coding: event kind, tags, replaceability/deletion semantics, creator target, timestamp rules, relay selection, and migration/version tag.
- Count at most one current attestation per follower/creator relationship.
- Ignore malformed events, self-follows, deleted/replaced events, and events outside the selected protocol version.
- Treat counts as eventually consistent and relay-scoped. Never claim a global Nostr total.
Read path and caching
- Add a dedicated count service/store; do not add follower scans to
channelProfile.jsrendering or the normal feed bootstrap. - Fetch only when a channel profile is opened, with a bounded relay set, cancellation on profile navigation, in-flight deduplication, and a short cache TTL.
- Render a compact skeleton or omit the count while loading. A failed count lookup must never block profile metadata, video loading, zap controls, or subscriptions.
- Expose source/coverage only in a low-noise detail surface if needed (for example, "BitVid-visible followers"), not as a misleading exact total.
Channel-profile UI
- Place the count in the creator summary/stat row near videos/zaps, not in the profile modal.
- Use the chosen product label consistently:
BitVid followersfor public attestations;Creator-reported subscribersfor self-reported data. - Provide an accessible label and compact mobile layout; large counts use locale-aware formatting.
- The viewer's private Subscribe/Unsubscribe control remains unchanged. If an opt-in public follow is added, it is a separate, explicit privacy choice.
Abuse and privacy safeguards
- Do not expose who follows whom by default beyond the public attestations the viewer chose to publish.
- Do not rank or moderate creators solely by this count.
- Rate-limit/bound relay queries and deduplicate by author; document that sybil resistance is not provided by a raw public count.
- Preserve viewer blocks/mutes and creator visibility rules in any optional follower preview; the count itself must not leak a viewer's private list.
Tests and acceptance criteria
- Unit tests: unique-author counting, replacement/deletion, malformed events, self-follow exclusion, cache TTL, and formatted display values.
- Service tests: bounded/cancelled relay queries, timeout/failure returns an unavailable state without clearing a good cached count.
- UI tests: loading, available, unavailable, and mobile wrapping states.
- Manual QA: opening a channel profile has no visible impact on Home feed or private subscription list loading; toggling a private subscription publishes no public attestation unless the viewer explicitly opts in.
Non-goals for the first release
- A global Nostr subscriber count.
- Inferring counts from private encrypted lists.
- Follower directories, recommendations, notifications, or monetized tiers.
- Using counts as a trust, moderation, or discovery ranking signal.
Implementation order
- Approve the product definition and public/private wording.
- Complete protocol/convention research and record the selected event shape.
- Build the bounded count store with tests and fixtures.
- Add channel-profile presentation and responsive UI tests.
- Run privacy/performance QA before enabling public-attestation publishing.