Skip to content

Note

このドキュメントは2026-02-27 03:19PLaMo Translation Modelを使用して自動翻訳されました。

FEP-7458: repliesコレクションの適切な使用方法について

概要

ActivityPub仕様では、inReplyTo属性が設定されたオブジェクトやアクティビティを単に「発見した」場合に生じる副作用は定義されていません。現在主流の実装では、消費時に暗黙的に返信関係を再構成しており、制作者側では明示的にはrepliesコレクションを維持しないケースが一般的です。このFEPは、repliesコレクションを明確に活用し、その管理方法を具体的に規定することを目的としています。

問題提起

(本セクションは規範的ではない記述です)

ActivityPub仕様では、アクティビティに対する副作用は定義されているものの、オブジェクトを発見した際に発生する副作用については明示されていません。ソーシャルウェブにおいて一般的なユースケースとして、自身のオブジェクトで他のオブジェクトに返信する場合がありますが、これは当該オブジェクトが元のオブジェクトへの応答であることを示しています。しかし、ほとんどの実装ではこの「返信」関係をそこまで厳密に管理していません。一般的には、オブジェクトが他のサーバーへ送信される際にはCreateアクティビティを介して行われ、そのCreateアクティビティの対象オブジェクトはキャッシュされ、何らかの形で「返信」関係が追跡・関連付けられると想定されています。ActivityPub仕様で「replies」について言及されている箇所は、『ゴーストリプライ』問題を回避するための受信箱転送機能に関する記述のみです。ここから推測されるのは、送信者は事前にすべての関係者に適切に対処することが慣習として求められているという点です。

現在欠けているのは、事後的な暗黙的再構築に依存するのではなく、制作者自身が管理する返信関係の正統性と権限を明示的に認識・管理する仕組みです。FEP-5624はこの問題に対し、事後的な暗黙的再構築をさらに強化する別アプローチを提案しています。

一方、FEP-7888では、会話を管理するアクターの正統性と権限を明示的に認識・管理する類似の仕組みが規定されています。これはやはり、事後的な暗黙的再構築に依存するのではなく、AddアクティビティとRemoveアクティビティに基づく明示的な構築方法を採用しています。本FEPは、repliesコレクションの明示的な管理をサポートしつつ、contextの使用とは独立した形で記述することを目的としています。つまり、作成者アクターはメタデータとしてinReplyTo属性を使用する選択肢を持ちながら、同時にcontextへの参加の有無を個別に選択できるということです。

具体的な処理フロー例

(本セクションは規範的ではない記述です)

アリスが投稿を行います:

{
    "@context": "https://www.w3.org/ns/activitystreams",
    "id": "https://alice.example/outbox/1",
    "summary": "Alice created a note",
    "actor": "https://alice.example",
    "type": "Create",
    "object": {
        "id": "https://alice.example/objects/1",
        "type": "Note",
        "content": "Hello",
        "replies": "https://alice.example/objects/1/replies"
    },
    "cc": ["https://alice.example/followers", "as:Public"]
}

ボブが返信を行います:

{
    "@context": "https://www.w3.org/ns/activitystreams",
    "id": "https://bob.example/outbox/2",
    "summary": "Bob replied to Alice's note",
    "actor": "https://bob.example",
    "type": "Create",
    "object": {
        "id": "https://bob.example/objects/2",
        "type": "Note",
        "content": "Hi!",
        "inReplyTo": "https://alice.example/objects/1"
    },
    "to": "https://alice.example",
    "cc": ["https://alice.example/followers", "https://bob.example/followers"]
}

アリスはボブの返信を明示的に承認します(自動的または手動による承認)。アリスはボブからの依頼に従い、このアクティビティを自身のフォロワーに転送します。さらにアリスは、ボブの返信をrepliesコレクションに追加します:

{
    "@context": "https://www.w3.org/ns/activitystreams",
    "id": "https://alice.example/outbox/3",
    "summary": "Alice added Bob's note as a reply",
    "actor": "https://alice.example",
    "type": "Add",
    "object": "https://bob.example/objects/2",
    "target": "https://alice.example/objects/1/replies",
    "to": "https://bob.example",
    "cc": ["https://alice.example/followers", "https://bob.example/followers"]
}

