Forwarded activities are believed as far as their origin vouches

A thread's server passes on what happens in it, signed with its own key: Mastodon forwards the replies to its
accounts' posts and their deletions, Friendica every activity in its threads. PrivaPub answered them 401, which also
tells a sender its signature failed. Now they get 202 and nothing in them is believed: a forwarded Create or Update is
taken as its object reads at the actor's origin, a Delete of a public or unlisted copy once that origin answers 404 or
410 (RemoteActorService.IsGone; FederationHttp remembers the status of a refusal), anything else is let go, and our own
activities coming back are ignored. A forwarded copy has its own dedupe key, so one that failed never hides the
author's own delivery.

A reply in the thread of someone followed here is kept, as Mastodon keeps them. Mastodon delivers a reply to the
followers of the account it answers; PrivaPub dropped those as unaddressed, which the pasture showed: the outsider's
reply its Mastodon scenario said was never delivered had been, and was thrown away.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
This commit is contained in:
thepraandClaude Opus 5.5 committed 2026-10-05 09:34:08 +02:00
1 parent 01808fa644
commit 7eb7c017a5
12 files changed
+334 -21

No files matched your search

@@ -61,6 +61,16 @@ namespace PrivaPub.Federation.Inbox
Record(job, payload, activity, type, started, new ArrivalVerdict(), Interactions.Deferred, "actor-unavailable");
return JobOutcome.Retry("the actor could not be loaded");
}
if (payload.ForwardedBy != default)
{
var (confirmed, drop) = await Forwarded.Confirm(activity, type, actor.ActorURI, _remoteActors, token);
if (drop != default)
{
Record(job, payload, activity, type, started, new ArrivalVerdict(), Interactions.Dropped, drop);
return JobOutcome.Done;
}
activity = confirmed;
}
var arrival = new Arrival(Id(activity), type, actor.ActorURI, payload.Inbox, payload.KeyId, payload.Algorithm,
payload.SignedHeaders ?? Array.Empty<string>(), payload.ReceivedAt ?? job.CreatedAt, activity["@context"]?.ToJsonString());