TL;DR A repost (boost) by a federating member is invisible to their Mastodon followers — repost_post/2 has no federation hook. Emit an Announce on repost and Undo(Announce) on un-repost. Split out of #843 (Part 1); parent tracker #784.
Where: Vutuv.Posts.repost_post/2 + unrepost_post/2 (lib/vutuv/posts.ex, ~line 647); activity builders in VutuvWeb.Fediverse.Docs; enqueue + gates in Vutuv.Fediverse.maybe_federate/2. Architecture: docs/architecture/fediverse.md.
Now: repost_post/2 inserts the PostRepost row and only broadcasts the in-app feed event (broadcast_new_repost/1); unrepost_post/2 deletes the row. Neither federates — unlike create_post/update_post/delete_post, which call Vutuv.Fediverse.federate_*. So a boost never leaves vutuv.
Want:
- Reposting enqueues an
Announce to the reposter's Fediverse followers, but only when all three hold: (1) the reposter federates (Vutuv.Fediverse.federated?/1), (2) the reposted post is fully public (Vutuv.Posts.restricted?/1 false — already guaranteed at repost time by check_visibility_lock/2), (3) the original author federates too — the Announce object is the original Note's id (https://<host>/<author>/posts/<id>); for a non-federating author that URL serves no Note, so Mastodon could not render the boost.
- Un-reposting enqueues the matching
Undo(Announce).
- Activity ids must be stable so the
Undo references the same Announce (e.g. <note-url>#announce-<reposter-username>).
reposter's followers' servers
^
| Announce { object: https://<host>/<original-author>/posts/<id> }
|
repost_post/2 -> Vutuv.Fediverse.federate_repost(post, reposter)
unrepost_post/2 -> Vutuv.Fediverse.federate_unrepost(post, reposter)
Notes for someone new to the code:
- Hook inside
repost_post/2 where both the %PostRepost{} and the original %Post{} (with post.user_id) are in scope — broadcast_new_repost/1 alone doesn't know the original author.
- Follow the shape of
Vutuv.Fediverse.maybe_federate/2 for the federated?/public gates and the delivery-queue enqueue.
- Tests:
test/vutuv/posts_federation_test.exs covers the existing Create/Update/Delete hooks — use it as the template. Start with a test (project rule).
Acceptance:
- Repost by a federating member of a federating member's public post → one
Announce per distinct follower inbox; un-repost → Undo(Announce) with a matching id.
- Repost of a non-federating author's post, or by a non-federating member → nothing enqueued.
mix precommit green; any new gettext strings ship with German translations.
TL;DR A repost (boost) by a federating member is invisible to their Mastodon followers —
repost_post/2has no federation hook. Emit anAnnounceon repost andUndo(Announce)on un-repost. Split out of #843 (Part 1); parent tracker #784.Where:
Vutuv.Posts.repost_post/2+unrepost_post/2(lib/vutuv/posts.ex, ~line 647); activity builders inVutuvWeb.Fediverse.Docs; enqueue + gates inVutuv.Fediverse.maybe_federate/2. Architecture:docs/architecture/fediverse.md.Now:
repost_post/2inserts thePostRepostrow and only broadcasts the in-app feed event (broadcast_new_repost/1);unrepost_post/2deletes the row. Neither federates — unlikecreate_post/update_post/delete_post, which callVutuv.Fediverse.federate_*. So a boost never leaves vutuv.Want:
Announceto the reposter's Fediverse followers, but only when all three hold: (1) the reposter federates (Vutuv.Fediverse.federated?/1), (2) the reposted post is fully public (Vutuv.Posts.restricted?/1false — already guaranteed at repost time bycheck_visibility_lock/2), (3) the original author federates too — theAnnounceobject is the original Note's id (https://<host>/<author>/posts/<id>); for a non-federating author that URL serves no Note, so Mastodon could not render the boost.Undo(Announce).Undoreferences the sameAnnounce(e.g.<note-url>#announce-<reposter-username>).Notes for someone new to the code:
repost_post/2where both the%PostRepost{}and the original%Post{}(withpost.user_id) are in scope —broadcast_new_repost/1alone doesn't know the original author.Vutuv.Fediverse.maybe_federate/2for thefederated?/public gates and the delivery-queue enqueue.test/vutuv/posts_federation_test.exscovers the existing Create/Update/Delete hooks — use it as the template. Start with a test (project rule).Acceptance:
Announceper distinct follower inbox; un-repost →Undo(Announce)with a matching id.mix precommitgreen; any new gettext strings ship with German translations.