- Session.Line carries `author` (record always persisted it; the read
side never surfaced it) — group bubbles now wear the WRITER's name and
picture instead of the group's initial for every message.
- Story cards use the author's real picture (your own from myAvatar).
- avatarShared marker stamps the peer's device set, not just the blob
id: a bare marker outlived their reinstall and they saw initials for
ever. Old markers mismatch once and self-heal with one resend.
- QR: AddressCard embeds ?u=<handle> so a same-relay scan resolves
through the ordinary username lookup, and the Home + Messages bars
gain a scanner — WebRTC's own Camera2 capture rendered to a
SurfaceViewRenderer with each frame's Y plane offered to zxing:core
(the one new dependency; decode only, no second camera framework).
parseScannedAddress mirrors iOS ContactCard.decode's refusals.
- Messages screen matches iOS: bare title with scan + add-contact
actions, New group beside the Groups heading (GroupsSection's own
label, always drawn now, carries it), New chat beside CHATS with a
contact picker, and the duplicated GROUPS label is gone.
- Story composer gains a per-story audience: Everyone / Only… /
All except… chips with a member checklist, seeded from the account
setting, never written back to it. postStory takes the override.
- AddContactForm accepts a prefill so a scan lands in the field —
looked up, then added, never auto-added.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>