From 5c93b7496e228e4949688c858d1254d95b880e0b Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Sun, 21 Jun 2026 23:10:19 -0400 Subject: [PATCH] docs(nip71): audited moderation/WoT/mute/NSFW interop requirements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Audit (verified in code) of how moderation, web-of-trust, mute/block lists, and the site ALLOW_NSFW_CONTENT config interact with NIP-71 interop: - Controls key on author pubkey + event id, so they apply to NIP-71 videos automatically IF ingested videos share the feed pipeline (blacklist-filter, moderation/WoT, suppression, kids, nsfw). - Phase 1 (outbound): gate the mirror on ALLOW_NSFW_CONTENT (don't mirror NSFW from an instance that forbids it); builder stays pure + always sets content-warning. - Phase 2 (inbound) gap: mergeNip71MetadataIntoVideo does NOT map content-warning → isNsfw, so foreign NSFW would bypass the site filter — must add that mapping; plus route ingest through the full pipeline and trust-gate unknown authors. - Kids feed already safe (allowlist on isForKids). No code changes yet (both items land in their phases); captured as checklist items. Co-Authored-By: Claude Opus 4.8 --- docs/nip71-migration-plan.md | 39 +++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/docs/nip71-migration-plan.md b/docs/nip71-migration-plan.md index 5f0d610f..05509fc7 100644 --- a/docs/nip71-migration-plan.md +++ b/docs/nip71-migration-plan.md @@ -169,7 +169,9 @@ not a format problem. ### Phase 1 — Outbound publish/edit/delete (the headline feature) - Edit form toggle: **"Also publish to other Nostr video apps (NIP-71)"** — off by - default, gated to **public + HTTPS-url + public-access-verified** videos. + default, gated to **public + HTTPS-url + public-access-verified** videos, and + **not offered for `isNsfw` videos when `ALLOW_NSFW_CONTENT=false`** (see + "Moderation, web-of-trust, mute/block & NSFW"). - Surface the same control in the **My Videos tab** (per-video mirror status + toggle; it already lists owned videos with action buttons). Optional bulk "make discoverable" there later. @@ -210,6 +212,41 @@ not a format problem. --- +## Moderation, web-of-trust, mute/block & NSFW (audited 2026-06-22) + +The existing controls key on **author pubkey** and **event id**, so they apply to +NIP-71 videos automatically — *as long as ingested videos flow through the same feed +pipeline*. One real gap (inbound NSFW) + one config-respect (outbound). + +**Outbound (Phase 1):** +- [ ] Respect the site `ALLOW_NSFW_CONTENT` config (`config/instance-config.js`, + default `false`): when false, **do not offer/allow the mirror for `isNsfw` + videos** — an instance that won't surface NSFW shouldn't publish it outward. + The pure builder stays config-agnostic and always sets `content-warning` when + NSFW; gate at the call site. +- Mute/block/WoT/admin-blacklist don't newly apply outbound — it's the user's own + content (a blacklisted user can't publish anyway). + +**Inbound (Phase 2) — the real moderation work:** +- [ ] **`content-warning` → `isNsfw`**: `mergeNip71MetadataIntoVideo` does NOT + currently map a NIP-71 `content-warning` to `video.isNsfw`. The site NSFW + filter keys on `isNsfw`, so foreign NSFW would bypass it. Map it in the ingest + path so `ALLOW_NSFW_CONTENT=false` filters foreign NSFW too. +- [ ] **Same pipeline, no bypass**: route every ingested video through the existing + stages — `blacklist-filter` (`shouldIncludeVideo`: admin/event-id blacklist + + blocked authors), `moderation` (admin whitelist/blacklist + trusted-mute / + trusted-report thresholds = web-of-trust), watch-history suppression, + kids-audience, NSFW. These key on pubkey/id, so mute lists (NIP-51 kind 10000), + blocks, admin lists, and WoT thresholds catch foreign authors automatically. +- [ ] **Trust gate for strangers**: don't surface unknown/untrusted foreign authors + by default — apply the same trust-seed / web-of-trust gating native videos get + (consider requiring author ∈ WoT, or a stricter default threshold for ingest). +- **Kids feed is already safe**: `kidsAudienceFilterStage` is allowlist-based + (`isForKids !== true` ⇒ excluded) and also drops `isNsfw` + disallowed + content-warnings, so foreign videos (no `isForKids`) never enter the kids feed. + +--- + ## Enrichment backlog (nice-to-have, not v1) `bitrate`, `waveform`, multiple resolution `imeta` variants + multi-audio (`ov`/language) tracks, `text-track` (WebVTT captions/subtitles/chapters),