FEP-1580: Move Actor Objects with a `migration` Collection

Hey everyone, i see there is a FEP category, but i’m not allowed to make a new post there.

Actual draft needs some work, editing and a few open topics have already been raised, but opening this now since the shape of it is there.

let’s make full-on migration a reality, posts and all baby

Prior FEPs (FEP-7628, FEP-E965) describe an ability for an Actor to move to a new id, often hosted on a different server instance,
however they do not describe a mechanism for moving objects that belong[^belong] to that actor.

This FEP describes a mechanism of migrating objects belonging to a moved Actor to the target instance using two OrderedCollections created by the target instance:

  • a migration collection that contains a mapping from source object URIs to new URIs on the target instance, and
  • a moves collection that contains the actor Move activities that prove a migration has taken place and allows verification of object signatures in the case the source Actor is no longer available.

This FEP attempts to balance effectiveness, performance, security, and ease of implementation by allowing 3rd-party instances to gradually update their local copies of the affected Objects. “Push”-style migration where the source instance is still active and cooperative, “Pull”-style migration where the source instance is uncooperative or unavailable, and given appropriate proofs, migration from an exported collection of objects and activities are all described. The migration operation is agnostic to the type of the Objects being migrated, supporting protocol evolution to unanticipated Object types across instances with varying support for them. Collection-based object migration is orthogonal to, and compatible with content-addressed or other portable object schemes (e.g. FEP-ef61).

tl;dr: to migrate objects, create a mapping from the old to new objects on the target instance, and let 3rd-party instances gradually migrate their local representations using that map.

edit: shoutout to that moves collection design and how i’ve been totally bittorrent-brained for like 9 months and now think everything needs to have an infohash and be self-validating

1 Like

one thing that i think warrants some discussion is the handling of object updates during migration - i’m thinking of proof being one property that is almost certain to mutate when migrated, and other things like the uris for likes and reposts and etc. also should change. as written currently this would all be handled by asking the target instance for an updated version of the object after the URI is remapped, but it could also be done in the migration collection directly with an attached update activity. This would I think be the better implementation if server-to-server updates were partial updates, however server-to-server updates are always complete objects and partial updates are only spec’d for client-to-server interactions.

it is probably too much to also add an additional PartialUpdate activity to support server-to-server partial updates in this one FEP, but if we had something like that then it could look something like this:

{
  "id": "https://example.com/chuckTargetson/migration/page/0",
  "type": "OrderedCollectionPage",
  "partOf": "https://example.com/chuckTargetson/migration",
  "next": "https://example.com/chuckTargetson/migration/page/1",
  "items": [
    {
      "type": "Move",
      "actor": "https://source.example.com/barbaraSourceworth",
      "origin": "https://source.example.com/barbaraSourceworth/posts/12345",
      "target": "https://example.com/chuckTargetson/items/98765",
      "attachment": {
        "type": "PartialUpdate",
        "proof": {"...", "..."},
        "likes": "https://example.com/chuckTargetson/items/98765/likes",
        "...": "..."
      }
    },
  ]
}

Serializing the entire updated object in the migration collection would make that collection much more expensive to serialize, and part of the goal of the design with keeping it as just source->target mappings of URIs is to make that step very cheap so that the “main” part of migration could be done quickly (instances remapping objects to a new URI with a new owner) and then fully refreshing the object could be spaced out over a much longer period of time. so it’s sort of an empirical question of whether everyone hitting one bottleneck of enumerating a gigantic collection is faster or slower than everyone hitting a very cheap collection and coming back later to sip updates over a week.

The semantics of “move with update” are a little awkward but i think they’re correct (?) - activitypub specs Update as “update its copy of the object of the same id” and so explicitly forbids “moving” the object. Move is unspec’d by activitypub, and activitystreams has no detail aside from the description in the notes, which is very general, but the use here conforms to prior use from actor moves.