Fix per-app AP delivery, NULL uniqueness, and reverse discovery

- Delivery handler now signs/delivers using the per-app domain that
  matches the follower's subscription (not always federation domain)
- app_domain is NOT NULL with default 'federation' (sentinel replaces
  NULL to avoid uniqueness constraint edge case)
- Aggregate actor advertises per-app actors via alsoKnownAs
- Migration backfills existing NULL rows to 'federation'

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
giles
2026-02-23 19:25:24 +00:00
parent f2262f702b
commit 1bb19c96ed
9 changed files with 117 additions and 80 deletions

View File

@@ -144,7 +144,7 @@ async def handle_follow(
body: dict,
from_actor_url: str,
domain: str,
app_domain: str | None = None,
app_domain: str = "federation",
) -> None:
"""Process a Follow activity: add follower, send Accept, backfill."""
remote_actor = await fetch_remote_actor(from_actor_url)
@@ -204,8 +204,8 @@ async def handle_follow(
await send_accept(actor_row, body, follower_inbox, domain)
# Backfill: deliver recent posts (filtered by origin_app for per-app follows)
origin_app = app_domain if app_domain and app_domain != "federation" else None
await backfill_follower(session, actor_row, follower_inbox, domain, origin_app=origin_app)
backfill_origin = app_domain if app_domain != "federation" else None
await backfill_follower(session, actor_row, follower_inbox, domain, origin_app=backfill_origin)
async def handle_undo(
@@ -213,7 +213,7 @@ async def handle_undo(
actor_row: ActorProfile,
body: dict,
from_actor_url: str,
app_domain: str | None = None,
app_domain: str = "federation",
) -> None:
"""Process an Undo activity (typically Undo Follow)."""
inner = body.get("object")
@@ -485,7 +485,7 @@ async def dispatch_inbox_activity(
body: dict,
from_actor_url: str,
domain: str,
app_domain: str | None = None,
app_domain: str = "federation",
) -> None:
"""Route an inbox activity to the correct handler."""
activity_type = body.get("type", "")