NIP fixes:
- RelayMembers (13534): use NIP-43 `member` tags (not `p`) and set the required
NIP-70 `-` protected tag.
- Profile (kind 0): remove display-name support entirely (getter, setter, display()
fallback, and the search weight).
- Comment (1111): A/a tags now carry a real address, not the event id.
- BlossomServerList (10063): normalize server URLs with normalizeUrl (HTTP), not
normalizeRelayUrl (which forced wss://).
- HandlerRecommendation (31989): fix inverted removeRecommendation filter; add
setSupportedKind()/supportedKind() for the NIP-89 d-tag.
- Report (1984): place the report-type string on the e tag (note reports) or p tag
(profile reports); always emit the p tag.
Docs/skills:
- Add @welshman/domain docs (docs/domain/) and the welshman-domain skill.
- Prune @welshman/util docs/skill of the moved Profile/List/Handler/Encryptable
helpers; register domain in the sidebar, index, and skills README.
- Apply accuracy fixes to the @welshman/app docs/skill.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BsMjvv7krpZeHK1Njeneru
Replace the single DomainObject/EncryptableList classes with a read/write split
that removes the optional-event ambiguity:
- base.ts: EventReader<P> (static kind; fromEvent(event, signer?) eagerly computes
a generic `plain`, validates leniently, throws-or-passes; lazy method accessors;
group/protect/expires + extraTags carry-over; builder()) and EventBuilder<P>
(chainable setters, buildTags/buildContent, validate-on-emit).
- List.ts: ListReader/ListBuilder for NIP-51 lists (decrypt-on-read into `plain`,
re-encrypt-on-emit, tag mutators).
- Every kind converted to a <Noun> reader + <Noun>Builder pair; membership ops
split into per-kind reader/builder pairs over a shared abstract base.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V67tPYdvh1qCkjEBhJGZUR
Iterate on @welshman/domain following review:
- base: add `group`/`protect`/`expires` behavior tags (parsed in base, emitted
via addBehaviorTags before hashing) and an `extraTags` passthrough (opt-in via
reservedTagKeys) so tag carry-over lives in one place; migrate Handler, Comment,
Thread onto it. Comment gains nested root/parent ref structs + setters.
- List: fix inverted keepTags; add clearTags/clearPublicTags/clearPrivateTags and
use them in the relay/server list setters.
- RelayList: preserve complementary read/write capability instead of dropping
modeless entries.
- Split Relay/Room membership ops into per-kind classes (RelayAddMember/
RelayRemoveMember, RoomAddMember/RoomRemoveMember) over a shared base.
- TimeEvent (renamed from CalendarEvent): derive "D" day tags in toTemplate.
- Feed: default to an empty feed, fail parse when the "feed" tag is missing.
- RelaySet added; CommunityList renamed to GroupList; predicate bare add/remove
mutators; RoomMeta uses randomId; PollResponse.selections drops pollType.
- Remove ChannelList, FileServerList, Settings, and event-asserting getAddress/
display accessors.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V67tPYdvh1qCkjEBhJGZUR