A deleted post's id given to a new post is that new post

PrivaPub remembers a deleted remote post's id for 90 days so that a late Create cannot bring it back. Gancio numbers a
new event after the last one it keeps, so deleting its last event gives the next the same id, and that event was
dropped as deleted. A Create published after the deletion is now kept as the new post; the deleted one's own Create,
however late, still is not. Checked live: Gancio's scenario passes again (17 checks).

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-06 16:29:21 +02:00
1 parent af2c61292b
commit cb34ab88f7
4 files changed
+78 -4

No files matched your search

@@ -118,10 +118,17 @@ namespace PrivaPub.Federation.Inbox.Handlers
Arrival.Drop("duplicate");
return;
}
if (await DB.Default.Find<DeletedObject>().Match(d => d.ObjectURI == note.Id).ExecuteAnyAsync(token))
// a deleted post stays deleted however late or often its Create comes; but an id its server gives a new post again
// (Gancio numbers an event after the last one it keeps, so a deleted last event's id comes back), published after
// the deletion, is that new post
if (await DB.Default.Find<DeletedObject>().Match(d => d.ObjectURI == note.Id).ExecuteFirstAsync(token) is { } tombstone)
{
Arrival.Drop("deleted");
return;
if (Value(note.Raw, "published") == default || note.Published <= tombstone.DeletedAt)
{
Arrival.Drop("deleted");
return;
}
await DB.Default.DeleteAsync<DeletedObject>(tombstone.ID);
}
var to = note.To.Concat(Strings(activity["to"])).Distinct(StringComparer.Ordinal).ToList();