Add external Activity delivery transport for companion stores#3548
Add external Activity delivery transport for companion stores#3548Jiwoon-Kim wants to merge 1 commit into
Conversation
|
Thanks for splitting this out and for asking the API-shape question directly — that makes this easy to answer honestly: I don't think we need either variant. Not a new The two capabilities you're missing are already available, just not where you looked:
So the composition boundary I'd suggest is one step to the left of where this PR draws it: the official plugin owns inbound validation and the signature implementation (both already exposed), and the companion owns everything keyed by its own domain model — including outbound spooling. There's also a concrete problem with the implementation as-is: the transport rows reuse the If there's an upstream change worth making here, it's documentation: the Closing the loop with #3541: this is the same pattern — the extension points you need keep turning out to already exist. That's a good sign for the composition approach, but it means the upstream diffs should be shrinking toward docs, not growing toward new APIs. |
|
Thank you. I moved the composition boundary exactly as suggested. The companion now owns a private I also removed all new In the current branch, the stock Dispatcher did not reach a second HTTP delivery because the experimental rows had The revised implementation passes the outbound suite against both the fork and unmodified ActivityPub 9.0.2, including real request signing, a single-job worker lock, URI idempotency, and proof that the stock Outbox query cannot discover a Bridge job. See Jiwoon-Kim/axismundi@ff959fe. This code PR is no longer needed, so I am closing it. I will prepare the much smaller documentation change for the existing |
Summary
This draft explores a supported outbound transport surface for companion plugins that own their own Actor, Object, Activity, and relationship stores.
It adds an opt-in
deliver_activity()API that accepts:actor_uri,key_id, and a non-secretprivate_key_ref); andThe official plugin remains responsible for the transport spool, transient key resolution, HTTP signatures, retries, and delivery. The caller remains authoritative for Activity and relationship state.
API shape question
Before treating this particular API as final, I would appreciate maintainer guidance on the smallest preferred extension shape.
The companion needs only two capabilities that the current Outbox API cannot express:
WP_UserID; andWould you prefer extending the existing
add_to_outbox()/Outbox::add()path to accept those two inputs instead of adding a separatedeliver_activity()entry point? Reusing the existing path would be welcome if it can preserve the external Actor identity and avoid deriving recipients from the official follower store.This draft uses a separate transport-only spool because the current path:
user_can_activitypub( $user_id );That makes a virtual Actor discoverable through the existing Actor filters, but it cannot send as the same URI-backed identity without creating duplicate domain state or a split signing identity.
Implementation
ap_outboxtransport row identified idempotently by Activity URI.activitypub_resolve_external_signing_identityduring the worker run.Reference composition and E2E
The reference implementation is the Axismundi ActivityPub Bridge 0.0.14 Alpha, together with:
A signed bidirectional Follow/Accept E2E passed against mastodon.social:
accepted.The staging Actor is @thaumiel999@designbusan.ai.kr.
Scope of the current E2E evidence is Follow/Accept. Like, Undo, shared-Inbox delivery, and Create delivery remain separate activity-level scenarios.
Validation
Relationship to #3541
#3541 addresses selective module initialization and the inbound composition side. This draft is independent of that branch and contains only the outbound transport surface.
Refs #3533