Files
bitvid/docs/channel-subscriber-counts-plan.md
T

114 lines
5.2 KiB
Markdown

# 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:
1. **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.
2. **Creator-reported count:** creator publishes a signed number. This is cheap,
but is self-reported and must be labelled as such.
3. **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.js` rendering 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 followers` for public
attestations; `Creator-reported subscribers` for 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
1. Approve the product definition and public/private wording.
2. Complete protocol/convention research and record the selected event shape.
3. Build the bounded count store with tests and fixtures.
4. Add channel-profile presentation and responsive UI tests.
5. Run privacy/performance QA before enabling public-attestation publishing.