feat(nostr): implement Phase 3 codecs

Event formats live in codecs so the core never learns which kind stores roles,
which d identifier is used, or how a legacy list is shaped.

- bech32/NIP-19 decoding, verified against the NIP-19 test vector, so the core
  can stay hex-only and dependency-free
- canonical v1 codec on kind:30078 with namespaced d identifiers, role rosters
  carrying both role labels and explicit capabilities, and size-bounded policy
  documents that return null rather than throwing on malformed JSON
- NIP-56 reports, resolving the report type across the three tag layouts
  clients use and excluding relay hints from the type position
- NIP-51 mute lists; encrypted entries are flagged, never decoded
- legacy admin-list codec supporting all five migration stages, with editors
  surfaced separately so a UI permission cannot silently become signing authority
- replaceable selection with a deterministic same-timestamp tiebreak, without
  which two relays returning events in different orders would produce different
  state on different clients

129 codec tests; 402 total.
This commit is contained in:
thePR0M3TH3AN committed 2026-08-09 17:39:37 -04:00
1 parent 4f689184e2
commit 5e0fffb32e
14 files changed
+2308 -2

No files matched your search

+2
View File
@@ -69,6 +69,8 @@ const MUTE_THRESHOLDS = {
* Surfaces differ only in how they treat a hide and whether a viewer may
* override: discovery feeds decline to hard-hide so that a single stale list
* cannot empty a feed, while playback enforces the full decision.
*
* @type {import('@nostr-governance/core').PolicyDefinition}
*/
export const REFERENCE_POLICY = createPolicyDefinition({
id: "reference-video-app",