Files
amethyst/amethyst
Claude d73348d19b feat(concord): CORD-05 §6 Direct Invites — wire fixes, send, and a headless inbox
quartz:
- ConcordDirectInvite: NIP-59 timestamp tweak (seal and wrap backdated up to
  2 days, rumor keeps the send time), NIP-40 expiration on the wrap matching
  expires_at, open()/openSeal() returning the seal-verified sender, rejecting a
  rumor whose pubkey differs from the seal's (anti-spoofing), an unverified seal,
  a non-3313 rumor, and bundles failing the §1 bounds or the owner proof.
- ConcordInviteVend: the vend rule (a link gets no Private Channel keys, a
  member exactly what their channel-scoped Roles entitle) and the catch-up rule
  for an already-joined community (new keys only on the same root, epoch and
  control_pk; the base never moves).

commons:
- ConcordActions.directInviteFor/buildDirectInvite/openDirectInvite,
  directInviteDeliveryRelays (10050, else NIP-65 read, else stock), and a since
  parameter on directInvitesFilter.
- ConcordDirectInviteInbox: dedupe by wrap id, skip expired wraps, park
  validated invites, remember declines; visible() hides joined communities but
  keeps catch-ups; acceptPlan() decides join / catch-up / refuse.
- AccountConcordActions: sendConcordDirectInvite, refreshConcordDirectInvites,
  acceptConcordDirectInvite (shares the link join path, now factored into
  joinValidatedConcordInvite), declineConcordDirectInvite.
- The NIP-17 seal handler routes a kind-3313 rumor to the inbox instead of the
  cache/chat feeds; declined wrap ids persist per account.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PmuzkD5qdqgv6dMeRMoC5N
2026-09-29 18:11:18 +00:00
..