ボブはこの更新を確認し、元の返信内容を悪意のある内容に修正します:

{
    "@context": "https://www.w3.org/ns/activitystreams",
    "id": "https://bob.example/outbox/4",
    "summary": "Bob updated a note",
    "actor": "https://bob.example",
    "type": "Update",
    "object": {
        "id": "https://bob.example/objects/2",
        "type": "Note",
        "content": "Alice sucks lol",
        "inReplyTo": "https://alice.example/objects/1"
    },
    "to": "https://alice.example",
    "cc": ["https://alice.example/followers", "https://bob.example/followers"]
}

アリスはこの更新を自動的に転送するか、あるいは手動で確認します。その後、アリスは返信が編集されたことに気づきます。そこでアリスは最終的にこの返信を削除することを決定します:

{
    "@context": "https://www.w3.org/ns/activitystreams",
    "id": "https://alice.example/outbox/5",
    "summary": "Alice removed a reply",
    "actor": "https://alice.example",
    "type": "Remove",
    "object": "https://bob.example/objects/2",
    "target": "https://alice.example/objects/1/replies",
    "to": "https://bob.example",
    "cc": ["https://alice.example/followers", "https://bob.example/followers"]
}

ボブはこの削除アクティビティを悪意を持って転送しないことを選択します。

チャーリーはボブをフォローしていますが、アリスはフォローしていません。チャーリーのクライアントは、チャーリーの受信箱にアクティビティ2、3、および4を取得しています。

現行の動作では、チャーリーはアリスの投稿を取得するものの、アリスのrepliesコレクションを確認したりその機能を利用したりしません。ボブの返信はそのままアリスの投稿への応答として表示され続けます。

提案されている動作では、チャーリーはまずアリスのrepliesコレクションを確認することになります。アリスが自身の返信を削除しているため、このコレクションにはボブの返信は含まれません。したがって、チャーリーはボブの返信を正式な返信として認識・処理することはありません。

行動要件

  • inReplyTo属性が設定されたオブジェクトに遭遇した場合、ActivityPubクライアントは以下の検証を行うべきです:現在のオブジェクトが実際にinReplyTo.repliesコレクションの有効なメンバーであることを確認すること。(さらなるFEPによって、コレクション全体を参照することなくこの検証を証明できる仕組みが提供される可能性があります。)
    • もし現在のオブジェクトが返信コレクションに存在しない場合、ActivityPubクライアントはこの返信を確認済みとしてマークしないか、あるいはキャッシュされた返信を提示する際に完全に非表示にする選択肢があります。
  • inReplyTo属性が自身のアクターを指すオブジェクトを含むアクティビティまたはその対象オブジェクトに遭遇した場合、ActivityPubアクターは以下のプロパティを持つアクティビティを送信する必要があります:
    • type配列には必ずAddを含めること
    • objectにはinReplyToを宣言しているオブジェクトを指定すること
    • targetには自身のオブジェクトのrepliesコレクションを指定すること
    • このアクティビティの宛先指定プロパティには、object.attributedToアクター、およびその他の指定されたアクター(自身のfollowersや他のaudienceなど)に加えて、そのアクターのfollowersも含めるべきです
  • ActivityPubアクターは以下のプロパティを持つアクティビティを送信することで、自身が所有するrepliesコレクションからオブジェクトを削除したことを通知すべきです:
    • type配列には必ずRemoveを含めること
    • objectにはinReplyToを宣言しているオブジェクトを指定すること
    • targetには自身のオブジェクトのrepliesコレクションを指定すること
    • このアクティビティの宛先指定プロパティには、object.attributedToアクター、およびその他の指定されたアクター(自身のfollowersや他のaudienceなど)に加えて、そのアクターのfollowersも含めるべきです

参考文献

著作権

CC0 1.0 Universal(CC0 1.0)パブリックドメイン献呈

法律で認められる範囲において、このFediverse Enhancement Proposalの著者らは、本著作物に関するすべての著作権および関連する権利を放棄しています。