Feature: direct notes are private mentions, not posts (shaer-tqc)
A C2S note addressed to specific actors (no Public, no followers) no
longer becomes a site post: it routes through the outbox machinery as
a direct note, the Mastodon DM model. deliverDirectNote resolves each
recipient, stores the note in ap_outbox (visibility 'direct' plus the
recipient list) and delivers to exactly those inboxes: no followers
fan-out. buildReplyNote addresses a direct row to its recipients only,
cc empty, so it cannot be boosted and never shows in timelines. This
is also the ward call-for-help leg: client to own outbox, server
S2S-signed to each guardian's inbox on any instance; a guardian on
plain Mastodon sees a private mention.
Hardening: a C2S Announce or Like of a non-public local post returns
403 not_public (the Mastodon 422 equivalent), and an inbound boost or
like on a fan_only/friends/direct post is dropped instead of stored.
Direct with no resolvable recipient is refused (400 no_recipients).
Changed files:
src/services/ActivityPubService.js
- deliverDirectNote (resolve, store, deliver to recipients only)
- ingest routes direct before the reply/post paths
- buildReplyNote: direct rows -> to recipients, empty cc
- C2S 403 + inbound drop on non-public targets
src/config/database.js
- additive columns ap_outbox.visibility, ap_outbox.to_actors
New file:
test/c2s-direct.test.js
- direct addressing pinned, no_recipients, 403 on boost/like
-robo
Co-Authored-By: Claude Opus 4.8 <noreply@…>