Files
amethyst/quartz/src/androidMain
Claude ab1c71a5ef fix(quartz): address audit findings on the link-review fixes
Bugs:
- Address.isOfKind / AddressSerializer.isOfKind (all actuals) indexed past
  the end of a value that is exactly the kind string, so a hostile
  ["request","31872"] threw from every RequestTag reader. Bounds-checked.
- AddressMemberTag accepted an naddr (AddressSerializer decodes bech32) and
  returned the raw bech32 as the member key, and isTag / parseAsHint were
  looser than parse. All readers now gate on the allocation-free
  CoordinateShape, which also stops a WARN log per rejected member.
- Voice replies dropped an address- or identifier-rooted thread (only E was
  inherited) and rooted replies to pre-NIP-22 voice replies at the reply.
  rootScopeTags() now inherits E/A/I + K/P, and derives the root from a
  legacy reply's lowercase e/p when its parent is a voice message.
- Interactive-story reading states published by the old builder carry no
  root tag: root() falls back to the d-tag (always the root's address) and
  update() writes the missing A tag.
- Event.dTag() now defers to AddressableEvent, so a replaceable list seen
  as a plain Event gets the same address as the cache (zap a-tags, backup
  slots). EncryptionKeyListEvent (10044) ignores a stray d like the lists.
- deleteRecommendation wrote the 38000 address twice: build() adds it now
  that MintRecommendationEvent is addressable.
- The NIP-87 wallet and mint-directory backfills scanned only cache.notes;
  addressable events live in cache.addressables.

Cleanups: the new hex checks reuse HexKey.isValid(), the nip29 readers are
single-pass, and WinnerTag.isTag agrees with parse.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pu8Fpp4KbXaiax8YTYxhJm
2026-09-29 15:58:40 +00:00
..