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.